Gemma 4 31BのvLLM / SGLang比較
Blackwell 96GBでGemma 4 31BのNVFP4・FP8・MTPを比較。LLM導入で見る生成速度、KV容量、coding-agentの出力を記録します。
Gemma 4 31B ITを RTX PRO 6000 Blackwell 96GB 1枚で動かし、vLLM 0.21.0 と SGLang gemma4-mtp を比べました。coding-agent の作業で、KV cache dtype、KV pool、MTP投機デコードの違いを確認します。
vLLM は NVFP4 / FP8 block、SGLang は FP8 block + BF16 KV / FP8 KVを使いました。速度とKV容量はvLLM、ツール利用と出力の印象はSGLang FP8 KVが良かったです。生成内容は動画に残しています。
動画
SGLang の実行動画です。
動画リンク: https://www.youtube.com/watch?v=YlysBl5Qg34
動画リンク: https://www.youtube.com/watch?v=cgYbqnwqygM
比較一覧
RedHatAI の同じ FP8 モデルを ctx 256K で確認しました。NVFP4 は NVIDIA のモデルです。
| Config | Runtime | Weights | KV cache | KV pool | Peak TG | Typical TG | Peak accept | Notes |
|---|---|---|---|---|---|---|---|---|
| A | vLLM 0.21.0 | NVFP4 | FP8 | 876K tok | 109.8 tok/s | 90-100 tok/s | 99.5% | 262K ctx、MTP x4 |
| B | vLLM 0.21.0 | FP8 block | FP8 | 876K tok | 115.3 tok/s | 80-100 tok/s | 93.5% | 262K ctx、MTP x4 |
| C | SGLang gemma4-mtp | FP8 block | BF16 | 69.7K tok | 約80 tok/s | 55-75 tok/s | 約90% | 262K ctx、SWAKVPool、MTP x5/6 |
| D | SGLang gemma4-mtp | FP8 block | FP8 | 139.5K tok | 約93.8 tok/s | 70-90 tok/s | 約96% | 262K ctx、SWAKVPool、MTP x5/6 |
- NVFP4では繰り返しに陥ることがありました。samplingか設定のミスかもしれません。
- 単一ストリームのTGは vLLM + MTP + prefix caching が最も高い帯でした。
- vLLMの速度はMTP accept rateに連動して2つの帯に分かれました。
- SGLangのFP8 KVは、同じSWAKVPool容量でBF16 KVの約2倍のtokenを確保できました。
- SGLang FP8 KVは速度が低いものの、coding-agentの出力は良いと感じました。
min_pも設定できます。
比較したかったこと
比較した条件は5つです。
- Runtime:
vLLMとSGLang - Weight quantization:
NVFP4とFP8 block - KV cache dtype:
FP8とBF16 - Context budgetとKV pool topology: vLLMのflat KVとSGLangのsliding-window KV pool
- Speculative decoding: MTP x4とMTP x5/6
coding-agent は長い文脈、tool call、自由記述、構造化出力を扱います。LLM導入時の速度を見積もるため、MTPの受理率が高い区間と低い区間を確認しました。
Hardware
| 項目 | 値 |
|---|---|
| GPU | NVIDIA RTX PRO 6000 Blackwell 96GB (SM120) |
| Host | AMD EPYC、768GB DDR5 ECC |
A. vLLM 0.21.0: NVFP4 weights + FP8 KV
AはNVFP4 4-bit weights、FP8 KV、Gemma 4 Assistant draft modelによるMTPです。contextは262,144、num_speculative_tokens=4 にしました。(公式cookbook)
Configuration
| 項目 | 値 |
|---|---|
| Runtime | vLLM 0.21.0 |
| GPU | RTX PRO 6000 Blackwell 96GB |
| Quantization | ModelOpt NVFP4 weights |
| KV cache | FP8 |
| Context length | 262,144 |
| Tensor parallel | 1 |
| Speculative decoding | Gemma 4 MTP、4 speculative tokens |
| Attention backend | Triton Attention |
| Sampling backend | FlashInfer |
| Compile backend | torch.compile / Inductor |
起動コマンド
実行コマンドです。再利用時に残った不要なenvも含みます。
podman run --rm \
--name test-model \
--device nvidia.com/gpu=0 \
--ipc=host \
-p 8000:8000 \
-v /mnt/data/models:/hf/hub:ro \
-e HF_HOME=/hf \
-e HF_HUB_OFFLINE=1 \
-e TORCH_CUDA_ARCH_LIST=12.0 \
-e VLLM_FLASHINFER_MOE_BACKEND=throughput \
-e VLLM_TARGET_DEVICE=cuda \
-e VLLM_USE_FLASHINFER_MOE_FP4=1 \
registry.home.arpa/vllm/vllm-openai:v0.21.0-ubuntu2404 \
/hf/hub/models--nvidia--Gemma-4-31B-IT-NVFP4/snapshots/e5ef03afa233c35cb000323ff098d4291e1dd07c \
--host 0.0.0.0 \
--port 8000 \
--served-model-name test-model \
--dtype auto \
--kv-cache-dtype fp8 \
--tensor-parallel-size 1 \
--trust-remote-code \
--gpu-memory-utilization 0.85 \
--max-num-seqs 1 \
--async-scheduling \
--enable-auto-tool-choice \
--tool-call-parser gemma4 \
--reasoning-parser gemma4 \
--speculative-config '{"model":"/hf/hub/models--google--gemma-4-31B-it-assistant/snapshots/4735700dca7bd22fad5dc348c228b50ec6cbac6d","num_speculative_tokens":4}' \
--max-model-len 262144 \
--override-generation-config '{"temperature":0.9,"top_p":0.85,"top_k":64,"presence_penalty":0.0,"repetition_penalty":1.13}'
実測ログ
実行中の代表値です。
Generation throughput: 95.9 tok/s acceptance length: 4.28 draft acceptance: 82.0%
Generation throughput: 95.3 tok/s acceptance length: 4.18 draft acceptance: 79.5%
Generation throughput: 109.8 tok/s acceptance length: 4.97 draft acceptance: 99.2%
Generation throughput: 107.6 tok/s acceptance length: 4.98 draft acceptance: 99.5%
集計値です。
| 指標 | 値 |
|---|---|
| Generation throughput | 最大109.8 tok/s |
| Typical active generation | 90-100 tok/s前後 |
| Mean MTP acceptance length | 最大4.98、max 5相当 |
| Average draft acceptance rate | 80-90%前後 |
| Best draft acceptance rate | 99.5% |
| GPU memory used for model load | 32.06 GiB |
| KV cache size | 876,006 tokens |
速度は95 tok/s前後と107 tok/s以上に分かれました。GPU loadよりMTP accept rateに連動しています。
KV cacheは876K tokensで、262K contextの約3.3倍です。ただし --max-num-seqs 1 なので、単一セッションでは余剰分を使い切りません。tool-callの安定性も調べました。vLLM + MTP、text-onlyでは min_p が使えず、temperature、top_p、top_k、repetition_penalty を調整しましたが、安定した設定は決まりませんでした。
崩れた場面では、Zedが (Sigh) と (Laughter) を繰り返しました。その間もvLLMはaccepted/drafted throughputとacceptance rateを出し続けていました。

