9.1 推理指标体系:QPS、TTFT、TPOT 与吞吐的关联
推理性能指标体系(QPS、TTFT、TPOT、ITL、Throughput、显存峰值、GPU 利用率)、指标间关联与 trade-off、百分位 vs 均值、Goodput 与 SLO
“优化效果需要量化验证”——第 9 章建立完整的推理性能评估体系。9.1 是地基:把指标定义清楚、把指标之间的关联讲明白。核心观点一句话:单一指标无法反映全貌,TTFT 漂亮不代表吞吐高,吞吐高不代表体验好。要同时看”延迟类”和”吞吐类”指标,并用百分位(而不是均值)说话。
📑 目录
- 1. 为什么指标要成体系
- 2. 延迟类指标:TTFT / TPOT / ITL / E2EL
- 3. 吞吐类指标:QPS / Token Throughput / 并发
- 4. 资源类指标:显存峰值与 GPU 利用率
- 5. 均值 vs 百分位:用 P99 而不是 Average 说话
- 6. 指标间的关联与 Trade-off
- 7. Goodput 与 SLO:从”多快”到”达标率”
- 📝 总结
- 🎯 自我检验清单
- 📚 参考资料
1. 为什么指标要成体系
推理服务有三个不同的观察视角,每个视角各有专属指标:
| 视角 | 关注问题 | 指标类型 |
|---|---|---|
| 用户体验 | 用户等多久? | 延迟类(TTFT/TPOT/ITL) |
| 业务容量 | 每秒能服务多少请求? | 吞吐类(QPS/Throughput) |
| 成本效率 | 算力用满了吗?钱花哪了? | 资源类(显存/利用率) |
三个视角互相牵制:压吞吐会伤延迟,保延迟会压吞吐。只看单一视角会做出错误决策——比如”QPS 翻倍”的优化如果导致 TTFT P99 从 300ms 涨到 3s,对交互式业务就是灾难。所以指标体系必须同时覆盖三个视角,并理解它们之间的 trade-off(第 6 节)。
📌 关键点:指标体系的用途是支持决策(扩容?调参?换架构?),不是发报告。每个指标都要能回答”它变了,我该做什么”。
2. 延迟类指标:TTFT / TPOT / ITL / E2EL
2.1 请求的时间线
一个请求的生命周期:
请求到达 ── 排队 ── Prefill ──┐
├── Decode 第 1 token ── … ── Decode 第 N token ── 完成
TTFT ◄─────┘
E2EL ◄───────────────────────────────────────────────────────┘
| 指标 | 全称 | 定义 | 典型基线(交互场景) |
|---|---|---|---|
| TTFT | Time To First Token | 请求发出到第一个 token 返回 | 300-500ms P99 |
| TPOT | Time Per Output Token | 首个 token 之后每个输出 token 的间隔 | 20-40ms P99 |
| ITL | Inter-Token Latency | 任意两个相邻 token 的间隔(含首 token 前?) | ≈ TPOT 同量级 |
| E2EL | End-to-End Latency | 请求发出到全部输出完成 | 视 max_tokens 而定 |
📌 关键点:
- TTFT 由 Prefill 主导:prompt 越长 TTFT 越长(KV 计算与分配);并发高时还要加排队时间。
- TPOT 由 Decode 主导:是”模型单步计算 + 调度开销”的体现,与模型大小、batch 大小强相关。
- ITL vs TPOT 的细微差别:ITL 是所有相邻 token 间隔(含第一个),TPOT 严格排除首 token。多数场景两者数值接近,但压测报告会分别给出(vllm bench 两者都报)。
2.2 为什么分开看 TTFT 和 TPOT
同一个”端到端延迟”可以有不同的内部结构:
场景 A:TTFT=2.5s, TPOT=30ms, 输出 100 token → E2EL = 2.5 + 3.0 = 5.5s
场景 B:TTFT=0.3s, TPOT=60ms, 输出 100 token → E2EL = 0.3 + 6.0 = 6.3s
- A 像”读论文”:等很久才开口,但开口后很流畅 → 适合 RAG/长文档问答
- B 像”打字机”:马上开口,但一直慢 → 适合流式对话/搜索建议
体验模型不同,优化重点就不同。只看 E2EL 会掩盖”慢在开头”还是”慢在全程”。
3. 吞吐类指标:QPS / Token Throughput / 并发
| 指标 | 定义 | 关注点 |
|---|---|---|
| QPS(Requests/s) | 每秒完成的请求数 | 业务容量;受请求长短影响 |
| Output Token Throughput | 每秒生成的输出 token 数(tok/s) | 算力效率;与 QPS 成正比但更稳定 |
| Total Token Throughput | 每秒处理的总 token(输入+输出) | 综合负载能力 |
| 并发(Concurrency) | 同时在处理的请求数 | 压测的设置参数,不是结果指标 |
📌 关键点:QPS 不是独立的性能指标,而是负载形状的函数。同样的服务:短请求 QPS 可以上千,长请求只有几十。跨场景比较必须用 Output Token Throughput(甚至”每 GPU 的 tok/s”)。这也是 MLPerf 等权威基准用 token 而不是请求做单位的原因(9.4)。
4. 资源类指标:显存峰值与 GPU 利用率
4.1 显存峰值(Peak Memory)
- 组成:模型权重 + KV Cache + 激活值 + 碎片
- 决定:能否装下模型、最大并发能开多大(KV 池大小)
- 监控:
nvidia-smi/ vLLM metrics(gpu_cache_usage_perc)
4.2 GPU 利用率
- GPU 利用率 ≠ 算力利用率:
nvidia-smi的利用率是”采样时间内有 kernel 在跑的百分比”,不能反映 kernel 是否吃满 SM。 - 更准的信号:SM 占用率(Nsight)、算力(FLOPs 实际/峰值)、内存带宽利用率。
- 推理场景的典型”虚高”:小 batch 下利用率 90%+ 但吞吐很低——因为 kernel 小、启动开销占比大。
💡 提示:GPU 利用率要结合 batch 大小 一起看:利用率高 + batch 小 = kernel 级低效(启动开销);利用率高 + batch 大 = 真负载。诊断时先看 batch 再信利用率。
5. 均值 vs 百分位:用 P99 而不是 Average 说话
延迟分布是长尾的——均值会被少数慢请求拉高,也会掩盖”大部分请求都慢”:
示例:10 个请求的 TTFT(ms)
[80, 82, 85, 90, 95, 100, 120, 300, 800, 2400]
均值 = 415ms(看起来还行?)
P50 = 97.5ms(一半请求 < 100ms,很好)
P99 ≈ 2400ms(最差用户等了 2.4 秒!)
- 均值:适合容量规划(总工作量),不适合体验评估
- P50:典型体验
- P95/P99:尾部体验——交互式业务的 SLO 基本都挂在 P99 上
- P99 的代价:要保障 P99,就得留裕量(低水位运行),吞吐会下降——这是延迟和吞吐 trade-off 的量化表达
📌 关键点:行业惯例(MLPerf Interactive、各云厂商 SLO):TTFT P99 ≤ 300-500ms、TPOT P99 ≤ 40ms 这类”百分位 + 阈值”写法,而不是”平均延迟 < 1s”。定 SLO 时先定百分位,再定阈值。
6. 指标间的关联与 Trade-off
6.1 核心三角:延迟 / 吞吐 / 成本
延迟(低)
╱ ╲
╱ ╲
吞吐(高)─── 成本(低)
- 并发 ↑ → 吞吐 ↑,但延迟 ↑(排队变长、batch 变大单步变慢)
- batch 大 → TPOT 涨:一个 decode 步处理 N 个请求,单请求变慢但总量变大
- 为保 P99 降并发 → 吞吐掉 → 单 token 成本涨
6.2 负载形状的干扰
| 因素 | 对指标的影响 |
|---|---|
| prompt 长度分布 | 长 prompt → TTFT 涨、prefill 占比大 |
| 输出长度分布 | 长输出 → TPOT 主导、QPS 掉 |
| 到达模式(Poisson/burst) | 突发 → P99 涨、均值几乎不变 |
| 请求间前缀重合度 | 重合高 → APC 命中 → TTFT/吞吐双赢 |
💡 提示:压测必须固定负载形状再谈指标比较(9.2 的可复现配置)。“这次比上次快 20%“如果负载形状变了,结论无效——先验证负载一致性,再读指标差。
6.3 用一张图看全貌
评估一个推理系统,最少要同时拿到:
- TTFT P50/P99(体验的”开口”)
- TPOT P50/P99(体验的”流畅度”)
- Output Token Throughput(算力效率)
- 显存峰值 + KV 利用率(容量边界)
- 并发-延迟曲线(容量拐点,第 7 节的 SLO 视角)
7. Goodput 与 SLO:从”多快”到”达标率”
7.1 Goodput 定义
Goodput = 满足 SLO(服务等级目标)的吞吐。不是”每秒多少请求”,而是”每秒多少达标请求”:
SLO: TTFT ≤ 500ms
并发 100 时:QPS=80,但其中 20 个 TTFT > 500ms
→ Goodput = 60 QPS(而不是 80)
Goodput 把延迟约束和吞吐合并成一个指标(源自 DistServe 论文,vLLM bench 的 --goodput 参数直接实现)。
7.2 为什么 Goodput 重要
- 传统基准误导:峰值吞吐对应的并发点往往延迟已不可接受——“峰值 QPS”是卖点,但生产用不到
- Goodput 是 SLO 的函数:同一系统,TTFT≤300ms 的 Goodput 可能只有 TTFT≤600ms 的 1/3(9.4 的 AMD 案例:300ms 约束下 Goodput 为 0,600ms 约束下 2500+ tok/s)
- 采购/扩容决策:以 Goodput 而非峰值吞吐做容量规划,才能保证”买了就能用”
📌 关键点:定 SLO 是产品决策,测 Goodput 是工程执行。SLO 五要素:指标(TTFT/TPOT/E2EL)+ 百分位(P99)+ 阈值(500ms)+ 统计窗口(5 分钟)+ 达标率(99.9%)。写进 SLA 前先拿压测数据校准”可达成性”。
7.3 与第 7 章的关系
第 7 章讲的是”架构上怎么分离 Prefill/Decode 让两者各得其所”——分离的收益必须用 Goodput 验证:同样的 SLO 下,PD 分离架构能扛住更高的并发而达标率不掉。指标是架构决策的裁判。
📝 总结
- 三视角指标体系:延迟(TTFT/TPOT/ITL/E2EL)、吞吐(QPS/tok/s)、资源(显存/利用率)
- TTFT vs TPOT:慢在”开口”还是”全程”,优化方向完全不同
- QPS 依赖负载形状:跨场景比较用 Output Token Throughput
- GPU 利用率要结合 batch 看:高利用率 + 小 batch = kernel 级低效
- 用百分位说话:P50 是典型体验,P99 是 SLO 挂载点
- 核心 trade-off:并发↑ → 吞吐↑ 但延迟↑;保 P99 → 留裕量 → 成本↑
- Goodput = 达标吞吐:SLO 的函数,容量规划的可靠依据
🎯 自我检验清单
- 画一个请求的时间线,标出 TTFT/TPOT/ITL/E2EL 各自覆盖哪段?
- 场景 A(慢 TTFT 快 TPOT)和场景 B(快 TTFT 慢 TPOT)分别适合什么业务?
- 为什么 QPS 不能跨负载形状比较?该用什么指标?
- “GPU 利用率 95% 但吞吐低”可能是什么原因?
- 均值 415ms 而 P99 2400ms 的例子说明了什么?
- 并发上升时 TTFT/TPOT/吞吐各自怎么变?为什么?
- Goodput 和 Throughput 的区别?定 SLO 的五个要素是什么?
📚 参考资料
- DistServe: Disaggregating Prefill and Decoding for Goodput-optimized LLM Serving(https://arxiv.org/abs/2401.09670)
- vLLM 官方文档:vllm bench serve(Serving Benchmark Result 输出字段)(https://docs.vllm.ai/en/latest/benchmarking/cli.html)
- MLPerf Inference:LLM 基准的 latency target(TTFT/TPOT P99 定义)(https://mlcommons.org/benchmarks/inference-datacenter/)
- 华为云/阿里云 LLM 服务 SLO 白皮书(TTFT/TPOT P99 的行业实践)