理解 LLM 推理性能:Latency、Throughput 与 Goodput
讨论 LLM Serving 性能时,“快”至少有三层含义:用户多久看到第一个 token,后续 token 生成是否流畅;系统单位时间能够完成多少工作;以及在延迟目标下,有多少请求真正达标。本文从一次请求的 Prefill 和 Decode 出发,依次介绍 TTFT、TPOT、ITL、E2E Latency、Throughput、SLO 与 Goodput,说明为什么峰值吞吐并不等于良好的在线服务。
本文只讨论 LLM Serving 的延迟、吞吐与服务水平,不涉及回答质量、安全性和推理成本。
1. 从一次 LLM 请求开始:Prefill 和 Decode
用户发起一次 LLM 请求后,模型并不是直接“连续写出”完整回答,而是大致经历两个阶段:先理解输入,再逐步生成输出。
1.1 Prefill:处理输入
在 Prefill 阶段,模型会处理用户输入的 Prompt,并为其中的 token 计算和保存中间结果。这些结果会被存储在 KV Cache 中,供后续生成使用。
Prompt 越长,模型需要处理的输入内容越多,准备阶段通常也越耗时。这个阶段可以理解为模型先“读完题目并建立上下文”。
1.2 Decode:逐步生成
完成输入处理后,模型进入 Decode 阶段。模型每次根据已有上下文生成一个新的 token,再把这个 token 加入上下文,继续生成下一个 token:
由于模型需要根据前面的内容逐步生成,Decode 通常不能像处理输入那样大规模并行。KV Cache 可以避免模型反复计算已经处理过的上下文,但模型仍然需要不断读取缓存并生成新的 token。
这个阶段可以理解为模型“一个字一个字地写答案”。输出越长,Decode 持续的时间通常也越长。
因此,一次请求可以简单表示为:
Prefill 和 Decode 的计算特征不同:前者更像是一次性处理大量输入,后者更像是反复进行小步计算。正是这种差异,使 LLM Serving 需要同时考虑用户等待时间和系统整体吞吐能力。后文将分别介绍用于衡量这些表现的具体指标。
2. Latency 与 Throughput
理解 Prefill 和 Decode 之后,我们就可以开始讨论一个 LLM 推理系统到底“快不快”。这里存在两个不同的观察视角:
- 站在用户的角度,我们关心一次请求需要等待多久,这对应 Latency。
- 站在系统的角度,我们关心单位时间内能够完成多少工作,这对应 Throughput。
Latency 和 Throughput 并不是同一个问题:一个系统可以让少量用户获得很低的延迟,也可以通过批处理同时服务大量用户、获得很高的聚合吞吐,但很难在所有负载下同时把两者做到最好。
2.1 Latency:一个请求需要等多久?
Latency 描述单个请求的响应速度,直接影响聊天、代码补全等交互式应用的用户体验。对于流式生成请求,常见的延迟指标包括:
- TTFT(Time To First Token):从计时起点到收到第一个输出 token 的时间。它主要受到请求排队、调度、Prefill 计算和首 token 采样等因素影响。TTFT 越低,用户越快看到模型开始回复。
- ITL(Inter-Token Latency):相邻两个输出 token 之间的时间间隔。ITL 描述流式生成过程中每一次停顿的长短;ITL 越低、波动越小,输出通常越流畅。
- TPOT(Time Per Output Token):第一个 token 返回后,平均生成一个后续 token 所需的时间。它可以理解为一次请求在 Decode 阶段的平均 ITL。
- E2E Latency(End-to-End Latency):从计时起点到完整响应生成结束所经历的总时间。
这里的“计时起点”需要在 benchmark 中明确说明。客户端口径通常从发出请求开始计时,包含网络和协议开销;服务端口径则可能从服务收到请求开始计时,更侧重 Serving 系统本身。只有测量边界一致,延迟数字才适合直接比较。
下图展示了一次流式生成请求中各项延迟指标的测量范围:

