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 の mimo2 MTP tensor はこの実行時点では使われていない
  • ik_llama.cpp は MiMo 2.5 対応自体はあるが、fused QKV layout を読めず、この量子化では未検証になった

環境

項目内容
GPUNVIDIA RTX PRO 6000 Blackwell Max-Q 96GB x 2
CPUAMD EPYC 9175F 16-Core, SMT disabled
RAM約 755GB DDR5 ECC, 6000 MT/s
Runtimeggml-org/llama.cpp:full-cuda13
Blackwellnative 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 と説明されている。

項目内容
ModelMiMo V2.5 Pro
Architecturemimo2
Parameters1.02T total / 42B active
QuantizationIQ2_S
GGUF size297.45 GiB
Layer layoutblk.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
CUDA0blk.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
CUDA1blk.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 GPUDual GPU改善
Long prefill562.62 tok/s645.70 tok/s+14.8%
Short prefill32.49 tok/s51.46 tok/s+58.4%
Decode short12.51 tok/s16.60 tok/s+32.7%
Decode long12.43 tok/s16.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.jsonvite.config.tstsconfig.jsonsrc/ を順に見てから着手した
  • npm install で依存関係を整えてから実装に入った
  • ディレクトリを作ってからファイルを書く順序を守った
  • TypeScript の discriminated union で予約ステータスを設計した
  • str_replace で既存ファイルを差分編集し、丸ごと壊さなかった
  • package.jsonnpm 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 なしではデバッグ、パターンマッチングの生成、量的な開発が厳しい。トークンも以前より少し使うだけで制限に近づいていくので、なんとか年内に仕上げたいところだ。

参考リンク