計測した実行構成

Qwen3-Coder-Next の約80B MoE を、BF16 CPU、IQ4_NL Hybrid / GPU、nvfp4 GPU で動かしました。コード生成、レビュー、セキュリティ監査の開発支援を想定しています。

同じ環境で速度、出力、VRAMを比較しました。BF16 CPU は7.59 tok/s、IQ4_NLは59–85 tok/s、nvfp4のログは17–100 tok/sでした。

目的

  1. BF16 CPU推論の速度と品質を確認(精度最優先モード)
  2. IQ4_NL Hybrid構成でExpert Offloadの速度ペナルティを定量化
  3. nvfp4 GPU推論のスループットを計測
  4. コーディングタスクでの品質評価
  5. Qwen3-Next-80B-A3B-Thinking(Q4_K_M)のCPU推論時のSWAキャッシュ挙動を記録

実験環境

項目仕様
CPUAMD EPYC 9175F(Zen 5, 16C, L3 512MB)
GPUNVIDIA RTX PRO 6000 Blackwell Max-Q(96GB VRAM)
メモリDDR5-6400 768GB(12ch)
OSUbuntu 24.04 LTS

3構成の概要

構成Runtime量子化Expert配置ctx
A: CPU BF16llama.cppBF16(無量子化)全CPU16k
B: Hybrid offloadik_llama.cppIQ4_NLExpert=CPU, Attn=GPU65k
C: GPU nvfp4vLLMnvfp4全GPU32k

結果

構成A: BF16 CPU推論(th=13, ctx=16k)

指標実測値
PP速度(短prompt)33.37 tok/s
PP速度(287トークン)117.40 tok/s
TG速度(持続)7.59 tok/s
TTFT(287トークン)約2.58秒

2,233 tokens の出力でも速度は一定でした。KV cache は q8_0 にしています。

4-bit の影響を避けて比較するため BF16 を使いました。12チャネル DDR5-6400 と Zen 5 AVX-512 BF16 の構成で、decode は7.59 tok/sでした。帯域と演算の寄与は個別には測っていません。

構成B: IQ4_NL Hybrid(Expert CPU offload, ctx=65k)

Run A: exps=CPU(Expert重みをCPUに配置)

指標実測値
GPU buffer(weights)1,403 MiB
CPU buffer(weights)41,472 MiB
graph_splits98
TG速度(加重平均)58.94 tok/s
PP速度(代表値)761-1,120 tok/s

Run B: exps=CPUなし(全重みGPU)

指標実測値
GPU buffer(weights)42,875 MiB
graph_splits2
TG速度(加重平均)85.36 tok/s
PP速度(代表値)880-3,572 tok/s

Expert Offloadの速度ペナルティ: -31%(58.94 -> 85.36 tok/s)

Run A は大半の weights が CPU で、GPU は約1.4 GiBでした。graph_splits は98で、CPU / GPU 間の同期と転送が多い構成です。

Run B は各 task が約85 tok/sに揃いました。GPU weights は42.9 GiB、graph_splits は2でした。

加重平均の算出方法

各 task の gen_tps を gen_tokens 数で重み付けしています。長い生成ほど平均への寄与が大きくなります。

  weighted_gen_tps = S(gen_tokens_i * gen_tps_i) / S(gen_tokens_i)
  

代表的なtask結果(Run A: exps=CPU)

taskprompt tokensprompt tpsgen tokensgen tpstotal ms
82100291.936659.141,458.59
2563,7571,045.8914159.715,953.40
6521,594761.226758.943,230.68
922908678.8118058.524,413.36
2,6632,284961.733,81058.8067,175.38

代表的なtask結果(Run B: exps=CPUなし)

taskprompt tokensprompt tpsgen tokensgen tpstotal ms
2121356.7147185.755,551.35
1,71876880.411,03685.4112,215.63
3,5396472,561.141,42185.5316,866.17
4,9611551,397.332,00785.2823,646.46
9,63830513.4547585.645,605.00