图:TTFT 描述回答何时开始,ITL 和 TPOT 描述回答过程中的生成速度,E2E Latency 描述完整请求最终耗时。
假设一次请求共生成了 个输出 token,那么在忽略少量测量误差的情况下,可以近似写成:
这个关系说明:对于短回答,TTFT 在总体体验中占比更高;对于长回答,持续生成阶段的 TPOT 会逐渐成为 E2E Latency 的主要组成部分。
2.2 Throughput:整个系统能处理多少工作?
如果说 Latency 关注的是一个请求有多快,那么 Throughput 衡量的是推理系统在单位时间内能够完成多少工作,反映系统整体的服务能力。
Request Throughput
Request Throughput 衡量系统单位时间内完成的请求数量,通常以 表示,也常写作 RPS(Requests per Second):
RPS 可以反映系统处理并发请求的能力,但不能体现每个请求包含的实际工作量。例如,生成一句简短问候与生成一篇长文,对模型造成的计算负载显然不同。因此,当输入长度、输出长度或流量模式不一致时,直接比较 RPS 很容易产生误导。
影响 RPS 的因素包括:
- Prompt Length 和 Generation Length
- 模型规模、精度与硬件配置
- Batch Size、并发度和请求到达模式
- Prefix Cache、Speculative Decoding 等优化方式
- 推理引擎的调度与内存管理能力
Token Throughput
Token Throughput 衡量系统单位时间内处理或生成的 token 数量,通常以 表示,也常写作 TPS(Tokens per Second)。根据统计对象不同,可以进一步分为:
- Input Token Throughput:系统单位时间内实际处理的输入 token 数。
- Output Token Throughput:系统单位时间内生成的输出 token 数。
- Total Token Throughput:输入与输出 token 的合计吞吐量。
在 LLM 性能讨论中,还需要特别区分单用户生成速度和系统聚合吞吐量:
- Per-user Output Token Rate 描述单个请求每秒收到多少输出 token,在稳定生成阶段近似为 。
- Aggregate Output Token Throughput 描述所有并发请求每秒生成的输出 token 总数。
提高并发度可能让 Aggregate TPS 上升,却同时让单个用户的 TPOT 变差。因此,“系统每秒生成多少 token”和“一个用户看到文字出现得多快”是两个不同的问题。
Input TPS 与 Output TPS 对不同 workload 的意义也不同:
- 对于长文档摘要等长输入、相对短输出的任务,Prefill 占比更大,因此 Input TPS 更值得关注。
- 对于短 Prompt、长输出的聊天或内容生成任务,Decode 占比更大,因此 Output TPS 和单用户 TPOT 更关键。
改变输入和输出长度会改变 Prefill 与 Decode 的工作占比,所以不同长度分布下测得的 TPS 不能直接比较。阅读 benchmark 时,至少应确认 TPS 指的是 Input、Output 还是 Total TPS,以及它是单请求速度还是系统聚合吞吐。
随着 Batch Size 和并发请求数增加,系统聚合 TPS 通常会先上升,直到计算能力、显存容量或内存带宽达到饱和。超过饱和点后,继续增加请求不一定能提高实际吞吐量,反而可能导致队列增长、延迟恶化,甚至出现超时或请求失败。
3. 从 Throughput 到 Goodput:高并发下怎样才算“好”?
实际的 LLM Serving 系统通常需要在 Throughput 和 Latency 之间做权衡。更大的 Batch Size 和更高的并发度能够提高 GPU 利用率与系统聚合吞吐,但也可能增加排队时间和资源竞争,使 TTFT、TPOT 或尾部延迟变差。
因此,评价在线服务时不能只问“峰值 Throughput 有多高”,还要问:在满足业务延迟要求的前提下,系统能够持续完成多少请求? 要回答这个问题,我们需要进一步引入延迟分布、SLO 和 Goodput。
3.1 为什么提高 Throughput 可能让用户变慢?
单个请求执行 Decode 时,每一步只生成一个新 token,工作量较小,通常难以充分利用 GPU。Serving 系统因此会把多个请求组织到同一个 batch 中执行,让一次计算同时服务多个序列。

图:Batching 让多个请求共享一次模型执行,有助于提高 GPU 利用率和聚合吞吐量。
不过,Batching 并不是免费的。随着系统负载增加,新请求可能需要在队列中等待;新的 Prefill 还可能与正在进行的 Decode 竞争执行时间和硬件资源。因此,更高的并发度与更大的 batch 可能同时带来:
- 更高的 Request Throughput 和 Aggregate TPS
- 更长的排队时间与 TTFT
- 更差的 TPOT 或更明显的 token 间隔波动
- 更严重的 Tail Latency
Sarathi-Serve 研究的核心正是这种 throughput–latency trade-off:Decode Batching 有利于系统吞吐,但 Prefill 与 Decode 在同一个 Serving Engine 中交错执行时,也会造成延迟干扰。论文通过 Chunked Prefill 和 Stall-free Batching 缓解这一问题。(arXiv)
下图用一条简化曲线展示负载增加时延迟的变化:

图:负载较低时,提高请求到达速率可以增加系统吞吐,而 Latency 变化较小;接近饱和点后,排队开始快速增长,Latency 随之显著恶化。
这说明,把 GPU 跑得很满并不等于用户体验就很好。在高并发环境中,系统吞吐和单请求延迟必须结合起来观察。
3.2 单一平均值看不见尾部延迟
即使我们开始关注 Latency,只看平均值仍然不够。平均延迟告诉我们所有请求平均需要等待多久,却无法展示这些延迟在请求之间是如何分布的。两个平均延迟相同的系统,实际体验可能完全不同。
假设两个系统分别处理了 100 个请求:
| 系统 | 请求延迟分布 | 平均延迟 |
|---|---|---|
| A | 100 个请求都是 200 ms | 200 ms |
| B | 98 个请求为 100 ms,2 个请求为 5.1 s | 200 ms |
系统 A 的所有请求都在 200 ms 完成;系统 B 的大多数请求虽然更快,却有 2% 的请求需要等待 5.1 秒。两者得到的平均延迟完全相同,只看 Mean,我们无法区分这两种截然不同的分布。
因此,在线服务通常还会观察 Median、P90、P95 和 P99 等延迟分位数。下面是一种常见的右偏延迟分布:大多数请求集中在左侧的低延迟区域,少量请求散落在右侧,形成一条长尾。

图:P50 描述延迟分布的中心位置,Mean 会被右侧慢请求拉高,而 P95、P99 等高分位数用于观察分布尾部。
这些统计量分别回答不同的问题:
- Mean(平均值):所有观测值之和除以请求数,能够反映整体平均水平,但容易受到极端值影响。
- Median / P50(中位数):一半请求的延迟不超过该值,常用来描述典型请求所处的位置。
- P95 / P99:分别表示至少约 95% / 99% 的请求延迟不超过该值,常用来量化高延迟尾部。
以 TTFT 为例:
可以理解为:在当前样本和统计方法下,约 99% 的请求 TTFT 不超过 2 秒;剩余约 1% 的请求可能更慢,甚至慢得多。
分布右侧的高延迟请求所体现的问题,通常称为 尾部延迟(Tail Latency)。生产环境之所以关注它,是因为即使绝大多数请求都很快,少量严重变慢的请求仍然会影响服务的稳定性。P95、P99 等高分位数正是量化尾部延迟的常用方法。
不过,分位数仍然只是在描述系统“慢到了什么程度”,它不会自动告诉我们这样的延迟是否符合业务要求。要判断服务是否足够快,还需要为这些指标设定明确目标——这就引出了 SLO。
3.3 SLO:多快才算“合格”?
同样是 2 秒的 TTFT,对于离线文档总结可能完全可以接受;对于 IDE 中的实时代码补全,却可能已经明显影响使用体验。因此,生产系统不能只把目标写成:
还需要根据业务场景,为关键指标设定可以测量和验证的目标。这就是 SLO(Service Level Objective,服务水平目标)。
这里可以顺便区分两个相关概念:
- SLI(Service Level Indicator) 是实际测量到的服务指标,例如 P99 TTFT 为 1.7 秒。
- SLO 是希望 SLI 达到的目标,例如 P99 TTFT 不超过 2 秒。
例如,一个交互式应用可以规定:
这是一种总体百分位目标:它要求在指定统计窗口和工作负载下,约 99% 的请求满足相应的延迟边界。SLO 把抽象的“响应要快、生成要流畅”转换成了可以验证的服务目标。
现实中的标准化 benchmark 也会采用类似设计。例如,MLPerf Inference v6.0 为 GPT-OSS 120B Interactive 场景设置了 P99 TTFT ≤ 2.0 s、TPOT ≤ 15 ms 的 latency constraints;DeepSeek-R1 Interactive 的约束则是 P99 TTFT ≤ 1.5 s、TPOT ≤ 15 ms。这些阈值只适用于对应的模型、数据集与场景,不应该直接照搬到所有 LLM 应用中,但它们很好地展示了 SLO 的作用。(MLCommons)
除了总体百分位目标,Goodput Benchmark 还经常使用单请求合格阈值。例如,规定一个请求必须同时满足:
只有同时满足两个条件,这个请求才被视为合格请求。
有了 SLO,问题就从“哪个系统的 Latency 更低”进一步变成:在满足业务延迟要求的前提下,系统每秒能够完成多少个合格请求? 这正是 Goodput 要回答的问题。
3.4 Goodput:满足 SLO 的有效吞吐量
Throughput 统计系统每秒完成了多少请求,而 Goodput 只统计其中满足全部单请求 SLO 的请求。按照 AIPerf 的定义:
如果一个请求的 TTFT 达标,但 TPOT 超过阈值,那么它仍然不能被计入 Goodput。因此:
换句话说,Throughput 衡量的是系统完成工作的速度,Goodput 衡量的是系统完成符合既定服务目标的工作的速度。(NVIDIA Docs)
假设在相同的工作负载、测试时长和 SLO 下测试两个 Serving 系统:
| 系统 | Request Throughput | Goodput | SLO 合格率 |
|---|---|---|---|
| Server A | 100 req/s | 60 req/s | 60% |
| Server B | 85 req/s | 80 req/s | 94.1% |
Server A 的原始吞吐更高,但高负载使大量请求违反了延迟 SLO,最终每秒只有 60 个合格请求。Server B 的原始吞吐稍低,却能让每秒 80 个请求满足全部 SLO。因此,如果目标是在既定延迟约束下提供稳定服务,Server B 反而具有更高的有效服务能力。
DistServe 进一步把这一思想作为 LLM Serving 的系统优化目标:给定应用的 TTFT 和 TPOT 要求后,系统应该优化在这些延迟约束下能够持续服务的最大请求速率,而不是只追求没有延迟约束的峰值 Throughput。DistServe 通过分离 Prefill 与 Decode,减少两阶段之间的资源干扰,并分别优化资源配置。(arXiv)
vLLM 的 Benchmark CLI 也提供了 --goodput 参数,可以为 ttft、tpot 和 e2el 设置以毫秒为单位的单请求阈值。例如,在完整的 vllm bench serve 命令中加入:
--goodput ttft:2000 tpot:50
表示只有 TTFT 不超过 2000 ms、且 TPOT 不超过 50 ms 的请求才会被计入 Goodput;任何一个条件不满足,该请求就不算合格。这里省略了模型、后端、数据集和请求速率等其他 Benchmark 参数。(vLLM)
3.5 Goodput 如何随系统负载变化?
Goodput 不是一个脱离测试条件的固定数字,它会随着请求到达速率、并发度、输入输出长度和 SLO 阈值发生变化。
- 负载较低时:请求几乎不需要排队,大部分请求都能满足 SLO,因此 Goodput 通常接近 Request Throughput。
- 负载接近饱和点时:Request Throughput 可能仍在上升,但排队和资源竞争开始推高 TTFT、TPOT 与尾部延迟,两条曲线逐渐分离。
- 系统过载后:Request Throughput 往往趋于平台,Goodput 则可能停止增长甚至下降,因为越来越多的请求虽然最终完成,却已经违反了 SLO。
下图展示了 Offered Load 增加时 Throughput 和 Goodput 的典型变化:

图:低负载时 Throughput 与 Goodput 接近;负载升高后,违反 SLO 的请求越来越多,两条曲线开始分离。
绿色曲线的峰值是当前测试条件下测得的 Maximum Goodput;达到这个峰值时对应的 Offered Load,可以理解为系统接近可用容量边界时的负载水平。
这也说明,报告 Goodput 时必须同时说明测试条件,至少包括:
- 模型、精度、推理引擎和硬件配置
- 输入与输出长度分布
- 请求到达模式、请求速率和最大并发度
- TTFT、TPOT 或 E2E 等 SLO 阈值
- Benchmark 持续时间、预热方式和请求数量
- 超时、失败请求与取消请求的处理方式
只有这些条件基本一致,两个 Goodput 数字才具有可比性。最终,我们真正关心的不是系统在不考虑延迟时能够“塞进”多少工作,而是:
4. 小结
评价一个 LLM Serving 系统,需要从单个请求一路看到整个系统:
- TTFT、TPOT、ITL 和 E2E Latency 描述单个请求各阶段需要等待多久。
- Mean、P50、P95 和 P99 描述大量请求中的延迟分布,帮助我们区分平均体验、典型体验和尾部延迟。
- Request Throughput 和 Token Throughput 描述系统单位时间内完成了多少请求或处理了多少 token。
- SLO 为这些指标设定业务上可以接受的边界。
- Goodput 描述单位时间内有多少请求真正满足了全部单请求 SLO。
这些概念之间的关系可以概括为:

图:Latency 描述单请求体验,Throughput 描述系统处理能力,SLO 划定合格边界,Goodput 则衡量满足边界的有效请求吞吐。
参考资料
- Key metrics for LLM inference (LLM Inference Handbook)
- vLLM — Metrics (vLLM)
- vLLM —
vllm bench serve(vLLM) - NVIDIA AIPerf Metrics Reference (NVIDIA Docs)
- MLPerf Inference v6.0 — GPT-OSS 与 DeepSeek-R1 Interactive 场景 (MLCommons)
- DistServe: Disaggregating Prefill and Decoding for Goodput-optimized Large Language Model Serving (arXiv)
- Taming Throughput-Latency Tradeoff in LLM Inference with Sarathi-Serve (arXiv)