GLM-5.2 (744B-A40B)のGGUFをローカルで動かす: MTPは効いたか、量子化とexpert配置をいくつか試した記録
GLM-5.2 (744B-A40B MoE)のGGUF量子化モデル2種(1.630bpw / 2.244bpw)を、dual RTX PRO 6000 Blackwell Max-Q (96GBx2) + 768GB RAMのhomelabで動かした記録。作者は2x24GB VRAM向けの構成でMTPによりTG 11.81→18.02 t/s・draft acceptance 0.98を報告しているが、192GB VRAMの手元で試した範囲ではMTPを入れるとTGはむしろ落ちた。
sokann/GLM-5.2-GGUFを手元で動かした記録。試したのはGLM-5.2-GGUF-1.630bpwとGLM-5.2-GGUF-2.244bpwの2つ。
2.244bpwのREADMEには、--spec-type mtp:n_max=4,p_min=0.5でMulti-Token Prediction (MTP)を有効にするとTGが11.81 → 18.02 t/sに上がり、draft acceptanceは0.98259 (508 accepted / 517 generated)に達した、と書かれていて、
受け入れ率は同じフラグで試しても0.8届かないくらいだったが、確かに指定のレイヤーに重みを載せて、-mla 1にするとTGは増えた。(もしかすると-cram 0 の可能性もあったかも
手元はRTX PRO 6000 Blackwell Max-Q 96GBx2 = 192GB VRAMに余裕がある分どうなるか気になったので、2つのモデルを落として、MTPのon/offやexpert配置をいくつか変えながら測ってみた。先に結論を書くと、自分が試した構成ではMTPを入れるとTGはむしろ落ちた。網羅的に試したわけではないので「MTPは効かない」と言い切れないけど、GLM-5.1でも以前ためしたことがあって、mtpを有効にするとTG-5くらいだった。(smol-IQ2K_Sだった記憶)
動画リンク: https://www.youtube.com/watch?v=Wm0SfXveHnQ
テスト環境
- GPU: NVIDIA RTX PRO 6000 Blackwell Max-Q 96GBx2 (PCIe Gen5, NVLinkなし) = 192GB VRAM
- CPU: AMD EPYC 9175F, 16 cores, L3 512MB
- RAM: 768GB DDR5
- Model: sokannのGGUF2種 — 1.630bpwと2.244bpw
- Base model: zai-org/GLM-5.2 (753B params / A40B active, arch
glm-dsa, 79 layers + NextN/MTP layer 1枚, 256 experts, top-8) - Runtime: ik_llama.cpp (CUDA 13), commit
29a54f4, Podman経由
今回落とした2つのモデル:
- 1.630bpw — expertsが
IQ1_S_R4/ 残りがQ6_0、142.9 GiB。192GB VRAMに丸ごと載る。 - 2.244bpw — expertsが
IQ2_KT/ 残りがQ6_0、196.756 GiB (PPL 3.8402)。KV cacheとcompute bufferを足すと192GBをわずかに超えるので、フルGPUには載りきらない。
IQ2_KTもIQ1_S_R4もik_llama専用のquant typeで、mainlineのllama.cppではロードできない(ggml type 133を弾く)。MTP/NextN layer (layer 78)はどちらもQ6_0。
--spec-type mtp:n_max=4,p_min=0.5がMTPを有効にするフラグ。n_maxは1回の投機ステップで提案するdraft tokenの最大数、p_minはdraft headがそのtokenに与える確率の下限で、これを下回る候補は提案されない。
Part 1 — 1.630bpw・フルGPU・MTP off
1.630bpw (142.9 GiB)は2枚に丸ごと載せて、CTX128Kで実行。
podman run --rm --device nvidia.com/gpu=all -p 8000:8000 --cap-add SYS_NICE \
-v /mnt/data/hf/hub/models--sokann--GLM-5.2-GGUF-1.630bpw:/models:ro,Z \
registry.home.arpa/ik_llama:latest \
-m /models/snapshots/451d18c5c05952bc322b9f9e612abc625d48b211/GLM-5.2-GGUF-1.630bpw.gguf \
--merge-qkv --ctx-size 131072 --parallel 1 --threads 15 --threads-batch 15 \
-ctk q8_0 -b 8192 -ub 2048 -ngl 80 -mla 3 -muge -ger -amb 512 \
--temp 0.6 --top-k 20 --top-p 0.95 --jinja --reasoning off \
--host 0.0.0.0 --port 8000 --warmup-batch --alias test-model
Offloadは80/80 layersがGPU (CUDA0 71.0GB / CUDA1 72.7GB / CPU 0.7GB)。zed editorのエージェントで試すと、概ね4k出力くらいから細かなミスが頻出する傾向があって、短出力でつかうならありかもって感じでした。
実測:
Overall: PP 359.5 t/s TG 39.0 t/s E2E 37.0 t/s
Long prefill: 14,895 tokens at ~747 t/s, 78 gen tokens at ~39 t/s, ~22 s total
Steady-state: PP ~250-450 t/s (cached-prefix dependent), TG ~34-40 t/s, E2E ~35 t/s
参考に、CPU only (EPYC + RAM、GPUなし)で18〜20 t/s前後というのもHFのcommunityで見たけどログはなかった。ただ、TGはでてもおそらくPPは結構きついと思う。 -cmoeだと動画に乗せているように試した感じ5 t/sくらいしかでなかった。
Part 2 — 同じ構成でMTP on
Part 1と同一の1.630bpwフルGPU構成に、--spec-type mtp:n_max=4,p_min=0.5を足しただけ。
# ... Part 1 と同一、加えて:
--spec-type mtp:n_max=4,p_min=0.5
実測:
MTP on: TG ~15-22 t/s draft acceptance swings 0.25-0.56 PP 350-750 t/s
MTPを入れるとTGはだいたい半分になった。draft acceptanceがdraft/verifyのオーバーヘッドを取り返すほど高くならない。
draftフィルタが厳しすぎる可能性を潰すために、p_minを0.0まで下げて(フィルタなしで投機を最大に)も試した:
MTP on, p_min=0.0: TG 17-23 t/s acceptance never cleared ~0.56
それでもacceptanceは~0.56までしか上がらなかった。
| Config (1.630bpw, full GPU) | MTP | TG (t/s) | Acceptance |
|---|---|---|---|
-ngl 80 -mla 3 -ger | off | 34-40 | — |
-ngl 80 -mla 3 -ger + spec-type | on | 15-22 | 0.25-0.56 |
-ngl 80 -mla 3 -ger + spec-type, p_min=0.0 | on | 17-23 | <= 0.56 |
Part 3 — 2.244bpw (大きいほうのモデル)
2.244bpw (196.756 GiB)はKVとcompute bufferまで数えると192GBに載りきらない。expertが何層か必ずCPUにこぼれる。試した中で安定して速かったのは2 GPU・-ngl 65・grouped expert routing (-ger)・MTP off。
podman run --rm -it --name test-model --network host --device nvidia.com/gpu=all --cap-add SYS_NICE \
-v /mnt/data/hf/hub/models--sokann--GLM-5.2-GGUF-2.244bpw:/models:ro,Z \
registry.home.arpa/ik_llama:latest \
-m /models/snapshots/16264a0f7b811d976a9acf704d8511f1127ada30/GLM-5.2-GGUF-2.244bpw.gguf \
--merge-qkv --ctx-size 102400 --parallel 1 --threads 15 --threads-batch 15 \
-ctk q8_0 -b 2048 -ub 2048 -sm graph -ngl 65 -mla 3 -amb 512 -muge -ger \
--temp 0.6 --top-k 20 --top-p 0.95 --jinja --reasoning off \
--host 0.0.0.0 --port 8000 --warmup-batch --alias test-model
実測:
2.244bpw, 2 GPU, ngl65, -ger, MTP off: PP 672 t/s TG 15.28 t/s
2.244bpwのベストは~15.28 t/sで、1.630bpwフルGPUの半分以下。品質(PPL 3.84)は上だけど、フルオフロードできない。
Part 4 — 単一GPUにexpertを詰めるだけ詰める(2.244bpw・MTP off)
1枚にできるだけexpertを詰めたらどこまで行くか。-otでexpert 3-5、40-42、60-77をCUDA0にルーティングした:
podman run --rm -it --name test-model --network host --device nvidia.com/gpu=0 --cap-add SYS_NICE \
-v /mnt/data/hf/hub/models--sokann--GLM-5.2-GGUF-2.244bpw:/models:ro,Z \
registry.home.arpa/ik_llama:latest \
-m /models/snapshots/16264a0f7b811d976a9acf704d8511f1127ada30/GLM-5.2-GGUF-2.244bpw.gguf \
-ngl 99 -cmoe \
-ot 'blk\.([345]|1[0-9]2[0-9]|6[0-9]|7[0-7])\.ffn_.*_exps\.weight=CUDA0' \
-ot 'blk\.6\.ffn_(up|gate)_exps\.weight=CUDA0' \
-ot 'blk\.(40|41|42)\.ffn_.*_exps\.weight=CUDA0' \
--threads 15 --threads-batch 15 -mla 3 -amb 512 -c 131072 -ctk q8_0 -khad \
-b 8192 -ub 4096 -wgt 1 -muge --jinja --parallel-tool-calls \
--chat-template-kwargs '{"reasoning_effort": "low"}' \
--host 0.0.0.0 --port 8000 --alias test-model
Offload: expert 3-6、40-42、60-77がCUDA0、残りはCUDA_Host (CPU)。CUDA0 buffer 74347 MiB、CUDA_Host buffer 124459 MiB。121.54 GiBのpinned host memoryの確保に起動時~13秒かかった。
実測(20,508-token prefill、-ub 4096):
2.244bpw, 1 GPU, expert-saturated, MTP off: PP 576.73 t/s TG 10.23 t/s
nvtopでGPU0が85GB/95GB (memory 88%, compute ~32%)。単一GPUでは一番速くて、後述のMTP構成(8.93 t/s, Part 8)より速い。1枚を限界まで詰めてMTP offで回すほうが速かった。
Part 5 — expertをCPUに寄せたときの下限(-ot exps=CPUと-cmoe)
レンジの下を見るために、expertをCPUに寄せた構成も測った。ほとんどCPU + 数層GPUだと:
1.630bpw, -ot exps=CPU hybrid, MTP on: TG 2.34-2.36 t/s (task 0/13)
2.244bpw, -cmoe (all experts CPU): prefill ~63 s for 20,480 tokens, TG a few t/s
-cmoeで全expertをCPUに置く構成は、動画のとおりTG 5 t/s前後しか出ない。しかも20,480 tokenのprefillだけで~63秒かかるので、実用ではなく下限の確認。上の-ot exps=CPU hybridはそこにMTP onを足したもので、2.34-2.36 t/sとさらに落ちる。CPU forwardが律速の構成でMTPを足すと、draft/verifyのオーバーヘッドでむしろ遅くなる方向に効く。
Part 6 — 2.244bpwの-nglを下げていく(何層がCPUに残るか)
2.244bpw・2 GPUで-nglを下げると上位layerのexpertがCPUに残る。1層CPUに置くごとのコストを見るために段階的に下げた。
-ngl 70 (10層をCPU)・MTP off:
podman run --rm -it --name test-model --network host --device nvidia.com/gpu=all --cap-add SYS_NICE \
-v /mnt/data/hf/hub/models--sokann--GLM-5.2-GGUF-2.244bpw:/models:ro,Z \
registry.home.arpa/ik_llama:latest \
-m /models/snapshots/16264a0f7b811d976a9acf704d8511f1127ada30/GLM-5.2-GGUF-2.244bpw.gguf \
--merge-qkv --ctx-size 32768 --parallel 1 --threads 15 --threads-batch 15 \
-ctk q8_0 -b 2048 -ub 2048 -ngl 70 -mla 3 -amb 512 -muge -ger \
--temp 0.6 --top-k 20 --top-p 0.95 --jinja --reasoning off \
--host 0.0.0.0 --port 8000 --warmup-batch --alias test-model
Offload: offloaded 70/80 layers to GPU、CUDA0 91.6GB / CUDA1 89.0GB / CUDA_Host 18.1GB。両GPUがほぼ満杯で、expert 69-78がCPU。
task 0: PP 611 t/s TG 17.64 t/s (20,502-token prefill)
task 69: PP 630 t/s TG 20.02 t/s
TGは17.6-20 t/sで、1.630bpwフルGPUのおよそ半分。nvtopではGPU1が100%に振れる横でGPU0が0%に落ちる動きが見えて、layerがCPU↔GPUを跨いでいるのが分かる。
-ngl 65 (15層をCPU)・MTP on: -ngl 65のhybridに--spec-type mtp:n_max=4,p_min=0.5を足すと:
2.244bpw, ngl65 hybrid, MTP on: TG 4.6 t/s acceptance 0.67-0.71
acceptanceが0.67-0.71と悪くなくても、baseのCPU forwardが遅すぎてMTPでは戻せない。
Part 7 — -mla 1 vs -mla 3
-mla 1はKV VRAMが少なくて済む代わりに-mla 3より遅い。速度とは別に、-mla 1のほうがMTP acceptanceは一貫して少し高かった。2 GPUと1 GPUの両方で同じ傾向だった。
2 GPU・-ngl 50・-otでexpert 3-9 / 40-49・MTP on:
# -mla 1 variant
... -ngl 50 -mla 1 -amb 512 -ot "blk\.([3-9]|4[0-9])\.ffn_.*_exps\.weight=CPU" ... \
--spec-type mtp:n_max=4,p_min=0.5
ngl50, ot[3-9/40-49], -mla 1, MTP on: PP 369 t/s TG 5.40 t/s acceptance 0.763
ngl50, ot[3-9/40-49], -mla 3, MTP on: PP 371 t/s TG 5.14 t/s acceptance 0.712
1 GPU・-ub 4096・MTP on:
1 GPU, -mla 1, MTP on: PP 406 t/s TG 6.52 t/s acceptance 0.766 (470-token gen)
1 GPU, -mla 3, MTP on: PP 505 t/s TG 7.05 t/s acceptance 0.682
-mla 1でacceptanceがだいたい+0.05 (2 GPU 0.712→0.763、1 GPU 0.682→0.766)、-mla 3のほうがPP/TGはわずかに上。どちらにしてもMTP offのbaselineには届かない。
Part 8 — 作者の-ot配置を再現してみる(今回のMTP最良)
2.244bpwのREADMEは2x24GB VRAM向けで、-cmoe + -ot + -mla 1 + -ub 2048 + -cram 0でほとんどのexpertをCPUに押し出す。その配置を手元のマシンに合わせて再現したら、今回のMTP runの中では一番高いacceptanceが出た:
podman run --rm -it --name test-model --network host --device nvidia.com/gpu=all --cap-add SYS_NICE \
-v /mnt/data/hf/hub/models--sokann--GLM-5.2-GGUF-2.244bpw:/models:ro,Z \
registry.home.arpa/ik_llama:latest \
-m /models/snapshots/16264a0f7b811d976a9acf704d8511f1127ada30/GLM-5.2-GGUF-2.244bpw.gguf \
--no-mmap -ngl 99 -cmoe -sm graph \
-ot 'blk\.([345])\.ffn_.*_exps\.weight=CUDA0' \
-ot 'blk\.6\.ffn_(up|gate)_exps\.weight=CUDA0' \
-ot 'blk\.(40|41|42)\.ffn_.*_exps\.weight=CUDA1' \
-mla 1 -amb 512 -c 102400 -ctk q6_0 -khad \
-b 2048 -ub 2048 -wgt 1 -cram 0 -muge -cuda graphs=1 \
--jinja --parallel-tool-calls \
--chat-template-kwargs '{"reasoning_effort": "high"}' \
--spec-type mtp:n_max=4,p_min=0.5 ...
Offload: expertはほぼCPU、blk 3-6 / 40-42だけGPU。実効VRAMフットプリント~48GB
-ot, MTP on: PP 351 t/s TG 8.93 t/s acceptance 0.835
今回のMTPではTG最良(8.93 t/s)・acceptance(0.835) 作者の構成はVRAM最小化の戦略で、~48GBで8.93 t/s出るのはコスパが良いと思う。
1.630bpw (sub-2-bit)の生成品質
短いいくつかの小さい関数を作らせたら実装〜修復までの破綻はなかった。ただ出力が4k tokenを超えたあたりから、細かいミスが連発し始めた。反復の多いコードで==が====になるような結果が多かった。
個人的には短い出力ならもしかしたら使えるかもって感じでした。出力にチェックをかけてSFT用データを短めに量産する、みたいな使い方なら大規模パラメーターならではの内容が取れて活きるかもだけど、長文をやっても歩留まりが悪いと思う。
結果まとめ(今回試した範囲)
| Config | Quant | GPUs | MTP | PP (t/s) | TG (t/s) | Acceptance | VRAM |
|---|---|---|---|---|---|---|---|
Full GPU -ngl 80 | 1.630 | 2 | off | 250-750 | 34-40 | — | 144GB |
Full GPU -ngl 80 + spec | 1.630 | 2 | on | 350-750 | 15-22 | 0.25-0.56 | 144GB |
| Full GPU, p_min=0.0 | 1.630 | 2 | on | 350-750 | 17-23 | <= 0.56 | 144GB |
-ngl 65 -ger -sm graph | 2.244 | 2 | off | 672 | 15.28 | — | 2枚フル+15層CPU |
-ngl 70 (10 CPU) | 2.244 | 2 | off | 611-630 | 17.6-20 | — | GPU180.6+CPU18.1 |
| 1 GPU expert-saturated | 2.244 | 1 | off | 576 | 10.23 | — | 85GB |
author -ot (blk 3-6/40-42) | 2.244 | 2 | on | 351 | 8.93 | 0.835 | ~48GB |
1 GPU -mla 1 | 2.244 | 1 | on | 406 | 6.52 | 0.766 | — |
1 GPU -mla 3 | 2.244 | 1 | on | 505 | 7.05 | 0.682 | — |
-ngl 50 ot, -mla 1 | 2.244 | 2 | on | 369 | 5.40 | 0.763 | — |
-ngl 50 ot, -mla 3 | 2.244 | 2 | on | 371 | 5.14 | 0.712 | — |
-ngl 65 hybrid | 2.244 | 2 | on | — | 4.6 | 0.67-0.71 | — |
-ot exps=CPU hybrid | 1.630 | — | on | — | 2.34-2.36 | — | — |
-cmoe (all CPU) | 2.244 | 2 | on | floor | few | — | — |
PP・TG・VRAMのトレードオフ
- 速度優先: 1.630bpwフルGPU・MTP off — ~37 t/s、VRAM ~144GB。
- VRAM最小: 作者の
-ot配置・MTP on — ~48GBでTG 8.93、PPは351止まりだけコスパよい。
まとめ GLM-5.2-GGUFを、GPU枚数・レイヤー配置・アテンションモード・MTPのon/offをいくつか変えて測った範囲での所感。 今回試したMTP構成は微妙な結果だったけど、VRAM 48GB・TG 8・PP 350くらいでGLM-5.2が動くなら、長時間のパイプ処理とかで使い所はありそう。 MTPのコストや、GLM-5.2を別のハード・別のエンジンで動かす際の工夫については、以下の記事が参考になる: https://dnhkng.github.io/posts/gh200-benchmarking-part-3-glm52/