構成C: nvfp4 GPU(vLLM, ctx=32k)

指標実測値
TG速度(安定時)17-100 tok/s(変動大)
PP速度17-669 tok/s(バースト時)

nvfp4 は vLLM の rolling average なので値が変動します。安定した生成窓では58–100 tok/sでした。

3構成比較サマリ

構成TG速度(tok/s)VRAM使用品質用途
A: BF16 CPU7.590最高精密レビュー・監査
B: Hybrid exps=CPU58.94~3GB良好通常コーディング
B: Hybrid 全GPU85.36~43GB良好高速コーディング
C: nvfp4 GPU58-100~22GB良好vLLM統合環境

コード生成の実演動画

コード生成と論理説明の実行を動画に記録しました。

動画リンク: https://www.youtube.com/watch?v=Hm8e7864Fcw

動画で生成の進み方と出力内容を確認できます。

考察

BF16 CPUの用途

7.59 tok/sは対話では遅いため、待てるレビューや監査を候補にしています。BF16 はこの比較の基準ですが、それだけで正確な判断を保証するものではありません。

Expert Offloadの31%ペナルティ

Expert Offload は VRAM を40GB以上減らし、TG は31%低下しました。graph_splits は2から98になり、同期と転送の増加が影響したと考えています。

今回の容量に収まる場合は、全 GPU の方が速い結果でした。

条件は A3B、n_ctx=65536、KV f16、n_batch=2048、-ngl 99 です。この条件の96GB級 GPU では、exps=CPUなし を標準候補にしています。

なぜ遅くなるか:構造的な観点

  1. 同期と転送: graph_splits=98で、CPU / GPU の境界を頻繁に通ります
  2. 容量: Run B の42.9 GiBは96GBに収まるため、Expert を CPUに移す必要がありません
  3. KV: n_ctx=65536 / KV f16の容量は、Expert Offloadでは減りません

コーディングタスクの出力

BF16 のタスクで確認した出力です。

  • SQLi と平文パスワードのリスクを指摘し、修正とユニットテストを生成しました
  • 仕様外の質問には「NOT IN SPEC」と返しました
  • Django 要件の90%を満たしましたが、一部のマルチテナント安全性を見落としました。ドラフトにレビューが必要です

SWAキャッシュ無効化の挙動(Qwen3-Next-80B-A3B-Thinking)

