見出し画像

DGX Spark / GB10でGemma 4 31Bを約5倍速くした話 (NVFP4 + MTP)

5月になってGoogle様から、MTPの話が出ていたので、試してみました。

というのも、DGX Spark、というかGB10を使っていて、ずっと思っていたことがあります。

大きいモデルは載る。でも遅い。

メモリはあるし、31BクラスのモデルもBF16で起動はできます。
ただし、素のままだとdecodeが遅くて、チャット用LLMとしてはかなり厳しい。

特にGemma 4 31BをBF16でそのまま動かすと、実測では 3.8 tok/s前後 しか出なかった。

正直、これはバックエンドの処理で時間に余裕があるときの使い方になってしまう。

ところが、今回 NVFP4量子化モデルGemma 4 MTP(Multi-Token Prediction) を組み合わせたら、かなり見え方が変わりました。

結論から言うと、GB10上でGemma 4 31B相当のモデルが、制御JSON生成タスクで 約19.79 tok/s まで出ました。

BF16 no-MTPでは 約3.77 tok/s だったので、約 5.25倍

これは普通うれしい数値です。
20token/s出ないとストレスに感じるというのが個人的な持論としてあるからです。

ということで、検証結果をまとめていきます。

検証環境

今回の環境は以下。

Machine:DGX Spark / GB10

Architecture:aarch64

GPU:NVIDIA GB10

Driver:580.142

CUDA:13.0

Container:vllm/vllm-openai:nightly-aarch64

vLLM:0.20.2rc1.dev246+g28ee78af5

使ったモデルは主にこのあたり。

BF16:
  google/gemma-4-31B-it

NVFP4:
  nvidia/Gemma-4-31B-IT-NVFP4

MTP assistant:
  google/gemma-4-31B-it-assistant

MTPは、Gemma 4用のassistant modelを使って、複数トークンを先読みする仕組みです。

詳しくはこちら


今回のログでも、Gemma4MTPModel として認識され、drafter modelのロード、embedding共有、draft layer割当まで確認できました。
つまり、普通のdraft model扱いではなく、Gemma 4 MTPとして動いています。

ということで、個人的な利用方法を検討するために簡単なベンチマークを取ってみました。

結果

今回の速度結果です。

以下コピペ用テキストで同じ内容です
| 構成 | short | medium | 制御JSON |

| BF16 no-MTP | 3.77 tok/s | 3.79 tok/s | 3.77 tok/s |
| NVFP4 no-MTP | 6.86 tok/s | 6.86 tok/s | 6.82 tok/s |
| BF16 + MTP | 8.33 tok/s | 10.13 tok/s | 12.21 tok/s |
| NVFP4 + MTP | 16.34 tok/s | 16.87 tok/s | 19.79 tok/s|

なお、ここでのtok/sはcompletion tokensベースで見ています。
入力promptのprefill時間を完全に分離したものではなく、実際にAPIリクエストを投げて返ってくるまでの時間から算出した実用寄りの値です。

一番重要なのはここ。

制御JSON生成:

BF16 no-MTP:
  3.77 tok/s
  68.984 sec

NVFP4 + MTP:
  19.79 tok/s
  13.982 sec

つまり、同じような制御JSON生成で、約69秒 → 約14秒まで短縮できました。

ベンチマーク内容

今回のベンチでは、3種類のプロンプトを使いました。

short

短い説明文を生成させるテスト。

Gemma 4 MTPの仕組みを日本語で150字で説明して。

短文応答でどれくらい出るかを見るためのもの。

リアルタイムチャットに近いですが、今、動かしているデジタルヒューマンなどで使うとなると、実際の会話システムではTTSやUI処理も入るので、これはあくまで単純な短文生成ベンチ。

medium

技術説明をある程度まとまった長さで生成させるテスト。

Gemma 4 MTPの仕組み、メリット、制約、ローカルLLM運用での使いどころを日本語で800字程度で説明してください。

短文よりもdecode量が増えるので、MTPの効果が出やすい。

