> 部署目标:在一台 8 卡 RTX 5090(每卡 32 GB)服务器上,用 vLLM 跑起 GLM-5.3-Flash 的 NVFP4 量化版,对外提供 OpenAI 兼容 API,支持 `/think` 深度思考模式与 Function Call。最终方案采用 **vLLM 官方 nightly 镜像 + Docker**,服务现稳定运行于 `http://10.168.2.103:8000/v1`(容器已连续运行 9 天+)。
## 一、为什么是这套组合
**模型**:`GLM-5.3-Flash-NVFP4`,架构为 `Glm5NextForConditionalGeneration`(`model_type: glm5_next`),原始 dtype bfloat16。NVFP4 量化后权重落盘 **185 GB**——全量 bf16 显然放不进任何单机,即便 4bit 也远超单卡,必须走张量并行。
**硬件**:8 × RTX 5090 32G,总显存约 **255.6 GB**。5090 是 Blackwell 架构(SM120),算力新、显存大,但对框架版本要求苛刻:稳定版 vLLM 尚未合入 `glm5_next` 架构支持 + NVFP4 反量化 kernel + SM120 后端三件套,**必须用 nightly 构建的 vLLM + CUDA 13.0**。
**量化格式**(来自 `config.json` 的 `quantization_config`):
```json
"format": "nvfp4-pack-quantized",
"input_activations": {
"num_bits": 4,
"group_size": 16,
"scale_dtype": "torch.float8_e4m3fn",
"strategy": "tensor_group",
"dynamic": "local"
}
```
注意 targets 只覆盖了 MoE 的 experts 层(`.*\\.layers\\.(?:[3-9]|[1-3][0-9]|4[0-4])\\.mlp\\.experts\\..*(gate|up|down)`)——**专家矩阵走 4bit,注意力与共享层保持 bf16**,这是精度与带宽的经典折中。vLLM 通过 `compressed-tensors` 反量化器原生识别,无需手动指定 `–quantization`。
## 二、软件栈:官方 nightly 镜像 + Docker
宿主机上先试过 conda 环境裸跑(conda env `glm53`,torch 2.13.0+cu130),能跑通但版本管理、依赖隔离都不干净,**最终生产方案切换到官方 vLLM 镜像**:
| 组件 | 版本/来源 |
|—|—|
| 镜像 | `vllm/vllm-openai:nightly-385dce36b`(官方 Buildkite 流水线构建 #6303) |
| vLLM | 0.28.1rc1.dev580+g385dce36b(nightly,commit 385dce36b) |
| 基础镜像 CUDA | 13.0.2(要求 NVIDIA 驱动 ≥ 535) |
| 运行方式 | Docker 容器 `glm53-flash`,`–gpus all`,`–restart unless-stopped` |
| 模型挂载 | `/home/x640/models` → 容器内 `/models` |
选官方 nightly 镜像而不是自建镜像,核心原因是 SM120 + NVFP4 的 kernel 组合在 nightly 里是齐的,`ENTRYPOINT ["vllm" "serve"]`,模型路径通过挂载传参即可,零额外打包工作。
## 三、启动命令(可直接抄)
以下 `docker run` 依据服务器上实际容器的 `docker inspect` 结果还原(镜像在服务器上以 sha 引用,label 中标注了 upstream tag):
```bash
docker run -d –gpus all \\
–name glm53-flash \\
–restart unless-stopped \\
-p 8000:8000 \\
-v /home/x640/models:/models \\
-v /home/x640/glm53_site:/site \\
-e VLLM_GLM53_CUDA_SPARSE_MLA=1 \\
-e VLLM_GLM53_MOE_INPUT_SCALE=1.0 \\
-e VLLM_ENGINE_READY_TIMEOUT_S=3600 \\
-e VLLM_USE_BREAKABLE_CUDAGRAPH=1 \\
-e NCCL_MIN_NCHANNELS=32 \\
-e NCCL_P2P_LEVEL=PXB \\
vllm/vllm-openai:nightly-385dce36b \\
/models/GLM-5.3-Flash-NVFP4 \\
–served-model-name glm-5.3-flash \\
–tensor-parallel-size 8 \\
–kv-cache-dtype fp8 \\
–block-size 256 \\
–max-model-len 131072 \\
–max-num-seqs 4 \\
–max-num-batched-tokens 512 \\
–gpu-memory-utilization 0.82 \\
–moe-backend flashinfer_cutlass \\
–no-enable-flashinfer-autotune \\
–tool-call-parser glm47 \\
–enable-auto-tool-choice \\
–reasoning-parser glm45 \\
–trust-remote-code \\
–enforce-eager
```
### 服务参数逐条解释
– **`–tensor-parallel-size 8`**:8 卡一张并行面,NVFP4 权重分片后每卡约 23 GB。
– **`–gpu-memory-utilization 0.82`**:比常见的 0.9 保守——SM120 上 CUDA context、NCCL buffer 的额外开销更大,0.82 是实测稳定的分界线(容器视角的模型/KV 预算;宿主机 nvidia-smi 实际每卡 ~30.3/32.6 GB,含驱动侧占用)。
– **`–max-model-len 131072`**:128K 上下文,取模型 config 的上限。
– **`–kv-cache-dtype fp8`**:KV cache 也压成 FP8,直接把可服务的 KV token 数翻倍。
– **`–block-size 256`**:大 block 减少 KV 管理开销,配合 MLA 类架构使用。
– **`–max-num-seqs 4` + `–max-num-batched-tokens 512`**:刻意收窄的调度水位。256 GB 显存看着多,128K 单请求的 KV 就要吃掉一大块,小 batch + 小 prefill chunk 保证长请求下不 OOM、时延可预期。
– **`–moe-backend flashinfer_cutlass`**:MoE 走 FlashInfer 的 CUTLASS 路径,与 NVFP4 反量化配合最优。
– **`–no-enable-flashinfer-autotune`**:关掉 FlashInfer 自动调优,省下每次启动十几分钟的 tune 时间,收益微乎其微。
– **`–tool-call-parser glm47` + `–enable-auto-tool-choice` + `–reasoning-parser glm45`**:GLM 系列的思考内容与工具调用解析器。没这两个,前端拿到的将是原始 `<think>` 标签和文本形式的工具调用,无法结构化拆分。
– **`–trust-remote-code`**:`glm5_next` 架构需要模型仓库内的自定义代码。
– **`–enforce-eager`**:关闭 CUDA Graph 捕获。代价是 decode 稍慢,换来的是显存余量和启动稳定性——在 0.82 水位 + fp8 KV 的组合下这是必要的取舍。
### 容器环境变量,每个都是踩坑换来的
1. **`VLLM_ENGINE_READY_TIMEOUT_S=3600`**——默认的引擎就绪超时远小于 185 GB 权重的加载时间(实测 **632 秒**),vLLM 会"误判死亡"提前退出。放宽到 1 小时。
2. **`VLLM_GLM53_CUDA_SPARSE_MLA=1`**——打开 GLM-5.3 的稀疏 MLA 注意力路径(SM120 专用 kernel),这是长上下文吞吐的关键开关。
3. **`VLLM_GLM53_MOE_INPUT_SCALE=1.0`**——MoE 专家层 NVFP4 输入 scale 的对齐参数。
4. **`VLLM_USE_BREAKABLE_CUDAGRAPH=1`**——允许 vLLM 在显存吃紧时放弃/分段 CUDA Graph 而不是崩溃。
5. **`NCCL_MIN_NCHANNELS=32` + `NCCL_P2P_LEVEL=PXB`**——8 卡 TP 的 all-reduce 通道数与 P2P 拓扑级别(同 PCIe switch 内优先走 PXB),为 5090 这类消费卡的 P2P 链路微调。
## 四、启动过程实录
从容器日志(`docker logs glm53-flash`,2026-09-21 12:47:16 起步):
```
12:47:16 vLLM API server 启动横幅 (version 0.28.1rc1.dev580+g385dce36b)
12:58:36 Loading weights took 632.80 seconds
12:59:37 GPU KV cache size: 149,796 tokens
Maximum concurrency for 131,072 tokens per request: 1.14x
```
几个值得注意的点:
– **权重加载 10 分半**是 185 GB 从磁盘灌进 8 卡的物理极限,期间日志静默,别慌,更别提前 kill。
– **KV cache 149,796 tokens、131K 单请求并发 1.14x**:这是最诚实的容量数字——fp8 KV + 0.82 水位下,系统同时塞得下约一个半满长 128K 请求。日常短对话的并发远不止这个数(短请求的 KV 占用按比例缩小),但**长文档场景必须按 1~2 个并发来规划业务**。
– 模型在容器内以 `/models/GLM-5.3-Flash-NVFP4` 路径加载(宿主机挂载进来的)。
## 五、验收:API 实测
### 1. 模型注册
```bash
$ curl http://10.168.2.103:8000/v1/models
{"id":"glm-5.3-flash","root":"/models/GLM-5.3-Flash-NVFP4",
"max_model_len":131072, …}
```
### 2. 思考模式拆分(reasoning parser 生效)
```bash
$ curl -s http://10.168.2.103:8000/v1/chat/completions \\
-H "Content-Type: application/json" \\
-d '{"model":"glm-5.3-flash",
"messages":[{"role":"user","content":"What is 17*23?"}],
"max_tokens":256}'
```
返回:
– `message.content` → `"391"`(答案正确)
– `message.reasoning_content` → 思考过程独立成字段,与正文干净分离
– `usage` → prompt 25 tokens / completion 47 tokens,其中 `reasoning_tokens: 43`
### 3. 显存水位
```
每卡:~30.3 GiB / 32.6 GiB(约 93%,含 CUDA context 与 NCCL 开销)
```
## 六、客户端对接注意事项
– **base URL**:`http://10.168.2.103:8000/v1`,模型名固定 `glm-5.3-flash`(注意不是磁盘目录名)。
– **思考内容**:需要深度思考时在 user 消息开头加 `/think`,结果读 `reasoning_content` 字段;不要自己去解析 `<think>` 标签。
– **工具调用**:OpenAI tools 协议直接可用(`–enable-auto-tool-choice` 已开)。
– **长上下文并发**:如上文 KV cache 数据,131K 级别请求的稳态并发约 1.14x,批量长文摘要务必串行或分批。
– **Windows 下 curl 发中文 body 有编码坑**:Git Bash 会把 UTF-8 转 GBK 导致 `There was an error parsing the body`。要么用纯 ASCII 测试体,要么走 Python/Postman 发请求。
## 七、总结
| 项目 | 数值 |
|—|—|
| 部署形态 | Docker(vllm/vllm-openai nightly-385dce36b,CUDA 13.0.2) |
| 总显存 / 实际占用 | 255.6 GB / ~93% |
| 权重落盘 | 185 GB(NVFP4,专家层 4bit + 共享层 bf16) |
| 单卡模型分片 | ~23 GiB |
| 权重加载耗时 | 632.8 s(约 10 分半) |
| 最大上下文 | 131072 tokens |
| KV cache | 149,796 tokens(fp8),131K 请求并发 1.14x |
| 启动总时长 | 约 11~12 分钟 |
核心经验一句话:**新架构 + 新量化 + 新 GPU(SM120)意味着必须上 nightly 框架,而 Docker 官方镜像是唯一省心的载体**;剩下的坑几乎全部集中在"加载超时、KV 容量规划、显存水位"这三件事上,各自都只需要一行参数就能解决。
部署本身没有任何无法复现的黑魔法——`docker run` 抄走,改改挂载路径就能跑。
网硕互联帮助中心




评论前必须登录!
注册