跳转至

推理性能优化

优化前先确定目标。交互式聊天更关心首 token 时间,批处理更关心总吞吐,Agent 同时受模型生成和工具等待影响。

四个核心指标

指标 含义 常见瓶颈
TTFT 请求到首 token 的时间 排队、长输入 prefill、冷启动
TPOT 首 token 后每个 token 的时间 显存带宽、批量、跨卡通信
Throughput 每秒总输出 token 或完成请求 批处理、调度、GPU 利用率
E2E latency 用户看到完整结果的时间 输入、输出长度、工具和重试

同时记录输入 token、输出 token、并发、模型、量化、硬件和版本。缺少这些维度的 tokens/s 无法复现。

理解 prefill 与 decode

  • Prefill 一次处理输入上下文,通常偏计算密集。超长提示词会明显拉高 TTFT。
  • Decode 逐 token 生成,通常偏显存带宽密集。并发与 KV Cache 决定能装多少活跃序列。

这解释了为什么“缩短上下文”常常比换更快 GPU 更有效,也解释了批量为什么能提升吞吐但可能损害单请求时延。

优化顺序

1. 删除无效 token

  • 不重复发送固定文档、历史对话和工具说明。
  • RAG 只放与问题相关、去重后的片段。
  • 设置合理最大输出,要求结构化且简洁的结果。
  • 对可复用长前缀启用供应商缓存或引擎 prefix caching。

2. 连续批处理

使用 vLLM/SGLang 等调度器动态合并不同时间到达的请求。增大批量前同时观察 P95 TTFT,吞吐提升不应把交互请求全部排队。

3. KV Cache 管理

  • 限制最大上下文和活跃序列。
  • 在支持时评测 FP8 KV Cache。
  • 按短、长请求分队列,避免长请求阻塞短请求。
  • 缓存命中率低时,不要为 prefix cache 保留过多显存。

4. 权重量化

方法 典型场景 取舍
FP8/INT8 数据中心新 GPU、高质量要求 约 2 倍权重压缩,质量通常接近基线
AWQ/GPTQ 4-bit NVIDIA 生产推理 约 4 倍压缩,需要校准或预量化权重
GGUF Q4/Q5/Q8 本地、CPU/GPU 混合 硬件覆盖广,量化等级选择丰富
bitsandbytes 4/8-bit 快速实验、QLoRA 易用,但推理加速不保证

Hugging Face 量化选型明确提醒:量化后必须在自己的任务和硬件上同时评测质量和速度。显存更小不一定代表延迟更低。

5. 并行策略

  • Tensor parallel:单层跨多卡切分,适合模型单卡放不下;依赖高速互联。
  • Pipeline parallel:不同层放在不同卡,可能产生流水线气泡。
  • Data parallel:每卡完整副本,提高独立请求吞吐;需要每卡能放下模型。
  • Expert parallel:MoE 专用,专家跨卡分布;通信模式与 dense 模型不同。

优先选择“单卡能放下就单卡”。多卡不是免费显存,通信会增加复杂度和时延。

6. 推测解码

用小 draft 模型或多 token 预测提出候选,再由目标模型验证。接受率高时能降低 decode 延迟,任务分布变化时收益可能消失。上线前比较:接受率、总吞吐、P95 和额外显存。

7. 编译和专用内核

FlashAttention、CUDA Graph、torch.compile、TensorRT-LLM、Marlin 等可带来收益,但高度依赖模型、GPU、形状与版本。一次只改变一个变量,保存可回退配置。

基准测试矩阵

至少覆盖:

维度 建议点位
输入长度 512、2K、8K、目标 P95、最大允许值
输出长度 32、256、目标 P95、最大允许值
并发 1、2、4、8,直到错误或 P95 超标
请求类型 短问答、长文档、结构化输出、工具调用
模型配置 基线精度、候选量化、缓存开关

每轮先预热,报告均值和 P50/P95/P99,不只报告最好一次。

性能排障

TTFT 高
  -> 是否排队?
  -> 输入是否过长?
  -> prefix cache 是否命中?
  -> prefill 是否被小 batch 或跨卡通信限制?

TPOT 高
  -> GPU 利用率与显存带宽是否饱和?
  -> batch 是否过小?
  -> 量化内核是否真正启用?
  -> tensor parallel 是否跨慢速 PCIe?

吞吐低但 GPU 空闲
  -> CPU tokenizer、网络、序列化或同步工具是否阻塞?
  -> 服务是否错误地串行处理?
  -> 请求是否频繁冷启动或加载 adapter?

十步性能实验

  1. 固定模型 revision、引擎镜像、启动参数、GPU 时钟和功率上限。
  2. 保存真实流量的输入/输出 token 分布,不用单一固定长度代替。
  3. 单并发预热,确认质量和输出 token 数没有异常变化。
  4. 建立无量化、无特殊优化的可解释基线。
  5. 分别扫描并发、输入长度和输出长度,找到第一次违反 SLO 的点。
  6. 同步采集网关队列、CPU、GPU、显存、网络和引擎 scheduler 指标。
  7. 每次只改变一个高影响变量,至少重复三轮。
  8. 对量化和推测解码重新跑质量集,不默认结果等价。
  9. 计算每成功任务成本,而不是只比较峰值吞吐。
  10. 保存胜出配置、失败配置和回滚命令。

从指标形状判断瓶颈

观测 更可能的瓶颈 下一步验证
TTFT 随输入长度近似线性增长 prefill 计算或输入过长 缩短上下文、拆分长短队列
TTFT 随并发陡增,TPOT 稳定 排队或调度上限 看 queue time、限制 admission
TPOT 高且 GPU 显存带宽接近饱和 decode 带宽 测量化、增大有效 batch
GPU 利用率低且 CPU 满载 Tokenizer/序列化 并行 tokenizer、批量处理
多卡比单卡更慢 通信或切分不当 查看拓扑,降低 TP 或换高速互联
P50 正常但 P99 极差 长请求干扰或周期性抖动 按长度分队列,关联 GC/缓存/网络

实验记录样例

experiment: exp-017-fp8-kv
baseline: exp-012-bf16-kv
immutable:
  model_revision: "<commit>"
  engine_image: "<digest>"
  gpu: "H200-SXM"
  workload: "traffic-2026-09-01-v3"
change:
  kv_cache_dtype: fp8
result:
  task_pass_rate_delta_pp: -0.2
  ttft_p95_delta_pct: -3.1
  throughput_delta_pct: 18.4
  peak_vram_delta_gib: -21.7
decision: accept_after_high_risk_review

优化停止条件

当候选已满足业务 SLO,继续追求实验室峰值可能增加维护风险。出现以下任一情况应暂停:质量下降触碰门禁;收益小于测量噪声;需要使用未获支持的内核;回滚时间超过目标;运维团队无法观察新增机制。

核心原则:性能问题必须先定位发生在排队、prefill、decode、工具还是网络。把端到端慢统一归因于“模型太大”,会把工程时间花在错误位置。