
320B の GLM-5.3-Flash を DGX Spark 2 台で動かして 2 台にする価値を測ってみた
はじめに
こんにちは、クラスメソッド製造ビジネステクノロジー部の森茂です。
前回、320B の GLM-5.3-Flash を DGX Spark 1 台に 2-bit の GGUF で載せて、17.7 tok/s で動かしました。320B の MoE が机の上の 1 台で読める速さで返ってくるのは、それだけでも面白い光景でした。ただ、量子化は 2-bit まで削っていますし、思考を既定の max のまま動かすと日本語 10 課題に 15 分かかります。同じモデルをもう 1 台につないだらどうなるか、というのが今回の話です。
2 台あれば統合メモリは合わせて 242 GiB で、コミュニティが公開している NVFP4 の checkpoint(181 GiB)がそのまま載ります。削りは 2-bit よりずっと浅く、エンジンは vLLM のテンソル並列です。DGX Spark を 2 台つないで大きなモデルを動かす話は DeepSeek で 2 回書いてきましたが、1 台で測ったのと同じハーネス、同じ課題で 1 台と 2 台を横に並べられるのは今回が初めてです。2 台目を買う価値はあるのか、という問いに GLM-5.3-Flash で答えてみます。速度が伸びるのは分かりきっているので、見たいのは動くかどうかより、1 台編と同じ課題で使い物になる水準かどうかです。
先に結論を書いておくと、単発の速度は 17.7 → 30.8 tok/s の 1.7 倍で、日本語 10 課題は 927 秒が 344 秒になりました。**動くだけではなく、仕事の道具として使える水準です。**コード生成は 5 問すべて完答、バグ入りリポジトリの修正は 54 秒で完走、ツール呼び出しは tool_choice=required まで契約どおりで、10 ターンの壁打ちでも前提の想起は全問正解でした。ただ、2 台の価値は速度の倍率ではなかった、というのが今回の手応えです。投機デコードを載せたまま 262K コンテキストで 8 スロットが載り、8 並列の合計で 76.4 tok/s、200K トークンのプロンプトを読ませても合言葉を返します。1 人でコードを書く、長い文書を読ませる、数人で使う、多人数で共有する、と用途ごとに構成を選べるので、個人の検証機がチームのサーバーになります。ただ現時点では落とし穴も 1 つあって、日本語は 1 万字に 2 個ほどの割合で漢字が壊れます。原因と対策まで書きました。
1 台編(2026-08-30 時点の記事です)で素性、reasoning_effort、量子化、画像は見終えているので、この記事では 2 台で変わるところに絞ります。
2 台の配線は DeepSeek V4 Flash-0731 の 2 台編(2026-08-10 時点の記事です)から変えておらず、QSFP 直結に MTU 9000 の RDMA のままです。
この記事では、GLM-5.3-Flash の NVFP4 checkpoint を DGX Spark 2 台の vLLM で動かし、投機デコードと並列数を振って用途別の構成を決めるまでと、1 台編と同じハーネスでの比較、日本語の文字化けの原因と対策を紹介します。2 台目を買うか迷っている人に刺さるといいなと思っています。
検証環境は QSFP 直結の DGX Spark 2 台と vLLM のテンソル並列
構成は 1 台を head、もう 1 台を worker にした vLLM の TP=2 です。head が OpenAI 互換の API を受け、重みは 2 台に半分ずつ載ります。環境を表にまとめます。
| 項目 | 内容 |
|---|---|
| 機体 | DGX Spark × 2(GB10、統合メモリ 121 GiB、driver 580.159.03、Docker 29.2 + compose v5) |
| ノード間 | QSFP 直結 200GbE、RoCE v2、MTU 9000。nccl-tests の all_reduce 12.14 GB/s、all_gather 11.57 GB/s |
| 役割 | head(rank 0、API は 127.0.0.1:8888)と worker(rank 1、--headless)を 1 台ずつ |
| image | ghcr.io/tonyd2wild/vllm-glm53-flash:sm121-v11-dflash2(20.7 GB。vLLM 0.1.dev20051、torch 2.13.0+cu130、flashinfer 0.6.17、NCCL 2.29.7、CUDA 13.0) |
| checkpoint | LibertAIDAI/GLM-5.3-Flash-NVFP4(131 ファイル、181 GiB) |
| drafter | incoai/GLM-5.3-Flash-DFlash2(2.2 GB、CC BY-NC-ND 4.0) |
| 起動時間 | worker と head を立ててから API が応答するまで 868〜990 秒 |
構成を図にすると次のとおりです。
compose と env、起動と停止のスクリプト、パッチはひとまとめにして公開しています。読者が今日動かすならこちらの README の手順が近道で、この記事はその裏側の実測と壁の話です。
触らない固定値だけ先に書いておきます。--block-size 2304 は fp8 の paged MQA が要求する page サイズで、外すとエラーなしに出力が壊れます。--language-model-only はマルチモーダルの front-end を読み込まないためのもので、これが無いと 15.7 GiB 余計に食います。tool call の parser は glm47 で、glm を指定すると何も言わずに tool call が消えます。起動順は worker を先に立てて 25 秒待ってから head で、止めるときは両 rank をそろって落とします。片方だけ落とすと残った GPU が 100% のまま固まります。あとはホスト側で vm.swappiness=0 と drop_caches を起動前に入れておくくらいです。
公式の image では起動できず、コミュニティの image とパッチで動かした
vLLM は GLM-5.3-Flash のリリースに合わせて専用の image vllm/vllm-openai:glm53-flash-arm64-cu130 を出していますが、GB10 の 2 台構成ではこのモデルを起動できませんでした。重みのロードと NCCL の接続までは通り、warmup で次の assert が出ます。
RuntimeError: concat_and_cache_mla, /workspace/csrc/libtorch_stable/cache_kernels.cu:866, pe_dim must be 64 for fp8_ds_mla
--kv-cache-dtype を fp8、fp8_e4m3、auto と変えても同じでした。GLM-5.3-Flash は rope の次元が 0 の NoPE モデルで、DeepSeek Sparse Attention の indexer が使うキャッシュ経路を stock のカーネルが受け付けないためです。2 台の Spark で動いたという報告はどれもパッチ済みの image か plugin を使っていて、stock 単体で動いた例は見つかりませんでした。
そこで本線は、tonyd2wild さんが公開している v11 の image に、同じ方が配っている SM121 向けの top-k パッチを compose の bind mount で当てた構成です。パッチは stock との差分 2 か所で、GB10 の共有メモリに収まらない persistent_topk を避けます。これが無いと長いプロンプトで engine が落ちるとのことで、実際この構成では 200K のプロンプトまで通りました。起動は 988 秒で、モデル一覧、数学 1 問、tool call の 3 つのゲートを通っています。
速度を決めるのは投機デコードで、DFlash2 が最速だった
起動できたので、day-1 の構成から 1 因子ずつ変えて測りました。強制長 256 トークンの greedy で、C=1 は 3 回の中央値、コード生成は effort=low の 5 問を実際に解かせたときの実効 tok/s です。行はすべて v11 image + top-k パッチ + fp8_e4m3 KV で、262K コンテキスト、2 スロットです。
| 構成 | C=1 tok/s | TTFT 秒 | C=2 合計 | コード生成 tok/s | head 使用 GB |
|---|---|---|---|---|---|
| 投機なし | 14.55 | 0.231 | 27.19 | 12.06 | 114 |
| MTP k=3 | 27.78 | 0.251 | 30.63 | 22.40 | 117 |
| MTP k=4(day-1) | 25.67 | 0.362 | 37.03 | 22.27 | 117 |
| MTP k=5 | 24.53 | 0.385 | 25.52 | 22.58 | 117 |
| DFlash2 k=7 | 30.84 | 0.236 | 38.15 | 28.24 | 112 |
投機なしの 14.55 tok/s はコミュニティの報告(14.3〜14.6)と一致していて、ここが分母です。モデルに内蔵された MTP ヘッドを使うだけで 24.53〜27.78 tok/s と、+76〜91% になります。k=3 が単発で最速、k=4 が 2 並列の合計で最良、k=5 は並列で落ちる、という並びで、1 台の llama.cpp で draft 3 が最も効いた傾向と同じでした。
さらに伸びたのが DFlash2 です。incoai が公開している GLM-5.3-Flash 専用の drafter で、2.2 GB の別モデルを一緒に読み込みます。単発 30.84 tok/s、コード生成 28.24 tok/s で、MTP k=4 と比べると単発で +20%、コードで +27% でした。速さの差は受理率の差だと見ていますが、今回は受理率そのものは測っていません。1 つ注意があって、この drafter は CC BY-NC-ND 4.0 で配布されています。検証はこれで進めましたが、商用で使うなら MTP k=4 の行が上限になります。
KV キャッシュの型と文脈長は、単発の速度に効きませんでした。KV を bf16 にすると単発は 25.62 tok/s で k=4 の 25.67 と変わらず、2 並列の合計は 30.2 と fp8 の 37.0 を下回ります。262K のままでも 65K に落としても、単発は 27.2 と 28.0、8 並列の合計は 76.4 と 76.0 で差なしです。文脈を削って速度を稼ぐ必要はありません。差が 3% 以内の行は同じと読んでいます。
MoE backend の flashinfer_cutlass、CUDA graph、batched 8192、autotune off、b12x、util 0.90 は今回未測です。
262K のまま 8 スロットが載り、用途は 2 構成で足りる
次に並列数です。1 台編では 65K コンテキストの 8 スロットが上限でしたが、2 台では 262K のまま 8 スロットが載りました。GLM-5.3-Flash は 45 層のうち 34 層が KV キャッシュを持たない線形 attention(KDA)で、9 GiB に固定した KV プールに vLLM の起動ログで 1,103,764 トークン分が入ります。構成ごとの並列合計を並べます。
| 構成 | C=1 | C=2 | C=4 | C=8 |
|---|---|---|---|---|
| 262K、2 スロット、MTP k=4(day-1) | 25.7 | 37.0 | — | — |
| 262K、8 スロット、MTP k=4 | 27.2 | 28.9 | 56.3 | 76.4 |
| 262K、2 スロット、DFlash2 k=7 | 30.8 | 38.1 | — | — |
8 スロットにしても単発は落ちず、MTP k=4 で 8 並列の合計 76.4 tok/s です。1 台の llama.cpp が 8 並列で 63.97 tok/s だったので、合計でも 2 台が上に出ました。一方 DFlash2 を 8 スロットの serve に載せると、4 並列の 70.8 tok/s が峰で、8 並列では 58.9 まで落ちます。drafter が並列で計算を取り合っているのだと思いますが、これは解釈です。1 人なら DFlash2、共有するなら MTP k=4、と投機の種類で使い分ける形になります。
ここまでの実測から、構成は 2 つに絞れました。1 人で使うなら 262K に 2 スロットで DFlash2 を載せた構成 S、数人から多人数で共有するなら 262K の 8 スロットに MTP k=4 です。文脈長を 1 台編の 65K まで落とす必要はなく、262K のままで速度は変わりません。用途ごとの判定は、品質の結果を見たあとで「用途別にどれを選ぶか」の章にまとめます。
公開したレシピでは構成 S が既定で、共有用は起動時に OVERRIDES で切り替えます。
# 共有用: drafter を外して MTP k=4 で 262K × 8 スロット
OVERRIDES="SPEC_METHOD=mtp MTP_NUM_TOKENS=4 KV_CACHE_MEMORY_BYTES=9663676416 MAX_NUM_SEQS=8" scripts/start-worker.sh
1 台のときは「自分が使うための箱」でしたが、262K の文脈を 8 本抱えたまま合計 76 tok/s が出ると、部署の何人かで叩くサーバーとして成立します。2 台にして一番変わったのは速度の数字より、この使い方の幅かなと思っています。
200K トークンのプロンプトでも合言葉を返した
長文は構成 S で測りました。リクエストごとに固有の干し草を用意して 50% の深さに合言葉を埋め、強制長 512 トークンで TTFT、prefill、decode を取り、別のリクエストで合言葉を聞いて想起を確かめます。
| prompt tok | 実測 tok | TTFT 秒 | prefill tok/s | decode tok/s | 合言葉 |
|---|---|---|---|---|---|
| 2,048 | 2,022 | 1.5 | 1,391 | 27.5 | ✅ |
| 8,192 | 8,140 | 5.4 | 1,510 | 71.1 | ✅ |
| 32,768 | 32,751 | 22.2 | 1,473 | 50.9 | ✅ |
| 131,072 | 130,975 | 90.2 | 1,452 | 21.9 | ✅ |
| 200,000 | 200,342 | 139.2 | 1,439 | 21.5 | ✅ |
prefill は 1,391〜1,510 tok/s で 200K まで平坦で、TTFT は長さに比例します。200K トークンのプロンプトだと最初の 1 文字が返るまで 139.2 秒、合言葉は 5 サイズすべてで正しく返ってきました。decode が 8K と 32K で跳ねているのは投機の受理率が上がったためで、干し草を復唱するような出力だと drafter がよく当たります。投機ありの decode は生成する内容に依存するので、長文の指標としては TTFT と prefill を見るのが安全ですね。
2 本同時も回しました。200K を 2 本流すと TTFT は 218.9 秒、prefill は 1 本あたり 1,052 tok/s、合計の decode は 3.3 tok/s で、310 秒で 2 本とも完走します。合わせて 400K トークン分の文脈を同時に抱えた計算です。文脈上限は 262K に設定しているので、1M までは今回試していません。
1 台と同じハーネスで測ると何が変わるのか
ここからは 1 台編と同じ課題を、8 スロットに DFlash2 を載せた serve で回した結果です。文脈長だけは 1 台と同じ 65K に揃えましたが、前章のとおり速度には効きません。1 台の列は 2-bit の GGUF を llama.cpp で動かした前回の値をそのまま使っています。
| 項目 | 2 台 NVFP4(DFlash2、8 スロット) | 1 台 2-bit GGUF |
|---|---|---|
| 速度 C=1 tok/s(TTFT 秒) | 32.34(0.261) | 17.72(0.333) |
| 並列 C=8 合計 tok/s(1 本あたり) | 58.85(15.9)。MTP k=4 なら 76.4 | 63.97(8.42) |
| 日本語 10 課題、effort=max | 7/9、13,833 tok、344.3 秒 | 6/9、14,708 tok、927.0 秒 |
| 日本語、effort=high | 5/9、59.9 秒 | 7/9、141.4 秒 |
| 日本語、effort=low | 7/9、43.4 秒 | 7/9、98.0 秒 |
| コード生成 5 問(max、high、low、16k) | すべて 5/5 完答、49/49 通過 | 4/5(8192 予算の max)、ほかは 5/5、49/49 |
| ツール呼び出し | 5/5、1 メッセージに並列、required 遵守、擬似 FS ✅ | 同じ |
| コード修正(effort=max) | 5/5、6 ターン、17 ツール実行、54.1 秒 | 5/5、5 ターン、10 ツール実行、72.0 秒 |
| エージェント適性で落ちたプローブ | 多ツール選択のみ(3 水準とも) | max は同じ。low と high は長い system prompt も |
| 壁打ち A、B、C(effort=low) | 354 秒、118 秒、62 秒 | 433 秒、209 秒、88 秒 |
| 画像 | 対象外(--language-model-only) |
図表 4/4、OCR の文字誤り率 0.0 |
KV キャッシュの型は 2 台が fp8_e4m3、1 台が f16 で、ここだけは揃えられていません。effort=max の行は 8192 トークンの予算で、固有名詞を残して要約する 1 課題が両機とも思考で予算を食い切って本文が空のまま終わっています。この課題は予算を 16,384 にした別の行で測り直していて、2 台は 6/9、431.3 秒でした。
時間はどの項目でも短くなっています。日本語 10 課題の effort=max は 927 秒が 344 秒、壁打ち A は 433 秒が 354 秒、コード修正は 72 秒が 54 秒です。既定の max のまま動かしても 6 分弱で返ってくるので、1 台編で書いた「max はローカルの速度と桁が合わない」は、2 台だと少し柔らぐ感触でした。合否のほうは、落ちる課題が 50 字制約、指定語、固有名詞と 1 台のときと同じ顔ぶれです。effort=high の 5/9 が 1 台の 7/9 より低く見えますが、1 台編で low を 3 回反復したときも 7/9、7/9、6/9 と揺れていたので、1 回の測定で能力差とは言えません。壁打ち 3 シナリオの機械照合は前回同様に全問正解でした。
並列は正直に書いておくと、DFlash2 の 8 並列合計は 58.85 tok/s で、1 台の 63.97 を下回ります。前章で見たとおり DFlash2 が並列で不利になるためで、1 本あたりは 15.9 tok/s と 1 台の 8.42 より速く、共有するなら MTP k=4 で 76.4 まで出ます。合計だけを見て 2 台が遅いと読まないでください。
エージェント適性の表は、ハーネスが依存する能力を個別に突くプローブであって、ハーネス本体を動かした結果ではありません。2 台では 3 水準とも 40 ツール規模からの選択だけが落ち、1 台で low と high が落としていた長い system prompt は通りました。これも単発の測定なので、量子化の差と断定はしていません。判定は 1 台編と同じで、opencode のようにツールが多いクライアントでは厳しく、Hermes Agent 相当なら使える、です。
日本語は 1 万字に 2 個の割合で漢字が壊れる
本戦の途中で、壁打ちの出力に見慣れない文字が混ざっていることに気づきました。本戦の serve で回した壁打ち A と B の 27,757 字に、U+FFFD の置換文字が 7 個です。「許容�囲」「�実的」のように漢字 1 文字だけが欠けていて、同じプローブを 1 台の 2-bit GGUF で回した 28,000 字超にはゼロでした。速度で構成を決めたあとに、日本語で使うには別の条件があると分かった形です。
条件を 1 つずつ潰しました。表の U+FFFD は出力全体に含まれる置換文字の数です。
| 条件(v11、marlin、fp8_e4m3 KV、temperature 1.0、top_p 0.95) | U+FFFD | 字数 | 1 万字あたり |
|---|---|---|---|
| DFlash2 k=7(構成 S) | 7 | 27,757 | 2.5 |
| MTP k=4 | 5 | 27,823 | 1.8 |
| MTP k=4 + top_k 40 | 13 | 27,475 | 4.7 |
| 投機なし | 2 | 11,840 | 1.7 |
| 投機なし + min_p 0.05(low、high) | 9、2 | 11,787、14,635 | 7.6、1.4 |
| 投機なし + KV bf16 | 14 | 27,937 | 5.0 |
| 投機なし + UTF-8 ガード | 0 | 24,590 | 0.0 |
| 1 台 2-bit GGUF、llama.cpp(参考) | 0 | 28,000+ | 0 |
投機の種類を変えても、外しても出ます。llama.cpp の既定に合わせて top_k 40 や min_p 0.05 で裾を刈っても消えず、KV を bf16 にしても消えません。つまりサンプラーの裾でも KV の精度でもなく、モデルが主要な候補として不正なトークンを選んでいます。
ここで一度、判定を間違えました。logprobs の bytes からトークン列を自前で復号すると文字化けが消えたので、vLLM の増分 detokenizer の表示バグだと結論して表に書いたのです。ところが return_token_ids で受けたトークン ID を checkpoint 同梱の tokenizer.json でオフライン復号し直すと、content と同じ位置に置換文字が再現しました(3 例中 3 例)。logprobs の bytes は detokenizer を通ったあとの差分で、生の語彙バイトではなかったわけです。同じ経路の出力を根拠に経路の欠陥を判定していたので、当然見えません。撤回して、トークン列そのものを疑うことにしました。
原因は tokenizer の 2 バイト断片と 1 バイト継続の分割にある
tokenizer は zai-org 本家と md5 が一致しているので、checkpoint 側の改変ではありません。tokenizers ライブラリで語彙を眺めると、GLM-5.3 の byte-level BPE は日本語の新字体の多くを 1 トークンで持っておらず、「2 バイトの断片 + 1 バイトの継続」の 2 トークンで綴っています。測は e6b8 + ac、範は e7af + 84、陥は e999 + a5 という具合で、語彙 154,820 のうち 1,095 トークンは単体では正しい UTF-8 になりません。モデルは 2 バイトの断片を出したあと、1 バイトの継続を飛ばして次の文字へ進むことがあり、そのとき置換文字が生まれます。
壊れた語の統計がこの分割と一致します。「現実」は 66 回のうち 11 回壊れ、「効果測定」は 5 回、ほかに許容範囲、陥る、桁、継ぎ、併用、拡大、毀損と、どれも断片経路の字を含みます。一方、1 文字 1 トークンで綴れる「現場」は 95 回出てきて一度も壊れていません。どの層で継続の判断が崩れるのか、NVFP4 の marlin 経路なのか v11 のカーネルなのかは、まだ切り分けられていません。1 台の 2-bit GGUF を llama.cpp で回すと同じプローブでゼロなので、モデルの重みそのものではなく、この構成のどこかにある、というところまでです。
UTF-8 ガードで 0 になるが投機とは併用できない
原因層が分からなくても、症状は塞げます。vLLM v1 の logits processor として、バイト列が壊れるトークンを毎ステップでマスクする utf8_guard_lp.py を書きました。文字の途中で終わるトークンの直後は、欠けている継続バイトで始まるトークンだけを許し、文字の境界では継続バイトで始まるトークンを禁止し、単体で不正なトークンは常にマスクします。モデルは自分が書き始めた文字を書き終えるしかなくなります。
OVERRIDES="MTP_NUM_TOKENS=0 LOGITS_PROCESSORS=utf8_guard_lp:Utf8GuardLogitsProcessor" scripts/start-worker.sh
これで 24,590 字に置換文字 0、壁打ちの機械照合は全問正解、日本語比率も 0.945 以上を保ちました。狙った語も現実 15 回、測定 14 回、範囲 11 回がすべて正しく綴られています。
代償は速度です。vLLM は投機デコード中のカスタム logits processor を受け付けないので、ガードを使うには投機を外す必要があり、単発は投機なしの 14.6 tok/s に戻ります。壁打ち A の 10 ターンで比べると、DFlash2 の 353.8 秒がガードありでは 478.6 秒でした。契約書や手順書のように 1 文字の欠けが許されない用途ならガード、対話やコードなら投機、というのが今の使い分けです。4 つ目の構成として、レシピにも同じ行を入れてあります。
用途別にどれを選ぶか
動くことと使えることの間に線を引いておきます。ここでは、ハーネスの課題を落とさないこと、待ち時間が用途に見合うこと、tool_choice のような契約を守ること、文字が壊れないこと、の 4 つを満たせば使える、どれかに条件が付けば条件付き、と判定しています。
| 用途 | 構成 | 速度の目安 | 判定 | 根拠と条件 |
|---|---|---|---|---|
| 1 人でコードを書く、直す | 構成 S(262K、2 スロット、DFlash2 k=7) | 単発 30.8〜32.3 tok/s、コード生成の実効 28.2 tok/s | ✅ 使える | コード生成 5/5・49/49、修正 5/5 を 54.1 秒、ツール呼び出し 5/5 で required も遵守。40 ツール規模からの選択だけ弱い |
| 1 人で長い文書を読ませる、壁打ちする | 構成 S | 200K の TTFT 139.2 秒、prefill 1,391〜1,510 tok/s | ✅ 使える | 2K〜200K で合言葉すべて正答、10 ターンの壁打ちの想起 5 項目も全問正解。200K は最初の応答まで 2 分強待つ前提 |
| 数人から多人数で共有する | 262K、8 スロット、MTP k=4 | 単発 27.2 tok/s、8 並列の合計 76.4 tok/s | ✅ 使える | 4 人同時なら 1 人あたり 15.5 tok/s、8 人同時でも 12.61 tok/s(1 台の 8 人同時は 8.42)。8 本とも 262K の文脈を持てる。1 人用の DFlash2 は非商用ライセンスなので、商用で使うならこの構成 |
| 日本語を 1 文字も落とせない | 投機なし + UTF-8 ガード | 単発 14.6 tok/s | 🟡 条件付き | 24,590 字で置換文字 0、想起全問正解。壁打ち A が 353.8 秒 → 478.6 秒と待ちが増える |
| エージェントとして常駐させる | 構成 S | — | 🟡 条件付き | Hermes Agent 相当は使える、opencode と OpenClaw は多ツール選択で厳しい。プローブでの判定で、ハーネス本体は動かしていない |
表の上 3 行は、どれも課題を落としていません。速度だけ見ると 1 台の 17.7 tok/s でも読める速さでしたが、コード修正が 72 秒から 54 秒、既定の effort=max の日本語 10 課題が 15 分から 6 分弱になると、待っている感覚がかなり違います。個人的には、1 人でコードを書くのと、数人で共有して壁打ちに使うのが、今回一番手応えのあった使い方かなと思っています。
手応えとして残ったのは、320B のモデルが 2 台でチームの道具になることでした。テストが落ちる Python リポジトリを 6 ターン 54 秒で直しきり、12,242 字の文書に質問を 8 回重ねて 62 秒で答え、200K トークンを読ませても合言葉が返ります。それが 4 人で同時に叩いても 1 本 15.5 tok/s を保ち、クラウドではなく机の上の 2 台で動いています。
条件付きの 2 行は正直に書いておきます。日本語を 1 文字も落とせない用途は、投機を外す代わりに置換文字がゼロになるので使えはしますが、単発 14.6 tok/s は 1 台の 2-bit より遅く、待たされる感覚は戻ってきます。エージェントの常駐は、40 ツール規模から正しいツールを選ぶプローブが 3 水準とも落ちているので、ツールの多いクライアントでは 1 台編と同じく厳しいままです。ここは 2 台にしても変わりませんでした。
参考までに、同じプロンプトを Fireworks の GLM-5.3-Flash(glm-5p3-flash)に手元の Mac から投げて比べておきます。単発は中央値 46.6 tok/s(10 回、34.0〜51.8)で 2 台の 30.8 の 1.5 倍、8 並列では 1 本あたり 60 tok/s、合計 397 tok/s と 2 台の 5 倍です。差が大きいのは長い入力で、200K トークンの TTFT は 7.49 秒、手元は 139.2 秒でした。1 つの時間帯に 1 回測っただけの数字で、共有テナントなので回ごとの幅も大きいのですが、速度で 2 台が勝つ場面はほぼ無い、と読んでよさそうです。それでも 2 台を選ぶ理由があるとすれば、データを外に出さない、262K の文脈を自分の箱で抱える、トークン課金がない、の 3 つで、この記事の「チームで使える」はその前提での話です。
まとめ
DGX Spark 2 台で GLM-5.3-Flash の NVFP4 を vLLM で動かし、投機デコードと並列数を振って、1 台編と同じ課題で比べました。
使い物になるか、で言えばなります。1 人でコードを書いて直す、長い文書を読ませる、数人で壁打ちする、多人数で共有する、の 4 つの用途は、課題を落とさず、1 台より速く回りました。構成は用途で選びます。1 人なら 262K に DFlash2 を載せた構成 S で 30.8 tok/s、数人から多人数で共有するなら 262K の 8 スロットに MTP k=4 で合計 76.4 tok/s です。2 台の価値は単発の 1.7 倍より、この幅にありました。
条件付きが 2 つあります。日本語を 1 文字も落とせない用途は投機を外して UTF-8 ガードを入れ、14.6 tok/s で置換文字をゼロにします。ツールの多いエージェントクライアントは、多ツール選択の弱さが 2 台でも残るので厳しいままです。
限界も書いておきます。公式の stock image は起動できず、動いたのはコミュニティの image とパッチの上です。DFlash2 の drafter は CC BY-NC-ND 4.0 なので、商用では MTP k=4 が上限になります。文字化けの原因層は切り分けられておらず、ガードは投機と併用できません。MoE backend の cutlass、CUDA graph、batched 8192 は未測です。単発の速度も 30.8〜32.3 tok/s の幅で揺れています。
次は、同じ checkpoint を SGLang で動かして文字化けが出るかを見て、原因層を切り分けたいところです。RedHat が出している別の NVFP4 checkpoint で checkpoint 起因かどうかも確かめられそうです。
参考リンク
- LibertAIDAI/GLM-5.3-Flash-NVFP4 - Hugging Face
- zai-org/GLM-5.3-Flash - Hugging Face
- incoai/GLM-5.3-Flash-DFlash2 - Hugging Face — DFlash2 drafter(CC BY-NC-ND 4.0)
- tonyd2wild/GLM-5.3-Flash-NVFP4-DFlash2-2x-DGX-Spark — v11 image と SM121 top-k パッチ
- Libertai/glm53-flash-vllm-gb10 — stock image の assert と cutlass の util の床
- himorishige/glm53-flash-2x-dgx-spark-recipe — 今回の compose、スクリプト、パッチ
- GLM 5.3 Flash API & Playground | Fireworks AI — 参考比較に使った API
- 320B の GLM-5.3-Flash を DGX Spark 1 台で動かして実用の分かれ目を測ってみた(2026-08-30 公開)
- 284B の DeepSeek V4 Flash-0731 を DGX Spark 2 台で動かしてみた(2026-08-10 公開)
- DGX Spark 2 台をクラスタケーブルでつないでみた(2026-02 公開)








