4、吞吐量关键指标:Tokens/s、请求延迟、GPU利用率、如何衡量批处理效果
在vLLM生产环境调优中,批处理策略的优劣最终必须落到可量化的指标上。如果只凭“感觉变快了”或“显存好像没爆”来决策,很难在复杂负载下找到真正的瓶颈。本章围绕四个核心维度展开:Tokens/s(吞吐量)、请求延迟(Latency)、GPU利用率(Utilization),以及批处理效果的综合衡量方法。这四个指标并非孤立存在,它们之间存在相互制约关系——盲目追求吞吐量可能牺牲延迟,过度压低延迟又会浪费GPU算力。理解这些指标的定义、测量方法、权衡逻辑,是设计高效批处理策略的前提。
4.1 核心指标定义与测量原理
Tokens/s 是衡量系统吞吐量的最直接指标,表示每秒处理的token数量。在vLLM中,这个指标通常分为输入吞吐(处理用户请求中prompt token的速率)和输出吞吐(生成回复token的速率)。实际生产环境中,我们更关注综合吞吐,即(输入token数+输出token数)/总耗时。测量时需要注意:vLLM的/metrics端点暴露了vllm:generation_tokens_total和vllm:prompt_tokens_total计数器,配合Prometheus可以按时间窗口计算实时吞吐。
请求延迟并非单一数值,而是包含多个阶段:TTFT(Time To First Token)——从请求发出到收到第一个输出token的时间,反映系统响应速度;TPOT(Time Per Output Token)——生成每个输出token的平均耗时,反映生成效率;端到端延迟——整个请求从提交到完成的总时间。vLLM的日志中会记录每个请求的TTFT和生成耗时,也可以通过自定义中间件在API层埋点。
GPU利用率需要区分计算利用率和显存利用率。计算利用率可通过nvidia-smi的SM占用率查看,但更精细的指标来自DCGM(NVIDIA Data Center GPU Manager),它能提供SM活动周期、张量核心利用率、显存带宽利用率等。显存利用率则关注已分配显存占总显存的比例,vLLM的gpu_cache_usage_perc指标直接反映KV cache的占用情况。
# 实时查看GPU计算利用率与显存
nvidia-smi --query-gpu=utilization.gpu,memory.used,memory.total --format=csv
# 通过vLLM metrics端点获取吞吐数据
curl -s http://localhost:8000/metrics | grep vllm_generation_tokens_total
# 使用DCGM采集细粒度指标(需安装dcgm-exporter)
dcgm-exporter --collect-interval 1000
4.2 批处理效果的综合衡量方法
单一指标无法全面评估批处理策略。我们需要建立多维评估矩阵,将吞吐、延迟、利用率、质量(如生成内容的连贯性)纳入统一框架。推荐使用加权评分法:根据业务场景设定各指标权重,例如在线聊天场景延迟权重更高,离线批量生成场景吞吐权重更高。
| 评估维度 | 核心指标 | 测量方式 | 优化目标 |
|---|---|---|---|
| 吞吐量 | Tokens/s(综合) | Prometheus + vLLM metrics | 在满足延迟SLA前提下最大化 |
| 延迟 | TTFT / TPOT / P99端到端 | API埋点 + 日志分析 | P99 < 业务容忍阈值 |
| GPU计算利用率 | SM占用率 / 张量核心利用率 | DCGM / nvidia-smi | 保持80%以上且波动小 |
| 显存效率 | KV cache利用率 / 显存占用率 | vLLM gpu_cache_usage_perc | 避免OOM,预留安全余量 |
| 批处理效率 | 平均批大小 / 批处理频率 | vLLM日志统计 | 批大小与请求到达率匹配 |
操作流程建议:首先建立基准测试(使用固定请求集和并发数),记录当前基线指标;然后调整批处理参数(如--max-num-seqs、--max-num-batched-tokens),每次只改变一个变量;最后对比指标变化,找出最优配置。整个过程建议自动化,使用脚本循环测试不同参数组合。
4.3 案例拆解:在线推理服务的批处理调优
背景与约束:某SaaS公司提供代码补全服务,使用vLLM部署CodeLlama-13B模型,单卡A100-80G。业务要求P99端到端延迟小于2秒,同时希望最大化吞吐以降低单位成本。初始配置为--max-num-seqs 64,--max-num-batched-tokens 8192。
初始现象:通过监控发现,GPU计算利用率仅45%,但显存占用已达78%。进一步查看延迟分布:TTFT平均120ms,但P99达到800ms;TPOT平均35ms,P99为60ms。端到端P99为1.8秒,勉强达标但余量不足。吞吐量约为320 tokens/s。
分析判断:显存占用高但计算利用率低,说明KV cache分配过多但实际并发请求不足。TTFT的P99偏高,可能是由于批处理队列等待时间过长——当请求到达时,vLLM等待凑满64个序列才启动推理。TPOT相对稳定,说明生成阶段计算效率尚可。
实际操作步骤:
- 将
--max-num-seqs从64降至32,减少等待凑批的时间。 - 将
--max-num-batched-tokens从8192降至4096,降低单批计算压力。 - 启用
--enable-prefix-caching,利用代码补全场景中常见的前缀重复特性。 - 调整调度策略为
--scheduling-policy priority,优先处理等待时间较长的请求。
结果对比:调整后,TTFT P99从800ms降至350ms,端到端P99降至1.2秒。GPU计算利用率提升至68%,吞吐量提升至410 tokens/s(+28%)。显存占用降至65%,留出更多安全余量。代价是平均批大小从64降至约28,但整体吞吐反而提升,因为减少了无效等待。
max-num-seqs会导致请求在队列中空等,增加TTFT。建议根据实际QPS动态调整,或使用vLLM的--max-num-seqs配合--max-waiting-time(等待超时后即使未凑满也启动推理)。
4.4 常见误区与总结复盘
误区一:只关注平均延迟而忽略P99。平均延迟容易被少数极快请求拉低,无法反映真实用户体验。必须同时监控P95/P99,甚至P999。在批处理场景中,长尾延迟往往来自排队等待,而非计算本身。
误区二:认为GPU利用率越高越好。利用率接近100%可能意味着计算饱和,但也可能造成请求排队严重。合理的利用率应结合延迟SLA来看——如果利用率95%但P99延迟超标,说明已经过载。建议设置利用率阈值(如85%),超过时触发扩容或限流。
误区三:忽略输入与输出token的差异。输入token的处理是并行的(prefill阶段),而输出token是串行生成的(decode阶段)。一个包含长prompt的请求会显著增加prefill时间,影响同批其他请求的TTFT。在衡量吞吐时,应分别统计prefill吞吐和decode吞吐。
误区四:显存未满就盲目增加批大小。显存占用率不是唯一限制因素。即使显存有剩余,计算资源(SM、带宽)可能已经饱和。增加批大小可能导致每个请求的TPOT变长,反而降低整体效率。建议同时观察nvidia-smi的SM利用率和显存带宽利用率。
--enable-auto-tool-choice或配合Kubernetes HPA(Horizontal Pod Autoscaler)实现基于指标的自动扩缩容,但初始参数仍需人工调优。
总结:衡量批处理效果需要建立“吞吐-延迟-利用率”三角模型。Tokens/s反映系统产出能力,请求延迟反映用户体验,GPU利用率反映资源效率。三者相互制约,最优配置取决于业务优先级。建议建立持续监控体系,定期回顾指标变化,结合业务增长趋势提前调整批处理参数。vLLM提供了丰富的可观测性接口,善用这些数据是做好批处理优化的基础。