用上這個工具包,大模型推理性能加速達40倍

英特爾®Extension for Transformer是什麼?

英特爾® Extension for Transformers[1]是英特爾推出的一個創新工具包,可基於英特爾®架構平臺,尤其是第四代英特爾® 至強®可擴展處理器(代號Sapphire Rapids[2],SPR)顯著加速基於Transformer的大語言模型(Large Language Model,LLM)。其主要特性包括:

本文將重點介紹其中的LLM推理運行時(簡稱爲“LLM運行時”),以及如何利用基於Transformer的API在英特爾® 至強®可擴展處理器上實現更高效的LLM推理和如何應對LLM在聊天場景中的應用難題。

LLM運行時(LLM Runtime)

英特爾®Extension for Transformers提供的LLM Runtime[8]是一種輕量級但高效的LLM推理運行時,其靈感源於GGML[9],且與llama.cpp[10]兼容,具有如下特性:

LLM Runtime的簡化架構圖如下:

△圖1.英特爾® Extension for Transformers的LLM Runtime簡化架構圖

只需不到9行代碼,即可讓您在CPU上實現更出色的LLM推理性能。用戶可以輕鬆地啓用與Transformer類似的API來進行量化和推理。只需將 ‘load_in_4bit’設爲true,然後從HuggingFace URL或本地路徑輸入模型即可。

性能測試

經過持續努力,上述優化方案的INT4性能得到了顯著提升。本文在搭載英特爾® 至強®鉑金8480+的系統上與llama.cpp進行了性能比較;系統配置詳情如下:@3.8GHz,56核/路,啓用超線程,啓用睿頻,總內存 256 GB (16 x 16 GB DDR5 4800 MT/s [4800 MT/s]),BIOS 3A14.TEL2P1,微代碼0x2b0001b0,CentOS Stream 8。

當輸入大小爲32、輸出大小爲32、beam爲1時的推理性能測試結果,詳見下表:

△表1.LLM Runtime與llama.cpp推理性能比較(輸入大小=32,輸出大小=32,beam=1)

輸入大小爲1024、輸出大小爲32、beam爲1時的推理性能的測試結果,詳見下表:

△表2.LLM Runtime與llama.cpp推理性能比較(輸入大小=1024,輸出大小=32,beam=1)

根據上表2可見:與同樣運行在第四代英特爾® 至強®可擴展處理器上的llama.cpp相比,無論是首個token還是下一個token,LLM Runtime都能顯著降低時延,且首個token和下一個token的推理速度分別提升多達 40 倍[a](Baichuan-13B,輸入爲1024)和2.68倍[b](MPT-7B,輸入爲1024)。llama.cpp的測試採用的是默認代碼庫[10]。

而綜合表1和表2的測試結果,可得:與同樣運行在第四代英特爾® 至強®可擴展處理器上的llama.cpp相比,LLM Runtime能顯著提升諸多常見LLM的整體性能:在輸入大小爲1024時,實現3.58到21.5倍的提升;在輸入大小爲32時,實現1.76到3.43倍的提升[c]。

準確性測試

英特爾®Extension for Transformers可利用英特爾®Neural Compressor中的SignRound[11]、RTN和GPTQ[12]等量化方法,並使用lambada_openai、piqa、winogrande和hellaswag數據集驗證了 INT4 推理準確性。下表是測試結果平均值與FP32準確性的比較。

△表3.INT4與FP32準確性對比

從上表3可以看出,多個模型基於LLM Runtime進行的INT4推理準確性損失微小,幾乎可以忽略不記。我們驗證了很多模型,但由於篇幅限制此處僅羅列了部分內容。如您欲瞭解更多信息或細節,請訪問此鏈接:https://medium.com/@NeuralCompressor/llm-performance-of-intel-extension-for-transformers-f7d061556176。

更先進的功能:滿足LLM更多場景應用需求

同時,LLM Runtime[8]還具備雙路CPU的張量並行化功能,是較早具備此類功能的產品之一。未來,還會進一步支持雙節點。