制御JSON

バックエンド判断LLMを想定した構造化出力テスト。
入力として、現在状態と今回の差分を渡し、次ターン用の制御JSONを返させます。

具体的には以下のような内容。
(この前作ったAIノベルゲームでのLLM責務の一部です)

{
  "state_patch": {
    "npc_emotion": "...",
    "relationship_delta": 0,
    "scene_flags_add": [],
    "scene_flags_remove": []
  },
  "front_directive": {
    "goal": "...",
    "tone": "...",
    "avoid": [],
    "must_include": []
  },
  "event_candidates": [
    {
      "event": "...",
      "trigger": "...",
      "priority": 0.0
    }
  ],
  "continuity_check": {
    "contradictions": [],
    "risk": "low"
  }
}

このテストは、雑談ではなく、裏側で状態更新・方針生成・次ターン制御を行うバックエンドLLM用途を想定しています。

今回の検証では、この制御JSONが一番MTPと相性が良かった形でした。

改善倍率

BF16 no-MTP比で見ると以下です。

NVFP4だけでも約1.8倍くらい速くなりました。

そもそもDGX Spark でBF16で推論を常用して何かをすることは、ナンセンスなのは事実ですが、まあ、インパクトのある数値のために並べました。

NVFP4:
 1回あたりの推論を軽くする

MTP:
 本体モデルを呼ぶ回数を減らす

この2つを組み合わせたときに、一気に効果が出た感じです。

なぜ制御JSONが速いのか

今回、普通の文章生成よりも、制御JSON生成が一番伸びました。

理由はたぶん以下のような所だと思います。

- JSONは構造が固定されている
- キー名が予測しやすい
- 似たパターンが繰り返される
- 次トークンの予測が当たりやすい

MTPは、assistant modelが先のトークンを予測して、本体モデルが検証する仕組みです。

なので、自由文よりも、固定スキーマのJSONの方が相性が良い可能性があります。

今回の結果を見る限り、少なくとも制御JSON系ではかなり効いている感じです。

これでGB10は、速くて賢いLLMマシンになれるのか?

答えはNOです。

GB10がRTX5090やクラウドGPUみたいに、爆速チャットLLMマシンになったわけではありません。

Gemma 4 31B級で20 tok/s弱なので、フロント会話用としてはまだ重い形です。

ただし、使い方を変えると話が変わります。
GB10は、以下の用途には向いていない。

- リアルタイム雑談
- TTS前段の即時応答
- IDEのリアルタイム補完
- 1秒以内の短文応答

でも、こういう用途ならかなり使えると思います。

- 状態更新
- 方針生成
- 制御JSON生成
- コード設計
- ログ解析
- 破綻検出
- 複数コンポーネントの整理
- フロントLLMへの指示生成

つまり、GB10を「会話の口」にするのではなく、裏側で判断するバックエンドLLMとして使うこと。

ここがたぶん正解かと。

個人的に想定している使い方

デジタルヒューマン的なものとして、考えた場合の構成としては以下。

User
  ↓
Front LLM
  - 即時応答
  - TTS用speech生成
  - motion / expression制御
  - 軽量・高速モデル

  ↓ 非同期

Backend Control LLM on GB10
  - Gemma 4 31B NVFP4 + MTP
  - 状態差分パッチ生成
  - 次ターン方針
  - 矛盾検出
  - コード設計
  - ログ解析
  - 制御JSON生成

フロントLLMはテンポ重視。
GB10上の31Bは、裏側で重い判断。

この構成なら、10〜20秒程度の処理でも成立します。

むしろ、毎ターン同期で待つのではなく、裏で走らせて次ターン以降に効かせる方がいいです。

長期一時記憶としてのGB10

今回、速度ベンチだけではなく、長めのcontextでも試しました。

max_model_len=65536 で起動し、長い擬似セッションログを読ませました。

結果は以下。

25,902 tokens:
  48.936 sec
  重要情報の抽出は正解

