pastapaul commited on
Commit
db48f84
·
verified ·
1 Parent(s): 0af8877

Add validated RTX PRO 6000 (SM120) serving recipe

Browse files
Files changed (1) hide show
  1. README.md +81 -5
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).** Matches FP8 quality on **half the GPUs** (4×H200 vs 8) and is the **fastest
27
- GLM-5.2 quant for interactive/agentic serving on Hopper** in a matched, MTP-on head-to-head — with the
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). Blackwell serving needs additional
158
- kernel flags; recommended on Hopper.
 
 
 
 
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