然而,LLM Runtime的優勢不僅在於其更出色的性能和準確性,我們也投入了大量的精力來增強其在聊天應用場景中的功能,並且解決了LLM 在聊天場景中可能會遇到的以下應用難題:

關於第一個問題,LLM Runtime的對話功能通過納入更多對話歷史數據以及生成更多輸出加以解決,而llama.cpp目前尚未能很好地應對這一問題。

關於第二和第三個問題,我們將流式LLM(Steaming LLM)集成到英特爾®Extension for Transformers中,從而能顯著優化內存使用並降低推理時延。

Streaming LLM

與傳統KV緩存算法不同,我們的方法結合了注意力匯聚(Attention Sink)(4個初始token)以提升注意力計算的穩定性,並藉助滾動KV緩存保留最新的token,這對語言建模至關重要。該設計具有強大的靈活性,可無縫集成到能夠利用旋轉位置編碼RoPE和相對位置編碼ALiBi的自迴歸語言模型中。

△圖2.Steaming LLM的KV緩存(圖片來源:通過注意力下沉實現高效流式語言模型[13])

此外,與llama.cpp不同,本優化方案還引入了“n_keep”和“n_discard”等參數來增強Streaming LLM策略。用戶可使用前者來指定要在KV緩存中保留的token數量,並使用後者來確定在已生成的token中要捨棄的數量。爲了更好地平衡性能和準確性,系統默認在KV緩存中捨棄一半的最新token。

同時,爲進一步提高性能,我們還將Streaming LLM添加到了MHA融合模式中。如果模型是採用旋轉位置編碼(RoPE)來實現位置嵌入,那麼只需針對現有的K-Cache應用“移位運算(shift operation)”,即可避免對先前生成的、未被捨棄的token進行重複計算。這一方法不僅充分利用了長文本生成時的完整上下文大小,還能在KV緩存上下文完全被填滿前不產生額外開銷。

“shift operation”依賴於旋轉的交換性和關聯性,或複數乘法。例如:如果某個token的K-張量初始放置位置爲m並且旋轉了m×θifor i ∈ [0,d/2),那麼當它需要移動到m-1這個位置時,則可以旋轉回到(-1)×θi for i ∈ [0,d/2)。這正是每次捨棄n_discard個token的緩存時發生的事情,而此時剩餘的每個token都需要“移動”n_discard個位置。下圖以“n_keep=4、n_ctx=16、n_discard=1”爲例,展示了這一過程。

△圖3.Ring-Buffer KV-Cache和Shift-RoPE工作原理

需要注意的是:融合注意力層無需瞭解上述過程。如果對K-cache和V-cache進行相同的洗牌,注意力層會輸出幾乎相同的結果(可能存在因浮點誤差導致的微小差異)。

結論與展望

本文基於上述實踐經驗,提供了一個在英特爾® 至強®可擴展處理器上實現高效的低位(INT4)LLM推理的解決方案,並且在一系列常見LLM上驗證了其通用性以及展現了其相對於其他基於CPU的開源解決方案的性能優勢。未來,我們還將進一步提升CPU張量庫和跨節點並行性能。

歡迎您試用英特爾®Extension for Transformers[1],並在英特爾®平臺上更高效地運行LLM推理!也歡迎您向代碼倉庫(repository)提交修改請求 (pull request)、問題或疑問。期待您的反饋!

特別緻謝

在此致謝爲此篇文章做出貢獻的英特爾公司人工智能資深經理張瀚文及工程師許震中、餘振滔、劉振衛、丁藝、王哲、劉宇澄。

[a]根據表2 Baichuan-13B的首個token測試結果計算而得。[b]根據表2 MPT-7B的下一個token測試結果計算而得。[c]當輸入大小爲1024時,整體性能=首個token性能+1023下一個token性能;當輸入大小爲32時,整體性能=首個token性能+31下一個token性能。