BLOG ARTICLE
理解 LLM 推理性能:Latency、Throughput 与 Goodput
1. 从一次 LLM 请求开始:Prefill 和 Decode
在介绍指标之前,我们首先需要知道:LLM 是如何生成一段回答的? 对于典型的自回归大语言模型,一次生成请求可以粗略分成两个阶段:Prefill 和 Decode。
- Prefill:模型对输入序列进行前向计算,处理 Prompt 中的所有 token,并为各层生成和缓存对应的 Key / Value(KV Cache),为后续自回归生成提供上下文。Prefill 的计算开销是 TTFT(Time To First Token) 的主要组成部分之一。
- Decode:在已有 KV Cache 的基础上,模型以自回归方式逐步生成输出;每个 decoding step 生成一个新 token,并将该 token 对应的 Key / Value 追加到 KV Cache 中。Decode 阶段的性能主要体现在 TPOT(Time Per Output Token) 和 ITL(Inter-Token Latency) 等持续生成延迟指标上。
2. Latency 与 Throughput
理解 Prefill 和 Decode 之后,我们就可以开始讨论最核心的问题:一个 LLM 推理系统到底快不快? 这里其实存在两个完全不同的观察视角:
- 站在用户的角度,我们关心的是:我需要等多久?这对应 Latency。
- 站在服务器的角度,我们关心的是:单位时间内能够完成多少工作?这对应 Throughput。
2.1 Latency 延迟
Latency 衡量模型处理单个请求的响应速度,直接影响用户体验,尤其是在聊天、代码补全等交互式场景中。常见指标包括:
- TTFT(Time To First Token):从请求到达到第一个输出 token 返回的时间。TTFT 主要受到 Prefill 计算、请求排队和调度开销 影响。TTFT 越低,用户越快看到模型开始回复。
- ITL(Inter-Token Latency):相邻两个输出 token 之间的时间间隔。ITL 描述 Decode 阶段流式生成的连续性。ITL 越低、波动越小,输出通常越流畅。
- TPOT(Time Per Output Token):第一个 token 生成之后,平均生成一个后续 token 所需的时间。在用户看到文本逐字出现的流式场景中(例如 ChatGPT 的界面),TPOT 决定了体验的流畅程度。系统理想情况下应跟上或超过人类的阅读速度,以确保体验流畅。
- E2E Latency(End-to-End Latency):从请求到达到完整响应生成结束的总时间。
一次 LLM 请求的时间线,以及各项延迟指标之间的关系如下图所示:

