8.2 推理优化
核心问题: 如何提高 LLM 服务的吞吐、降低延迟,并控制显存占用?
在线 Notebook
对应的交互式版本可在 Google Colab 打开,统一使用方式见 第0章说明。
推理的两个阶段
自回归生成分成两个阶段:
| 阶段 | 做什么 | 主要瓶颈 |
|---|---|---|
| Prefill | 处理输入 prompt,构建初始 KV cache | 常受矩阵计算、输入长度和排队影响 |
| Decode | 每次生成一个新 token | 常受权重/KV 读取、批处理和调度影响 |
长 prompt 会让 prefill 变重,长输出会让 decode 持续占用资源。
图8.2-1:请求从入口控制、分词和调度进入 Prefill 与 Decode 两阶段,随后流式返回;生产指标再反馈到路由和配置。应先根据问题发生在哪个阶段选择优化手段:TTFT 异常优先检查输入与 Prefill,生成速度和并发异常优先检查 Decode、KV cache 与调度。
KV Cache
KV cache 保存历史 token 的 Key/Value,避免每生成一个 token 都重新计算全部上下文。
没有 KV cache:
每一步重新计算完整上下文
有 KV cache:
历史 K/V 复用,只计算新 token代价是显存占用会随上下文长度、batch size 和层数增长。长上下文服务的核心问题之一,就是 KV cache 管理。
批处理与调度
批处理可以提高 GPU 利用率,但会影响单个请求延迟。
| 策略 | 优点 | 代价 |
|---|---|---|
| 静态 batch | 实现简单 | 请求长度差异大时浪费 |
| 动态 batch | 提高吞吐 | 调度更复杂 |
| 连续批处理 | 适合流式生成 | 需要专门推理框架 |
服务型推理后端通常围绕 batch、KV cache、并行和内存碎片做优化。具体支持范围与收益依赖版本、模型和硬件,应在目标环境中测量。
Flash Attention
标准 attention 需要读写完整注意力矩阵,IO 成本高。Flash Attention 通过分块计算减少显存读写,提高训练和推理效率。
它主要解决 IO 和显存访问问题,在相同掩码和注意力定义下计算同一数学算子;由于浮点精度和归约顺序不同,数值结果不要求逐位一致。
优化指标
上线时至少同时看:
- 首 token 延迟(TTFT):排队、分词和 prefill 后多久开始返回;
- token 间延迟(TPOT)或生成速率:decode 阶段的交互体验;
- 端到端延迟:从请求进入到完成,报告 p50/p95/p99;
- 吞吐:请求/秒与 token/秒,并注明输入和输出 token 是否分开;
- 并发、队列长度、峰值显存和 OOM 率;
- 对应配置下的业务质量和错误率。
只优化吞吐可能牺牲交互体验,只优化延迟可能导致 GPU 利用率过低。
本章的 inference_benchmark.py 是公式和方向性关系模拟器,输出带有 simulated_estimate 标记,不代表任何硬件或推理框架的实测 Benchmark。生产选型需要在固定模型、版本、输入输出分布和并发条件下重新测量。
本节小结
- Prefill 主要受输入长度影响,decode 主要受生成长度和调度影响
- KV cache 是自回归推理提速的关键,但会显著占用显存
- 批处理提升吞吐,但会引入延迟和调度复杂度
- 推理优化必须同时评估吞吐、延迟、显存和稳定性
下一节: 8.3 成本优化