50,802 tokens:
  130.721 sec
  重要情報の抽出は正解

ちなみにここで見ているのは速度ではありません。

見たいのは、"長い作業セッションを、一時記憶として読めるか"という点。

結果として、50k tokens級の入力から、以下のような値を正しく拾えました。

{
  "fastest_config": "NVFP4 + MTP",
  "control_json_tokens_per_sec": 19.79,
  "improvement_over_bf16_no_mtp": 5.25,
  "recommended_role_for_gb10": "バックエンド判断LLM",
  "confidence": "high"
}

つまり、GB10は短文即応マシンではないが、長い作業ログや会話履歴を読んで、状態整理や方針生成を行うマシンとしては使える可能性があります。


64kは実用候補、131kは危険

さらに max_model_len=131072 でも起動自体はできました。

ただし、100k級の長文一時記憶テストを走らせたところ、SSHだけでなく画面出力も戻らないレベルでシステムが固まりました。
最終的にはハードリセットが必要でした。

なので、現時点の判断は以下です。

32k:
  普通に実用候補

64k:
  長期一時記憶としてかなり有望

131k:
  起動はできるが、長文実処理では危険

200k:
  未検証。131kで危険域だったため、今回は対象外。

GB10はメモリがあるので、長contextを使いたくなりますが、
実用では64kくらいを現実的なラインとして見る方がよさそうです。

実行コマンド

最終的に使えたコマンドはこれ。

sudo docker run --rm --gpus all \
  --ipc=host \
  -p 8000:8000 \
  --env HF_TOKEN="$HF_TOKEN" \
  --env HUGGING_FACE_HUB_TOKEN="$HF_TOKEN" \
  -v ~/hf-cache:/root/.cache/huggingface \
  vllm/vllm-openai:nightly-aarch64 \
  nvidia/Gemma-4-31B-IT-NVFP4 \
  --host 0.0.0.0 \
  --port 8000 \
  --max-model-len 4096 \
  --max-num-batched-tokens 8192 \
  --max-num-seqs 1 \
  --gpu-memory-utilization 0.85 \
  --speculative-config '{"method":"mtp","model":"google/gemma-4-31B-it-assistant","num_speculative_tokens":4}'

長期一時記憶寄りにするなら、たとえば64k。

sudo docker run --rm --gpus all \
  --ipc=host \
  -p 8000:8000 \
  --env HF_TOKEN="$HF_TOKEN" \
  --env HUGGING_FACE_HUB_TOKEN="$HF_TOKEN" \
  -v ~/hf-cache:/root/.cache/huggingface \
  vllm/vllm-openai:nightly-aarch64 \
  nvidia/Gemma-4-31B-IT-NVFP4 \
  --host 0.0.0.0 \
  --port 8000 \
  --max-model-len 65536 \
  --max-num-batched-tokens 65536 \
  --max-num-seqs 1 \
  --gpu-memory-utilization 0.90 \
  --speculative-config '{"method":"mtp","model":"google/gemma-4-31B-it-assistant","num_speculative_tokens":4}'

ただし、--max-num-batched-tokens などは今回の検証用の暫定値です。
本番運用するなら、context長、同時リクエスト数、KV cache、swap使用量を見ながら再調整が必要かと思います。

個人的最終評価

今回の結論は、GB10が爆速チャットLLMマシンになった、という話ではありません。

むしろ逆で、GB10を会話の口にするよりも、裏側の判断ノードとして使う方が向いているという判断です。

NVFP4 + MTPを使えば、31B級モデルでも制御JSON生成で約20 tok/s弱まで出る。

さらに64k context程度なら、長い作業セッションを一時記憶として読ませる用途にも使えそうです。

フロントではなくバックエンド。
即応ではなく重い判断。
短文雑談ではなく、状態整理・コード設計・ログ解析。

この使い方なら、GB10はかなり面白くなってきました。

次は26B A4B NVFP4を試す予定です。

とりあえず、本日はここまで。
2026/5/13

いいなと思ったら応援しよう!