服务指标:吞吐、延迟与 TTFT
1. 核心指标定义
TTFT (Time to First Token)
从请求发出到模型生成第一个 Token 的时间。
- :请求在队列中等待的时间
- :Prefill 阶段的计算时间(处理完整 Prompt)
QUESTION 面试题:TTFT 受哪些因素影响?如何优化? TTFT 受以下因素影响:
- 队列等待时间:高并发时请求排队等待
- Prefill 计算时间:与 Prompt 长度和模型大小成正比
- GPU 资源竞争:其他请求的 Decode 占用 GPU
优化方法:
- Chunked Prefill:长 Prompt 分块处理,避免阻塞
- Prefix Caching:共享前缀只 Prefill 一次
- Tensor Parallelism:多 GPU 并行 Prefill
- 优先级调度:短 Prompt 优先处理
TPOT (Time per Output Token)
生成每个后续 Token 的平均时间(不含第一个 Token)。
也称为 Inter-Token Latency (ITL)。
End-to-End Latency (E2E Latency)
从请求发出到完整响应返回的总时间。
Throughput (吞吐量)
单位时间内系统处理的总 Token 数。
可细分为:
- Prefill Throughput:Prompt Token 处理速率(tokens/s)
- Decode Throughput:生成 Token 处理速率(tokens/s)
- 总 Throughput:所有 Token 的总处理速率
QUESTION 面试题:TTFT、TPOT、Throughput 之间有什么关系和矛盾?
- TTFT 主要反映 Prefill 效率
- TPOT 主要反映 Decode 效率
- Throughput 反映系统整体处理能力
核心矛盾在于 Batch Size:
- 增大 Batch Size → 更高吞吐(GPU 利用率提升)→ 但 TTFT 和 TPOT 都会增加
- 减小 Batch Size → 更低延迟 → 但吞吐下降(GPU 利用率低)
在线服务需要在延迟和吞吐之间找到平衡点,通常通过 Continuous Batching 和合理的并发控制来实现。
2. 指标关系与权衡
吞吐 vs 延迟
吞吐量 (tokens/s)
↑
│ ★ 最优平衡点
│ ╱
│ ╱
│ ╱ ↑ 增大 Batch Size
│ ╱ 吞吐增加,延迟也增加
│╱
└──────────────────→ 延迟 (ms)
核心矛盾:
- 增大 Batch Size → 更高吞吐 → 更高延迟
- 减小 Batch Size → 更低延迟 → 更低吞吐
TTFT vs TPOT
| 维度 | TTFT | TPOT |
|---|---|---|
| 影响阶段 | Prefill | Decode |
| 计算特点 | 计算密集 | 访存密集 |
| 优化方向 | 并行处理 Prompt | 高效 KV Cache 访问 |
| 用户感知 | 首次响应速度 | 生成流畅度 |
3. Prefill 与 Decode 的不同特征
| 维度 | Prefill 阶段 | Decode 阶段 |
|---|---|---|
| 输入 | 完整 Prompt(数百到数万 Token) | 单个 Token |
| 计算量 | 大( 矩阵乘法) | 小( 矩阵乘法) |
| 内存访问 | 读取模型权重一次 | 读取模型权重 + 全部 KV Cache |
| 瓶颈 | 计算 (Compute-bound) | 内存带宽 (Memory-bound) |
| GPU 利用 | 高(矩阵乘法效率高) | 低(大量内存读取) |
| 批处理效果 | 良好(计算可并行) | 良好(分摊权重读取开销) |
QUESTION 面试题:为什么 Prefill 和 Decode 的瓶颈不同?
- Prefill:一次处理 N 个 Token,矩阵乘法为 规模,计算量大,GPU Tensor Core 充分利用。瓶颈在计算 FLOPs
- Decode:每次处理 1 个 Token,矩阵乘法为 规模,计算量极小,但需要从 HBM 读取完整模型权重和全部 KV Cache。瓶颈在 HBM 带宽
这决定了优化方向不同:Prefill 优化计算效率(FlashAttention、Tensor Core),Decode 优化访存效率(量化、GQA、KV Cache 压缩)
4. 各指标优化策略
4.1 优化 TTFT
| 策略 | 方法 | 效果 |
|---|---|---|
| Chunked Prefill | 将长 Prompt 分块处理 | 减少单次 Prefill 占用时间 |
| Prefix Caching | 缓存共享前缀的 KV Cache | 避免重复计算 |
| Tensor Parallelism | 多 GPU 并行处理 Prompt | 线性加速 Prefill |
| Speculative Prefill | 并行处理 Prompt 的多个部分 | 减少 Prefill 时间 |
| 优先级调度 | 短 Prompt 优先处理 | 降低小请求 TTFT |
4.2 优化 TPOT
| 策略 | 方法 | 效果 |
|---|---|---|
| Batch Size 调优 | 增大并发请求数 | 提高每 Token 效率 |
| Speculative Decoding | Draft Model 预测多 Token | 减少 Decode 步数 |
| KV Cache 量化 | FP8/INT4 KV Cache | 减少内存带宽需求 |
| GQA/MQA | 减少 KV 头数 | 减少 KV Cache 大小 |
| FlashAttention | 高效注意力内核 | 减少计算开销 |
| 模型量化 | INT4/INT8 推理 | 减少模型权重读取量 |
4.3 优化吞吐
| 策略 | 方法 | 效果 |
|---|---|---|
| Continuous Batching | 迭代级调度 | 最大化 GPU 利用率 |
| PagedAttention | 高效 KV Cache 管理 | 支持更多并发请求 |
| 量化 | INT4/INT8 推理 | 减少模型大小,增大 Batch |
| 多 GPU | TP/PP 并行 | 线性扩展吞吐 |
5. 推理阶段瓶颈分析
数学分析:Decode 单步耗时
对于大模型(7B+),Decode 阶段访存项远大于计算项:
以 LLaMA-3-8B (FP16, A100) 为例:
- 模型权重:16 GB
- HBM 带宽:2 TB/s
- 理论最短 Decode: ms/Token
- 实际:15-20 ms/Token(含 KV Cache 读取、算子开销等)
数学分析:Prefill 耗时
以 LLaMA-3-8B (FP16, A100 312 TFLOPS),Prompt = 1024 Token:
- FLOPs: FLOPs
- 理论时间: ms
- 实际:20-50 ms(算子效率约 50%)
QUESTION 面试题:为什么 LLM 推理的吞吐和延迟难以同时优化? 根本原因是 GPU 资源固定:
- 低延迟:需要小 Batch Size,每个请求快速完成,但 GPU 利用率低
- 高吞吐:需要大 Batch Size,GPU 充分利用,但每个请求等待时间更长
Continuous Batching 部分缓解了这个矛盾:完成的请求立即释放资源,新请求立即填入。但在极限并发下,延迟和吞吐的矛盾仍然存在。
工程实践中通过 SLA 驱动的调度 来平衡:设定延迟上限(如 P99 TTFT < 500ms),在此基础上最大化吞吐。
6. 基准测试工具
vLLM Benchmark Suite
# 吞吐测试
python benchmarks/benchmark_throughput.py \
--model meta-llama/Llama-3-8B \
--dataset-path ShareGPT_V3 \
--num-prompts 1000
# 服务延迟测试
python benchmarks/benchmark_serving.py \
--model meta-llama/Llama-3-8B \
--dataset-path ShareGPT_V3 \
--request-rate 10 # 每秒 10 个请求
NVIDIA genai-perf
genai-perf \
-m meta-llama/Llama-3-8B \
--service-kind openai \
--concurrency 32 \
--measurement-interval 10000
关键测试维度
| 维度 | 测试值 |
|---|---|
| 并发请求数 | 1, 8, 16, 32, 64, 128, 256 |
| Prompt 长度 | 128, 512, 1024, 4096 |
| 输出长度 | 32, 128, 512, 1024 |
| 请求速率 | 1, 5, 10, 20, 无穷 (burst) |
7. 实际性能参考
LLaMA-3-8B (FP16, 1xA100)
| 并发数 | TTFT (ms) | TPOT (ms) | 吞吐 (tokens/s) |
|---|---|---|---|
| 1 | 50-100 | 15-20 | 50-65 |
| 16 | 100-200 | 20-40 | 500-800 |
| 64 | 200-500 | 40-80 | 1500-2500 |
| 128 | 500-1000 | 60-120 | 2000-3500 |
LLaMA-3-70B (INT4, 4xA100)
| 并发数 | TTFT (ms) | TPOT (ms) | 吞吐 (tokens/s) |
|---|---|---|---|
| 1 | 100-200 | 30-50 | 20-33 |
| 16 | 200-400 | 50-100 | 200-400 |
| 64 | 500-1000 | 80-200 | 500-1000 |
| 128 | 1000-2000 | 100-300 | 800-1500 |
注意:以上数据为典型值范围,实际性能因硬件配置、驱动版本、框架版本而异。
8. SLA 设计参考
交互式应用(聊天机器人)
| 指标 | 目标值 | 依据 |
|---|---|---|
| TTFT | < 200ms | 用户可感知阈值 |
| TPOT | < 50ms | 流畅阅读体验(20 tokens/s) |
| P99 TTFT | < 500ms | 长尾用户体验 |
批量处理(文档摘要、翻译)
| 指标 | 目标值 | 依据 |
|---|---|---|
| 吞吐 | 最大化 | 每秒处理越多请求越好 |
| 延迟 | 次要 | 用户不等待单条结果 |
流式应用(代码补全)
| 指标 | 目标值 | 依据 |
|---|---|---|
| TTFT | < 100ms | 实时反馈 |
| TPOT | < 30ms | 逐字符显示 |
QUESTION 面试题:聊天机器人场景的推理 SLA 应该如何设计? 聊天机器人是交互式场景,用户体验是核心:
- TTFT < 200ms:用户发出消息后 200ms 内看到第一个字,感觉"即时响应"
- TPOT < 50ms:每秒生成 20+ Token,阅读流畅
- P99 延迟 < 1s:99% 的请求在 1 秒内完成
实现方法:
- 使用 Continuous Batching 保证并发下的延迟稳定
- 限制最大 Batch Size 以控制排队时间
- Prefix Caching 缓存 System Prompt
- 必要时用投机解码降低 TPOT
9. 监控与调优闭环
监控 → 发现瓶颈 → 调优 → 验证
│ ↑ │
↓ │ ↓
指标采集 A/B 测试 部署
│ │
├─ TTFT 分布 ├─ 对比新旧配置
├─ TPOT 分布 └─ 确认改善
├─ 吞吐趋势
├─ GPU 利用率
└─ KV Cache 使用率
关键监控指标
| 指标 | 告警阈值 | 可能原因 |
|---|---|---|
| TTFT P99 | > 1s | 排队过长、Prefill 阻塞 |
| TPOT P99 | > 100ms | Batch 过大、KV Cache 过大 |
| GPU 利用率 | < 50% | Batch 过小、负载不足 |
| KV Cache 使用率 | > 90% | 即将 OOM,需扩容 |
| 请求排队数 | > 100 | 吞吐不足,需扩容 |