MiMo V2.5 Pro IQ2_Sをローカルで動かす: RTX PRO 6000 Blackwell x1/x2 ベンチマーク
Xiaomi MiMo V2.5 Pro 1.02T MoE の IQ2_S GGUF を llama.cpp CUDA13 と RTX PRO 6000 Blackwell Max-Q x 2 で動かし、single/dual GPU の prefill と decode を実測。expert tensor 配置、MTP 未使用状態、ik_llama.cpp の fused QKV 互換性問題、オーケストレーター候補としての所感をまとめる。
Xiaomi MiMo V2.5 Pro (1.02T total / 42B active) の IQ2_S GGUF を、手元の dual RTX PRO 6000 Blackwell Max-Q で動かした。目的は単なる速度測定ではなく、マルチエージェント基盤のオーケストレーター候補として、常駐運用できる速度と扱いやすさがあるかを確かめることだった。
動画リンク: https://www.youtube.com/watch?v=tviNguY-HRE
結論から書くと、dual GPU で decode は安定して 16.5 tok/s 前後まで伸びた。single GPU の 12.4-12.5 tok/s から約 33% の改善だが、GPU を 2 枚使う構成としてのコスパは良くない。MIT ライセンスなので、バッチでデータセットを作るような用途では候補に残る、という感触だった。
今回の要点はこの 4 つに集約できる。
- decode は single GPU で 12.4-12.5 tok/s、dual GPU で 16.5-16.6 tok/s
- head / tail 寄せの配置では伸びが弱かったため、今回は expert tensor を比較的バランス良く配置した
- llama.cpp の MTP support は merge 済みだが、MiMo の
mimo2MTP tensor はこの実行時点では使われていない - ik_llama.cpp は MiMo 2.5 対応自体はあるが、fused QKV layout を読めず、この量子化では未検証になった
環境
| 項目 | 内容 |
|---|---|
| GPU | NVIDIA RTX PRO 6000 Blackwell Max-Q 96GB x 2 |
| CPU | AMD EPYC 9175F 16-Core, SMT disabled |
| RAM | 約 755GB DDR5 ECC, 6000 MT/s |
| Runtime | ggml-org/llama.cpp:full-cuda13 |
| Blackwell | native FP4 enabled |
モデルは AesSedai/MiMo-V2.5-Pro-GGUF の IQ2_S。Hugging Face 上の quant table では 297.45 GiB、2.50 BPW とされている。ベースモデルの XiaomiMiMo/MiMo-V2.5-Pro は MIT ライセンスで、model card では 1.02T total / 42B active、hybrid attention、3-layer MTP、最大 1M context と説明されている。
| 項目 | 内容 |
|---|---|
| Model | MiMo V2.5 Pro |
| Architecture | mimo2 |
| Parameters | 1.02T total / 42B active |
| Quantization | IQ2_S |
| GGUF size | 297.45 GiB |
| Layer layout | blk.0-blk.69 active layers, blk.70-blk.72 MTP heads |
起動コマンド
single GPU baseline は GPU 0 だけを使い、expert tensor の一部を CUDA0 に置いた。
podman run --rm \
--device nvidia.com/gpu=0 \
-p 8000:8000 \
--shm-size 8g \
--cap-add=SYS_NICE \
-v /mnt/data/models/models--AesSedai--MiMo-V2.5-Pro-GGUF:/models:ro,Z \
ggml-org/llama.cpp:full-cuda13 \
--server \
-m /models/snapshots/a8205a14c95fd13018a7776bf0778d1edb6ba2be/IQ2_S/MiMo-V2.5-Pro-IQ2_S-00001-of-00008.gguf \
--ctx-size 49152 \
-fa on -fit on \
-ngl 99 \
-ctk q8_0 -ctv q8_0 \
-ot "blk\.([0-3]|1[6-7]|2[6-7]|3[6-7]|4[6-7]|5[5-7]|6[6-9])\.ffn_.*_exps.*=CUDA0,exps=CPU" \
--no-mmap \
--parallel 1 \
--threads 15 \
--threads-batch 27 \
--batch-size 12288 \
--ubatch-size 6144 \
--jinja \
--kv-unified \
--host 0.0.0.0 --port 8000 \
--alias grandpa
dual GPU では expert tensor を CUDA0 と CUDA1 に分散した。非 expert tensor は -ngl 99 で GPU に置き、Flash Attention を維持する。
podman run --rm \
--device nvidia.com/gpu=all \
-p 8000:8000 \
--shm-size 8g \
--cap-add=SYS_NICE \
-v /mnt/data/models/models--AesSedai--MiMo-V2.5-Pro-GGUF:/models:ro,Z \
ggml-org/llama.cpp:full-cuda13 \
--server \
-m /models/snapshots/a8205a14c95fd13018a7776bf0778d1edb6ba2be/IQ2_S/MiMo-V2.5-Pro-IQ2_S-00001-of-00008.gguf \
--ctx-size 49152 \
-fa on -fit on \
-ngl 99 \
-ctk q8_0 -ctv q8_0 \
-ot "blk\.([0-3]|1[6-7]|2[6-7]|3[6-7]|4[6-7]|5[5-7]|6[6-9])\.ffn_.*_exps.*=CUDA0,blk\.([4-6]|1[8-9]|2[8-9]|3[8-9]|4[8-9]|5[8-9]|6[2-5])\.ffn_.*_exps.*=CUDA1,exps=CPU" \
--no-mmap \
--parallel 1 \
--threads 15 \
--threads-batch 27 \
--batch-size 12288 \
--ubatch-size 6144 \
--jinja \
--kv-unified \
--host 0.0.0.0 --port 8000 \
--alias grandpa
Expert Tensor 配置
| 配置先 | layer |
|---|---|
| CUDA0 | blk.0-blk.3, blk.16-blk.17, blk.26-blk.27, blk.36-blk.37, blk.46-blk.47, blk.55-blk.57, blk.66-blk.69 |
| CUDA1 | blk.4-blk.6, blk.18-blk.19, blk.28-blk.29, blk.38-blk.39, blk.48-blk.49, blk.58-blk.59, blk.62-blk.65 |
| CPU | 残りの expert tensor |
single GPU では CUDA0 に約 18 layer 分、CPU に約 52 layer 分の expert が残る。dual GPU では CUDA0 に約 18 layer、CUDA1 に約 17 layer、CPU に約 35 layer という配分になった。
297.45 GiB の IQ2_S は 192GB VRAM にはそのまま載らない。そこで、attention / norm / embedding は GPU に置いたまま、MoE expert tensor だけを -ot regex で分割した。今回の目的はまず動作と速度感を確認することだったので、より細かい layer 探索はしていない。
ベンチマーク結果
raw timing は次の通り。
Single GPU (1x RTX PRO 6000):
prompt eval time = 27716.99 ms / 15594 tokens ( 1.78 ms per token, 562.62 tokens per second)
eval time = 13512.61 ms / 169 tokens ( 79.96 ms per token, 12.51 tokens per second)
prompt eval time = 4185.57 ms / 136 tokens ( 30.78 ms per token, 32.49 tokens per second)
eval time = 164812.58 ms / 2048 tokens ( 80.47 ms per token, 12.43 tokens per second)
Dual GPU (2x RTX PRO 6000):
prompt eval time = 24150.56 ms / 15594 tokens ( 1.55 ms per token, 645.70 tokens per second)
eval time = 7892.13 ms / 131 tokens ( 60.25 ms per token, 16.60 tokens per second)
prompt eval time = 3109.48 ms / 160 tokens ( 19.43 ms per token, 51.46 tokens per second)
eval time = 123901.10 ms / 2048 tokens ( 60.50 ms per token, 16.53 tokens per second)
| 指標 | Single GPU | Dual GPU | 改善 |
|---|---|---|---|
| Long prefill | 562.62 tok/s | 645.70 tok/s | +14.8% |
| Short prefill | 32.49 tok/s | 51.46 tok/s | +58.4% |
| Decode short | 12.51 tok/s | 16.60 tok/s | +32.7% |
| Decode long | 12.43 tok/s | 16.53 tok/s | +33.0% |
decode は single GPU の 12.4-12.5 tok/s から、dual GPU では 16.5-16.6 tok/s に伸びた。伸び幅は約 33%。GPU 側で処理できる expert 活性が増えたぶん、CPU 経由の計算と転送の比率が下がった。
ただし、dual GPU でも CPU に約 35 layer 分の expert が残っている。毎 token で MoE router が選んだ active expert を CPU 側で計算し、GPU 側と同期する経路が残るので、decode はまだ CPU bound だ。16.5 tok/s 付近で頭打ちになった理由もここにある。
prefill は long で +14.8%、short で +58.4% 伸びた。short prefill の改善が大きいのは、小さい prompt では CPU/GPU 間の足回りより GPU 側の並列度が効きやすいからだと思う。
MTP はまだ使えていない
MiMo V2.5 Pro には 3-layer MTP heads が含まれている。AesSedai の GGUF にも blk.70-blk.72 の tensor は入っているが、この実行では llama.cpp に使われなかった。
W model has unused tensor blk.70.attn_output.weight (size = 106954752 bytes) -- ignoring
W model has unused tensor blk.70.attn_norm.weight (size = 24576 bytes) -- ignoring
W model has unused tensor blk.70.attn_sinks.weight (size = 512 bytes) -- ignoring
W model has unused tensor blk.70.ffn_norm.weight (size = 24576 bytes) -- ignoring
W model has unused tensor blk.70.ffn_gate.weight (size = 106954752 bytes) -- ignoring
W model has unused tensor blk.70.ffn_down.weight (size = 106954752 bytes) -- ignoring
W model has unused tensor blk.70.ffn_up.weight (size = 106954752 bytes) -- ignoring
W model has unused tensor blk.70.nextn.eh_proj.weight (size = 80216064 bytes) -- ignoring
W model has unused tensor blk.70.nextn.enorm.weight (size = 24576 bytes) -- ignoring
W model has unused tensor blk.70.nextn.hnorm.weight (size = 24576 bytes) -- ignoring
W model has unused tensor blk.70.layer_output_norm.weight (size = 24576 bytes) -- ignoring
... (same for blk.71, blk.72)
llama.cpp PR #22673 で MTP support は 2026-05-16 に master へ merge されている。PR の例でも --spec-type draft-mtp と --spec-draft-n-max を使う形になっている。ただし、今回の MiMo GGUF では mimo2 の MTP tensor がまだ runtime 側で認識されず、ロード時に捨てられる。
Xiaomi の model card では MTP による output speed の 3x 化が説明されている。手元の 16.5 tok/s にそのまま 3x を期待したいところだが、仮に +50% 程度でも dual GPU では 24 tok/s 台には届く。今使っているオーケストレーターモデルはだいたい 23-40 tok/s あたりに収まっているので、mimo2 MTP が llama.cpp mainline で実際に使えるようになった時点で、MiMo はもう一度測る価値があると思う。React SPA Spec で走らせた感触も良さそうだった。動画の挙動も参考になる。
ik_llama.cpp では fused QKV で止まる
ik_llama.cpp だともっと TG が伸びるので、本来は ik_llama.cpp でも測りたかった。MiMo 2.5 の support PR も ik_llama.cpp 側にすでにマージされていたので試したが、今回はだめだった。
モデルを読むと fused QKV layout が原因で落ちる。
Image: registry.home.arpa/ik_llama:latest (main branch with #1723 "Support Mimo-2.5")
Memory required for model tensors + cache: 314076 MiB
Memory available on all devices - compute: 92720 MiB
llm_load_tensors: ggml ctx size = 0.66 MiB
llama_model_load: error loading model: check_tensor_dims: tensor 'blk.0.attn_q.weight' not found
llama_model_load_from_file: failed to load model
llama_init_from_gpt_params: error: failed to load model
ik_llama.cpp issue #1769 で扱われている通り、原因は GGUF 側の fused QKV layout とのこと。Xiaomi が公開した MiMo V2.5 Pro safetensors は QKV が fused されており、ggml-org 系の変換は attn_qkv のまま GGUF 化する。一方、ik_llama.cpp 側は separate attn_q / attn_k / attn_v を期待しているため、blk.0.attn_q.weight が見つからない。今後 HF に他の量子化が上がってくるかもしれないが、モデルのダウンロードには時間がかかる。落とす前に、model card で QKV layout が ik_llama.cpp 側の期待と一致しているかを確認した方がよい。
separate Q/K/V の GGUF が出るか、ik_llama.cpp が load 時に un-merge するようになれば再検証できる。現時点では、MiMo V2.5 Pro IQ2_S は llama.cpp mainline での hybrid inference が実用的なルートになる。
コード生成タスクでの挙動
速度とは別に、React SPA のコード生成タスクも触った。React SPA Spec の scaffold 上に hair salon booking SPA を作らせるベンチマークで、完走前に止めたのでスコアは出していない。
それでも、tool use の初動はかなり堅実だった。
package.json、vite.config.ts、tsconfig.json、src/を順に見てから着手したnpm installで依存関係を整えてから実装に入った- ディレクトリを作ってからファイルを書く順序を守った
- TypeScript の discriminated union で予約ステータスを設計した
str_replaceで既存ファイルを差分編集し、丸ごと壊さなかったpackage.jsonがnpm install後に変わったことを検知して読み直した
ローカルモデルでは、terminal を使えない、存在しないファイルを編集しようとする、依存関係を入れずに生成を始める、といった失敗がよくある。MiMo は少なくともその層は越えていた。オーケストレーター候補として見るなら、速度だけでなく一定以上のパラメーター規模も必要なので、実際に長時間走らせてみたい。
ライセンスまわり
MiMo V2.5 Pro が魅力的なのは、MIT ライセンスの 1T-class MoE で、agentic workload を明確に意識しているところだ。Kimi-K2.6 のように性能面で魅力的なモデルでも、商用提供時に売上ベースの追加ライセンス確認が必要になる場合がある。今のところ 200B 超えのパラメーターでライセンスがクリアで、実用的なのは DeepSeek V4、GLM-5.1、MiMo V2.5 Pro だと思う。
結論
MiMo V2.5 Pro IQ2_S は、RTX PRO 6000 Blackwell Max-Q と llama.cpp CUDA13 で 12 tok/s (single GPU) から 16.5 tok/s (dual GPU) 前後で動いた。MTP の対応が進めば、既存のモデルでも output が大きく進歩する可能性があり、ますますローカル LLM の利用は当たり前になっていくのかもしれない。
Claude / Codex はたしかに素晴らしいが、いずれトークン単位での課金に寄っていくのではないかとも思っている。そのときに代替を用意したくても、エージェント開発をするためには Claude / Codex なしではデバッグ、パターンマッチングの生成、量的な開発が厳しい。トークンも以前より少し使うだけで制限に近づいていくので、なんとか年内に仕上げたいところだ。
