vLLM 推理服务性能调优实战:从 PagedAttention 到生产参数
·
vLLM 推理服务性能调优实战:从 PagedAttention 到生产参数
一、vLLM 为什么快
vLLM 成为大模型推理事实标准,核心靠两项技术:
PagedAttention(分页注意力)。传统推理中,KV Cache 需要为每个请求预分配连续显存,按最大可能长度预留,导致大量显存浪费在"用不上的位置"。PagedAttention 把 KV Cache 切成固定大小的块(类似操作系统的分页内存),按需分配、不连续存放。效果是显存碎片率大幅下降、利用率显著提升,同样的显存能装下更多并发请求。
Continuous Batching(连续批处理)。传统批处理要等一个 batch 全部生成完才处理下一个,GPU 在生成后期大量空转。连续批处理允许请求动态加入/退出 batch:某个请求生成了结束符就腾出位置给新请求。测试数据显示,混合负载下仅靠这一点就能把 GPU 利用率明显拉升。
这两项技术叠加,vLLM 对比朴素加载方式通常能带来数倍的吞吐提升,这也是"为什么必须用推理框架"的答案。
二、部署入门与关键参数
2.1 快速启动
# 单卡启动一个 7B 模型服务
vllm serve Qwen/Qwen2.5-7B-Instruct \
--served-model-name my-model \
--gpu-memory-utilization 0.90 \
--max-model-len 8192 \
--max-num-seqs 32
```
启动后即提供 OpenAI 兼容的 `/v1/chat/completions` 接口,业务侧零改造接入。
### 2.2 三个最影响性能的旋钮
**gpu-memory-utilization**:模型权重之外的显存用于 KV Cache 的比例上限。设太高容易 OOM(要给激活值留余量),设太低浪费吞吐潜力。经验做法:从 0.85-0.90 起步,压测无 OOM 再上调。
**max-num-seqs**:单次 batch 最多并发的序列数。调大提升吞吐、推高显存与延迟;调小降低延迟、牺牲吞吐。**吞吐与延迟的平衡主要靠它**——追求吞吐调到 64 甚至更高,追求交互式低延迟降到 8-16。
**max-model-len**:最大上下文长度。设太长会抢占 KV Cache 显存,导致并发能力下降;按业务实际需要设置,别贪大。
### 2.3 更长上下文的显存账
KV Cache 随"并发数 × 上下文长度"增长。100K 上下文的服务,KV Cache 往往比模型权重占的显存还多。长上下文场景优先考虑:开启 **prefix caching(前缀缓存)**——系统提示词、few-shot 这些共享前缀只算一次 KV;以及使用更省显存的 KV Cache 量化。
## 三、多 GPU 与分布式部署
单卡装不下或吞吐不够时,用张量并行(Tensor Parallelism)把模型按层切到多卡,卡间用 NCCL 通信。vLLM 只需一个参数:
```bash
vllm serve Qwen/Qwen2.5-27B-Instruct \
--tensor-parallel-size 4 \
--max-num-seqs 64
```
多副本部署时,常见拓扑是"每个 GPU 跑一个 vLLM 服务副本",前面挂反向代理做请求分发。注意:张量并行规模不是越大越好,通信开销会抵消算力收益,同节点内一般 4-8 卡为宜。
## 四、性能调优的实战方法论
调优不能靠猜,要按下面的循环走:
**第一步:先量化基线**。用压测工具(vLLM 自带 benchmark 脚本或第三方工具)测三组数据:TTFT(首 token 延迟)、TPS(吞吐)、p95 端到端延迟。没有基线,后面的所有"优化"都是玄学。
**第二步:按场景定目标**。对话/客服场景:TTFT 优先,压 max-num-seqs 降延迟;离线批量生成:TPS 优先,放开并发。**同一个服务不可能又低延迟又高吞吐,先想清楚业务要哪头。**
**第三步:逐个变量做对照实验**。每次只改一个参数:max-num-seqs、gpu-memory-utilization、KV cache 精度、调度策略。记录指标变化,找到当前硬件与负载下的最优组合。把实验记录保存下来,不同模型、不同负载的最优参数往往不同。
**第四步:关注特殊负载**。Agent 场景的负载特征和普通对话不同:工具调用多、单次请求 token 跨度大(从几十到几万)、请求到达模式突发性强。实测中有个反直觉发现:切换不同的 attention 后端(如 FlashAttention-2 与 Triton Attention),输出结果会出现"Top-1 翻转"——某些 token 的选择变了,长上下文中尤其明显。这意味着:**推理框架的"细节配置"也会影响模型行为,切配置后要做行为回归**,不能只看性能指标。
## 五、多模态与特殊场景
vLLM 已支持主流 VLM 模型。一个值得注意的新实践:视频理解任务中,把视频解码从 CPU(OpenCV+FFMPEG)迁移到 GPU(NVIDIA NVDEC 硬件解码,通过 PyNvVideoCodec 接入),多 GPU 节点可避免 CPU 成为瓶颈。注意事项:
- CUDA MPS 对多进程高并发场景性能至关重要,启动前确认守护进程已启动。
- - 为解码预留显存用 `--mm-ipc-gpu-memory-gb`,通过压测找"不影响吞吐的最小预留值"。
- - 实测在 8 块 GPU 的规模下,GPU 解码吞吐是 CPU 解码的两倍以上。
## 六、容量规划与基准参考
### 5.1 先估算,再买卡
部署前用三组数字做容量规划:**单请求平均 token 消耗、峰值 QPS、目标响应时间**。假设单请求平均 2000 token(输入+输出),峰值 50 QPS,则每秒需要处理 10 万 token。对照硬件实测吞吐(7B 模型 INT4 在单张消费级卡上通常 50-100 token/s 级别,27B 在 A100 上可达数百 token/s),就能算出需要几卡、要不要多副本。算清楚再扩容,避免"买了 8 卡利用率只有 20%"的常见浪费。
### 5.2 压测要点
压测脚本要模拟真实负载特征,而不是匀速打满:**对话场景要混合长短请求**(有的问题一句话、有的带长文档)、**Agent 场景要混合工具调用**(请求之间 token 跨度大)、**要有突发峰**(模拟营销活动瞬时流量)。压测同时记录 TTFT 的分布,因为"平均延迟正常、p95 爆炸"才是线上用户真实体验。
### 5.3 上下游联动优化
推理服务只是链路一环,端到端延迟还有三个常见优化点:
- **上游流式接入**:SSE 输出让首字尽早到达用户端,感知延迟大幅下降。
- - **下游解析瘦身**:模型输出后直接进下游逻辑,别做不必要的二次解析重排。
- - **入口缓存**:重复性请求(相同或相似 Prompt)命中语义缓存,直接跳过推理。
## 七、常见故障速查
| 症状 | 常见原因 | 对策 |
|---|---|---|
| 启动即 OOM | gpu-memory-utilization 过高,没给激活值留余量 | 降到 0.85 试,逐级上调 |
| 高并发才 OOM | max-num-seqs × 平均长度 × KV 开销超显存 | 降并发或限制 max-model-len |
| 延迟正常但吞吐上不去 | 请求排队堆积、batch 不饱满 | 调大 max-num-seqs,检查上游并发 |
| GPU 利用率低 | 小 batch + 请求稀疏 | 压测确认参数,必要时上连续批处理配置 |
| 换配置后答案变了 | attention 后端/精度切换导致解码行为变化 | 做输出回归对比,不只看性能 |
## 八、结语
vLLM 的价值在于把推理性能的优化从"玄学"变成"参数化"。但参数只是手段,**方法论才是核心**:先建基线、再定目标、单变量实验、特殊负载单独对待。把这条循环跑熟,你的推理服务才能在吞吐、延迟、显存三者之间找到属于自己的最优平衡点。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐



所有评论(0)