LLM 推論為何常卡在 decode 階段?
簡短答案
因為 decode 階段一次通常只產生一個 token,但每一步仍要讀取大量模型權重與 KV Cache。因此 GPU 計算單元可能不是忙著算,而是在等資料從記憶體搬過來,形成 記憶體頻寬瓶頸。
初學者理解
可以把 LLM 推論想成逐字寫文章:
看 prompt → 想下一個字 → 寫出一個 token → 再把這個 token 放回上下文 → 再想下一個 token問題是每想一個 token,都要查很多模型權重與過去上下文資訊。生成越長,KV Cache 越大,VRAM 壓力也越高。
Prefill 和 decode 的差異
- Prefill:一次讀入 prompt,較容易平行化。
- Decode:逐 token 生成,順序性強,容易被記憶體頻寬、KV Cache 與 latency 限制。
常見緩解方法
- 量化:減少權重與 cache 大小。
- continuous batching:讓多個請求一起提高吞吐。
- FlashAttention / PagedAttention:改善 attention 與 KV Cache 管理。
- KV Cache offload / compression:用較低成本容量層分擔 VRAM 壓力。
Caveat
不同 workload 的瓶頸不同。短 prompt、大 batch 的 prefill 可能更 compute-heavy;長上下文、低 batch、互動式回覆則更容易 decode-bound 或 memory-bandwidth-bound。
解法補充
新來源補充 decode 階段瓶頸的解法:量化減少讀取資料量,PagedAttention 降低 KV Cache 浪費,offload 擴大有效容量,推測解碼嘗試一次接受多個 token,continuous batching 提高 GPU utilization。