Preview (2026-08-31). The recipe and every number below are final and measured; the card is pending one last sign-off. Expect polish, not surprises.
GLM-5.3-Flash · 512k + MTP + vision, entirely in VRAM, on 2× RTX PRO 6000
524,288 tokens of context, MTP speculative decoding, and vision — simultaneously, with zero CPU offload — on two RTX PRO 6000 Blackwells (192 GB total, TP2, PCIe, no NVLink).
Three consecutive ~501,000-token prompts served to completion in 90–96 s each. 144.5 tok/s single-stream decode (MTP k=1 at 95.8% acceptance). Vision spot-set 10/10, before and after the 500k rounds. Teacher-forced quality 95.57% against the BF16-attention baseline — the same score this checkpoint gets running text-only (gate ≥95).
It fits because the ~19 GiB of BF16 the NVFP4 parent leaves behind — attention, shared/dense
MLP, lm_head, vision tower — is re-quantized to block-FP8, and because the sparse-MLA KV
cache drops from 656 to 444 bytes per token·layer: one fp8 + three fp6 tiles, minus a 128-byte
RoPE slot this NoPE model never reads. The BF16-attention parent cannot load on this hardware
without offloading experts to the CPU; this build serves half a million tokens on it with room
left for a draft model and a vision tower.
Every number on this card was measured on this box. The raw dumps ship in scripts/.
TL;DR
| 512k "everything" lane 🌮 | 262k c=4 lane | |
|---|---|---|
| max context | 524,288 | 262,144 |
| concurrent streams | 1 (requests queue) | 4 |
| decode, short ctx | 144.5 tok/s | 135.5 single · 289.2 aggregate @ c=4 |
| speculative decode (MTP) | k=1 (95.8% accept) | k=1 |
| multimodal | vision on — 10/10 spot-set | vision on — 10/10 |
| largest served prompt | 501,093 tok (3/3 clean, 90–96 s) | KV pool 473,550 tok (1.81× at 262k) |
| quality (TF top-1 vs BF16 base) | **95.57%**¹ (gate ≥95) | 95.57%¹ |
Both lanes run with zero CPU offload. The offloaded setup they replaced decoded at 87 tok/s.
¹ At the 8666 compact-KV rung (1 fp8 + 3 fp6 tiles, 444 B/row). The KV compaction that fits
MTP + vision at 524,288 costs zero measurable teacher-forced quality — the block-FP8 vision
tower freed the weights (87.28 vs 87.47 GiB/rank) that pay for the fp8 first tile. The all-fp6
6666 rung measures 94.10% with a ~0.2 GiB thinner pin, if margin ever matters more than the
last 1.5 points. Repetition probes at 251k: clean (worst 4-gram repeat 3, fail threshold ≥12).
Matched pair: this checkpoint does not load on stock vLLM or the vendor images.
glm5_nextlives in per-model images (vllm#53906 still open) which construct attention unquantized and cannot load an FP8lm_head. Use the patch set inserving/(Dockerfile included). Without it: aKeyErroronweight_scale_invor a vocab assert.
Quickstart
docker build -t local/vllm-glm53:fp8attn-512k serving/
docker build -t local/vllm-glm53:everything serving/everything-lane/
The 512k "everything" lane (MTP + vision + 524,288 — the headline config):
docker run --init --rm --gpus all --runtime nvidia --ipc=host --network host \
--shm-size=32g --ulimit memlock=-1 --ulimit stack=67108864 \
-e VLLM_ENGINE_READY_TIMEOUT_S=3600 \
-e VLLM_KVQ_TILES=8666 \
-v /path/to/GLM-5.3-Flash-NVFP4-FP8ATTN-512K:/model:ro \
local/vllm-glm53:everything /model \
--served-model-name glm-5.3-flash \
--host 0.0.0.0 --port 8000 \
--tensor-parallel-size 2 \
--max-model-len 524288 \
--gpu-memory-utilization 0.95 \
--kv-cache-memory 3390000000 \
--kv-cache-dtype fp8 \
--max-num-seqs 1 \
--max-num-batched-tokens 1024 \
--limit-mm-per-prompt '{"image":1,"video":0}' \
--speculative-config '{"method":"mtp","num_speculative_tokens":1}' \
--kernel-config '{"enable_jit_warmup":false,"enable_cutedsl_warmup":false}' \
--compilation-config '{"cudagraph_capture_sizes":[1,2]}' \
--enable-prefix-caching \
--no-enable-flashinfer-autotune \
--enable-auto-tool-choice --tool-call-parser glm47 --reasoning-parser glm45 \
--trust-remote-code
Capture size 2 matters: MTP decode steps are 2 tokens, and an uncaptured size runs eager —
~27 tok/s instead of ~144. Images go in standard OpenAI image_url content parts (data URLs
supported).
VLLM_KVQ_TILES selects the compact-KV rung:
| rung | row | measured | when |
|---|---|---|---|
8666 |
444 B | 6,364 B/tok · TF 95.57% | the default above |
6666 |
416 B | TF 94.10% | ~5% thinner KV pin, if margin is tighter than quality |
8888 |
528 B | bit-identical to stock rows | provable-zero KV delta, ~15% more KV/token |
| unset | 656 B | pool 417,631 tok | stock rows; caps this feature set at 327,680 |
262k c=4 concurrency lane — the same command with --max-model-len 262144 --max-num-seqs 4 --max-num-batched-tokens 4096 --compilation-config '{"cudagraph_capture_sizes":[1,2,3,4,6,8]}'. Captures must reach 8:
MTP decode is 2 tokens per running sequence, so c=4 decode batches hit 8. Measured: c=1
135.5 tok/s, c=4 289.2 tok/s aggregate (72.3/stream, 2.1×); KV pool 473,550 tokens;
vision 10/10.
Max-quality text-only variant at 512k (TF 95.57%, 101.7 tok/s) — image
local/vllm-glm53:fp8attn-512k; drop -e VLLM_KVQ_TILES, --speculative-config, and vision:
--kv-cache-memory 4241026048 --limit-mm-per-prompt '{"image":0,"video":0}' --compilation-config '{"cudagraph_capture_sizes":[1]}'.
Margin disclosure. Min-free watermark during a full 512k prefill sampled 110–290 MiB across boots and rungs, with recoverable allocator retries at the deepest dips — by design, and with zero request failures across every soak and round. Do not co-locate other GPU tenants during long prefills.
Why every flag is load-bearing (what makes 512k + MTP + vision fit)
--kv-cache-memory(pinned) — the flag that makes the rest possible, and a disclosed trade: the pin bypasses vLLM's memory-profiling gate. On this GPU the boot-time free-memory reading is always ~93.89 of 94.97 GiB (the worker's own CUDA context ≈ 1.05 GiB counts as "used"), so--gpu-memory-utilization≥ 0.989 can never boot. The explicit pin skips profiling and the util gate;0.95is a formality. Headroom was then proven by real ~501k soaks, not a profiler.VLLM_KVQ_TILES=8666(compact KV rows) — the sparse-MLAfp8_ds_mlaKV row is 656 B/token: a 512 B fp8 latent plus a 128 B RoPE slot that is provably inert on this NoPE model (qk_rope_head_dim=0). The patch drops the dead slot and tiles the latent as one fp8 + three fp6 blocks → 444 B/row, 6,364 B/tok effective (measured). That is what lets a 532k-token pool plus the MTP draft's KV live in a 3.16 GiB/rank pin — canonical rows would need ~4.4 GiB this card does not have. Rows are re-staged to canonical 656 B on read; the attention cubin itself is untouched.--max-num-seqs 1 --max-num-batched-tokens 1024— the sparse-MLA prefill carries an O(context) transient (~4+ GiB at 500k). seqs 2 / batched 2048 passes short-context quality and then OOMs at a real 503k prefill. Single-sequence is the 512k use case; concurrent requests queue. (Concurrency wants the c=4 lane, which halves context to pay for it.)--compilation-config '{"cudagraph_capture_sizes":[1,2]}'— MTP decode steps are 2 tokens; both sizes must be captured or decode runs eager (~27 tok/s). JIT warmups off and the bounded-memory indexer (everything-lane/indexer.py) buy the rest.
What exactly is quantized (and what stays BF16, and why)
Rebuilt from the pristine parent by scripts/convert_fp8attn.py + convert_lmhead.py +
convert_fp8visual.py — CPU-only, deterministic, calibration-free, bit-for-bit reproducible
(determinism experimentally verified). 549 tensors go BF16 → F8_E4M3 weight + FP32
weight_scale_inv block scales, dispatched via a MIXED_PRECISION manifest in config.json:
| family | FP8 block | size | round-trip err |
|---|---|---|---|
| routed experts (incl. MTP draft) | NVFP4 — unchanged, LibertAIDAI's work | 163.3 GiB | — |
| KDA q/k/v + b/f_a/g_a (34 layers) | [32,32] | 6.46 → 3.23 GiB | ~2.3–2.4% |
| o_proj, all 46 layers | [128,128] | 3.63 → 1.81 GiB | ~2.3% |
| MLA q_a/kv_a/q_b (12 layers) | [128,128] | 0.75 → 0.38 GiB | 0.12–0.16% |
| shared experts + dense MLP | [128,128] | 2.86 → 1.43 GiB | 0.16% |
| lm_head | [128,128] | 1.18 → 0.59 GiB | 2.64% |
| vision tower Linears (ViT mlp/qkv/proj + merger, 124 tensors) | [128,128] | 1.02 → 0.51 GiB | 2.64–2.65% |
Kept BF16 on purpose: kv_b_proj (MLA absorbs it to BF16 at runtime anyway), KDA f_b/g_b
(the upstream authors are most explicit about delta-rule precision there), the sparse indexer,
embed_tokens, the vision conv/norm remainder (patch_embed, downsample), norms, routers.
The MLA/MLP families measure near-lossless (0.12–0.16%) because base GLM-5.3 is natively block-FP8 — those BF16 tensors are dequantized copies of FP8 originals. The KDA projections sit at the ~2.3% E4M3 floor: a real numerics change on a precision-sensitive path, which is why the quality gate exists. We do not call the attention conversion lossless; we call it 95.57% teacher-forced, with protocol, n, and raw dumps published.
Block [32,32] for the fused KDA in_proj: vLLM fuses q,k,v,b,f_a,g_a into one module with a
32-row b shard at a non-128-aligned offset; the block must be square and divide 32.
Integrity: 121 shards, 150,651 tensors, index↔header cross-check zero mismatches; total_size
exact (186,149,192,912 B = 173.36 GiB).
Measured evidence (memory ledger · fit ladder · quality gates · kernel story · one honest negative)
All numbers measured on 2× RTX PRO 6000 Blackwell Workstation (96 GB, TP2, PCIe), vLLM
0.1.dev20051+g487ecf187 in the patched image. Raw dumps ship in scripts/.
Memory (per rank, vLLM's own ledger). At identical flags to the old offloaded config, FP8 attention+MLP moved the KV pool 340,163 → 645,997 tokens (+90%) and max loadable context 315,392 → 524,288. Offload-free at 524,288: weights+non-torch 84.77 GiB/rank (MTP-off −2.01, vision-skip −0.53, FP8 lm_head −0.29 — each landed to the decimal), KV pinned 3.95 GiB = 526,825 tokens at fp8 (~7.84 KiB/token/rank).
The fit ladder (how the flags were found):
| # | attempt | result |
|---|---|---|
| A | util 0.985, seqs 2, b2048, MTP/mm off | FAIL — avail 3.08 vs 3.92 GiB; O(maxlen) profile peak |
| B | util 0.99 + trims | FAIL — util ≥0.989 can never boot (own CUDA context in the reading) |
| B3 | --kv-cache-memory pin |
boots + serves; pool 552,543 tok |
| C1 | + tuned kernels, seqs 2 | quality PASS, 101.7 tok/s — OOM at a real 503k prefill (O(context) indexer transient) |
| C2 | seqs 1, b1024, pin 3.95, graphs [1] | ACCEPTANCE PASS — 3×503k clean, watermark 290 MiB, zero failures |
| D | + MTP + vision at 524,288, stock KV rows | cannot fit — draft KV alone wants ~1.5 GiB the card doesn't have |
| D2 | + VLLM_KVQ_TILES=6666, pin 3.07 |
ACCEPTANCE PASS — every gate on one boot; TF 94.10% |
| E | + block-FP8 vision tower | weights 87.28 vs 87.47 GiB/rank; vision 12/12 = BF16 baseline |
| E2 | + rung 8666, pin 3.16 |
TF back to 95.57% — the freed weights fund the fp8 first tile |
The everything lane at 524,288 (acceptance boot + rung-promotion confirmations): KV pool
547,486 tokens from a 3.16 GiB/rank pin (6,364 B/tok measured vs 6,352 predicted from the
row math); MTP active at 95.8% acceptance; 144.5 tok/s median short-context decode;
vision 12/12 objective probe + 10/10 spot-set, re-probed clean after the 500k rounds;
repetition probes at 251k clean (worst 4-gram 3); fresh ~501k-token prefills in 85–96 s,
zero hard OOMs across 5 rounds and 3 boots; min-free watermark sampled 110–270 MiB
(boot-variance-dominated, recoverable allocator retries at the deepest dips). The rung ladder
is exact: all-fp6 6666 fits with the fattest margin at 94.10% TF; 8666 recovers 95.57%,
paid for by the FP8 vision tower's freed weights; bit-identical 8888 would need ~0.5 GiB more
pin than exists.
Quality gates (protocol: teacher-forced, identical context, n=271 scored positions; plus 10
greedy generations; scored against the unmodified NVFP4 parent under the unpatched vendor
image — reproduce with scripts/compare.py):
| metric | MLP-only FP8 | + attention FP8 | pre-recal | shipped (recal scales) | everything lane (8666 KV) |
|---|---|---|---|---|---|
| teacher-forced top-1 | 97.4% | 97.05% | 96.68% | 95.57% (gate ≥95) | **95.57%**² (gate ≥95) |
| greedy agreement to 1st divergence | 94.7% | 90.5% | 60.0% (n=25, noisy)¹ | 90.82% | — |
| long-gen degeneracy | none | none | none | none, incl. 2,712-tok gens at 225k & 259,632 ctx | none, incl. 2,912-tok gens at 251k ctx |
¹ Greedy chains on a reasoning model diverge at the first flipped token; teacher-forced is the signal.
² At the 8666 KV rung + block-FP8 vision tower (scripts/results-tf-8666.json). The all-fp6
6666 rung measures 94.10% (96.31% agreement vs the text-only lane's own dump) — disclosed,
selectable by env when a thinner KV pin matters more than the last 1.5 points.
The patched image is bitwise neutral for BF16-attention checkpoints (100.00% agreement,
|Δlogprob| = 0.00000 vs the vendor image). MTP acceptance stays 81–98%. 17×23 → 391 on every
configuration, including served at the 524,288 ceiling.
The kernel story. vLLM ships zero SM120-tuned w8a8 block-FP8 triton configs. The fused
KDA in_proj (N=12576, K=4096, block [32,32]) ran a default config at 313 µs/call — 43.8% of
decode GPU time going to one GEMM. One autotuned JSON (ships in serving/configs/, 22.3 µs at
M=1) plus dropping CPU offload took the checkpoint 66 → 142 tok/s at 114k. Same BLOCK_SIZE_K
k-split, so numerics unchanged. The block-128 GEMMs already ran vendored DeepGEMM SM120 kernels
at ~1.35 TB/s and were left alone.
One honest negative. MLP-only FP8 (round 1) was a net loss: vLLM reserves the profiled activation peak, and activating the FP8 block-GEMM path costs a fixed +0.80 GiB/rank regardless of layer count — it outspent the 0.71 GiB saved (pool −2.8%). Only when attention (+2.81 GiB/rank) joined did the fixed cost amortize 4:1. If you are building a partial-FP8 derivative: go all-in or don't bother.
Input-scales provenance. The parent's expert input_scale tensors went through three
revisions in one day: an input_scale=1.0 placeholder (357b45cc), its retraction
(discussion #7 —
small-amax blocks underflow to zero, input-dependent repetition), and a same-day recalibration
(caca4e6a). This repo pins caca4e6a and gates it directly: 95.57% TF (gate ≥95),
repetition probes clean at 225k and 259,632-token contexts (worst 4-gram repeat 3 and 2 vs fail
≥12), a 503,374-token round in 80.4 s. Dumps: scripts/results-recal.json,
results-longrep-recal.json, results-longrep-prod-topup.json.
Credits
- LibertAIDAI/GLM-5.3-Flash-NVFP4 — the NVFP4 expert quantization and input scales this build stands on.
- chriswritescode-dev/glm-5.3-flash-sm120 —
the SM120 image lineage
serving/patches against; and the vLLM project (Apache-2.0). - local-inference-lab — independently landed
the equivalent MLA quant-config passthrough in their fork
(
8590bf9c) around the same time. - brandonmusic/GLM-5.3-Flash-tr3-4bpw — first zero-offload long-context GLM-5.3 on this hardware (EXL3 route); worth a look if 4-bit KV trade-offs suit you.
Repo layout
├─ model-000{01..120}-of-00120.safetensors # 173.4 GiB: NVFP4 experts + block-FP8 + BF16
├─ model-input-scales.safetensors # recalibrated scales (parent @caca4e6a)
├─ config.json # MIXED_PRECISION manifest (38k+ entries)
├─ serving/ # matched-pair runtime patch (Apache-2.0, vLLM-derived)
│ ├─ Dockerfile ├─ kda.py ├─ model.py ├─ modelopt.py ├─ configs/*.json
│ └─ everything-lane/ # + MTP/vision/512k patch set (compact KV, bounded indexer)
└─ scripts/ # conversion + acceptance harness + raw quality dumps
serving/ is the public cstechdev/vllm:glm53-flash-nope-sm120-cu130-20260826-r1 image (the
chriswritescode-dev/glm-5.3-flash-sm120
overlay of the official per-model image) plus exactly four files: the KDA and MLA quant_config
passthroughs, the FP8_BLOCK dispatch + FP8 lm_head loader, and the SM120-tuned triton config.
serving/everything-lane/ layers the MTP + vision + 512k patch set on top: compact KV rows
(VLLM_KVQ_TILES), the bounded-memory sparse-MLA indexer, and the embedding/vision
quant_config passthroughs. Apache-2.0, SPDX headers retained; the base image is pulled from
Docker Hub, not redistributed.
Known limitations
- Matched pair — loads only under the
serving/patched images. - 512k is single-stream (
--max-num-seqs 1); the sparse-MLA prefill transient is O(context). Concurrency is the c=4 lane's job, at half the context. - One image per prompt as configured (
--limit-mm-per-prompt); the vision tower ships block-FP8 (12/12 objective probe, identical to its BF16 baseline). Video untested. - 110–290 MiB margin during a full 512k prefill (boot-variance-dominated) — no co-tenants.
- The
6666rung trades quality for pin (94.10% vs 95.57%) — selectable, disclosed, off by default. - SM120 only measured — the format is hardware-agnostic; the kernel selection and tuned config are not.
License
Weights MIT © 2026 Z.AI Co., Ltd (LICENSE verbatim). Chain:
zai-org/GLM-5.3-Flash →
LibertAIDAI/GLM-5.3-Flash-NVFP4
(caca4e6a; NVFP4 expert quantization and input scales are their work) → this repo (block-FP8
attention/MLP/lm_head/vision). serving/*.py Apache-2.0 (vLLM-derived). Conversion CPU-only,
deterministic, calibration-free; scripts/convert_fp8attn.py + convert_lmhead.py +
convert_fp8visual.py reproduce the checkpoint bit-for-bit. Not affiliated with Z.ai / Zhipu
or LibertAI.
- Downloads last month
- 245