ローカルLLM KV キャッシュ量子化ガイド 2026年版:llama.cpp / vLLM で KV Cache を Q4 / Q8 に落として VRAM と tok/sec はどう変わるか
コンテキスト長 32K / 128K で VRAM が足りなくなる主犯は KV Cache です。llama.cpp の --cache-type-k q4_0 / vLLM の kv_cache_dtype で Q8 / Q4 に量子化すると、VRAM は半分〜1/4 に、tok/sec は 5〜15% 落ちる、が現実線です。設定手順・精度への影響・Flash Attention との相性まで、実装レベルで整理します。
- #KV Cache
- #量子化
- #llama.cpp
- #vLLM
- #SGLang
- #Ollama
- #Flash Attention
- #128K コンテキスト
- #ローカルLLM
- #VRAM
本記事は Amazon.co.jp および各販売店のアフィリエイトリンクを含む場合があります。推奨は性能・コスパ・実機ベンチマーク基準で編集判断しており、提供記事は受け付けていません。詳細は プライバシーポリシー をご覧ください。

結論:KV Cache は 32K / 128K コンテキストで VRAM を食う主犯です。llama.cpp の --cache-type-k q8_0 / vLLM の kv_cache_dtype="fp8_e5m2" で Q8 / FP8 に量子化すると、VRAM は半分に、tok/sec は 3〜8% 落ちるだけで、Perplexity は 0.2〜0.5% しか悪化しません。Q4_0 まで落とせば VRAM は 1/4、tok/sec は 7〜15% 低下、Perplexity は 1〜2% 増。128K コンテキストを常用するなら Q8 が実質デフォルトで、モデル本体を Q4 のままにしても KV Cache は Q8 に寄せる、というのが 2026 年時点の実運用の主流です。
ローカル LLM のコンテキスト長を 128K に伸ばしたら「VRAM が足りない」と怒られた経験がある方は、多くの場合、真犯人は KV Cache です。Llama 3.3 70B(GQA・n_kv_heads=8・head_dim=128・n_layers=80)を 128K コンテキストで動かすと、モデル本体(Q4_K_M で約 40GB)に加えて KV Cache が FP16 で約 40GB、合計で 80GB を超えます。RTX 5090(32GB)どころか、RTX PRO 6000 Blackwell(96GB)でも余裕がありません。このボトルネックを解消するのが KV Cache 量子化です。llama.cpp / vLLM / SGLang / Ollama それぞれで実装が入っており、実運用に耐えるレベルまで枯れてきました。本記事では設定手順・精度への影響・Flash Attention との相性を、実装別に整理します。
用語対応表:cache-type-k / kv_cache_dtype / OLLAMA_KV_CACHE_TYPE
同じ「KV Cache 量子化」でも、バックエンドごとにパラメータ名がバラバラです。最初に対応表を置きます。
| バックエンド | パラメータ | 指定できる値 | Flash Attention 要件 |
|---|---|---|---|
| llama.cpp | --cache-type-k / --cache-type-v | f16 q8_0 q4_0 q4_1 iq4_nl | K は不要、V は必須 |
| vLLM | --kv-cache-dtype / kv_cache_dtype | auto(FP16 相当)fp8(= fp8_e4m3)fp8_e5m2 | 内部デフォルト有効 |
| SGLang | --kv-cache-dtype | auto fp8_e5m2 fp8_e4m3 | 内部デフォルト有効 |
| Ollama | OLLAMA_KV_CACHE_TYPE 環境変数 | f16 q8_0 q4_0 | OLLAMA_FLASH_ATTENTION=1 が必要 |
| Text Generation WebUI | --cache_8bit --cache_4bit(llama.cpp バックエンド時) | フラグ | Exllama v2 は独自 |
llama.cpp の q8_0 / q4_0 は 整数量子化、vLLM / SGLang の fp8_e5m2 / fp8_e4m3 は FP8 浮動小数点 です。仕組みは違います。実効容量削減はほぼ同じで、FP16 の半分になります。
KV Cache の容量式:なぜ 128K で 40GB になるか
KV Cache の容量は次の式で決まります。
KV Cache 容量 = 2 × n_layers × n_kv_heads × head_dim × context_len × dtype_bytes
「2」は Key と Value の 2 系統ぶんです。GQA(Grouped-Query Attention)採用モデルでは n_kv_heads が n_heads より少ないため、MHA より小さくなります。Llama 3.x / Qwen 3 系はすべて GQA です。
代表モデルで計算した KV Cache 容量は次のとおりです(context を伸ばした時の増分です)。
| モデル | n_layers | n_kv_heads | head_dim | 8K FP16 | 32K FP16 | 128K FP16 | 128K Q8 | 128K Q4 |
|---|---|---|---|---|---|---|---|---|
| Llama 3.1 8B(GQA 8) | 32 | 8 | 128 | 1.0 GB | 4.0 GB | 16.0 GB | 8.0 GB | 4.0 GB |
| Qwen 3 14B(GQA 8) | 40 | 8 | 128 | 1.3 GB | 5.2 GB | 20.8 GB | 10.4 GB | 5.2 GB |
| Qwen 3 32B(GQA 8) | 64 | 8 | 128 | 2.0 GB | 8.0 GB | 32.0 GB | 16.0 GB | 8.0 GB |
| Llama 3.3 70B(GQA 8) | 80 | 8 | 128 | 2.5 GB | 10.0 GB | 40.0 GB | 20.0 GB | 10.0 GB |
| gpt-oss 20B(GQA 8) | 40 | 8 | 128 | 1.3 GB | 5.2 GB | 20.8 GB | 10.4 GB | 5.2 GB |
Llama 3.3 70B を 128K コンテキストで回すと、KV Cache だけで 40GB。モデル本体(Q4_K_M で約 40GB)を足すと 80GB です。
RTX 5090 では明らかに足りません。RTX PRO 6000 Blackwell(96GB)でようやくギリギリ、というのが FP16 KV Cache の現実です。
Q8_0 に量子化すれば KV Cache は 20GB に半減し、Q4_0 なら 10GB に落ちます。この差が「モデル本体を Q4 に維持したまま 128K を使えるか」の分岐点です。
KV Cache とコンテキスト長の関係の入門は「ローカルLLM のコンテキスト長と VRAM の関係 2026年版」で扱っています。
llama.cpp:—cache-type-k / —cache-type-v と Flash Attention
llama.cpp が最も広く使われている構成なので、まずこれから見ます。設定例は次のとおりです。
# K のみ Q8 量子化(Flash Attention 不要)
./llama-server -m Llama-3.3-70B-Instruct-Q4_K_M.gguf \
--cache-type-k q8_0 \
-c 32768 -ngl 99 --host 0.0.0.0 --port 8080
# K と V の両方を Q8 量子化(Flash Attention 必須)
./llama-server -m Llama-3.3-70B-Instruct-Q4_K_M.gguf \
--cache-type-k q8_0 --cache-type-v q8_0 \
--flash-attn \
-c 32768 -ngl 99 --host 0.0.0.0 --port 8080
# 最大圧縮:K と V の両方を Q4_0
./llama-server -m Llama-3.3-70B-Instruct-Q4_K_M.gguf \
--cache-type-k q4_0 --cache-type-v q4_0 \
--flash-attn \
-c 131072 -ngl 99 --host 0.0.0.0 --port 8080
--cache-type-v は Flash Attention 有効時のみ動く、というのが llama.cpp の実装制約です。
--flash-attn を付け忘れると、V 側のパラメータが黙って無視されます(ログに警告は出ますが停止はしません)。起動ログを確認してください。
推論チューニング全般(--n-gpu-layers の刻み方、--n-batch の調整、CPU オフロード)は「ローカルLLM 推論チューニングガイド 2026年版」で扱っています。
llama.cpp の cache-type 別 tok/sec と Perplexity
Llama 3.3 70B Q4_K_M / RTX 5090 32GB + CPU オフロード構成での llama.cpp 実測レンジ(Reddit r/LocalLLaMA、GitHub Issues、Hugging Face Model Cards 集約)は次のとおりです。
| K / V dtype | KV Cache(128K) | tg tok/sec | pp512 tok/sec | Perplexity 増 |
|---|---|---|---|---|
| f16 / f16 | 40.0 GB | 100%(基準) | 100% | 0.0% |
| q8_0 / f16 | 30.0 GB | 96〜98% | 98〜99% | +0.1〜0.3% |
| q8_0 / q8_0 | 20.0 GB | 92〜97% | 97〜99% | +0.2〜0.5% |
| q4_0 / q8_0 | 15.0 GB | 90〜95% | 96〜98% | +0.5〜1.0% |
| q4_0 / q4_0 | 10.0 GB | 85〜93% | 94〜97% | +1.0〜2.0% |
「Q8 K + Q8 V が最良のバランス」 と言えます。
VRAM は半分、tok/sec の低下は 3〜8%、Perplexity 増は 0.5% 未満です。長文の後半で文体がぶれることも稀で、実用上は FP16 と区別できません。
Q4_0 まで落とすのは、RTX 5090(32GB)で 70B を 128K で無理やり動かしたい、という場面に限定されます。tok/sec の低下は許容範囲です。文体のばらつきが増えるので、長い翻訳や小説生成には向きません。
Flash Attention 2 / 3 の内部仕様と KV Cache の関係は「Flash Attention 2 / 3 の中身と何が速くなったのか 2026年版」で扱っています。
vLLM:kv_cache_dtype=“fp8_e5m2” / “fp8_e4m3” の違い
vLLM は本番運用向けのバックエンドです。FP8 KV Cache が Hopper / Ada Lovelace / Blackwell 世代でハードウェア加速されます。CLI での指定は次のとおりです。
# vLLM のオンライン推論サーバー起動時
vllm serve meta-llama/Llama-3.3-70B-Instruct \
--tensor-parallel-size 2 \
--max-model-len 131072 \
--kv-cache-dtype fp8_e5m2 \
--gpu-memory-utilization 0.92
Python API から呼ぶ場合は LLM(model=..., kv_cache_dtype="fp8_e5m2") です。
fp8_e5m2 と fp8_e4m3 のどちらを選ぶか
FP8 には 2 種類あります。e5m2(指数 5bit、仮数 2bit)と e4m3(指数 4bit、仮数 3bit)です。
- fp8_e5m2:ダイナミックレンジが広い(±57344 まで表現可)、仮数の解像度が粗い。KV Cache 用途で広く使われる既定値。ほとんどのモデルでこれを選べば OK
- fp8_e4m3:ダイナミックレンジが狭い(±448 まで)、仮数の解像度が細かい。スケーリング係数の調整が必要で、モデル配布側が
hf-quant-scaleを提供している場合に本領を発揮する
vLLM 公式のガイドは 「特別な理由がなければ fp8_e5m2」 です。
fp8_e4m3 は DeepSeek / Mistral などのモデル配布時に scale が公開されている構成で、より高い精度を狙う時に選びます。
vLLM FP8 と Ampere(A100 / RTX 3090)の落とし穴
FP8 演算のハードウェア加速は Hopper(H100 / H200)、Ada Lovelace(L40S / RTX 4090 / RTX 5090 / Blackwell)で入っています。Ampere 世代(A100 / RTX 3090 / RTX A6000)では FP8 のハードウェア命令がなく、内部で FP16 にプロモートされて計算されます。結果として:
- VRAM 節約効果はある(KV Cache 自体は FP8 で保存される)
- tok/sec は下がる(FP16 プロモート分のオーバーヘッド)
Ampere で「vLLM FP8 KV Cache を試したら遅くなった」は既知の挙動です。
Ampere 世代なら kv_cache_dtype=auto(FP16)のままで良い、というのが実運用の判断です。
SGLang:—kv-cache-dtype fp8_e5m2 と RadixAttention
SGLang は vLLM に近い API です。RadixAttention によるプレフィックス共有が特徴です。KV Cache 量子化の指定は vLLM とほぼ同じです。
python -m sglang.launch_server \
--model-path meta-llama/Llama-3.3-70B-Instruct \
--tp 2 \
--context-length 131072 \
--kv-cache-dtype fp8_e5m2
RadixAttention のプレフィックス共有と FP8 KV Cache は独立して動作します。
プレフィックス共有によってヒットしたキャッシュも FP8 で保存されるので、複数リクエストが同じシステムプロンプトを使う構成では VRAM の合計消費が明確に下がります。
Ollama:OLLAMA_KV_CACHE_TYPE 環境変数
Ollama は v0.3 以降で環境変数指定に対応しました。CLI に組み込みのフラグはありません。systemd や Docker の起動時に環境変数を渡す運用です。
# systemd の場合
sudo systemctl edit ollama
# 以下を追記
# [Service]
# Environment="OLLAMA_KV_CACHE_TYPE=q8_0"
# Environment="OLLAMA_FLASH_ATTENTION=1"
sudo systemctl restart ollama
# Docker の場合
docker run -d \
-e OLLAMA_KV_CACHE_TYPE=q8_0 \
-e OLLAMA_FLASH_ATTENTION=1 \
-p 11434:11434 \
ollama/ollama
OLLAMA_FLASH_ATTENTION=1 を同時に指定しないと、V 側の量子化が効きません。
Open WebUI / LibreChat のような UI 側から切り替えることはできず、モデル単位の細かい制御もできない、というのが llama.cpp 直叩きとの違いです。日常運用で「モデルごとに切り替えなくていい」場合は Ollama で十分です。モデルごとに Q8 / Q4 / f16 を出し分けたい構成なら llama.cpp サーバーを直接立てるほうが柔軟です。
Q8 と Q4、どちらまで下げるか:判断表
用途別の判断軸を 1 枚に集約します。
| 用途 | 推奨 KV dtype | 理由 |
|---|---|---|
| チャット・コード補助(context 32K まで) | f16 のまま | KV Cache が小さいので圧縮不要 |
| 長文翻訳・要約(context 32〜128K、Perplexity 重視) | Q8 K + Q8 V(vLLM なら fp8_e5m2) | VRAM 半減、Perplexity 増 0.5% 未満 |
| RTX 5090 32GB で 70B を 128K 常用したい | Q4 K + Q4 V | VRAM 1/4、tok/sec 10% 減、Perplexity +1〜2% |
| 本番 API 代替、複数リクエスト並列 | vLLM fp8_e5m2 | Hopper / Ada / Blackwell 世代の FP8 加速で最速 |
| Ampere 世代(A100 / RTX 3090) | f16 のまま | FP8 加速が無く、量子化しても遅くなる |
| モデルウェイトも極限まで圧縮したい | ウェイト Q4_K_M + KV Q8 | ウェイト Q4 + KV Q4 の二重圧縮は Perplexity が跳ねる |
モデルウェイトの量子化フォーマット(GGUF Q4_K_M / GPTQ / AWQ / EXL2)と KV Cache 量子化は別軸です。ウェイト側の量子化整理は「ローカル LLM 量子化フォーマット徹底解説 2026年版」で扱っています。
KV Cache は Q8 に寄せる、モデルウェイトは Q4_K_M / AWQ を選ぶ、というのが 2026 年時点の標準的な組み合わせです。
トラブルシューティング:起動時にエラーが出る 3 パターン
実運用で遭遇する典型的なエラーです。
- llama.cpp で
--cache-type-v q8_0を指定して起動時に警告:--flash-attnを付け忘れています。llama.cpp は Flash Attention 有効時のみ V 側量子化が動きます - vLLM で
kv_cache_dtype=fp8_e5m2を指定して tok/sec が下がる:Ampere 世代の GPU です。nvidia-smi --query-gpu=name --format=csvで Compute Capability を確認し、8.9(Ada)以上でないと FP8 加速はありません - Ollama で
OLLAMA_KV_CACHE_TYPE=q8_0が効かない:v0.3 未満です。ollama --versionで確認し、v0.3 以降にアップデートしてください
3 番目の Ollama は既定が f16(FP16)なので、環境変数を設定していなければ KV Cache は圧縮されていません。「Ollama で VRAM が足りない」と感じたら、まず OLLAMA_KV_CACHE_TYPE=q8_0 OLLAMA_FLASH_ATTENTION=1 を試すのが最短ルートです。
まとめ:Q8 KV Cache を実質デフォルトに
KV Cache 量子化は 2024〜2025 年の 2 年で急速に枯れ、2026 年時点では Q8 KV Cache を実質デフォルトとして扱える 段階になりました。VRAM は半分、tok/sec の低下は 3〜8%、Perplexity 増は 0.5% 未満、というトレードオフに反対する理由はほぼありません。一方で Q4 KV Cache は、RTX 5090(32GB)や RTX 4090(24GB)で 70B を 128K で無理やり動かしたい、という場面に限定した選択肢です。tok/sec の低下より、Perplexity +1〜2% と文体ばらつきのほうが体感で目立ちます。長文翻訳や小説生成では Q8 を上限に据えるほうが安全です。
FP8(vLLM / SGLang)は Hopper / Ada Lovelace / Blackwell 世代で使うと最速の選択肢になりますが、Ampere 世代では逆に遅くなる、という世代依存があります。GPU の Compute Capability を確認してから採用してください。
入手先・関連商品
当サイトは Amazon.co.jp アソシエイト・プログラムに参加予定です。下記リンク経由で購入された場合、紹介料を受け取ることがあります。読者の負担は増えません。リンクは記事評価とは独立しており、編集判断には影響しません。
128K コンテキスト + Q8 KV Cache を現実的に扱える構成の代表例です。
- GeForce RTX 5090(32GB)を Amazon.co.jp で探す — 32〜70B クラスを Q4_K_M + Q8 KV で回すコンシューマ最上位
- MacBook Pro 16 M4 Max(64GB)を Amazon.co.jp で探す — 統合メモリで 70B + Q8 KV を持ち運びできる Apple Silicon 構成
- GMKtec EVO-X2 Ryzen AI MAX+ 395(128GB)を Amazon.co.jp で見る — 96GB を VRAM に割り当てられる Strix Halo ミニPC、70B / 120B を 128K で常用したい向け
RTX PRO 6000 Blackwell(96GB)は国内 Amazon での取扱が安定していないため、パソコン工房・ドスパラなどの法人向け窓口で見積り購入するのが確実です。
あなたに合うPCを診断する
用途や予算をもう少し細かく入力すると、3つの候補構成を提案します。
→ 診断スタート
関連記事
よくある質問
- KV Cache 量子化で tok/sec はどれくらい落ちますか?
- llama.cpp(Vulkan / CUDA / ROCm いずれも)で FP16 → Q8_0 に落とすと 3〜8%、Q4_0 に落とすと 7〜15% の tok/sec 低下が公開実測の中央値です。vLLM の FP8(fp8_e5m2 / fp8_e4m3)は Hopper / Ada Lovelace 世代の H100 / L40S / RTX 5090 で 2〜5% と最も低下が小さく、Ampere 世代(A100 / RTX 3090)では FP8 のハードウェア加速が無いため kv_cache_dtype=auto(FP16)のほうが速い、という差があります。
- KV Cache 量子化で精度(Perplexity)はどれくらい悪化しますか?
- Llama 3.3 70B / Qwen 3 32B / gpt-oss 20B クラスで、FP16 → Q8_0 は Perplexity で 0.2〜0.5% 増、FP16 → Q4_0 は 1〜2% 増、というのが llama.cpp のリファレンス実装の値です。vLLM の FP8 kv_cache_dtype は FP16 とほぼ差がなく、0.1〜0.3% 増に収まる例が多いです。実運用の体感で言えば、Q8 は「言われないと気づかない」、Q4 は「長文の後半で稀に文体がぶれる」レベルです。
- Flash Attention を有効にしないと KV Cache 量子化は使えませんか?
- llama.cpp では K(キー)の量子化は Flash Attention 無しでも使えますが、V(バリュー)の量子化(--cache-type-v)は Flash Attention 有効時のみ動きます。vLLM / SGLang は Flash Attention(または FlashInfer)が内部でデフォルト有効なので、この制約は意識せず使えます。llama.cpp で --cache-type-v q8_0 を指定して起動時にエラーが出る場合、多くは --flash-attn を付け忘れているケースです。
- Llama 3.3 70B を 128K コンテキストで動かすと KV Cache は何 GB になりますか?
- Llama 3.3 70B(GQA、n_kv_heads=8、head_dim=128、n_layers=80)で 128K コンテキストの KV Cache は、FP16 で約 40GB、Q8_0 で約 20GB、Q4_0 で約 10GB になります。RTX 5090(32GB)で 70B Q4_K_M モデル本体(約 40GB)を 128K で動かすには、モデル本体だけでも収まりません。実運用では 70B Q4_K_M + 128K + Q4 KV Cache でも合計 50GB 超で、RTX PRO 6000 Blackwell(96GB)か Mac Studio M3 Ultra、あるいは Strix Halo ミニPC(96GB VRAM 割当)が必要です。
- Ollama で KV Cache 量子化はどう有効化しますか?
- Ollama v0.3 以降は環境変数 OLLAMA_KV_CACHE_TYPE=q8_0 または q4_0 を設定するとサーバー起動時に有効化されます。同時に OLLAMA_FLASH_ATTENTION=1 を設定しないと V 側の量子化が効きません。既定は f16(FP16)です。UI(Open WebUI / LibreChat)から切り替えることはできず、systemd や Docker の環境変数で指定するのが標準的な運用です。