B. vLLM 0.21.0: FP8 block weights + FP8 KV
BはAと同じvLLM 0.21.0で、weightsだけNVFP4からFP8 blockへ変えました。KVはFP8のままです。
Configuration
| 項目 | 値 |
|---|---|
| Runtime | vLLM 0.21.0 |
| GPU | RTX PRO 6000 Blackwell 96GB |
| Quantization | FP8 block |
| KV cache | FP8 |
| Context length | 262,144 |
| GPU KV cache size | 876,006 tokens |
| Speculative decoding | Gemma 4 Assistant draft model、num_speculative_tokens=4 |
実測値
Generation throughput: up to 115.3 tok/s
Typical active generation: around 80-100 tok/s
Mean MTP acceptance length: up to 4.74
Average draft acceptance rate: around 80-88%
Best draft acceptance rate: 93.5%
GPU KV cache size: 876,006 tokens
AからBで、peak throughputは109.8から115.3 tok/sへ上がり、peak draft acceptanceは99.5%から93.5%へ下がりました。FP8 KVは共通で、KV poolも876K tokensのままです。
C. SGLang gemma4-mtp: FP8 block weights + BF16 KV
CはSGLang gemma4-mtp、FP8 block weights、BF16 KVです。sliding-window対応の SWAKVPool なので、vLLMのflat KVとは容量の見え方が異なります。
前日に公開された lmsysorg/sglang:gemma4-mtp のimageを使いました。NEXTNからFROZEN_KV_MTPへ変わったコミットかもしれません。

