连续批处理与调度
解码是访存受限的:每生成一个 token,要把全部权重读一遍,算术强度 ≈ 1(见 Roofline),Tensor Core 利用率不到 1%。唯一的解药是批处理——一次权重读取服务多个请求。但传统静态批处理有个致命缺陷:要等最慢的请求凑齐再换批。连续批处理(continuous batching)解决它,是现代推理引擎(vLLM 等)的核心创新。
解码为什么需要批处理
Section titled “解码为什么需要批处理”单请求解码的速度上限(见算术强度的算例):
70B 模型单请求最快 24 tokens/s,与算力无关——彻底的访存受限。批处理的收益:
| batch | 每次权重读取服务的 token | 算术强度 | 总吞吐 |
|---|---|---|---|
| 1 | 1 | ~1 | 24 tokens/s |
| 8 | 8 | ~8 | ~130 tokens/s |
| 32 | 32 | ~32 | ~430 tokens/s |
| 128 | 128 | ~128 | ~1100 tokens/s(接近计算受限边界) |
吞吐随 batch 近线性增长,直到算术强度逼近平衡点——这就是"推理集群靠 batch 赚钱"的数学根据。batch 的上限由 KV cache 决定(见上一章)。
静态批处理的问题
Section titled “静态批处理的问题”传统做法(如 naive 的 batch API):凑一批请求,一起解码,全部完成后才接新请求。
batch: [请求A(要出10个token) 请求B(要出500个token) 请求C(10个)]时间: ──────────────────────────────────────────────────→ A██ C██ ························· B████████████████ ↑ A、C 早就完成,GPU 为 B 空转几百步最慢的请求决定整批的时间——请求长度方差大的真实流量里,GPU 大部分时间在为长请求空转。这就是静态批处理的原罪。
连续批处理:迭代级调度
Section titled “连续批处理:迭代级调度”连续批处理(continuous batching / iteration-level scheduling):每一步解码都重新组批——完成的请求立刻退出,新请求立刻加入,GPU 永不空转:
step: 1 2 3 4 5 6 7 ...batch: ABC ABC ABC BC BC BCD BCD ... ↑A在第3步完成退出 ↑D在第6步插入收益:吞吐提升 2–20 倍(取决于请求长度方差),这是 vLLM 们相对 naive 部署的核心优势。
调度器每步要回答三个问题:
- 谁退出:完成的请求(EOS)退出,释放 KV 页
- 谁加入:等待队列里的请求,有 KV 空间就加入(prefill 先行)
- 谁被抢占:KV 池不足时,最晚的请求被换出(preemption)——抢占频繁说明并发配置超出 KV 容量
Prefill 与 Decode:两种负载
Section titled “Prefill 与 Decode:两种负载”一个请求的生命周期有两段性质完全不同的负载:
| Prefill(处理 prompt) | Decode(逐 token 生成) | |
|---|---|---|
| 计算量 | 大(整个 prompt 一次算完) | 小(每步一个 token) |
| 算术强度 | 高(~数百,接近计算受限) | 低(~1,访存受限) |
| 延迟特征 | 一次长计算(TTFT 的主体) | 多次短迭代 |
| 瓶颈 | 算力 | 带宽 |
混合调度的冲突:prefill 是计算密集的"大块",decode 是访存密集的"碎步"。混在同一个 batch 里互相干扰(prefill 的长计算让 decode 的步进卡顿——TPOT 抖动)。
解法见下一章:Prefill/Decode 分离部署。本节的调度器至少要做分级的混合策略(chunked prefill:prefill 切成小块与 decode 交错)。
调度参数与监控
Section titled “调度参数与监控”核心参数与它们的联动:
| 参数 | 影响 | 经验 |
|---|---|---|
| max_batch_size / 并发上限 | 吞吐 vs KV 压力 | 由 KV 池反推,别拍脑袋 |
| chunked prefill 块大小 | TTFT vs TPOT 抖动 | 块越小 TTFT 越平滑,开销略增 |
| 抢占策略 | 公平性 vs 抖动 | 重计算式抢占(丢 KV 重算)vs 换出式 |
| 请求优先级 | SLO 分级 | 高优请求优先 prefill |
监控指标(推理服务的生命线):
- TTFT(首 token 延迟):prefill 排队与计算的时间,用户体验的第一指标
- TPOT(每 token 间隔):decode 的步进时间,抖动比均值更重要
- 吞吐(tokens/s):batch 效率的直接体现
- KV 池使用率 / 抢占次数:容量配置是否合理的直接信号
- 解码访存受限(算术强度 ~1),单请求吞吐上限 = 带宽 ÷ 权重;批处理让吞吐近线性增长。
- 静态批处理被最慢请求绑架;连续批处理每步重组批,吞吐提升 2–20 倍。
- 调度器三问:谁退出、谁加入、谁被抢占;抢占频繁 = KV 容量配置不足。
- Prefill(计算受限)与 decode(访存受限)性质相反,混批互相干扰,chunked prefill 或分离部署。
- TTFT/TPOT/吞吐/KV 使用率是四个生命线指标;TPOT 看抖动不看均值。
- KV Cache 与 PagedAttention — 上一章:批处理的上限
- 分布式推理:Prefill/Decode 分离 — 下一章:分离调度
- 算术强度与 Roofline — 批处理收益的数学根据
- 投机解码 — 批处理之外的延迟优化