不只是模型優化:LLM 推理效能的系統工程思維

LLM 推理效能的瓶頸,往往不在模型壓縮或硬體升級,而是其獨特的兩階段運算:Prefill 與 Decode。當我們將推理視為一個系統工程問題,拆解並針對這兩個特性截然不同的階段進行分離、快取與智慧調度,就能有效釋放硬體潛力,實現數量級的吞吐量提升。這不僅是技術優化,更是從模型中心轉向「推理系統工程」的思維躍遷,是打造高效能、高資源利用率 AI 服務的關鍵。

不只是模型優化:LLM 推理效能的系統工程思維

許多團隊在優化大型語言模型(LLM)推理效能時,常將焦點放在模型壓縮、量化或硬體升級。然而,我的觀察是,真正能拉開差距、實現數量級吞吐量提升的關鍵,往往不在模型本身,而在於對整個推理(inference)執行路徑的系統化工程。核心在於,我們必須停止將 LLM 推理視為一個單一的黑箱運算,而是要深刻理解其內部的兩個核心階段——Prefill 與 Decode——並針對它們截然不同的運算特性進行分離、快取與智慧調度。這是一種從模型優化轉向「推理系統工程」(inference systems engineering)的思維躍遷,也是打造高效能、高資源利用率 AI 服務的決勝點。

為什麼 LLM 推理的效能瓶頸,往往不在模型本身?

要理解這個問題,我們必須先拆解一個 LLM 生成回應時的內部工作流程。自迴歸(Autoregressive)模型的生成過程,本質上可以分為兩個非常不同的階段:

首先是Prefill(或稱 Prompt Processing / Encoding)階段,負責處理使用者輸入(prompt)。模型會一次性地、並行地處理整個輸入序列,計算出所有 token 的 key-value (KV) states。這個階段的特性是運算密集(Compute-bound),能充分利用 GPU 的並行運算能力,但通常只佔整個生成過程的一小部分時間。

接著是Decode(或稱 Decoding / Generation)階段。在 Prefill 完成後,模型進入逐字生成,一次只生成一個 token,並將其加到序列中進行下一次預測。這個過程是循序的、記憶體頻寬密集(Memory-bound)。每一步都依賴前一步結果,無法並行,且需反覆讀寫巨大的 KV Cache。這也解釋了為何 LLM 生成文字時,會一個字一個字跳出。

這兩個階段的運算特徵天差地遠。Prefill 像短跑衝刺,瞬間需要大量計算資源;Decode 像馬拉松,每一步計算量不大,但步數極多,且持續對記憶體頻寬造成壓力。傳統的推理服務框架,如 FasterTransformer 或 DeepSpeed Inference,常將兩者綑綁處理,導致嚴重的資源浪費:在執行 Decode 階段時,大量為並行運算設計的計算單元處於閒置狀態,而在處理長的 Prefill request 時,又可能阻塞住許多短的 Decode request。

Prefill 與 Decode 分離,如何開啟系統化優化的大門?

既然這兩個階段的特性如此不同,最直觀的優化思路就是將它們徹底分開,並由一個更高層的排程器(scheduler)來管理。這就是所謂的「Prefill/Decode 分離」(P/D Separation)。這個概念讓推理系統可以將 Prefill 和 Decode 任務視為不同種類的工作,並將它們分配到最適配的硬體資源上,甚至在同一個 GPU 上進行更智慧的時分複用。

例如,系統可以將多個使用者的 Prefill 請求組合成一個大的批次(batch),一次性在 GPU 上完成運算,最大化計算單元的利用率。而對於大量的 Decode 請求,系統則可以採用持續批處理(continuous batching)等策略,動態地將已經完成 Prefill 的請求加入到 Decode 批次中,避免 GPU 因為等待最慢的請求完成而閒置。

像是 vLLM 這個高效能的 LLM 推理服務框架,其核心創新之一就是基於 PagedAttention 機制,實現了對 KV Cache 的精細化記憶體管理,這也為 P/D 分離與更靈活的排程策略打下了基礎。實驗證明,這類架構的吞吐量相較於傳統的靜態批處理(static batching)方式,可以提升 2-4 倍之多。

如何透過快取與排程,最大化硬體利用率?

僅僅分離 Prefill 和 Decode 還不夠,真正的魔鬼藏在細節裡,也就是如何管理它們共享的狀態——KV Cache。KV Cache 儲存了 prompt 和已生成 token 的注意力計算結果,是避免重複運算的關鍵,但它也非常佔用 GPU 記憶體,動輒數 GB 甚至數十 GB。

一個進階的作法是建立一個獨立的、跨請求的 KV Cache 服務,或稱「LMCache」。最近一篇由 Toshihiko Fukuyama 撰寫的實作指南,就探討了如何利用 AWS 的基礎設施(如 EKS、S3、ElastiCache for Redis)來建構一個具備 P/D 分離和外部 LMCache 的實驗環境。

其核心思想是將Prefill 節點專門用於處理輸入 prompt,計算出初始的 KV Cache,並將其寫入外部快取服務(如 Redis)。而Decode 節點則從佇列中接收任務,從外部快取讀取對應的 KV Cache,然後開始逐字生成,每生成一個新 token,就更新 KV Cache 並寫回。

外部化 KV Cache,能帶來哪些實際效益?

這種外部化 KV Cache 的架構,為 LLM 推理服務帶來了幾個顯著的好處。首先,計算節點變得狀態無關:Prefill 和 Decode 節點本身不儲存長期的 KV Cache 狀態,這意味著它們可以被輕易地擴展、縮減或替換,大幅提升了系統的彈性與容錯能力。

其次是跨請求的快取重用。如果多個使用者請求有相同的前綴(例如,使用了同一個系統提示或進行 RAG 的相同文件上下文),外部化的 LMCache 可以直接重用已經計算好的 KV states,省去大量重複的 Prefill 運算。根據 Microsoft 的 Orca 系統研究,有效的快取策略可以將平均延遲降低 30% 以上。

最後,它也實現了異構硬體部署的彈性。我們可以為運算密集的 Prefill 任務分配具備高計算能力的 GPU(如 NVIDIA H100),而為記憶體頻寬密集的 Decode 任務分配另一種更具成本效益的硬體,實現更精細的資源配置與成本優化。

最終,LLM 推理效能的優化,是一場關於「流程」與「狀態」的戰爭。我們需要將運算流程(Prefill/Decode)拆分到極致,同時將共享狀態(KV Cache)管理得足夠高效與通用。

當然,這樣的架構也帶來了新的複雜性,例如網路延遲、快取一致性、以及更複雜的排程邏輯。它未必適用於所有場景,尤其是在單一使用者、低延遲需求的應用中。然而,對於需要服務大量併發使用者、追求最大吞吐量與資源利用率的場景(如公有雲 API 服務、大型企業內部平台),這種系統工程的思維方式,才是通往規模化、可持續營運的正確道路。我們需要思考的不再只是單一請求如何跑得更快,而是整個系統在負載下的整體表現如何最佳化。

延伸閱讀

我是江中喬,專注於 AI Agent Architecture、Memory Governance 與 Cognitive Diversity,持續研究如何打造能夠長期協作、可信任且可治理的 AI 系統。