🎓 レベル:発展 | 重要度:A(必須) 📎 前提:VRAM所要の見積もり | 原理:推論の実務(機械学習)
要点(結論先出し)
- KVキャッシュ=過去トークンのKey/Valueを保存し、再計算を避ける仕組み。コンテキスト長に比例して線形に増える。
- 式:
KV[bytes] = 2 x 層数 x KVヘッド数 x head_dim x bytes_per_elem x コンテキスト長。長文では重みより大きくなることも。 - 削減策は2つ:GQA(KVヘッドを減らす設計、約4倍級の削減)とKVキャッシュ量子化(FP16→8bit/4bitで半分以下)。
概念 ── なぜKVを貯めるのか
自己回帰生成では、各ステップで過去全トークンのKey/Valueが要ります。毎回再計算すると遅いので、一度計算したK/Vをキャッシュします。速度のための仕組みですが、その代償が文脈長に比例して膨らむメモリです。原理は機械学習へ → 推論の実務。
仕組みと計算実証(lab出力)
対応lab vram_sizing.py(Llama系8B相当:32層・KVヘッド8・head_dim128):
FP16 KV: 1トークン = 128 KiB
ctx= 4096 -> 0.50 GiB
ctx= 8192 -> 1.00 GiB
ctx= 32768 -> 4.00 GiB
ctx=131072 -> 16.00 GiB
Q8 KV: 1トークン = 64 KiB(半分)
ctx= 32768 -> 2.00 GiB
8Bの重みが約4.5GiBなのに、128KコンテキストのKVは16GiB——長文では文脈のほうが重い。コンテキスト長を倍にすればKVも倍、という線形の増加を体で覚えてください。
削減策1 ── GQA(設計側の工夫)
MHA(KVヘッド32): 512 KiB/token
GQA(KVヘッド 8): 128 KiB/token -> 4.0x 削減
**GQA(Grouped Query Attention)**は複数のQueryヘッドでKVヘッドを共有する設計。KVヘッド数が減るぶん、上の式が直接小さくなります。近年のモデルが長文を現実的に扱えるのはこの寄与が大きい(要最新確認)。
削減策2 ── KVキャッシュ量子化(実行側の工夫)
KVをFP16ではなく8bit/4bitで持てば、bytes_per_elem が半分/4分の1に。品質低下を抑えつつKVを圧縮できます(対応エンジン・要最新確認)。長文をどうしても通したいときの有効手段。
運用の勘所
- コンテキスト長は必要なだけ。「長ければ安心」はVRAMを溶かす。
- 長文が要るなら:GQAモデルを選ぶ → KVを量子化 → それでも溢れるなら入力を要約/分割(RAG的に)→ ローカルRAGの構成
- サイジング時は最大入力長でKVを見積もる(実運用の最悪ケース)。
なぜそうするか
OOMの主因は重みよりKVであることが多い。KVが線形に増える式を持っていれば、「このコンテキスト長は載らない」を事前に判断でき、無駄な再起動とクラッシュを避けられます。GQA・KV量子化を知っていれば、買い替えずに長文を通せます。
⚠️ よくある落とし穴
- コンテキスト長を最大に固定:使わない長さのKVがVRAMを占有。
- 重みだけ見てKVを忘れる:長文入力で突然OOM。
- KV量子化を品質劣化と決めつけ:多くの用途で許容範囲(要最新確認)。まず試す。
- head_dim・層数を実モデルで確認しない:式の係数はモデル諸元依存。要最新確認。
対応lab
local-llm-study/labs/vram_sizing.py… KV/トークン・コンテキスト別KV・GQA削減を計算実証。
関連
- 見積もりの式 → VRAM所要の見積もり
- 収める実務 → オフロードと量子化でメモリに収める
- 長文を畳むRAG → ローカルRAGの構成