Add validated RTX PRO 6000 (SM120) serving recipe
Browse files
README.md
CHANGED
|
@@ -23,9 +23,10 @@ An **INT4 weight-only (W4A16) quantization of GLM-5.2** that preserves the BF16
|
|
| 23 |
layer for speculative decoding. Quantized from [zai-org/GLM-5.2](https://huggingface.co/zai-org/GLM-5.2)
|
| 24 |
with [llm-compressor](https://github.com/vllm-project/llm-compressor) (GPTQ).
|
| 25 |
|
| 26 |
-
**Built for Hopper (H200)
|
| 27 |
-
GLM-5.2 quant for interactive/agentic serving on
|
| 28 |
-
lowest time-to-first-token by a wide margin.
|
|
|
|
| 29 |
|
| 30 |
## Why this model
|
| 31 |
|
|
@@ -134,6 +135,77 @@ vllm serve <repo> --tensor-parallel-size 4 --enable-expert-parallel \
|
|
| 134 |
--max-model-len 32768 --gpu-memory-utilization 0.92 --trust-remote-code
|
| 135 |
```
|
| 136 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 137 |
## Method
|
| 138 |
|
| 139 |
1. **GPTQ W4A16** (group-128, asymmetric) on the routed experts only, with attention/dense/MTP/embeddings/
|
|
@@ -154,8 +226,12 @@ asymmetric-MoE serving fix, and the Blackwell toolchain gaps).
|
|
| 154 |
- 1M-context serving requires all 8 H200s; 4×H200 serves up to ~128K (single-stream engine ceiling ~239K),
|
| 155 |
with MTP acceptance ~38% (vs ~46–52% on 8×H200).
|
| 156 |
- Asymmetric weights require `--enable-expert-parallel` to serve correctly.
|
| 157 |
-
- Pin vLLM v0.23.x (v0.24+ DSA-indexer layout change breaks loading).
|
| 158 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 159 |
|
| 160 |
## Acknowledgements
|
| 161 |
|
|
|
|
| 23 |
layer for speculative decoding. Quantized from [zai-org/GLM-5.2](https://huggingface.co/zai-org/GLM-5.2)
|
| 24 |
with [llm-compressor](https://github.com/vllm-project/llm-compressor) (GPTQ).
|
| 25 |
|
| 26 |
+
**Built for Hopper (H200), validated on Blackwell (8×RTX PRO 6000, SM120).** Matches FP8 quality on
|
| 27 |
+
**half the GPUs** (4×H200 vs 8) and is the **fastest GLM-5.2 quant for interactive/agentic serving on
|
| 28 |
+
Hopper** in a matched, MTP-on head-to-head — with the lowest time-to-first-token by a wide margin. A
|
| 29 |
+
complete, quality-validated RTX PRO 6000 recipe is in the **Serving on Blackwell** section below.
|
| 30 |
|
| 31 |
## Why this model
|
| 32 |
|
|
|
|
| 135 |
--max-model-len 32768 --gpu-memory-utilization 0.92 --trust-remote-code
|
| 136 |
```
|
| 137 |
|
| 138 |
+
## Serving on Blackwell — 8×RTX PRO 6000 (SM120)
|
| 139 |
+
|
| 140 |
+
Validated end-to-end on **8× RTX PRO 6000 (96 GB, SM 12.0, PCIe)**: quality matches the H200 deployment
|
| 141 |
+
(GSM8K 0.948, IFEval 0.909/0.920, MATH-500 0.954 math-verify, RULER@32K 0.918 / @64K 0.826 — all within
|
| 142 |
+
margin of the H200 column above), **zero token corruption**, with MTP speculative decoding and cudagraphs
|
| 143 |
+
both working. Throughput on this config:
|
| 144 |
+
|
| 145 |
+
| concurrency | 1 | 4 | 8 | 16 | 32 | 64 |
|
| 146 |
+
|---|---|---|---|---|---|---|
|
| 147 |
+
| output tok/s | 50 | 148 | 280 | 400 | 613 | **989** |
|
| 148 |
+
|
| 149 |
+
For reference, `nvidia/GLM-5.2-NVFP4` on the same box (MTP **off** — a matched MTP-on NVFP4 run was not
|
| 150 |
+
completed) measures 36 tok/s at c=1 and 447 at c=64. Single-stream speed is memory-bandwidth-bound on this
|
| 151 |
+
hardware (~50 vs ~126 tok/s on H200); the sweet spot is concurrent/batch serving.
|
| 152 |
+
|
| 153 |
+
**Why SM120 needs a different recipe:** no SM120 sparse-MLA kernel supports GLM-5.2's DSA head layout, so
|
| 154 |
+
DSA sparse attention is disabled and the model serves through dense `TRITON_MLA`. That takes four one-line
|
| 155 |
+
patches on the official `vllm/vllm-openai:glm52` image:
|
| 156 |
+
|
| 157 |
+
```dockerfile
|
| 158 |
+
FROM vllm/vllm-openai:glm52
|
| 159 |
+
|
| 160 |
+
# 1. Disable DSA sparse attention (no SM120 sparse-MLA backend for this head size)
|
| 161 |
+
RUN sed -i 's/self\.is_v32 = hasattr(config, "index_topk")/self.is_v32 = False/g' \
|
| 162 |
+
/usr/local/lib/python3.12/dist-packages/vllm/model_executor/models/deepseek_v2.py
|
| 163 |
+
|
| 164 |
+
# 2-4. Skip the now-orphaned DSA indexer weights during load (deepseek_v2.py,
|
| 165 |
+
# deepseek_mtp.py, glm4_moe_mtp.py): guard `param = params_dict[name]` with
|
| 166 |
+
# `if name not in params_dict: continue`
|
| 167 |
+
RUN python3 - <<'EOF'
|
| 168 |
+
import re
|
| 169 |
+
base = '/usr/local/lib/python3.12/dist-packages/vllm/model_executor/models/'
|
| 170 |
+
for f in ('deepseek_v2.py', 'deepseek_mtp.py', 'glm4_moe_mtp.py'):
|
| 171 |
+
p = base + f
|
| 172 |
+
src = open(p).read()
|
| 173 |
+
src = re.sub(r'(\s+)param = params_dict\[name\]',
|
| 174 |
+
r'\1if name not in params_dict:\n\1 continue\n\1param = params_dict[name]', src)
|
| 175 |
+
open(p, 'w').write(src)
|
| 176 |
+
EOF
|
| 177 |
+
```
|
| 178 |
+
|
| 179 |
+
Then serve (`docker build -t glm52-mtp-sm120 .` first):
|
| 180 |
+
|
| 181 |
+
```bash
|
| 182 |
+
docker run -d --gpus all --ipc=host --shm-size 16g \
|
| 183 |
+
-v /path/to/GLM-5.2-W4A16-MTP:/model:ro -p 8000:8000 \
|
| 184 |
+
-e NCCL_P2P_DISABLE=1 -e VLLM_USE_DEEP_GEMM=0 -e VLLM_MOE_USE_DEEP_GEMM=0 \
|
| 185 |
+
glm52-mtp-sm120 /model \
|
| 186 |
+
--tensor-parallel-size 8 --enable-expert-parallel \
|
| 187 |
+
--attention-backend TRITON_MLA \
|
| 188 |
+
--speculative-config '{"method":"mtp","num_speculative_tokens":1}' \
|
| 189 |
+
--compilation-config '{"cudagraph_mode":"PIECEWISE","cudagraph_capture_sizes":[2,4,8,16,32,64],"max_cudagraph_capture_size":64}' \
|
| 190 |
+
--max-model-len 131072 --max-num-seqs 64 --gpu-memory-utilization 0.92 \
|
| 191 |
+
--reasoning-parser glm45 --tool-call-parser glm47 --enable-auto-tool-choice \
|
| 192 |
+
--disable-custom-all-reduce --trust-remote-code
|
| 193 |
+
```
|
| 194 |
+
|
| 195 |
+
Every deviation from the Hopper command is load-bearing:
|
| 196 |
+
|
| 197 |
+
- **bf16 KV cache** (no `--kv-cache-dtype fp8`) — fp8 KV overflows SM120's per-SM shared memory in the
|
| 198 |
+
TRITON_MLA kernel (102,400 > 101,376 bytes).
|
| 199 |
+
- **`PIECEWISE` cudagraph mode** — FULL decode graphs + MTP produce degenerate output on TRITON_MLA (its
|
| 200 |
+
decode kernel only handles single-token queries; MTP verify sends multi-token queries). PIECEWISE routes
|
| 201 |
+
them through the prefill path correctly and still gives ~10× over eager at c=1.
|
| 202 |
+
- **MTP `num_speculative_tokens=1`**, with cudagraph capture sizes divisible by (1 + k) = 2.
|
| 203 |
+
- **`VLLM_USE_DEEP_GEMM=0`** — DeepGEMM's attention path doesn't support SM120.
|
| 204 |
+
- **`--attention-backend TRITON_MLA`** — the dense-MLA backend that works once DSA is disabled.
|
| 205 |
+
|
| 206 |
+
A one-shot bootstrap script (HF download → image build → launch, idempotent) exists in the companion
|
| 207 |
+
repository as `scripts/bootstrap_sm120_glm52_w4a16_mtp.sh`.
|
| 208 |
+
|
| 209 |
## Method
|
| 210 |
|
| 211 |
1. **GPTQ W4A16** (group-128, asymmetric) on the routed experts only, with attention/dense/MTP/embeddings/
|
|
|
|
| 226 |
- 1M-context serving requires all 8 H200s; 4×H200 serves up to ~128K (single-stream engine ceiling ~239K),
|
| 227 |
with MTP acceptance ~38% (vs ~46–52% on 8×H200).
|
| 228 |
- Asymmetric weights require `--enable-expert-parallel` to serve correctly.
|
| 229 |
+
- Pin vLLM v0.23.x (v0.24+ DSA-indexer layout change breaks loading).
|
| 230 |
+
- On Blackwell SM120 (RTX PRO 6000) use the dedicated recipe above: DSA sparse attention must be disabled
|
| 231 |
+
(dense TRITON_MLA), KV cache stays bf16, cudagraphs run in PIECEWISE mode, and MTP is limited to k=1.
|
| 232 |
+
Quality is unaffected (validated at parity with H200); single-stream throughput is bandwidth-bound at
|
| 233 |
+
~50 tok/s, so size deployments for concurrent traffic. FULL-cudagraph + MTP on TRITON_MLA is an upstream
|
| 234 |
+
kernel gap (vllm-project/vllm#21505), not fixable by configuration.
|
| 235 |
|
| 236 |
## Acknowledgements
|
| 237 |
|