vLLM 高并发部署 GLM 5 避坑指南

你在本地跑 GLM 5,几个并发请求下推理速度还过得去,但一旦部署成线上 API 服务、并发一上来,延迟暴涨,甚至 GPU 显存溢出——这在 vLLM 部署中几乎是新人必踩的坑。本文用真实踩坑经验告诉你:不是 vLLM 不行,而是你没配对它。

上周,一个做客服机器人的朋友苦笑着说:“我把 GLM 5 部署到 vLLM 上,单次请求只要 1.2 秒,结果 5 个用户同时用,第 6 个请求直接报错,GPU 显存爆了。”他以为 vLLM 的 PagedAttention——一种让显存像操作系统内存分页一样灵活管理的技术——能自动搞定一切,于是随手敲了个 vllm serve 就上线了。

这就是根源。vLLM 0.21.0 虽然强大,但它不是插上电就能抗住高并发的万能药。下面我会逐坑拆解,也会告诉你每一条配置意味着什么,你的硬件成本能省在哪里。

坑一:GPU 显存被“占满”没留饭钱

vLLM 默认的 gpu_memory_utilization(显存使用比例)是 0.90,乍一看没问题,但 GLM 5 是个重载模型,其注意力层的 KV 缓存——每次对话需要暂存的历史信息——会随并发量快速增长。你把显存的 90% 给了模型权重,留给 KV 缓存的空间就只剩可怜的 10%,多来几个请求当然挤爆。

解决办法是主动降低权重占用,给缓存留出“饭钱”。以单张 24GB 显存的 RTX 4090 为例(fp16 下 GLM 5 约需 14GB):

vllm serve glm-5 \
  --gpu-memory-utilization 0.65 \
  --max-model-len 4096 \
  --max-num-seqs 16

0.65 预留了约 8GB 给 KV 缓存,max-model-len 控制单条请求的最大上下文长度,越长缓存吃得越狠。max-num-seqs 16 则声明你期望同时处理 16 个请求,vLLM 会据此自动计算每块缓存页的大小。

这意味什么? 如果你原计划跑 4 并发,可能要买 2 张卡,调参后一张就能兜住——硬件成本直接打对折。

坑二:KV 缓存被“短请求”耗尽

你或许遇到过这种情况:并发数调到 16,观察 GPU 显存也没满,但请求队列却越堆越长。原因是 vLLM 的 KV 缓存块是提前分配、按需增长的,但每个块的大小受 max-model-lenmax-num-seqs 影响。如果你允许的上下文太长(例如 32768),一个请求的缓存块就会占据大量空间,使得系统能同时服用的请求数远少于你设置的 max-num-seqs

暴露这个问题的信号是:vLLM 日志中出现 Preemption is triggered(抢占式回收)。这意味着缓存已满,新请求必须踢掉老请求的缓存,造成严重延迟。

关键参数是 max-num-batched-tokens,它限制一次推理中最多处理的 token 总数(输入+输出)。把它调低,就是在一顿饭里只让有限的食物进锅,保证每个人都能分到。

vllm serve glm-5 \
  --max-num-batched-tokens 8192 \
  --max-num-seqs 24

这里 8192 意味着如果有 24 个并发请求同时活跃,每个请求平均只能用约 341 个 token 的注意力窗口——短任务没问题,长文本生成则会慢下来,但至少不会卡死。

这意味什么? 你知道自己系统的边界在哪:到底是吞吐优先,还是单请求延迟优先。在客服场景,后者不如前者重要。

坑三:误以为并发越高越好

有人会想:“既然我买了 A100-80G,那就把 --max-num-seqs 怼到 128。”结果发现 GPU 时钟周期全花在调度上,实际吞吐量不升反降。

vLLM 的连续批处理(Continuous Batching)——不等整个 batch 跑完就插入新请求——虽然降低了空洞时间,但 batch 太大意味着更强的显存碎片和更高的调度成本。经验上,GLM 5(约 8B 参数)在 A100 上的最优并发数落在 32~64 之间。监控指标也很直观:

curl http://localhost:8000/metrics | grep vllm_num_running_seqs
# 如果该值长期贴着 max-num-seqs,说明并发可能偏高

调优时可以先用压测工具逐步加流,观察 GPU 利用率与 TTFT(首 token 延迟)的拐点。

坑四:结尾停不下来,输出乱码

vLLM 0.21.0 会将 HuggingFace 原版模型转换为自己的内部格式,GLM 5 需要显式信任其 tokenizer 的额外代码,并且要匹配正确的对话模板。如果漏掉 --trust-remote-code,或者用了默认的 tokenizer_mode,模型可能连结束符 eos_token 都识别不了,生成无止尽。

安全启动方式是:

vllm serve glm-5 \
  --trust-remote-code \
  --tokenizer-mode auto \
  --chat-template /path/to/glm5_chat_template.jinja

如果没有自定义模板文件,可使用内置的 --chat-template llama_3 (GLM 5 兼容此格式),但一定要提前测试多轮对话的终止逻辑。


踩完这几个坑,你的 GLM 5 部署才会从“形似”走向“神似”。高效推理不仅关乎响应速度,更直接牵连着 GPU 小时账单。当你用一张卡扛住 30 并发,而不是被迫扩到两台,节省的不只是 50% 的成本——还可能是一个团队一整个季度的云预算。而这些,都藏在你启动命令的那几个看似不起眼的参数里。


皖ICP备2025105865号-2|皖公网安备34010402704739号