4、性能瓶颈日志识别:TTFT、ITL、吞吐量与批处理异常
性能问题,说白了就是用户觉得“慢”。在vLLM里,慢分好几种。有的慢在第一个字,有的慢在中间的字,有的干脆整体吞吐上不去。我这些年排查下来,发现大部分性能瓶颈都能从日志里找到蛛丝马迹。今天咱们就聊聊怎么从日志里把这些“罪魁祸首”揪出来。
4.1 TTFT异常日志:首Token延迟过高
TTFT,全称Time to First Token。用户问一个问题,到模型吐出第一个字,这个时间就是TTFT。我见过最夸张的一次,TTFT飙到了8秒,用户直接以为服务挂了。
正常TTFT应该在什么范围?
我个人习惯,对于在线推理服务,TTFT控制在500ms以内算及格,200ms以内算优秀。如果超过1秒,就得警惕了。
日志里怎么看?
vLLM的日志会记录每次请求的TTFT。你可以在日志里搜索类似这样的关键字:
INFO 02-28 10:15:23 metrics.py:123] Avg request TTFT: 0.452s
INFO 02-28 10:15:23 metrics.py:124] P99 request TTFT: 1.234s
注意看P99。平均值0.45s看起来还行,但P99到了1.23s,说明有1%的用户体验很差。我建议重点关注P99和P999。
- 模型加载慢:首次请求时模型还没完全就绪
- 显存不足:KV Cache分配失败,触发重试
- 调度器瓶颈:请求排队时间过长
- 输入过长:预填充阶段耗时太久
4.2 ITL抖动日志:词间延迟不稳定
ITL,Inter-Token Latency,就是每个字之间的延迟。用户感觉“模型说话一顿一顿的”,多半是ITL抖动造成的。
正常ITL应该什么样?
理想情况下,ITL应该是一条平稳的直线。如果出现明显的“锯齿状”波动,那就是抖动。
日志里怎么看?
vLLM的日志会记录每个token的生成时间。你可以通过分析日志中的token时间戳来判断:
# 日志示例(简化)
Token 1: 0.000s
Token 2: 0.045s
Token 3: 0.052s
Token 4: 0.048s
Token 5: 0.210s # 这里出现了抖动!
Token 6: 0.051s
Token 7: 0.047s
看到Token 5了吗?从0.048s突然跳到0.210s,这就是典型的ITL抖动。为什么会这样?
ITL抖动常见原因:
- 批处理大小变化:当前批次处理完了,新批次还没准备好
- 显存带宽争抢:多个请求同时读写显存
- CPU调度延迟:操作系统把vLLM进程挂起了
- 模型并行通信:TP或PP的通信延迟不稳定
4.3 吞吐量下降日志:整体性能滑坡
吞吐量,就是单位时间内能处理多少个请求。这个指标下降,说明系统整体性能在退化。
日志里怎么看?
vLLM会输出吞吐量相关的指标:
INFO 02-28 10:15:23 metrics.py:130] Avg throughput: 12.5 req/s
INFO 02-28 10:15:23 metrics.py:131] Avg token throughput: 456.7 tokens/s
如果你发现吞吐量从12.5 req/s降到了8.2 req/s,那就得查原因了。
吞吐量下降常见原因:
| 原因 | 日志表现 | 排查方向 |
|---|---|---|
| 显存碎片化 | KV Cache分配失败次数增加 | 检查显存使用率,考虑重启服务 |
| 请求模式变化 | 平均输入长度变长 | 分析用户输入分布 |
| 硬件降频 | GPU利用率下降但温度升高 | 检查散热和功耗限制 |
| 调度策略问题 | 等待队列长度持续增加 | 调整max_num_seqs参数 |
4.4 批处理大小异常日志:调度器的“心跳”
批处理大小,是vLLM调度器的核心参数。它决定了每次推理时,有多少个请求被一起处理。批处理大小异常,往往意味着调度器出了问题。
日志里怎么看?
vLLM的调度器日志会记录每次调度的批处理大小:
INFO 02-28 10:15:23 scheduler.py:245] Running batch size: 8
INFO 02-28 10:15:23 scheduler.py:245] Running batch size: 12
INFO 02-28 10:15:23 scheduler.py:245] Running batch size: 4
INFO 02-28 10:15:23 scheduler.py:245] Running batch size: 2 # 异常!
批处理大小突然从12降到2,说明什么?说明有大量请求被提前结束了,或者调度器判断当前无法容纳更多请求。
批处理大小异常常见原因:
- 请求提前终止:用户取消了请求,或者触发了stop条件
- 显存不足:无法为更多请求分配KV Cache
- max_num_seqs设置过小:人为限制了批处理大小
- 请求长度差异过大:长请求和短请求混在一起,调度器难以优化
知识体系总览
下面这张图,是我自己总结的性能瓶颈日志识别框架。你可以把它当作排查时的“地图”:
这张图把四个性能指标和它们的常见原因串起来了。你排查的时候,可以按这个顺序来:先看TTFT和ITL有没有异常,这两个是用户直接感知的。如果没问题,再看吞吐量是不是下降了。最后,如果批处理大小异常,那基本就是调度器或者显存的问题。
公众号:蓝海资料掘金营,微信deep3321