简单来说:TTFT 决定“多久开始回答”,TPOT / ITL 决定“回答过程中有多快”,E2E Latency 则描述整个请求最终花了多久。
TPOT 和 ITL 的区别
- 对于单个请求:
Average ITL = TPOT。 - 但统计多个请求时,两者可能不同:
- Average TPOT 通常是 request-weighted(按请求加权):先分别计算每个请求的 TPOT,再对所有请求取平均。它适合比较不同系统或配置下的单请求延迟,因为无论每个请求生成多少 token,所有请求都会被赋予相同的权重。
- Average ITL 通常是 token-weighted(按 token 加权):将所有请求中的相邻 token 时间间隔汇总到一起,再除以总的 token 间隔数。因此,输出更长的请求由于贡献了更多 token,会占据更大的权重。它更适合衡量系统整体的稳定生成性能,例如聚合的流式生成速度。
- 因此看 benchmark 时,一定要先确认论文或框架到底怎样定义 TPOT / ITL。不同的推理框架和论文可能会采用不同的计算方式,这会直接影响我们对性能数据的理解。
理解 Mean、Median 和 P99 Latency
在分析 LLM 性能,尤其是延迟时,只看一个数值通常是不够的。Mean、Median 和 P99 分别反映了性能的不同方面。
- Mean(平均值):所有观测值之和除以样本数量。Mean 可以反映整体的平均性能,但容易受到极端值(outlier)的影响。例如,如果某一个请求的 TTFT 异常高,就会把整体平均值拉高。
- Median(中位数):将所有观测值排序后位于中间的数值。Median 更能反映典型用户的体验,并且相比 Mean 对异常值更加稳定。如果 Median TTFT 达到 30 秒,就意味着大量用户都需要等待很长时间才能看到模型开始响应,这对于实时交互场景通常是不可接受的。
- P99(99th Percentile,99 分位数):表示 99% 的请求延迟都低于或等于这个值。P99 用于观察延迟分布的尾部,可以反映最慢的一小部分请求的表现。当用户要求服务具有较高稳定性,或者 SLA (Service Level Agreement,服务级别协议) 要求 99% 的请求都必须满足某个延迟目标时,P99 尤其重要。例如,如果 P99 TTFT 接近 100 秒,就意味着虽然只有少量请求受到影响,但这些用户可能会经历非常严重的等待。
类似地,你还可能看到 P90 或 P95,分别表示 90 分位和 95 分位延迟。它们同样用于观察接近最坏情况的性能,在一些 P99 过于严格或容易受到噪声影响的场景中更加实用。
综合来看:
- Mean:反映整体平均性能,也适合观察长期性能趋势。
- Median:反映大多数用户的典型体验。
- P99:反映尾部延迟(Tail Latency),而尾部延迟往往会直接影响生产环境中的用户体验和服务稳定性。
因此,在 LLM 性能 Benchmark 中,经常可以看到诸如 Mean TTFT、Median TPOT、P99 E2E Latency 这样的统计方式,用来从不同角度描述系统的延迟表现和用户体验。
2.2 Throughput 吞吐量
如果说 Latency 关注的是一个请求有多快,那么 Throughput 衡量的是推理系统在单位时间内能够处理多少工作量,反映系统整体的服务能力。常见的吞吐量指标包括:
Request Throughput
衡量系统单位时间内完成的请求数量,通常以 requests/s(RPS,Requests Per Second)表示。
RPS 可以粗略反映系统处理并发请求的能力,但它并不能体现每个请求实际包含的工作量。例如,生成一句 “Hi there!” 和生成一篇长文,对模型造成的计算负载显然不同。因此,当不同 workload 的输入长度、输出长度或流量模式不同时,直接比较 RPS 可能会产生误导。
影响 RPS 的因素包括:
- Prompt 的复杂度和长度
- 模型规模和硬件配置
- Batching、Caching、Inference Engine 等优化方式
- 单个请求的延迟
Token Throughput
衡量系统单位时间内处理或生成的 Token 数量,通常以 token/s(TPS,Token Per Second)表示。根据统计对象不同,可以进一步分为:
- Input Token Throughput:整个推理系统单位时间输入 token 数量。
- Output Token Throughput:整个推理系统单位时间生成的输出 token 数量。
- Total Token Throughput:同时统计输入和输出 token 的总吞吐量。
同时关注 Input TPS 和 Output TPS,有助于根据不同推理 workload 判断性能瓶颈。例如:
- 对于包含长文档的摘要任务,例如输入长度达到 2000 tokens,Input TPS 往往更加重要。
- 对于短 Prompt、长输出的 Chatbot 场景,例如
20-token Prompt → 500-token Response,Output TPS 往往更加关键。
因此,在阅读 Benchmark 或评估 LLM 推理性能时,一定要确认 TPS 指的是 Input TPS、Output TPS,还是输入和输出合并后的统计结果。不同定义反映的是系统不同方面的性能。
影响 TPS 的因素主要包括:
- Batch Size:增大 Batch Size 通常可以提升 TPS,直到系统达到饱和状态。
- KV Cache 的效率与显存占用。
- Prompt Length 和 Generation Length。
- GPU Memory Bandwidth 和 Compute Utilization。
也正因为 TPS 会受到这些因素影响,它有时很容易被误读,甚至可以通过改变 Benchmark 配置让数字“看起来更高”。例如:
- 更短的 Prompt 意味着每个请求需要完成的工作更少,因此某些测试条件下得到的 TPS 可能更高。
- 更大的 Batch Size 和更高的并发度,可以让 GPU 保持更高利用率,从而提高系统聚合 TPS(Aggregate TPS);但与此同时,也可能增加请求排队时间,使 TTFT 或单用户 TPOT 变差。
随着并发请求数不断增加,系统的总 TPS 通常会先持续上升,直到达到硬件计算或内存资源的饱和点(Saturation Point)。超过这个点之后,继续增加请求可能不再提高吞吐量,甚至会因为系统过载而导致整体性能下降。
3. 从 Throughput 到 Goodput:高并发下怎样才算“好”?
实际的 LLM Serving 系统通常需要在 Throughput 和 Latency 之间进行权衡:提高 Batch Size 和并发度可以提升系统吞吐量,但也可能增加请求排队时间,使 TTFT 或 TPOT 变差。如何在这种权衡下衡量一个系统真正“可用”的服务能力,就是这一节要讨论的 SLO 与 Goodput。
3.1 为什么提高 Throughput 可能让用户变慢?
一个请求单独执行 Decode 时,每一步只有少量工作,并不一定能够充分利用 GPU。于是 Serving 系统通常希望:把多个 request 放进同一个 batch。比如:
Batch Size = 1
GPU
┌─────┐
│ Req │
└─────┘
变成:
Batch Size = 8
GPU
┌─────────────────────────────────┐
│ R1 R2 R3 R4 R5 R6 R7 R8 │
└─────────────────────────────────┘
更多请求一起处理,可以提高 GPU 利用效率,也往往可以提高整个系统的 throughput。但问题也随之出现。随着系统负载不断增大,请求可能需要排队;新的 Prefill 还可能与正在进行的 Decode 竞争执行机会。因此,追求更大的 batching 和更高的系统 throughput,可能同时带来 TTFT、TPOT 或 tail latency 的增加。
Sarathi-Serve 研究的核心问题正是这个 throughput–latency trade-off:Decode batching 有利于系统吞吐,但 Prefill 与 Decode 在同一 serving engine 中交错执行时,又可能造成延迟干扰。(arXiv)
可以把一个 LLM 服务粗略想象成:
Latency
↑
│ ●
│ ●
│ ●
│ ●
│ ●
│ ●
│ ●
└──────────────────────────────────→ Throughput
↑
接近饱和
一开始增加负载时,系统 throughput 可以快速提高,而 latency 变化不大。
但达到某个区域以后,再继续压入请求,就会带来明显的排队和延迟增长。
因此: 一个系统把 GPU 跑得很满,并不等于用户体验就很好。
3.2 平均 Latency 也可能骗人
假设系统处理了 100 个请求:
99 个请求:100 ms
1 个请求:10 s
如果只报告:
Average Latency
那个极慢的请求很容易被平均值掩盖。
因此在线服务通常还会看 latency distribution,也就是:
- P50
- P90
- P95
- P99
例如:P99 TTFT = 2 s。
可以理解为:99% 的请求,其 TTFT 不超过大约 2 秒。
为什么要关注 P99?因为对于服务系统来说:“大部分用户很快”还不够,我们还要知道最慢的那部分用户有多慢。 这就是所谓的 Tail Latency。
Latency Distribution
可以用一个简单的分布图表示:
Requests
↑
│ █████
│ █████████
│ ██████████████
│ █████████████████
│ ████████████████████ ██
│████████████████████████___________██
└────────────────────────────────────────→ Latency
↑ ↑
P50 P99
这比用一大段文字解释 P99 更直观。
3.3 SLO:多快才算“合格”?
知道 TTFT、TPOT、P99 之后,还有一个问题:
TTFT 到底多少才算快?
TPOT 到底多少才算好?
这个答案并不是固定的。一个离线文档总结任务,可能并不在乎首 token 是否晚几秒出现。一个 IDE 里的代码助手,却可能对响应延迟非常敏感。
所以生产系统往往不会简单地把目标定义为“Latency 越低越好”,而是先定义一个服务目标:SLO。
SLO 是:Service Level Objective,服务水平目标。 可以简单理解成:系统希望达到的服务质量要求。
例如,我们可以规定 TTFT < 2 s、TPOT < 50 ms。只有满足这些条件的请求,才算达到了我们定义的服务目标。
现实 benchmark 中确实存在这样的设计。比如 MLPerf Inference v6.0 的 GPT-OSS 120B Interactive 场景设置了 99th-percentile TTFT ≤ 2.0 s、TPOT ≤ 15 ms 的 latency constraints;DeepSeek-R1 Interactive 的约束则是 99th-percentile TTFT ≤ 1.5 s、TPOT ≤ 15 ms。这些具体阈值针对特定 benchmark workload,并不是所有 LLM 应用都应该照搬,但很好地展示了 SLO 的思想。(MLCommons)
也就是说,我们不再问:谁的 latency 最低?而开始问:在满足业务 latency 要求的前提下,这个系统到底能服务多少请求? 这一步,就自然引出了 Goodput。
3.4 Goodput:真正“有用”的 Throughput
假设有两个服务器:
- Server A 最大可以处理
100 requests/s,但在高负载下,很多请求的 TTFT 都超过了我们的 SLO,最后只有60 requests/s满足要求。 - Server B 的最大 Throughput 只有
85 requests/s,但其中80 requests/s都满足我们的 TTFT 和 TPOT 要求。
放在一起:
| 服务器 | Throughput | 满足 SLO 的吞吐量 |
|---|---|---|
| Server A | 100 req/s | 60 req/s |
| Server B | 85 req/s | 80 req/s |
如果只看 Throughput,A > B;但如果看真正符合服务质量要求的请求,B > A。于是就有了 Goodput。AIPerf 当前给出的定义非常直接:
Goodput = 满足所有 SLO 的请求数 ÷ Benchmark 持续时间
也就是:单位时间内,真正满足 SLO 的请求数量。 因此 Goodput 一定小于或等于 Request Throughput。(NVIDIA Docs)
DistServe 进一步把这一思想直接作为 LLM Serving 的系统优化目标:给定应用的 TTFT 和 TPOT 要求以后,优化系统能够在这些 latency constraints 下持续服务的最大 request rate,而不是单纯追求没有延迟约束的峰值 throughput。(arXiv)
vLLM 当前的 benchmark CLI 也已经直接提供:
--goodput
参数,可以针对 ttft、tpot、e2el 设置 SLO,再计算相应的 goodput。(vLLM)
这让我们得到了一个很重要的结论:高 Throughput ≠ 好的 Serving 系统。
更完整的评价应该是:在满足 latency SLO 的前提下,系统能够保持多大的有效吞吐? 这才是 Goodput 真正想回答的问题。
Throughput 与 Goodput 对比
可以用一个简单的柱状图表示:
Throughput Goodput
Server A ██████████ ██████
100 60
Server B ████████▌ ████████
85 80
这也直观地说明了:最高 Throughput 并不一定意味着最高 Goodput。
4. 小结
如果关心单个用户感受到的响应速度,需要看 TTFT、TPOT 和 ITL;如果关心整个系统的处理能力,需要看 Throughput。
但一旦进入真实的多用户 LLM Serving 场景,问题就会进一步变成 Throughput 与 Latency 的权衡,此时还需要关注 P99、SLO 与 Goodput。 最终可以用三句话概括:
- Latency 回答:一个用户需要等多久。
- Throughput 回答:整个系统能够处理多少工作。
- Goodput 回答:在保证用户体验的前提下,系统真正能够处理多少工作。

参考资料
- vLLM — Metrics:适合了解 vLLM 在真实 Serving 系统中如何记录 TTFT、ITL、E2E Latency、Queue Time、Prefill Time、Decode Time 等指标。(vLLM)
- vLLM —
vllm bench serve:可以进一步了解 TTFT、TPOT、ITL percentile,以及基于 SLO 的 Goodput benchmark 是如何实际落地的。(vLLM) - NVIDIA AIPerf Metrics Reference:我最推荐作为“指标字典”使用,对 TTFT、ITL、Per-user Throughput、System Throughput、Goodput 等指标都给出了明确公式。(NVIDIA Docs)
- MLPerf Inference:适合了解工业标准 benchmark 为什么会同时设置 throughput 和 latency constraints,以及不同 workload 为什么需要不同 SLO。(MLCommons)
- DistServe: Disaggregating Prefill and Decoding for Goodput-optimized Large Language Model Serving:如果想真正理解 Goodput 为什么重要,这篇最值得读。(arXiv)
- Taming Throughput-Latency Tradeoff in LLM Inference with Sarathi-Serve:非常适合理解 Prefill / Decode 的执行特征以及 throughput–latency trade-off。(arXiv)