Configuration
| 項目 | 値 |
|---|---|
| Runtime | SGLang gemma4-mtp |
| GPU | RTX PRO 6000 Blackwell 96GB |
| Quantization | FP8 block |
| KV cache dtype | torch.bfloat16 |
| Context length | 262,144 |
| Speculative decoding | NEXTNからFROZEN_KV_MTPにauto-promote |
| Draft model | Gemma 4 Assistant draft model |
| Speculative steps | speculative_num_steps=5 |
| Draft tokens | speculative_num_draft_tokens=6 |
SWAKVPool初期化値
full_layer_tokens=69757
swa_layer_tokens=55805
max_total_num_tokens=69757
KV memory
SWA KV: 21.29 GB K + 21.29 GB V
Full KV: 2.66 GB K + 2.66 GB V
Total SWAKVPool usage: 47.90 GB
実測値
Typical decode throughput: around 55-75 tok/s
Peak throughput: around 80 tok/s class
Typical accept length: around 4.5-5.5
Typical accept rate: around 75-90%
Cの典型速度は55-75 tok/s、代表的なpeakは80 tok/s台でした。ログにはlow 90sの例もありますが、比較表では約80 tok/sとしています。KVは69.7K tokensで、vLLMの876K tokensより小さいです。
D. SGLang gemma4-mtp: FP8 block weights + FP8 KV
DはCのKV dtypeだけを torch.float8_e4m3fn に変えました。今回のSGLang構成では、coding-agentの作業が最も良いと感じました。
Configuration
| 項目 | 値 |
|---|---|
| Runtime | SGLang gemma4-mtp |
| GPU | RTX PRO 6000 Blackwell 96GB |
| Quantization | FP8 block |
| KV cache dtype | torch.float8_e4m3fn |
| Context length | 262,144 |
| Speculative decoding | NEXTNからFROZEN_KV_MTPにauto-promote |
| Draft model | Gemma 4 Assistant draft model |
| Speculative steps | speculative_num_steps=5 |
| Draft tokens | speculative_num_draft_tokens=6 |
SWAKVPool初期化値
full_layer_tokens=139515
swa_layer_tokens=111612
max_total_num_tokens=139515
KV memory
SWA KV: 21.29 GB K + 21.29 GB V
Full KV: 2.66 GB K + 2.66 GB V
Total SWAKVPool usage: 47.90 GB
実測値
Typical decode throughput: around 70-90 tok/s
Peak throughput: around 93.8 tok/s
Typical accept length: around 5.0-5.8
Typical accept rate: around 80-96%
Zed AgentでDjangoの予約管理機能を生成しながら、SGLangのdecode batch、accept length、accept rate、generation throughputを確認しました。

Cと同じ47.90GBのSWAKVPoolで、full-layer tokensは69,757から139,515、SWA layer tokensは55,805から111,612へ増えました。ほぼ2倍です。
FP8 KV scaling factorsが1.0にdefaultされた警告が出ました。今回の範囲では目に見える品質低下はありませんでした。
横断比較
C→Dはweightsを変えず、KVをBF16からFP8にして69.7Kから139.5K tokensへ増えました。A→Bはweightsを変えましたが、FP8 KVは共通で876K tokensでした。今回の容量差はKV dtypeに強く依存しています。
同程度のweight precisionでは、vLLMのraw throughputが高い結果でした。SGLangの出力品質と追従の良さは、今回の作業での主観的な評価です。
| 観点 | 一番良かった構成 | 理由 |
|---|---|---|
| 最高peak throughput | B: vLLM FP8 block + FP8 KV | 115.3 tok/sまで伸びた |
| 日常のthroughput安定性 | A: vLLM NVFP4 + FP8 KV | 90-100 tok/s帯で安定し、accept peakも高い |
| MTP acceptance ceiling | A: vLLM NVFP4 + FP8 KV | 99.5%まで見えた |
| SGLangの実用構成 | D: SGLang FP8 block + FP8 KV | BF16 KVよりcapacityが大きく、体感品質も良かった |
| KV capacity | A/B: vLLM FP8 KV | 876K tokensを確保 |
採用した構成と比較条件
Dの典型decodeは70-90 tok/sでした。速度だけでなく、ツール利用と出力の安定感を重視して選びました。
比較の条件と未解決の点です。
- vLLMは
--max-num-seqs 1の単一ストリーム測定。 - vLLMの値はruntime-reported
accepted throughput、SGLangの値はdecode throughputであり、完全に同じ指標ではない。 - MTPを使う構成ではGemma 4 Assistant draft modelを使っている。
- NVFP4は繰り返しで破綻する場面があり、samplingか設定に未確認の問題が残っている可能性がある。
私はSGLang FP8を採用しました。役割に合わせ、CTX 96-128K、KV FP8で使う想定です。
