Llama-4-ScoutのCPU / GPU速度とキャッシュ
CPU Q6_KとGPU nvfp4でLlama-4-Scoutを比較。LLM導入のバッチ・対話処理を分けるため、速度、cache、100k前後の文脈上限を記録します。
背景
Llama-4-Scoutは16エキスパート、17B活性パラメータのMeta MoEです。128エキスパートのMaverickよりCPUキャッシュを使いやすいのではないかと考えました。
CPU(Q6_K / llama.cpp)とGPU(nvfp4 / vLLM)で速度、品質、メモリを比較しました。CPUは初回とキャッシュが温まった後を分けて測っています。
目的は、GPUなしの llama.cpp で oneshot 要約や fire-and-forget の冪等パイプラインを動かせるか確認することです。GPUのnvfp4も日常の開発支援として使えるか調べました。
目的
- CPU Q6_K推論の定常速度を実測(キャッシュ温後)
- GPU nvfp4推論のPrefill/Decode速度とVRAM配分を記録
- mmapページキャッシュとprompt cacheの効果を定量化
- 100kコンテキスト境界の実態を把握
実験環境
| 項目 | 仕様 |
|---|---|
| CPU | AMD EPYC 9175F(Zen 5, 16C, L3 512MB) |
| メモリ | DDR5-6400 768GB(12ch) |
| GPU | NVIDIA RTX PRO 6000 Blackwell Max-Q(96GB VRAM) |
| OS | Ubuntu 24.04 LTS |
2構成
| 構成 | Runtime | 量子化 | 配置 | ctx |
|---|---|---|---|---|
| A: CPU | llama.cpp | Q6_K(3分割GGUF) | 全CPU | 8,192 |
| B: GPU | vLLM 0.14.0rc1 | nvfp4(NVIDIA ModelOpt) | 全GPU | ~110K |
結果
構成A: CPU Q6_K(th=16, ctx=8K)
| 指標 | 測定値 | 備考 |
|---|---|---|
| PP(Prefill) | 約40 tok/s | 2.5k-5kトークンでも安定 |
| TG(Decode) | 16.3-17.5 tok/s | 16コア均一負荷、温度64℃固定 |
初回はmmapのページフォールト、全promptの評価、KV初期化が重なり遅くなりました。mmap では、起動直後に全重みがRAMへ読み込まれているとは限りません。
2回目以降はOSページキャッシュとprompt cacheで定常速度へ達しました。LCP(Longest Common Prefix)が一致する場合、f_keep > 0.7を確認しています。
Prefillは残りますが、固定prefixを再利用すると差分だけの処理になります。
構成B: GPU nvfp4(vLLM, Blackwell 96GB)
| 指標 | 測定値レンジ | ピーク | 備考 |
|---|---|---|---|
| PP(Prefill) | 700-1,200 tok/s | 1,370 tok/s | 長文プロンプトで顕在化 |
| TG(Decode) | 30-60 tok/s | 112 tok/s | ウォームアップ後安定 |
Prefix Cache Hit Rateは10-48%でした。48%ではTTFTが短くなりました。
GPUのPrefillは1,370 tok/sで、aiderの反復リファクタリングの待ち時間が短く感じました。日本語の技術文書とDjango/Python設計では、FP4でも指示に沿う出力を得られました。
VRAM内訳
| 項目 | 占有量 |
|---|---|
| モデル常駐 | 約63.5 GiB |
| KVキャッシュ利用可能分 | 約20.2 GiB |
| 最大コンテキスト長 | 約110,256 tokens |
BF16相当のKVでは、1GPUの上限は約100kです。256k以上にはFP8 KVまたはTP=2が必要と整理しています。96GBでもモデルとKVが競合するため、ctxはその内訳で決めます。
比較サマリ
| 構成 | TG(tok/s) | VRAM | 用途 |
|---|---|---|---|
| A: CPU Q6_K | 16-17 | 0 | バッチ要約、F&Fパイプライン |
| B: GPU nvfp4 | 30-60 | ~64GB | aider、対話型コード生成 |
考察
CPUキャッシュ戦略の効果
CPUはキャッシュ温後に17 tok/sでした。今回の運用では次を重視しました。
--mlockで重みを物理メモリに固定します。- System Promptを固定し、LCPを一致させます。
- 再起動を避け、キャッシュを使い続けます。
oneshot 要約や同じprefixを持つ冪等バッチは、CPUで処理する候補です。業務システムへのLLM導入でも、対話処理とバッチ処理を分けて考えられます。
16エキスパートの構造的優位性
Scoutは16、Maverickは128エキスパートです。EPYC 9175Fの1CCD=1Core配置では、選択するexpertが少ないとL3に作業領域が残りやすいという解釈です。キャッシュ効果の因果を直接測った比較ではありません。
CPU速度はScout 17、Maverick 21-24 tok/sでした。モデルサイズの影響が大きいと考えています。Scoutは動作を予測しやすい印象でした。
nvfp4の品質
Django/Pythonの設計、ボイラープレート、ロジックレビューでは使える品質でした。数学の厳密な推論はやや弱く感じましたが、指示追従と日本語出力は安定していました。
感想
CPU 17 tok/sとGPU 30-60 tok/sの差は体感できました。非対話型の処理をCPUに任せれば、GPUを別モデルへ使えます。
GPUの1,370 tok/s Prefillと48%のPrefix Cacheは、aiderの待ち時間を減らしました。
固定prefixのバッチをCPU、低遅延の対話をGPUへ分ける構成を考えています。
再現方法
CPU Q6_K
numactl --cpunodebind=0 --membind=0 \
podman run --rm -it \
-p 8081:8080 --shm-size 16g --cap-add=SYS_NICE \
-v "$MO":/models:ro,Z $IMG \
--host 0.0.0.0 --port 8080 \
-m /models/Scout-17B-Q6_K.gguf \
--threads 16 --threads-batch 16 \
--batch-size 2048 --ubatch-size 512 \
--mlock --ctx-size 8192 --flash-attn on \
--parallel 1 --jinja
GPU nvfp4(vLLM)
vllm serve nvidia/Llama-4-Scout-17B-16E-Instruct-NVFP4 \
--dtype auto --gpu-memory-utilization 0.88 \
--max-num-seqs 1 --max-model-len 110000 \
--enable-prefix-caching --trust-remote-code
補足ノウハウ
キャッシュが効かなくなる条件
元のメモでは、次をキャッシュが効かなくなる条件として整理しています。
- prompt先頭のテンプレートやツール定義を1文字でも変えると、prompt cacheが無効になり全Prefillへ戻ります。
- プロセス再起動でOSページキャッシュがパージされ、cold startのI/O待ちが再発します。
- 上限に達すると古いpromptが破棄されます。
100kコンテキスト境界
nvfp4モデルは63.5 GiB、KVは約20 GiBでした。BF16 KVでは約110kが物理上限です。この記録では256k/512k向けにFP8 KV+TP=2へ広げる案を残しています。
