关键词: LLM 推理性能、TTFT、TTFAT、TBT、Output Speed、Throughput、Prefill、Decode、SLO、SLA、并发、tokens/s、llama.cpp、vLLM、SGLang
一、为什么不能只看一个 tokens/s
评估一个大模型推理方案时,最常见的错误有 3 个:
- 看到
80 tokens/s,就认为它一定比50 tokens/s快。 - 看到
TTFT很低,就以为整体对话体验一定流畅。 - 看到
Throughput很高,就默认它能服务好每一个用户。
这些判断都可能错。
因为大模型推理的"快",至少要拆成 3 层:
- 用户等第一个字出来要多久
- 开始输出之后,字蹦出来的速度快不快
- 整个系统在并发下,还能不能维持住前两层体验
如果不把这三层拆开,你看到的很多 benchmark 数字其实都只解释了问题的一部分。
二、先理解两个阶段:Prefill 和 Decode
在讲所有指标之前,先看一次请求的生命周期。
1. Prefill(预填充)
用户发来一段 prompt,模型先把整段输入"读完"。这一步就是 Prefill。
它的特点是:
- 输入 token 一次性并行计算
- 计算量大
- GPU 利用率高
- 主要瓶颈是算力(FLOPS)
也就是说,prompt 越长,Prefill 越慢,TTFT 通常也越高。
2. Decode(解码)
模型开始一个一个生成输出 token,这一步就是 Decode。
它的特点是:
- 每次只生成一个 token
- 计算量相对小,但频繁访问权重和 KV cache
- 主要瓶颈是显存带宽,而不是算力
这也是为什么很多 GPU 在 decode 阶段,看起来"算力没打满",但系统还是很慢。
3. 一个最简图
text
请求进入
│
├── Prefill:一次性处理整段 prompt
│ └── 结束时拿到第一个 token → 这段时间就是 TTFT
│
├── Decode:逐个生成输出 token
│ ├── token 与 token 之间的间隔 → TBT
│ └── 持续输出速度 → Output Speed
│
└── 最后一个 token 输出完成 → E2E Response Time
记住这两个阶段,后面所有指标都会变得很好理解。
三、延迟类指标:用户到底觉得快不快
这一类指标解决的是:用户视角下,等待体验怎么样。
1. TTFT(Time to First Token)
定义: 从请求发出到收到第一个 token 的时间。
这是用户最敏感的指标之一,因为它决定了用户会不会觉得"系统卡住了"。
一般来说:
- 短 prompt 场景里,
TTFT越低越好 - 长 prompt 场景里,
TTFT很容易被Prefill拉高
2. TTFAT(Time to First Answer Token)
定义: 从请求发出到收到第一个"真正答案 token"的时间。
它主要针对 reasoning 模型。
因为 reasoning 模型经常会先输出一段 thinking token。
这时:
TTFT可能很低- 但用户真正看到答案,要等很久
所以评估 reasoning 模型时,只看 TTFT 很容易被误导。
3. TBT(Time Between Tokens)
定义: 连续两个 token 之间的时间间隔。
这个值决定了流式输出时的"打字感"是不是顺滑。
如果 TBT 很抖动,哪怕平均速度不错,用户体感也会觉得一卡一卡的。
4. E2E Response Time
定义: 从请求发出到最后一个 token 输出完成的总时间。
它适合看:
- 非流式场景
- 长回答场景
- 用户真正要等多久才能拿到完整答案
简单理解就是:
text
E2E ≈ TTFT + 输出阶段耗时
四、速度类指标:模型产出内容到底有多快
这一类指标解决的是:模型的生成效率如何。
5. Output Speed(输出速度)
定义: 单个请求在输出阶段每秒生成多少 token。
这就是大家最常说的 tokens/s。
但要特别注意:
它通常只反映开始输出之后的速度,不包含前面等待首 token 的时间。
所以:
Output Speed高- 不一定代表整体体验好
6. Prefill Speed(预填充速度)
定义: Prefill 阶段每秒处理的输入 token 数。
如果你的业务是:
- 长文档摘要
- 长上下文 RAG
- 大量资料拼接后再问答
那 Prefill Speed 会非常重要,因为它直接决定长输入下的首 token 等待时间。
7. Decode Speed
定义: Decode 阶段每秒生成的输出 token 数。
很多情况下它和 Output Speed 是同一个意思,只是有些引擎文档更喜欢写 Decode Speed。
五、系统级指标:服务到底扛不扛得住
前面的指标更偏单请求体验。
一旦进入生产环境,你还必须看整个系统的容量。
8. Throughput(系统吞吐量)
定义: 整个服务在并发下,每秒处理的总 token 数。
它和 Output Speed 的区别非常重要:
Output Speed:单个用户看到的速度Throughput:整台机器 / 整个系统的总产出
一个经典误区是:
单用户 40 tok/s,系统就只能 40 tok/s。
其实未必。
因为在 decode 阶段,单个请求往往用不满 GPU。
通过 continuous batching,系统可以把多个请求拼起来一起算,所以系统级吞吐通常会比单用户速度大很多。
9. QPS / RPS
定义: 每秒能处理多少个完整请求。
它适合做:
- 容量规划
- 日调用量估算
- 接口规模预估
粗略关系是:
text
QPS ≈ Throughput / 平均每请求输出 token 数
10. Concurrent Users @ SLO
定义: 在满足目标服务体验前提下,系统最多能同时服务多少用户。
例如你定义:
P95 TTFT <= 2.5sP25 Output Speed >= 20 tok/s
那么 Concurrent Users @ SLO 问的就是:
在这个门槛下,最多还能扛多少并发用户?
这个指标非常重要,因为它直接对应:
- 要买几张卡
- 能服务多少用户
- 扩容成本是多少
六、SLI / SLO / SLA 到底怎么区分
很多人讲到这里就会混掉:
TTFT、Output Speed这些是指标?P95 TTFT <= 2.5s这算什么?- 对客户承诺"3 秒内响应"又算什么?
最简单的记法是:
| 缩写 | 全称 | 中文 | 一句话理解 |
|---|---|---|---|
SLI |
Service Level Indicator | 服务级别指标 | 测什么 |
SLO |
Service Level Objective | 服务级别目标 | 要达到什么水平 |
SLA |
Service Level Agreement | 服务级别协议 | 对外承诺什么 |
放到推理评测里就是:
SLI
你测出来的这些值:
TTFTOutput SpeedSuccess RateThroughput
都叫 SLI。
SLO
你自己给这些指标设门槛:
P95 TTFT <= 2.5sP25 Output Speed >= 20 tok/sSuccess Rate >= 99%
这就是 SLO。
SLA
如果你再把这些目标写进客户合同或服务承诺:
- "95% 请求 3 秒内返回首 token"
- "月可用性 99.9%"
这就变成了 SLA。
一句话记忆:
SLI 是温度计,SLO 是及格线,SLA 是写进合同里的承诺。
七、为什么 benchmark 很强,不等于可以上线
这一步特别容易被忽略。
很多 benchmark 只给你 SLI,但人会自动脑补成:
- 这个系统够好
- 这个系统可以上线
- 这个系统能对外承诺
但中间其实还差两步:
- 你有没有定义适合业务的
SLO - 这个系统有没有长期稳定满足这些
SLO
所以一定要记住:
一个漂亮的 SLI,不等于一个合格的 SLO;一个合格的 SLO,也不等于你已经可以对外给 SLA。
八、买卡决策为什么一定要看"每美元 Throughput"
到了采购阶段,只看 tokens/s 会非常危险。
因为采购真正关心的不是:
- 哪张卡更快
而是:
- 同样的钱,能换来多少吞吐?
- 同样的用户体验目标下,要买多少张卡?
11. 每美元 Throughput
如果你知道:
- 系统吞吐:
throughput(tok/s) - 每小时成本:
cost_per_hour
那可以算:
text
每美元吞吐 = throughput × 3600 / cost_per_hour
反过来,也可以算:
text
每 1M 输出 token 成本 = cost_per_hour × 1,000,000 / (throughput × 3600)
一个最直观的例子
| 方案 | Throughput | 成本 |
|---|---|---|
| A | 200 tok/s |
$2/h |
| B | 320 tok/s |
$5/h |
如果只看吞吐,B 更强。
但算每美元吞吐:
- A:
200 × 3600 / 2 = 360,000 tok/$ - B:
320 × 3600 / 5 = 230,400 tok/$
所以:
B 更强,但 A 更划算。
九、买卡决策为什么还要看"每用户显卡数"
另一个特别重要的指标是:
Users / GPU @ SLO- 或者倒过来看:
GPU / User @ SLO
如果:
- 在目标 SLO 下,系统最多支撑
N个用户 - 当前用了
G张卡
那么:
text
Users / GPU = N / G
GPU / User = G / N
这两个值特别适合做容量规划。
比如:
- 一张 L20 扛
4个并发用户 - 一张 H20 扛
8个并发用户
那如果你有 40 个并发需求:
- L20 需要
10张 - H20 需要
5张
所以真正该比较的不是"哪张卡更值",而是:
哪套系统在目标 SLO 下更值。
十、不同场景该看什么指标
这是最实用的一张表。
| 场景 | 核心指标组合 | 为什么 |
|---|---|---|
| 对话助手 / 客服 | TTFT + Output Speed + P95 延迟 |
用户对卡顿极敏感 |
| Copilot / 代码补全 | TTFT + 短回答 E2E |
输出短,首 token 更关键 |
| 长文档处理 / RAG | Prefill Speed + TTFT(长输入) |
prompt 很长,prefill 决定体验 |
| 批量离线处理 | Throughput |
更关心总产出,不太关心单用户延迟 |
| 容量规划 / 买卡 | Concurrent Users @ SLO + 每美元 Throughput |
直接对应硬件成本 |
| Reasoning 模型评估 | TTFAT + 总 E2E + 思考 token 占比 |
只看 TTFT 很容易被骗 |
十一、做本地评测时,至少记录哪些字段
如果你在用 llama.cpp、vLLM 或 SGLang 做测试,建议每次至少记录:
text
model: 模型名称
quant: 量化方式
gpu: 显卡型号
context_len: 上下文长度
batch_size: 并发数
prompt_tokens: 输入 token 数
completion_tokens: 输出 token 数
ttft_ms: 首 token 延迟
output_tps: 输出速度
throughput_tps: 系统总吞吐
vram_used_gb: 显存占用
有了这些结构化数据,你才可能做出真正有意义的横向比较。
十二、最容易踩的坑
1. 不同工具的 tokens/s 口径可能不一样
有的工具把 prefill 算进去,有的只算 decode。对比前一定先确认口径。
2. 量化对 prefill 和 decode 的影响不同
量化通常对 decode 的收益更明显,因为 decode 更受访存限制。
3. 长上下文会同时拖慢 prefill 和 decode
- Prefill 变慢:输入 token 变多
- Decode 变慢:KV cache 变大
4. Throughput 高,不代表每个用户都快
有些系统靠更激进的大 batch 拉高总吞吐,但单用户 TTFT 和 Output Speed 会变差。
5. Reasoning 模型的 TTFT 很会"骗人"
第一个 token 可能很快出来,但用户真正看到答案,可能已经是十几秒后。
十三、最后一句总结
不要再用一个 tokens/s 就评价一个推理方案。
你至少要拆开看:
- 用户体感:
TTFT + TBT + E2E - 生成效率:
Output Speed + Prefill Speed - 服务容量:
Throughput + Concurrent Users @ SLO - 成本效率:
每美元 Throughput + 每用户显卡数
只有把这几层拆清楚,你才能真正回答:
这个推理方案到底适不适合我的业务。