11.1 优化选型决策树:按症状选择技术
从症状(TTFT/TPOT/显存/尾延迟/吞吐)到技术的选型决策树,各技术的适用场景、原理出处与收益预期
模块四讲了 10 章技术,但真实场景里没人会问你”用什么技术”,只会告诉你”服务太慢了”。11.1 把问题反转过来:从症状出发选技术——这是一棵决策树,也是一张”技术地图”,每个节点都指向原理出处(前几章的篇目),方便回溯。
📑 目录
- 1. 症状到技术的决策树总览
- 2. TTFT 过高怎么办
- 3. TPOT 过高怎么办
- 4. 显存不够怎么办
- 5. 尾延迟失控怎么办
- 6. 吞吐上不去怎么办
- 7. 决策树的使用方式
- 📝 总结
- 🎯 自我检验清单
- 📚 参考资料
1. 症状到技术的决策树总览
症状(来自 10.2 的指标)
│
├─ TTFT 过高(首 token 慢)
│ ├─ prefill 计算慢 → Chunked Prefill / FlashAttention / GEMM 优化
│ ├─ 排队太久 → Continuous Batching / 扩容 / PD 分离
│ └─ 重复 prefill → 前缀缓存 / 前缀感知路由
│
├─ TPOT 过高(生成慢)
│ ├─ decode 访存受限 → FlashAttention / 量化 / KV 压缩
│ ├─ 每步都算一长串 → 投机解码(5 章)
│ └─ 批次内互相拖累 → 抢占策略 / 动态批
│
├─ 显存不够(OOM / KV 太小)
│ ├─ 权重太大 → 量化(4 章)/ TP(6 章)
│ ├─ KV 太小 → PagedAttention / 量化 KV / 更长上下文分离
│ └─ 批次受限 → Chunked Prefill / 流式
│
├─ 尾延迟失控(长尾恶化)
│ ├─ 长请求堵塞 → PD 分离(7 章)/ SLO 感知调度
│ └─ 抢占风暴 → 预留 KV 预算 / 大 batch 拆分
│
└─ 吞吐上不去(QPS 低)
├─ 单请求太贵 → 量化 / 投机解码 / 更优 GEMM
├─ 批次利用率低 → Continuous Batching / 前缀缓存
└─ 多卡协同差 → TP/PP/EP 组合(6 章)
📌 关键点:先定位症状,再选技术。同样的”慢”,TTFT 慢和 TPOT 慢是两种病(prefill 是算力型、decode 是访存型,见第 2 章),用错药无效还浪费排查时间。
2. TTFT 过高怎么办
2.1 判断先于行动
先看 10.2 的指标拆解:
request_queue_time_seconds 高?→ 排队问题(调度/容量)
request_prefill_time_seconds 高?→ prefill 计算问题
前缀命中率低且重复前缀多?→ 缓存问题
2.2 技术选项
| 症状细节 | 技术 | 原理出处 | 收益预期 |
|---|---|---|---|
| prefill 计算慢(长 prompt) | Chunked Prefill | 2 章(vLLM 调度) | 首个 token 提前,避免长 prefill 独占 |
| prefill 计算慢(kernel 效率) | FlashAttention / GEMM 优化 | 2 章 | 30-60% prefill 提速 |
| 排队太久(负载超容) | Continuous Batching | 2 章 | 队列更短、利用率更高 |
| 排队太久(副本不够) | 扩容(KEDA) | 10.3 | 线性收益(有加载延迟) |
| 重复 prompt 反复算 | 前缀缓存 + 前缀路由 | 3 章 + 10.3 | 命中场景 prefill 近乎归零 |
| 长 prefill 阻塞 decode | PD 分离 | 7 章 | TTFT 与 TPOT 双降 |
💡 提示:TTFT 优化有个”免费优先”原则:前缀缓存(开个 flag)→ 队列指标核对(可能是容量问题)→ 再上重武器(PD 分离)。先确认症状归属,重武器留给真需要的地方。
3. TPOT 过高怎么办
3.1 判断先于行动
先看:
decode 阶段的 GPU 利用率(Nsight,9.3)
是否访存受限(FLOPs 远低于峰值但显存带宽打满)
spec_decode 接受率(如果已开投机,5 章)
3.2 技术选项
| 症状细节 | 技术 | 原理出处 | 收益预期 |
|---|---|---|---|
| decode 访存受限(普遍情况) | FlashAttention / 量化(权重 4-bit) | 2 章 + 4 章 | 权重变小 → 访存变快 |
| decode 访存受限 | KV 量化 / KV 压缩 | 4 章 | KV 变小 → 更高 batch |
| 每步只出一个 token | 投机解码(EAGLE-3 等) | 5 章 | 2-3x token/s |
| 批量内互相拖累 | 抢占 / 动态批 / max_num_seqs 调优 | 2 章 | 尾部更稳 |
| 单卡算力不够 | TP(多卡并行) | 6 章 | 单请求时延下降 |
📌 关键点:TPOT 优化的第一课是”访存受限”(第 2 章):decode 阶段瓶颈是显存带宽不是算力,所以量化权重的收益在 decode 阶段最明显——这也是”量化 + 推理”组合的黄金场景。
4. 显存不够怎么办
4.1 判断先于行动
显存四件套(10.4):权重 + KV Cache + 激活 + 冗余
先算:哪一项吃掉了大头?
70B FP16 → 权重 140G(大头是权重)
长上下文 128K → KV Cache 爆炸(大头是 KV)
短模型高并发 → 激活/batch 峰值(大头是 batch)
4.2 技术选项
| 大头 | 技术 | 原理出处 | 收益预期 |
|---|---|---|---|
| 权重 | 量化(W8A8 / W4A16 / INT8/FP8) | 4 章 | 权重减半到 1/4 |
| 权重 | 张量并行(TP) | 6 章 | 按卡数均摊(有通信开销) |
| KV Cache | KV 量化(FP8/INT8) | 4 章 | KV 减半 |
| KV Cache | 更长上下文专用部署(PD 分离 + 独立 KV 预算) | 7 章 | 各资源按需 |
| batch/激活 | Chunked Prefill | 2 章 | 峰值激活下降 |
💡 提示:显存优化的决策顺序:先量化权重(改动最小)→ 不够再上 KV 量化 → 还不够再考虑 TP。TP 是把显存问题变成通信问题的转移(第 6 章),能用量化解决的别用 TP 解决。
5. 尾延迟失控怎么办
5.1 判断先于行动
尾延迟 = 长请求/长 prefill 堵塞短请求
先看:
是否有超长请求混在批次里(max_model_len 不设上限)
抢占次数(num_preemptions)是否持续 > 0
长尾出现在特定负载时段(高峰)还是全天
5.2 技术选项
| 症状细节 | 技术 | 原理出处 | 收益预期 |
|---|---|---|---|
| 长 prefill 堵塞 decode | PD 分离(prefill 与 decode 独立实例) | 7 章 | 尾延迟显著下降 |
| 抢占风暴 | 预留 KV 预算 / 降低 max_num_seqs | 2 章 | 抢占比下降 |
| 无上限长请求 | max_model_len 上限 / 超时熔断 | 10.3 | 尾部稳定 |
| 长尾 SLO 敏感 | SLO 感知调度(vLLM Scheduler 定制) | 2 章 | 按优先级服务 |
📌 关键点:尾延迟的本质是”共享资源的强隔离问题”——一个长请求的 KV 占用会影响所有短请求。PD 分离(7 章)是结构性解法;请求上限与配额是操作性解法;生产上两者都要。
6. 吞吐上不去怎么办
6.1 判断先于行动
先看:
最大吞吐 vs 当前吞吐(9.2 压测建立基线)
GPU 利用率(compute 利用率 vs 显存带宽利用率)
前缀命中率(缓存是不是白开了)
6.2 技术选项
| 症状细节 | 技术 | 原理出处 | 收益预期 |
|---|---|---|---|
| 利用率低(batch 不满) | Continuous Batching / 请求并发池 | 2 章 | 利用率 50%→85%+ |
| 单请求 FLOPs 太贵 | 量化 / 投机解码 | 4 章 + 5 章 | 20-60% |
| 前缀重复 | 前缀缓存 + 路由 | 3 章 + 10.3 | 命中场景吞吐翻倍 |
| 多卡协同差 | TP/PP/EP 组合调优 | 6 章 | 线性扩展(网络好时) |
| 长序列比例高 | PD 分离 | 7 章 | 吞吐与 SLO 双赢 |
💡 提示:吞吐优化的”杠杆顺序”:调度(Continuous Batching)→ 缓存(前缀)→ 计算(量化/投机)→ 并行(多卡)。前两个是配置级改动,后两个是架构级改动——先榨干配置,再动架构。
7. 决策树的使用方式
使用流程:
1. 建基线:9.2 压测当前吞吐/TTFT/TPOT(没有基线一切免谈)
2. 定症状:10.2 指标拆解,确认症状归属(排队?prefill?decode?显存?)
3. 查树选技术:按上表命中 1-3 个候选
4. 最小改动优先:配置级(缓存/调度)→ 模型级(量化)→ 架构级(并行/PD)
5. 验证闭环:改完重压测,对比基线,确认收益(9.4 回归门禁)
错误用法:
✗ 症状没定位就上 PD 分离(可能只是容量不够,扩容就解决了)
✗ 一次叠加多个技术(收益归属不清,回归无法定位)
✗ 用理论收益代替实测(9.4:每个优化必须进回归门禁)
📌 关键点:决策树的终点不是”选了什么技术”,而是”收益被验证了”。每个优化动作的闭环:改配置 → 压测 → 对比基线 → 记录到回归门禁。没有闭环的优化是”感觉变快了”,不可积累。
📝 总结
- 先定位症状,再选技术:TTFT(prefill/排队/缓存)≠ TPOT(访存/decode/投机)
- TTFT:前缀缓存免费优先 → Chunked Prefill → PD 分离
- TPOT:量化(访存受限的黄金解)→ 投机解码 → TP
- 显存:先量化权重 → KV 量化 → 再 TP
- 尾延迟:PD 分离(结构)+ 请求上限/配额(操作)
- 吞吐:调度 → 缓存 → 计算 → 并行,先配置后架构
- 使用流程:基线 → 定位 → 选技术 → 最小改动 → 验证闭环
🎯 自我检验清单
- “服务慢”的第一步动作是什么?(建基线、拆指标)
- TTFT 慢的三个分支各自对应什么技术?
- 为什么量化在 decode 阶段收益最明显?
- 显存优化的决策顺序?
- 尾延迟的本质问题与两个解法层次?
- 吞吐优化的杠杆顺序?
- 优化动作的闭环是什么?
📚 参考资料
- 本模块各章:第 2 章(调度/Attention)、第 3 章(前缀缓存)、第 4 章(量化)、第 5 章(投机解码)、第 6 章(并行)、第 7 章(PD 分离)、第 9 章(压测/Profiler)、第 10 章(扩缩容/监控)
- vLLM 官方文档:Performance Benchmarking(https://docs.vllm.ai/en/latest/performance/benchmarks/benchmarks.html)
- vLLM 官方文档:Optimization(https://docs.vllm.ai/en/latest/configuration/optimization.html)