別モデルの Qwen3-Next-80B-A3B-Thinking(Q4_K_M)を CPUで使うと、SWA(Sliding Window Attention)や hybrid / recurrent memory に関係する prompt の全量再処理が起きました。

  slot update_slots: id  1 | task 6686 | forcing full prompt re-processing due to lack of cache data (likely due to SWA or hybrid/recurrent memory, see https://github.com/ggml-org/llama.cpp/pull/13194#issuecomment-2868343055)

slot update_slots: id  1 | task 6686 | erased invalidated context checkpoint (pos_min = 223, pos_max = 223, n_swa = 1, size = 75.376 MiB)
  

約75MiBの checkpoint が破棄されました。Qwen3-Coder-Next IQ4_NL の GPU 検証では見られなかったため、モデルと実行方式を区別して記録しています。

用途別の候補

LLM導入の用途別候補です。

  • BF16 CPU: 待ち時間を許容する監査とレビューの比較基準
  • IQ4_NL Hybrid / GPU: 59–85 tok/sでの日常の生成
  • nvfp4 / vLLM: tool-call-parser、prefix caching、API 統合を使う構成

再現方法

BF16 CPU

  podman run --rm -it \
  -p 8081:8080 --shm-size 16g --cap-add=SYS_NICE \
  -v /mnt/data/hf/hub/models--unsloth--Qwen3-Coder-Next-GGUF:/models:Z \
  compute.home.arpa/llamacpp-zen5:qwen3-coder-next \
  -m /models/snapshots/.../BF16/Qwen3-Coder-Next-BF16-00001-of-00004.gguf \
  --cache-type-k q8_0 --cache-type-v q8_0 \
  --flash-attn on --ctx-size 16384 \
  --parallel 1 --threads 13 --threads-batch 13 \
  --batch-size 2048 --ubatch-size 512 \
  --jinja --host 0.0.0.0 --port 8080
  

IQ4_NL Hybrid(Expert CPU offload)

  IMG=compute.home.arpa/ik_llama-cuda
MO=/mnt/data/hf/hub/models--ubergarm--Qwen3-Coder-Next-GGUF
MODEL=/models/snapshots/.../Qwen3-Coder-Next-IQ4_KSS.gguf

podman run --rm -it --device nvidia.com/gpu=all \
  -p 8001:8080 --shm-size 16g --cap-add=SYS_NICE \
  -v "$MO":/models:ro,Z $IMG \
  --host 0.0.0.0 --port 8080 -m "$MODEL" \
  -c 65536 --threads 13 --threads-batch 23 \
  -b 2048 -ub 2048 -ngl 99 \
  -ot exps=CPU -fa on --no-mmap --jinja
  

IQ4_NL全GPU(Expert GPUロード)

  podman run --rm -it --device nvidia.com/gpu=all \
  -p 8001:8080 --shm-size 16g --cap-add=SYS_NICE \
  -v "$MO":/models:ro,Z $IMG \
  --host 0.0.0.0 --port 8080 -m "$MODEL" \
  -c 65536 --threads 13 --threads-batch 23 \
  -b 2048 -ub 2048 -ngl 99 \
  -fa on --no-mmap --jinja
  

nvfp4 GPU(vLLM)

  podman run --rm --device nvidia.com/gpu=all \
  --security-opt seccomp=unconfined --cap-add SYS_NICE --shm-size=16g \
  -v /mnt/data/hf:/data/hf:Z \
  -v /opt/containers/runtime/vllm/data/gpu_cache:/data/cache:Z \
  -p 8000:8000 \
  -e HF_HOME=/data/hf -e HF_DATASETS_CACHE=/data/hf \
  -e VLLM_CACHE_ROOT=/data/cache -e HF_HUB_OFFLINE=1 \
  -e FLASHINFER_DISABLE_VERSION_CHECK=1 \
  compute.home.arpa/vllm-gpu:nightly vincentzed-hf/Qwen3-Coder-Next-NVFP4 \
  --dtype auto --gpu-memory-utilization 0.88 \
  --max-num-seqs 1 --max-model-len 32768 \
  --enable-prefix-caching --trust-remote-code \
  --enable-auto-tool-choice --tool-call-parser qwen3_coder \
  --reasoning-parser qwen3 --served-model-name qwen3-coder-next-nvfp4
  

Qwen3-Next-80B-A3B-Thinking(CPU推論)

  podman run --rm \
  -p 8081:8080 --shm-size 1g \
  -v /opt/containers/runtime/llamacpp/data/models:/models:Z \
  compute.home.arpa/llamacpp-zen5:latest \
  -m /models/Qwen3-Next-80B-A3B-Thinking-Q4_K_M.gguf \
  --ctx-size 16384 --threads 15 \
  --jinja --reasoning-budget 512 \
  --host 0.0.0.0 --port 8080
  

補足ノウハウ

256kコンテキスト設定

IQ4_NL は ctx=262144まで設定できますが、Expert Offloadと256kでは KV容量が増えます。今回の運用案はctx=65536程度です。

graph_splitsの意味

graph_splits は計算グラフの分割数です。今回は exps=CPUで98、全GPUで2でした。CPU / GPU間の同期と転送が増える配置の参考になります。

運用指針

  • 96GB級GPUでは、基本はexps=CPUなしをデフォルトにする
  • exps=CPUはVRAMが溢れる、または不安定になる場面だけで使う
  • 次はKV量子化とコンテキスト設計を改善候補にします
  • BF16 CPU推論は、待ち時間を許容するバックグラウンド処理の比較基準にします