目錄
如果你用過 ChatGPT 或任何基於 Transformer 的語言模型,KV Cache 就是讓回應速度「可接受」的關鍵技術。沒有它,模型每生成一個字就要重算所有前面的字的注意力——對長文本來說計算量會以二次方爆炸。這篇文章解釋 KV Cache 是什麼、為什麼有效、以及現代 LLM 如何在記憶體限制下繼續優化它。
TL;DR
KV Cache 在 Transformer 的 self-attention 計算中,把前面所有 token 的 Key 和 Value 矩陣儲存起來,讓每一個新 token 只需計算自己的 KQ 查詢,然後從快取中讀取歷史的 KV 進行注意力計算。這把自回歸生成的時間複雜度從 O(n²) 降到 O(n),代價是記憶體佔用隨序列長度線性成長——這在長文本推論時會成為 GPU 記憶體瓶頸。
設計哲學
理解 KV Cache 需要先理解 Transformer 的 self-attention 是怎麼做的。
對輸入序列中的每個 token,self-attention 計算三個向量:
- Query (Q):「我想查什麼?」
- Key (K):「我有什麼可以被查?」
- Value (V):「如果查到我,回傳什麼?」
注意力分數是 Q 和每個 K 做點積,softmax 後加權對 V 求和:
Attention(Q, K, V) = softmax(QK^T / √d_k) × V
在自回歸生成(autoregressive generation)模式下,模型一次生成一個 token,生成第 n 個 token 時,它的 Q 要跟前面所有 n-1 個 token 的 K 做點積。如果不快取,每生成一個 token 就要重新計算所有之前 token 的 K 和 V——這就是 O(n²) 問題的來源。
KV Cache 的解法簡單直接:計算過的 K 和 V 就存著,下次直接讀。每個新 token 只需計算自己的 Q、K、V,然後把新的 K、V 拼接到快取裡,再用 Q 查整個快取。
核心概念
快取結構
生成第 t 個 token 時:
KV Cache = { K_1, K_2, ..., K_{t-1},
V_1, V_2, ..., V_{t-1} }
步驟:
1. 計算當前 token 的 Q_t, K_t, V_t
2. 把 K_t 加到 KV Cache → K_1...K_t
3. 把 V_t 加到 KV Cache → V_1...V_t
4. Attention(Q_t, [K_1...K_t], [V_1...V_t]) → 輸出
這樣每個 token 的計算量是 O(n)(對快取中所有 K/V 做點積),生成整個長度 n 的序列的總計算量是 O(n²),但攤分到每個 token 是 O(n),避免了重複計算。
記憶體佔用
KV Cache 的記憶體佔用計算如下:
KV Cache 大小 = 2 × n_layers × n_heads × d_head × seq_len × bytes_per_element
以 Llama 3.1 8B 為例(32 層,32 個 KQ head,128 維度,float16):
- 每個 token 佔用:2 × 32 × 32 × 128 × 2 bytes = 524,288 bytes ≈ 0.5 MB
- 128K 上下文長度的快取:128K × 0.5 MB = 64 GB
這就是為什麼在長文本推論下,KV Cache 會把 GPU 記憶體塞滿。一個 A100(80GB 顯存)跑 128K 上下文的 8B 模型,光快取就要 64GB,幾乎沒空間放模型權重了。
Prefill 與 Decode 兩個階段
LLM 推論分兩個階段:
Prefill(預填充):把整個輸入 prompt 一次性計算,建立初始 KV Cache。這個階段計算密集,GPU 使用率高。
Decode(解碼):每次生成一個 token,從 KV Cache 讀取歷史 KV,計算量相對小,但受限於記憶體頻寬(從 GPU HBM 讀取大量快取)。在長序列下,decode 階段的瓶頸是記憶體頻寬而非算力。
跟常見替代方案比較
| 方案 | 優點 | 缺點 | 適用情境 |
|---|---|---|---|
| 完整 KV Cache | 實作最簡單、速度最快 | 記憶體隨序列線性增長 | 短到中等序列 |
| Multi-Query Attention (MQA) | KV 快取縮小 n_heads 倍 | 模型需要重新訓練 | 推論延遲敏感場景 |
| Grouped-Query Attention (GQA) | 平衡 MHA 品質和 MQA 效率 | 同樣需重新訓練 | Llama 3、Mistral 等現代模型 |
| Multi-head Latent Attention (MLA) | 快取壓縮至低維隱空間 | 推論時需要額外投影 | DeepSeek V3 |
| 滑動視窗注意力 | O(w×n) 而非 O(n²) | 失去遠距離依存 | Mistral 的部分層 |
| KV Cache 淘汰(Eviction) | 控制記憶體上限 | 可能丟失重要 token | MorphKV 等研究 |
GQA(Grouped-Query Attention) 是目前最廣泛採用的優化。以 Llama 3.1 為例,它把 32 個 Query head 分成 8 組,每組共用一組 KV,KV Cache 大小降為原來的 1/4。效能損失小,但記憶體節省顯著。
MLA(Multi-head Latent Attention) 是 DeepSeek V2/V3 的創新。它把 K 和 V 投影到低維的隱向量(latent vector),快取這個壓縮後的表示,推論時再展開。理論上快取大小可降低 5-13 倍,但實作複雜度更高。
適合 / 不適合的情境
KV Cache 效益最大的場景:
- 長對話(多輪問答,每輪 prompt 包含完整歷史)
- RAG(Retrieval-Augmented Generation)的文件擷取後分析
- 批次推論(多個請求共享部分 prefix,可用 prefix caching 優化)
KV Cache 遭遇瓶頸的場景:
- 超長文本(100K+ token):快取本身就超過 GPU 記憶體
- 高並發服務(同時服務多個用戶):每個 session 都要維護自己的快取
- 邊緣部署(記憶體極度受限):快取大小難以滿足
整體來說
KV Cache 是現代 LLM 推論可行的基礎技術,沒有它,你在 ChatGPT 上的每個回應都會慢上幾個數量級。但它也是限制長文本 LLM 部署規模的關鍵瓶頸。
2025 年的研究方向集中在三個面向:壓縮(GQA、MLA)、淘汰(智慧地丟棄不重要的 token 的快取)、分散式快取(PagedAttention、vLLM 的快取管理)。這些技術的進步直接決定了 LLM 服務在成本和延遲上的可能性邊界。
參考資料
相關標籤
相關文章
LLM 推論時的三個層次:Decoding、Workflow、Reasoning 技術整理
LLM 的輸出品質由三個層次共同決定:token 層級的 decoding 策略、任務層級的 workflow 設計、以及模型層級的 reasoning 能力。搞清楚這三層的差異,才能針對問題選對工具。
再見,所有的爬蟲勇士:Python 在 AI 時代的角色轉變
Python 依然是 AI 開發的主力語言,但 AI 工具的普及讓「寫 Python 程式碼」和「做 AI 開發」這兩件事的界線越來越模糊——這篇文章探討 Python 在 AI 時代的定位轉變。
Transformer 怎麼知道詞的順序?從絕對位置編碼到 RoPE 的演進
Transformer 的 self-attention 天生不知道詞的順序,位置編碼是補救措施。從正弦函數絕對編碼、可學習絕對編碼、相對位置編碼,到 RoPE(旋轉位置嵌入)——現代 LLM 幾乎都用 RoPE,因為它是免參數、天然表達相對距離、且可外推到更長序列的最佳方案。