GLM-5.2 IQ4_XS on 4× GB10 — 6.28 tok/s, DSA active, full recipe

GLM-5.2 IQ4_XS on 4× GB10 — 6.28 tok/s, DSA active, full recipe

4.6 was so proud we decided to share our first GLM-5.2 run on a four-node DGX Spark cluster.
Everything you need to reproduce it is below.

HARDWARE

  • 4× MSI EdgeXpert GB10, 128GB unified memory each
  • MikroTik CRS812 switch, 200G QSFP56 DAC (one cable per node)
  • DGX OS 7.5.0, Driver 580.142, CUDA 13.0
  • Firmware: EC 10700, SoC 10800 (see note at bottom — this matters)

MODEL

  • unsloth/GLM-5.2-GGUF, UD-IQ4_XS (~365GB across 4 nodes)
  • MIT license, 744B total / 40B active, 256 experts (8 per token)
  • 1M context window

BUILD
git clone GitHub - ggml-org/llama.cpp: LLM inference in C/C++ · GitHub
cd llama.cpp
cmake -B build
-DGGML_CUDA=ON
-DCMAKE_CUDA_ARCHITECTURES=121a-real
-DCMAKE_BUILD_TYPE=Release
cmake --build build -j$(nproc)

LAUNCH (4-node RPC)

Nodes 2-4 (RPC workers):

./build/bin/llama-rpc-server --host 0.0.0.0 --port 50052

Node 1 (head — serves the model):

./build/bin/llama-server
–model <path-to-iq4_xs-shards>/GLM-5.2-IQ4_XS-00001-of-00009.gguf
–rpc 10.10.10.2:50052,10.10.10.3:50052,10.10.10.4:50052
–ctx-size 1048576
–n-gpu-layers 999
–port 8080
–host 0.0.0.0

Transport is RPC over TCP/IP across the QSFP fabric. Not RDMA —
llama.cpp RPC doesn’t use NCCL.

RESULTS
All numbers measured, not estimated.

Smoke tests: 3/3

  • Arithmetic (2+2) ✓
  • Code gen (Python function) ✓
  • 1M-context needle retrieval ✓

Finance quality (ES futures margin calc, temp 0, max reasoning): 12/12

  • Model inferred the $50/point multiplier without being told
  • Correctly handled the “at maintenance, not below” edge case

Throughput:
C=1: 6.28 tok/s decode (rock stable, 6.27-6.29)
C=4: 9.07 aggregate / 2.32 per-request
C=8: 8.50 aggregate — drops below C=4

Concurrency doesn’t scale. RPC pipeline serialization is the ceiling.
This is a single-user research model on llama.cpp, not a throughput server.

Load time: ~24 min (CPU-bound IQ4_XS repack on ARM, one-time cost).

DSA STATUS: ACTIVE
Confirmed through the runtime path, not inferred from the model name.
glm-dsa.cpp selected, lightning indexer executing, sparse KV cache active.
This is real DSA, not a dense-MLA fallback.

MTP STATUS: NOT ACTIVE
The GGUF carries the NextN/MTP tensors (block 78). llama.cpp supports
–spec-type draft-mtp. But glm-dsa.cpp explicitly skips the NextN layers
when building the graph. MTP is in the weights but not wired to the
glm-dsa path.

VLLM / SGLANG ON GB10: BLOCKED
DSA through vLLM or SGLang hits the DeepGEMM arch-gate on SM121
(arch_major must be 9 or 10; SM121 = 12). Same wall as GLM-5.1.
vLLM PR #43477 targets SM120 — unclear if it extends to SM121 and GLM-5.2.

Our separate b12x kernel verification (June 16) confirmed sparse-MLA runs
correct on SM121 (cos≈0.99999). The kernels work. The engine glue doesn’t.

ASKS

  1. MTP + glm-dsa: Anyone wiring the NextN/MTP head into the glm-dsa graph?
    That’s the biggest speed lever.
  2. vLLM/SGLang DSA on SM121: Anyone testing PR #43477 on GB10 with GLM-5.x?
  3. Multi-node transport: Anyone running GLM 5.x multi-node with something
    faster than llama.cpp RPC?

FIRMWARE NOTE (helps everyone, not GLM-specific)
If you’re running MSI EdgeXpert and haven’t checked for firmware updates:
do it now. We had EC 10600 and SoC 10700 sitting. Flashing
to EC 10700 / SoC 10800 cleared a stuck power state that was costing us
on every model. Our 397B SGLang went from 12.8 to 20.83 tok/s after the flash.to a 41-46 C=1 range with MTP. Check: sudo fwupdmgr get-updates

