核心概念
這篇 Hugging Face 技術部落格(2026 年 5 月 14 日)是「高效 LLM 推論」系列第二篇,聚焦一個無需修改模型或 kernel、卻能帶來約 22% 加速的優化:讓 CPU 和 GPU 同時工作,而不是輪流等待。
同步推論的隱性浪費
在標準的連續批次(Continuous Batching)推論中,每個 step 是串行的:
- CPU 準備批次輸入(選請求、更新 KV cache、建立張量)
- CPU 將資料搬到 GPU(H2D 傳輸)
- GPU 執行前向傳播(forward pass)
- GPU 將結果送回 CPU(D2H 傳輸)
- CPU 讀取結果,進入下一輪
問題在於:GPU 計算時 CPU 閒置;CPU 準備下一批次時 GPU 閒置。在每秒數百個 step 的推論迴圈中,空檔累積成真實損失。
作者實測(8B 模型、batch size 32、生成 8K tokens):GPU 有 24% 的時間處於閒置。理論上若能消除 CPU 開銷,生成時間可從 300.6 秒降至 228 秒,完全不需動模型。
CUDA 串流:建立並行通道
核心工具是 CUDA 串流(CUDA Streams)。同一串流內的操作依序執行,不同串流的操作可並行執行。
PyTorch 預設使用「default stream」,具同步特性:任何進入 default stream 的操作都必須等所有串流完成才能啟動——這等同於強制串行,破壞並行化。
非同步批次推論需要三條非默認串流:
- H2D 串流:CPU → GPU 資料搬運
- Compute 串流:GPU 前向傳播
- D2H 串流:GPU → CPU 結果回傳
使用非默認串流的關鍵:enqueue 操作後控制權立即返回 CPU,GPU 在背景執行,CPU 不等待。
CUDA 事件:跨串流依賴管理
僅有串流不夠——若三條串流完全獨立,Compute 串流可能在 H2D 尚未完成時就啟動前向傳播,讀到垃圾資料。
**CUDA 事件(Events)**解決跨串流依賴:
stream.record(event):在串流當前位置插入標記,GPU 執行到此時將事件設為「完成」stream.wait(event):讓串流暫停直到事件完成,但 CPU 呼叫立即返回(只有等待的串流被保留)
如此,CPU 可快速連續 enqueue 所有 GPU 工作(H2D → record/wait → Compute → record/wait → D2H),然後自由去準備下一批次;GPU 依事件自行協調執行順序,完全不需 CPU 持續介入。
關鍵要點
-
雙緩衝區防止 Race Condition:Batch N 與 N+1 不能共用同一組裝置端輸入緩衝區(GPU 還在讀 N 的輸入,CPU 就在寫 N+1 的),解法是兩組張量交替(Slot A / Slot B),代價是 RAM 與 VRAM 加倍
-
CUDA Graph 記憶體池:CUDA Graph 預錄操作序列並綁定特定記憶體地址,兩個 slot 需要兩個 graph。使用共享記憶體池讓兩個 graph 共用記憶體,因為 N 和 N+1 永遠不同時執行,總 VRAM 幾乎與一個 graph 相同
-
Carry-over 機制:準備 Batch N+1 的輸入時,Batch N 的輸出 token 還不存在(N 尚未執行)。解法是以 0 為佔位符,N 完成後在啟動 N+1 的 Compute 之前執行輕量的「carry-over」步驟(選取 N 的輸出 token → 加回 N+1 的輸入),整個步驟被納入 CUDA Graph capture,開銷可忽略
-
唯一的 CPU 阻塞點:整個非同步迴圈只有一次
d2h_done_event.synchronize()——CPU 讀取 Batch N 的結果、調度 Batch N+2。這個等待幾乎無法消除,但因模型計算遠比 CPU 調度耗時,通常不構成瓶頸 -
實測結果:GPU 利用率從 76.0% 提升至 99.4%;生成時間從 300.6 秒降至 234.5 秒(22% 加速)。比理論最大值 24% 少 2%,差距正是那個無法消除的同步點
實務應用
這項優化已實作於 transformers 函式庫,入口在 continuous_batching.py,非同步邏輯集中在 ContinuousBatchingAsyncIOs 類別。
最適場景是長序列生成(16K+ tokens),尤其是強化學習訓練(RLHF / GRPO)——因為生成步驟越多,CPU 閒置時間累積越顯著。
實施成本:RAM/VRAM 約 2 倍(雙緩衝區;CUDA Graph 記憶體池可緩解 VRAM 問題);程式複雜度顯著增加(需管理串流、事件、雙 slot、carry-over 邏輯)。
核心前提:GPU compute 必須是瓶頸(幾乎對所有現代大型模型成立),否則消除 CPU 開銷無效。vLLM 等主流推論框架也採用類似非同步設計,這篇文章提供從第一原理出發的系統性說明,有助於理解框架底層機制。
Hugging Face 推論供應商生態系:DeepInfra 整合實錄 vLLM V0 升級 V1:強化學習訓練的後端正確性優先原則
延伸觀點
來源:arxiv.org/abs/2504.06319(KV Cache 非同步預取)、blog.vllm.ai/2025/09/05(vLLM 架構剖析)
記憶體搬運才是 LLM 推論最深層的瓶頸。HF 的非同步批次處理解決的是 CPU 批次準備與 GPU 計算的串行問題;arxiv 的研究則指向更底層:即使 GPU 已在計算,HBM(GPU 高頻寬記憶體)載入 KV Cache 的延遲仍在卡住注意力計算。兩篇研究的解法同出一轍——利用空閒的硬體資源提前搬運資料:HF 用 CPU 空閒時間準備下一批次,arxiv 用矩陣乘法期間的閒置記憶體頻寬將 KV Cache 預取到 L2 快取。兩種優化正交,可以疊加。
vLLM 的架構印證了「積木式組合」的設計哲學。vLLM 在連續批次的基礎上,疊加了 PagedAttention(KV Cache 分頁管理)、前綴快取(共同前綴復用)、投機解碼(輕量草稿模型批量提議 token)等多層優化。這與 HF 文章描述的非同步批次同屬「不改模型架構,純粹從調度與記憶體管理挖效率」的思路——每一層優化都針對不同的閒置資源(CPU 時間、記憶體頻寬、重複 KV 計算)。
長序列是所有這些優化最有價值的場景。兩篇文章都明確指出 16K+ token 生成的重要性:序列越長,每次 decode 步驟的 KV Cache 越大,HBM 延遲累積越顯著,CPU 批次準備相對 GPU 計算的比例也越低。強化學習訓練(RLHF/GRPO)是典型受益場景。
反向連結
以下頁面引用了本頁: