💡

RX7900XTX + WSL2 + ROCm + vLLMでKVキャッシュをFP8量子化してコンテキスト長を2倍にする

に公開
1

はじめに

前回の記事「RX7900XTX + WSL2 + ROCm + vLLMでローカルLLM環境を構築する」では、
単に環境構築するという話で終わっていましたが、そこから一歩進んで「この 24GB VRAM で、できるだけ長いコンテキストを扱いたい」と思い、vLLM の KV キャッシュ量子化を使ってコンテキスト長を伸ばしてみました。

この記事では、RX 7900 XTX + WSL2 + ROCm + vLLM という環境で、KV キャッシュを量子化する方法とその効果について書きます。


この記事で伝えたいこと

  • 前回記事の環境を使って、最小限の変更でコンテキスト長を伸ばす方法
  • vLLM v0.16.0 以降 + kv_cache_dtype="fp8_e4m3" の 1 行追加で、KV キャッシュを FP8 量子化できること
  • 実測として、30B AWQ モデルでコンテキスト長が約 2 倍になったこと

前提環境

基本的には、前回記事と同じ環境です。

  • GPU: AMD Radeon RX 7900 XTX (24GB VRAM)
  • ホスト OS: Windows 11
  • WSL2: Ubuntu 24.04
  • ROCm: 7.2
  • PyTorch: ROCm ビルド
  • vLLM: v0.16.0(ここが今回のポイント)

前回の記事では vLLM v0.15.0 を使っていましたが、この環境では v0.15.0 だと KV キャッシュの FP8 量子化が動きませんでした。
同じ環境で v0.16.0 に上げたところ、kv_cache_dtype="fp8_e4m3" が正常に動作し、KV キャッシュが量子化されることを確認しています。
理由については記事の後半で書いてます。


1. まず結論:この 1 行を足すだけでコンテキスト長がほぼ 2 倍になる

前回記事の続きとして、既に vLLM でモデルを動かせている前提で話を進めます。

やることは、パラメータに kv_cache_dtype="fp8_e4m3" を足してやるだけです。

Python から使う場合

from vllm import LLM, SamplingParams

llm = LLM(
    model="QuantTrio/Qwen3-Coder-30B-A3B-Instruct-AWQ",
    kv_cache_dtype="fp8_e4m3",  # ★この1行を足すだけ
)

sampling_params = SamplingParams(
    temperature=0.7,
    top_p=0.9,
    max_tokens=512,
)

outputs = llm.generate(
    ["Explain Kubernetes networking in detail"],
    sampling_params,
)
print(outputs[0].outputs[0].text)

OpenAI 互換 API サーバとして起動する場合

vllm serve QuantTrio/Qwen3-Coder-30B-A3B-Instruct-AWQ \
  --kv-cache-dtype fp8_e4m3 \
  --host 0.0.0.0 \
  --port 8000

2. 実測結果:30B AWQ モデルでコンテキスト長が約 2 倍になった

実験に使ったモデルは、QuantTrio/Qwen3-Coder-30B-A3B-Instruct-AWQ で、
kv_cache_dtype を指定しない場合(非量子化)と、kv_cache_dtype="fp8_e4m3" を指定した場合(量子化)でコンテキスト長がどの程度増えるのかを見てみました。

その結果:

設定 KV キャッシュとして扱えたトークン数
非量子化(FP16 相当) 43,472 トークン
FP8 量子化 86,976 トークン

きれいに 2 倍程度 まで伸びており、「24GB VRAM だけど 30B モデルをもう少し伸び伸び使いたい」という目的に対しては十分な効果が得られました。


3. 何故量子化するのに vLLM v0.16.0 が必要なのか

vLLM 自体は v0.15.0 の時点で FP8 KV キャッシュの仕組みを持っていましたが、実体としては NVIDIA CUDA 向けの実装が中心でした。
なので RX 7900 XTX + WSL2 + ROCm + vLLM v0.15.0 という組み合わせでは、kv_cache_dtype="fp8_e4m3" を指定するとエラーになり動作しませんでした。

そんな中、vLLM v0.16.0 で ROCm の FP8 KV キャッシュが公式サポートになりました。
公式ドキュメントでは、kv_cache_dtype="fp8_e4m3" を指定した例が CUDA / ROCm の両方について説明されています。
また、AMD 側の ROCm ドキュメントでも、vLLM v1 と組み合わせた推論最適化の一つとして FP8 量子化が紹介されています。

補足ですが、calculate_kv_scales=True を付けると Triton Attention 側の制約(q_scale != 1.0 が未対応)でこの環境ではエラーになるので、このオプションは付けない方が無難です。


4. vLLM(v1エンジン)を最適化するための設定について

KV キャッシュ量子化とは直接関係ありませんが、vLLM v1 をより快適に使うために設定しておいた方が良い項目を紹介します。

Paged Attention

  • KV キャッシュを固定サイズの「ページ」に分割して管理し、メモリ断片化を防ぐ仕組みです。
  • vLLM のコア機能で、特にオプションを弄らなくても常に有効になっています。

Chunked Prefill

  • 長いプロンプトを小さなチャンクに分割しつつ、Decode と重ねて実行することでレイテンシを抑える仕組みです。
  • ロングプロンプトを扱うときに「異様に最初のトークンが遅い」という事態を防いでくれます。

Automatic Prefix Caching

  • 同じシステムプロンプトや共通プレフィックスを複数リクエストで使う場合、その部分の KV キャッシュを再利用して TTFT(Time To First Token)を大幅に短縮する仕組みです。
  • 実運用では 50% 以上のキャッシュヒット率が報告されており、ロングプロンプトを多用するワークロードほど効果が大きいです。

torch.compile

  • PyTorch 2.0から導入されたモデル高速化コンパイラです。
  • これを有効化すると、VRAM へのアクセス回数が減り、Python側の呼び出しオーバーヘッドが減り、スループットが向上する様です。
  • デメリットは、vLLM の起動時間が遅くなり、VRAM の消費量がわずかに増えます。

まとめ

  • RX 7900 XTX + WSL2 + ROCm + vLLM という環境でも、vLLM v0.16.0 以降を使えば kv_cache_dtype="fp8_e4m3" による KV キャッシュ FP8 量子化が実用的に使えるようになる。
  • 実測として、QuantTrio/Qwen3-Coder-30B-A3B-Instruct-AWQ でコンテキスト長が約 43,472 → 86,976 トークンと、ほぼ 2 倍に伸びることを確認。
  • vLLM(v1エンジン)側の Paged Attention / Chunked Prefill / Prefix Caching などはデフォルトで有効なので、細かいチューニングをしなくても、ある程度は自動でいい感じにしてくれる。

前回の記事で環境構築まで終わっている人は、vLLM を v0.16.0 に上げて、kv_cache_dtype="fp8_e4m3" の 1 行を足すだけでこの恩恵を受けられます。

同じ環境で「もうちょっと長くコンテキストを取りたい」と思っている人の参考になればうれしいです。

Discussion

tayonstayons

先生、こんにちは。いくつか記事を拝見し、大変参考になりました。現在7900dを使用しているのですが、Minimax 2.5モデルのデプロイで問題が発生しています。先生も以前、同様の問題に遭遇されたことがあるでしょうか?