GLM-5.2-NVFP4 在 8×A800 上部署实战(下)
上篇讲了为什么 A800 跑不了 GLM-5.2,以及如何打补丁、修 API 漂移。本篇进入实操:构建镜像、启动、验证、踩坑和性能数据。
配套开源仓库:glm52-nvfp4-a800-vllm-deploy(Gitee)。
文章目录
- [GLM-5.2-NVFP4 在 8×A800 上部署实战(下)](#GLM-5.2-NVFP4 在 8×A800 上部署实战(下))
-
- [一 构建补丁镜像](#一 构建补丁镜像)
- [二 启动 GLM](#二 启动 GLM)
-
- [1. 准备模型目录](#1. 准备模型目录)
- [2. 启动容器](#2. 启动容器)
- [3. 关键参数解释](#3. 关键参数解释)
- [三 验证](#三 验证)
-
- [1. 看日志](#1. 看日志)
- [2. HTTP 冒烟](#2. HTTP 冒烟)
- [3. 功能验证](#3. 功能验证)
- [四 踩坑记录](#四 踩坑记录)
- [五 性能数据](#五 性能数据)
- [六 风险与边界](#六 风险与边界)
- [七 结语](#七 结语)
一 构建补丁镜像
把上篇改好的 9 个 Python 文件覆盖进 vllm/vllm-openai:v0.26.0 镜像里即可。Dockerfile 如下:
dockerfile
FROM vllm/vllm-openai:v0.26.0
COPY vllm/model_executor/layers/sparse_attn_indexer.py \
/usr/local/lib/python3.12/dist-packages/vllm/model_executor/layers/sparse_attn_indexer.py
COPY vllm/model_executor/models/deepseek_v2.py \
/usr/local/lib/python3.12/dist-packages/vllm/model_executor/models/deepseek_v2.py
COPY vllm/platforms/cuda.py \
/usr/local/lib/python3.12/dist-packages/vllm/platforms/cuda.py
COPY vllm/v1/attention/backends/mla/indexer.py \
/usr/local/lib/python3.12/dist-packages/vllm/v1/attention/backends/mla/indexer.py
COPY vllm/v1/attention/backends/mla/xpu_mla_sparse.py \
/usr/local/lib/python3.12/dist-packages/vllm/v1/attention/backends/mla/xpu_mla_sparse.py
COPY vllm/v1/attention/backends/mla/triton_mla_sparse.py \
/usr/local/lib/python3.12/dist-packages/vllm/v1/attention/backends/mla/triton_mla_sparse.py
COPY vllm/v1/attention/backends/registry.py \
/usr/local/lib/python3.12/dist-packages/vllm/v1/attention/backends/registry.py
COPY vllm/v1/attention/ops/mqa_logits_triton.py \
/usr/local/lib/python3.12/dist-packages/vllm/v1/attention/ops/mqa_logits_triton.py
COPY vllm/v1/attention/ops/triton_mla_sparse_kernel.py \
/usr/local/lib/python3.12/dist-packages/vllm/v1/attention/ops/triton_mla_sparse_kernel.py
构建:
bash
cd ~/glm52-deploy/vllm-src
docker build -t vllm/vllm-openai:v0.26.0-glm52-sm80 -f Dockerfile.glm52-sm80 .
配套开源仓库已经把改好的 9 个文件和 Dockerfile 打包好,你可以直接 git clone 后构建,不用手动改源码。
二 启动 GLM
1. 准备模型目录
- 假设你的模型权重放在
/data/models/GLM-5.2-NVFP4,后续挂载时只挂父目录:
bash
export MODEL_HOST_DIR=/data/models
2. 启动容器
bash
docker run -d --name glm52-nvfp4 \
--gpus all \
--shm-size=32g \
-e VLLM_ATTENTION_BACKEND=TRITON_MLA_SPARSE \
-e PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True \
-v /data/models:/models \
-p 8001:8001 \
vllm/vllm-openai:v0.26.0-glm52-sm80 \
/models/GLM-5.2-NVFP4 \
--host 0.0.0.0 --port 8001 \
--tensor-parallel-size 8 \
--trust-remote-code \
--dtype bfloat16 \
--gpu-memory-utilization 0.95 \
--max-model-len 65536 \
--kv-cache-dtype bfloat16 \
--max-num-seqs 16 \
--max-num-batched-tokens 8192 \
--served-model-name glm-5.2-nvfp4 \
--attention-config '{"sparse_mla_force_mqa": true}' \
--tool-call-parser glm47 --enable-auto-tool-choice \
--reasoning-parser glm45 \
--speculative-config '{"method":"mtp","num_speculative_tokens":5}'
配套脚本做了封装,直接:
bash
./scripts/deploy.sh start
3. 关键参数解释
| 参数 | 作用 |
|---|---|
--tensor-parallel-size 8 |
必须 8。433G 权重 TP8 每卡约 54GB,TP4 会超显存。 |
VLLM_ATTENTION_BACKEND=TRITON_MLA_SPARSE |
强制使用 sm80 唯一可用的稀疏后端。 |
--kv-cache-dtype bfloat16 |
⚠️ A800 不支持 fp8 KV,且合法值是 bfloat16 不是 bf16。 |
--attention-config '{"sparse_mla_force_mqa": true}' |
必填 。v0.26.0 的 forward_mha 未实现,不加真实 prefill 请求必崩。 |
--reasoning-parser glm45 |
把思考过程隔离到 reasoning 字段,content 只保留答案。 |
--tool-call-parser glm47 --enable-auto-tool-choice |
启用工具调用。 |
--speculative-config '{"method":"mtp","num_speculative_tokens":5}' |
启用 MTP 投机解码,sm80 实测可用。 |
相比官方博客的 Blackwell 命令,主要改动是:
fp8_e4m3→bfloat16- 增加
--attention-config '{"sparse_mla_force_mqa": true}' --gpu-memory-utilization 0.95以提升 KV 容量
三 验证
1. 看日志
bash
docker logs -f glm52-nvfp4
- 等到出现这两行,说明走的是稀疏路径,而不是 dense 回退:
text
[sparse_attn_indexer.py:790] DeepGEMM not supported on this platform; using Triton fallback for sparse attention indexer.
[cuda.py:487] Using TRITON_MLA_SPARSE attention backend out of potential backends: ['TRITON_MLA_SPARSE'].
- 以及
Application startup complete.
2. HTTP 冒烟
bash
curl -s http://127.0.0.1:8001/v1/models
time curl -s http://127.0.0.1:8001/v1/chat/completions \
-H 'Content-Type: application/json' -d '{
"model": "glm-5.2-nvfp4",
"messages": [{"role":"user","content":"What is 17 multiplied by 24? Answer briefly."}],
"max_tokens": 150, "temperature": 0.6
}'
实测返回 content = 408,reasoning 字段包含完整思考过程。
3. 功能验证
仓库里还有几个脚本:
bash
./scripts/sanity_check.py # Python 镜像自检
./scripts/bench.py # 并发压测
./scripts/ttft_test.py # 首 token 延迟
./scripts/ctx_4x32k_test.py # 4 并发 × 32k 上下文
./scripts/thinking_mode_test.py # thinking / 非 thinking 模式
四 踩坑记录
| 报错 | 原因 | 解法 |
|---|---|---|
invalid choice: 'bf16' |
v0.26.0 合法值是 bfloat16 |
改成 --kv-cache-dtype bfloat16 |
AttributeError: 'XPUMLASparseMetadata' object has no attribute 'num_decode_tokens' |
v0.26.0 元数据类缺字段 | 补字段 |
TypeError: non-default argument follows default argument |
dataclass 默认字段位置不对 | 默认字段放最后 |
NotImplementedError at forward_mha |
v0.26.0 base 未实现,prefill 请求触发 | 加 --attention-config '{"sparse_mla_force_mqa": true}' |
每次改代码重建镜像只要几秒,但重启要重新加载 433G 权重。页缓存热时 ~6 分钟,冷读 ~22 分钟,尽量一次多修几处。
五 性能数据
环境:8×A800 80GB PCIe,bf16 KV,TP8,开 MTP。
| 并发 | 无 MTP | 有 MTP | 提升 |
|---|---|---|---|
| 1(单流) | ~36 tok/s | 74--85 tok/s | ~2.2× |
| 4 | 105 tok/s | 160--196 tok/s | ~1.7× |
| 8 | 215 tok/s | 248--265 tok/s | ~1.2× |
| 16(峰值) | 327 tok/s | 386--393 tok/s | ~1.2× |
| 24 | 281 tok/s | 353--355 tok/s | ~1.3× |
- GPU 利用率:8 卡 94--96%
- 显存/卡:权重约 57GB + KV 13.2GB + CUDA graph 2.4GB
- TTFT:0.2--0.5s(prompt 80--960 token)
- 上下文:实测 4 路并发 × 约 30k token 全部成功,总 KV 容量 142,720 token
六 风险与边界
- 非官方路径:官方只认证 Blackwell,A800 是社区补丁方案,性能/上下文受限。
- 补丁脆弱:PR #47629 尚未合并进官方 release,随 vLLM 升级会漂移。
- 上下文上限:64k 已实测,达不到官方 1M 的规格。
- MTP 收益递减:draft 接受率随位置衰减,长输出时提速会变慢。
- 模型许可:本文不提供权重,请遵守模型版权方许可。
七 结语
- A800 上跑 GLM-5.2 虽然要多打几个补丁,但总体是可行的。希望这篇上下两篇的实战记录能帮你少踩几个坑。
如果你也想复现,直接拉配套仓库:
bash
git clone https://gitee.com/<your-name>/glm52-nvfp4-a800-vllm-deploy.git
cd glm52-nvfp4-a800-vllm-deploy
# 按 README 替换模型路径后一键构建 + 启动
版权声明:本文补丁基于 vLLM PR #47629,vLLM 采用 Apache-2.0 许可证。