CREDITS

  • ht12 — firmware pointer that solved our 397B throughput gap
  • lukealonso — b12x sparse-MLA verification on SM121
  • Unsloth — GLM-5.2 GGUF quantization
  • ggml-org — upstream llama.cpp with glm-dsa support
  • LA (Claude Opus 4.6) — cluster architecture, benchmark methodology,
    skill documentation, elimination ladder that traced the firmware root cause

— korpy

Thank you for detailed write up. Just downloaded Q4_K_S. Works great. Tons of headroom on the nodes. Any reason you’re picking IQ4_XS specifically?

Memory constraints as IQ4_XS (365GB) was the largest quant we could fit with enough headroom to see what it could do with KV cache at 1M context. IQ4_XS Accuracy wise is 97%+

What are you running it on? What tok/s are you getting?

Same rig (4× GB10, CRS812 200G, UD-IQ4_XS, DSA active). Added -fa auto (works on glm-dsa now — no need for -fa off), ngram self-spec (–spec-type ngram-map-k), -ub 1024, and an RDMA-WRITE patch for the RPC backend.

Final numbers at C=1:

  • Novel decode: ~6.8 tok/s (GB10 compute/mem-bw bound — your 6.28 regime)

  • Structured/high-overlap decode: ~24 tok/s (ngram self-spec, accept ≈0.99; ~29 at map-M=64)

  • Prefill: ~222 tok/s (-ub 1024)

  • RDMA WRITE: +4–22% on the wire, but C=1 decode unchanged — transport isn’t the bottleneck at this quant

  • MTP: still dead (failed to create MTP context, no NextN graph in glm-dsa)

TL;DR: -fa auto + ngram self-spec take structured decode ~6.5 → ~24 tok/s; novel stays GB10-bound at ~6.8.

Unfortunately, I can’t brag too much. I haven’t had time to really dive deep into my setup better.
But I would say Q4_K_S is probably a sweet spot for KLD. I didn’t do an overwrites of the allocator, and it was really just a plug-and-play. My llama branch is ancient and I should probably rebuild, but I do not see the attractive features like MTP available yet, so I will hold off for now.

Also the performance of the model really drops off as context grows, although a little better than Kimi2.6/Kimi2.7, so I do not see the viability of 1M context (possibly 256k).

We all start at 6+ tps tg. How bad does your tg gets at/close to 1M context? (or even at 512k).
I do not see it as very usable much past 128k. If it’s at 1.5 tg at a million, what is the point of pushing it that hard?

@x12-862, we ran the context sweep you asked about.
GLM-5.2 IQ4_XS unpruned, 4-node llama.cpp RPC, DSA active.

Context tok/s C=1 Finance gate
128K 6.38 12/12
256K 6.38 12/12
512K 6.39 12/12
1M 6.40 12/12

Decode is flat across the full envelope, so allocating up to 1M
doesn’t cost decode speed. Quality holds at every depth.
1M fits on 4× GB10 (124.6 GB/node), no OOM.

Caveat: these are decode-at-low-fill numbers. n_ctx is allocated
but the test prompts are short (~120 tokens). This proves the
model loads, serves, and stays correct at every depth. It does
not measure decode with 500K real tokens in-prompt. That’s a
separate test.

Load time: ~20-22 min per launch (CPU IQ4_XS repack on ARM,
one-time cost).

Best,

Mike

Great findings, especially the ngram self-spec results. We can confirm
the MTP wall independently. glm-dsa.cpp explicitly skips the NextN
layers.

Your ngram numbers are interesting for our use case (structured
document processing with lots of templated output). Planning to
test it on our rig.

A few questions:

  • What map-M value gave you the best tradeoff on mixed content?
  • Does ngram self-spec combine with fa auto cleanly?
  • The RDMA WRITE patch — is that upstream or your own?

Also ran a context sweep since you and x12-862 asked:

Context | tok/s C=1 | Finance gate
128K | 6.38 | 12/12
256K | 6.38 | 12/12
512K | 6.39 | 12/12
1M | 6.40 | 12/12

Decode flat across the full envelope. 1M fits on 4x GB10, no OOM.
Caveat: decode-at-low-fill (short prompts, allocated context).
Does not measure decode with 500K real tokens in-prompt.

Current best map-M on mixed content → --spec-ngram-map-k-size-m 48 (m48n8), though I wouldn’t say it’s a settled “best”

No issues with ngram and fa auto

The RDMA WRITE is local brew, vibed up with Opus.

Thanks for confirming asthat lines up perfectly.

Our 15.3 to your 24 gap is your RDMA-WRITE patch. Our M-scaling
divergence (M=48 beats M=64 for us, opposite for you) is the same
cause on stock TCP RPC the batched verify forward in speculative
decode is wire-bound, so larger draft batches cost more than they
save. Your cheaper wire makes larger M pay off.

M=48 best on mixed content matches our finding exactly.

Nice work vibing the RDMA patch with Opus — that’s a real lever
for anyone running multi-node llama.cpp RPC on QSFP fabric.