
Article
Qwen3.6をNVFP4版に差し替えたら、GX10でちゃんと速くなった
GX10でQwen3.6を動かせるようになって、OpenClawやAtlasからも使えるところまで来た。
前回までの流れでは、最終的にQwen/Qwen3.6-35B-A3BをvLLMで直接起動する構成に落ち着いていた。GGUFのQ4版は速いが、実用上はtext-onlyだった。Qwen3-VLやSGLangも面白かったが、OpenClaw/Atlasの実用経路ではまだ不安があった。
一方、Hugging Face版のQwen/Qwen3.6-35B-A3BをvLLMで起動すると、テキスト、画像、tool callingを同じOpenAI互換APIで扱える。速度もGemma 4 NVFP4 vLLMよりかなり速い。これでいったん実用候補になった。
ただ、ひとつ気になっていたことがある。
GX10はBlackwell世代のGB10を積んでいる。BlackwellといえばNVFP4だ。では、いま動いているQwen3.6はNVFP4を使えているのか。
答えは、最初は「使えていなかった」。
BF16で動いていたQwen3.6
いままで動かしていたのは、これだった。
model: Qwen/Qwen3.6-35B-A3B
runtime: vLLM
served model: gx10-qwen
context: 131072
dtype: bfloat16
input: text + image
tool parser: qwen3_coder
reasoning parser: qwen3
Qwen/Qwen3.6-35B-A3B自体は、Qwen公式のHugging Faceモデルだ。vLLMでは--dtype bfloat16で起動していた。
つまり、GX10のGPUがNVFP4を扱えるとしても、このモデル実行はNVFP4ではない。BF16で動いている。
ここが少しややこしい。
「GX10がNVFP4対応」と「いま使っているモデルがNVFP4」は別の話だ。GPU側が対応していても、モデルの重みがNVFP4向けに量子化されていて、runtimeがそれを認識して、そのkernelで動いていないとNVFP4実行にはならない。
GGUFのQ4_K_Mも4bitではあるが、これもNVFP4とは別物だ。llama.cpp系の量子化と、Blackwell Tensor Core向けのNVFP4は、同じ「4bit」という言葉でも中身が違う。
NVFP4版Qwen3.6があった
調べると、Qwen/Qwen3.6-35B-A3BをNVFP4量子化したモデルがあった。
RedHatAI/Qwen3.6-35B-A3B-NVFP4
モデルカードでは、Qwen/Qwen3.6-35B-A3BをNVFP4形式に量子化したpreliminary versionだと説明されている。重みとactivationの両方がNVFP4で量子化され、vLLMでの起動例として--reasoning-parser qwen3や--moe-backend flashinfer_cutlassが載っていた。
NVFP4自体は、NVIDIAがBlackwell世代で導入した4bit浮動小数形式だ。単に4bitに詰めるだけではなく、細かいスケーリングなどを使って、低精度でも精度劣化を抑えようとする形式らしい。
ということで、試す価値はある。
ただし、モデルを差し替えるとOpenClawやAtlas側が壊れる可能性がある。なので、同じURL、同じserved model nameで差し替え、ダメだったらすぐ戻せるようにした。
served model: gx10-qwen
endpoint: http://GX10:18081/v1
呼び出す側から見ると、モデル名は変わらない。中身だけBF16からNVFP4に差し替える。
戻すときは、BF16版の起動スクリプトを再実行すればよい。
ssh <hostname> '<start-qwen36-bf16-vllm>'
NVFP4版に戻すときはこちら。
ssh <hostname> '<start-qwen36-nvfp4-vllm>'
実際のホスト名やパスは公開記事では伏せている。ここで大事なのは、アプリ側のモデル名を変えずにバックエンドだけ差し替えたことだ。
NVFP4版の起動
NVFP4版は、次のような設定で起動した。
model: RedHatAI/Qwen3.6-35B-A3B-NVFP4
base model: Qwen/Qwen3.6-35B-A3B
runtime: vLLM
served model: gx10-qwen
context: 131072
dtype: auto
moe backend: flashinfer_cutlass
tool parser: qwen3_coder
reasoning parser: qwen3
vLLMのログでは、ちゃんとNVFP4として認識されていた。
quantization=compressed-tensors
Using FlashInferCutlassNvFp4LinearKernel for NVFP4 GEMM
Using 'FLASHINFER_CUTLASS' NvFp4 MoE backend
初回起動はそれなりに時間がかかった。
| item | value |
|---|---|
| checkpoint size | 23.32 GiB |
| weight download | 72.87s |
| safetensors weight load | 126.47s |
| model loading total | 203.23s |
| model loading memory | 21.88 GiB |
一度起動してしまえば、APIはいつも通りgx10-qwenとして見える。
id: gx10-qwen
root: RedHatAI/Qwen3.6-35B-A3B-NVFP4
max_model_len: 131072
NVFP4版ではKV cacheにもかなり余裕が出た。
available KV cache memory: 62.4 GiB
GPU KV cache size: 3,171,328 tokens
maximum concurrency for 131,072 tokens/request: 24.20x
これは数字としてかなり気持ちがいい。もちろん、実際の同時処理性能はプロンプト長、画像入力、tool calling、OpenClaw側の挙動に左右される。ただ、少なくともメモリ上の余裕はBF16より大きい。
同じベンチでBF16とNVFP4を比べる
比較は、BF16版とNVFP4版で同じプロンプトを投げた。
使ったのは、Atlas/OpenClawっぽい品質タスクと、tool call選択タスクだ。
品質タスクには、次のようなものを入れている。
- OpenClawでmodel.runは成功しているがTelegramグループに返事が見えない、という状況の診断
- Atlas検索結果だけを根拠に答える質問
- 破壊的操作を避ける安全確認
- embedding移行の実装方針
tool callタスクでは、search_hybrid、get_file、execを正しく選べるかを見る。
結果はこうだった。
| group | BF16 mean tok/s | NVFP4 mean tok/s | ratio |
|---|---|---|---|
| quality prompts | 29.99 | 38.86 | 1.30x |
| tool-call prompts | 22.25 | 32.07 | 1.44x |
NVFP4の方が、はっきり速い。
総実行時間でも短くなっている。
| group | BF16 total sec | NVFP4 total sec |
|---|---|---|
| quality prompts | 45.68 | 35.04 |
| tool-call prompts | 4.66 | 3.56 |
1.3倍から1.4倍くらいなので、劇的に別物というほどではない。でも、常用するローカルLLMとしては十分に大きい差だ。特にtool callの応答が軽くなるのは、OpenClawやAtlasの体感に効きそうだ。
個別結果
個別の結果も載せておく。
| run | group | task | sec | tokens | wall tok/s | finish | tools |
|---|---|---|---|---|---|---|---|
| BF16 | quality | ops_diagnosis | 13.90 | 420 | 30.23 | length | - |
| BF16 | quality | atlas_grounding | 2.97 | 85 | 28.64 | stop | - |
| BF16 | quality | safe_ops | 13.73 | 420 | 30.58 | length | - |
| BF16 | quality | implementation_plan | 15.08 | 460 | 30.50 | length | - |
| BF16 | tools | no_tool_needed | 0.75 | 14 | 18.77 | stop | - |
| BF16 | tools | search_needed | 1.53 | 37 | 24.14 | tool_calls | search_hybrid |
| BF16 | tools | get_file_needed | 1.24 | 29 | 23.46 | tool_calls | get_file |
| BF16 | tools | exec_needed | 1.15 | 26 | 22.62 | tool_calls | exec |
| NVFP4 | quality | ops_diagnosis | 9.66 | 384 | 39.76 | stop | - |
| NVFP4 | quality | atlas_grounding | 2.57 | 99 | 38.59 | stop | - |
| NVFP4 | quality | safe_ops | 11.08 | 420 | 37.92 | length | - |
| NVFP4 | quality | implementation_plan | 11.74 | 460 | 39.19 | length | - |
| NVFP4 | tools | no_tool_needed | 0.82 | 23 | 28.20 | stop | - |
| NVFP4 | tools | search_needed | 1.07 | 37 | 34.42 | tool_calls | search_hybrid |
| NVFP4 | tools | get_file_needed | 0.88 | 29 | 33.09 | tool_calls | get_file |
| NVFP4 | tools | exec_needed | 0.80 | 26 | 32.59 | tool_calls | exec |
tool callは、NVFP4でも期待通りだった。
search_needed -> search_hybrid
get_file_needed -> get_file
exec_needed -> exec
ここは大事だ。速度だけ上がっても、OpenAI互換のtool callingが崩れるとOpenClawやAtlasでは使いにくい。今回は少なくとも小テストでは崩れなかった。
画像入力も一応通った
Qwen3.6をvLLMで直接起動している理由のひとつは、画像入力を扱えることだ。
NVFP4版でも、直接APIの画像入力は通った。自由の女神のサンプル画像を投げると、日本語で風景の説明が返った。これはちゃんと画像を読んでいる。
ただし、別のサンプル画像ではHTTP 400になった。MPO画像として扱われ、Qwen3VLProcessor側で失敗したようだった。
なので、ここは少し注意が必要だ。
「NVFP4版は画像がまったく読めない」わけではない。一方で、「画像入力は完全に問題なし」と言うにはまだ早い。実際にOpenClawやAtlasから投げる画像形式で、もう少し確認したい。
ではNVFP4版を採用するのか
現時点では、NVFP4版をそのまま残している。
理由は単純で、BF16版より速く、同じserved model nameで差し替えられ、戻すのも簡単だからだ。
BF16:
Qwen/Qwen3.6-35B-A3B
29.99 tok/s quality
22.25 tok/s tools
NVFP4:
RedHatAI/Qwen3.6-35B-A3B-NVFP4
38.86 tok/s quality
32.07 tok/s tools
OpenClawやAtlasの呼び出し側から見ると、モデル名は今まで通りgx10-qwenのままだ。内部だけNVFP4になった。
このあとOpenClaw Gateway経由のテキスト呼び出しも再確認した。同じモデル参照のまま通り、NVFP4版として応答が返った。画面上の表示名だけ古いままだったので、そこはあとで直した。
この差し替え方は気に入っている。
ローカルLLMを実用で使うとき、モデルを変えるたびにアプリ側の設定を変えるのは面倒だ。今回は、バックエンド側だけを入れ替えて、アプリ側の設定は維持した。ダメだったら戻す。よければそのまま使う。
これはローカルAI専用機らしい運用だと思う。
NVFP4について、ようやく少しわかった
今回の収穫は、NVFP4が単なるスペック表の単語ではなくなったことだ。
最初は「GX10はNVFP4対応らしい」「QwenはNVFP4なのか?」くらいの理解だった。実際には、対応には少なくとも3つの層がある。
1. GPUがNVFP4を高速に扱える
2. モデルがNVFP4形式に量子化されている
3. runtimeがNVFP4用のkernelで実行できる
今回のログでは、2と3が見えた。
model: RedHatAI/Qwen3.6-35B-A3B-NVFP4
quantization: compressed-tensors
kernel: FlashInferCutlassNvFp4LinearKernel
moe backend: FLASHINFER_CUTLASS
これで初めて、GX10のNVFP4対応をちゃんと使っていると言えそうだ。
まとめ
Qwen3.6をBF16からNVFP4版に差し替えたら、GX10ではちゃんと速くなった。
この小さなベンチでは、品質系プロンプトで約1.30倍、tool call系で約1.44倍。しかも、同じgx10-qwenとして出せるので、OpenClawやAtlas側の設定を大きく変えずに試せる。
もちろん、これで全部解決ではない。
画像入力は一部のサンプルでprocessorエラーが出た。OpenClaw Gateway経由のテキストは通ったが、画像やtool-heavyな実運用は、NVFP4版としてもう少し見たい。モデルカードにもpreliminary versionとあるので、長期運用での安定性も見たい。
それでも、今回の結果はかなり良い。
GX10を買った理由は、Mac StudioからLLM負荷を逃がしたいことと、ローカルで色々なモデルや機械学習実験を試したいことだった。NVFP4版Qwen3.6は、その目的にかなり近いところにいる。
次にやるなら、OpenClaw/Atlasの実タスクをNVFP4版で流して、BF16版と体感がどれくらい違うかを見たい。


