← 返回题目列表

什么是 Continuous Batching?它为什么比静态批处理更适合大模型服务?

高频 中等 第 5 / 25 题 更新于 2026/08/03
Continuous Batching动态批处理调度吞吐量

简化版

Continuous Batching(连续批处理,又称 in-flight batching) 是大模型服务的核心调度技术:它以每轮 Decode 迭代为粒度重组 batch——已生成完的请求立即退出、腾出的槽位马上让新请求补进来,而不是等整批都结束。这样避免了静态批处理「被批内最长的请求拖住、短请求早早算完却干等着」的浪费,GPU 利用率和吞吐大幅提升。代价是要管理变长 KV Cache、准入控制、抢占和公平性。

详细版

静态批处理:把一批请求凑齐一起算,直到整批都完成才换下一批。生成长度不同时,短请求结束后仍占着槽位空转,还有 padding 带来的无效计算。

连续批处理:采用迭代级调度,每生成一轮 token 后就更新队列——移除已完成请求、加入等待请求,batch 组成随时间动态变化。

调度器受多重约束:最大活跃序列数、每轮 token 预算、KV Cache 容量、服务优先级。batch 越大通常吞吐越高,但可能让单请求等更久,所以要按 TTFT、TPOT、尾延迟 目标调参,不能一味求大。

完整版教学

一、静态 batch 的浪费:一个时间线例子

假设一批 3 个请求,分别要生成 10、50、200 个 token。静态批处理的问题在于「木桶效应」:

请求A(10 token):  ████ 结束后槽位空转 ──────────────────────
请求B(50 token):  ████████████ 结束后空转 ──────────────
请求C(200 token): ████████████████████████████████████
                    ↑ 整批直到 C(最长)结束才释放,A/B 的槽位白白闲置

请求 A 只需 10 轮就完事,但它的计算槽位要空等到第 200 轮 C 结束才释放,期间新请求只能在队列里排队。加上为对齐长度的 padding 无效计算,GPU 利用率很低。这在生成长度差异大的真实流量里损失巨大。

二、迭代级调度:每站都能上下车

Orca 提出的关键思想是:以「生成一轮 token」而非「整个请求」作为调度单位。每轮执行后,调度器:

  1. 把已生成完(遇到 EOS 或达长度上限)的请求移出 batch;
  2. 从等待队列拉入新请求填补空位;
  3. 继续下一轮。

于是 batch 不再在整个生成期固定,而是每轮动态变化。上面的例子里,A 第 10 轮结束就立刻退出、新请求 D 马上补位,槽位不再空转。现代框架(vLLM、TGI 等)把这类机制叫 Continuous Batching 或 In-flight Batching。

记忆钩子:静态批处理是”一车人必须等最慢的人才能开下一班”,连续批处理是”公交每一站都能上下车”——吞吐提升来自及时补位、不空转。

三、资源约束:不能只看请求数

新请求加入前,要为它的 prompt(prefill)和未来的 decode 预留 KV Cache。这里有个高频坑:只限制 batch 的请求数、不看 token 长度,会被长 prompt 瞬间打爆缓存。举例:限制「最多 32 个并发请求」,但若来了几个 32K token 的长请求,KV Cache 立刻耗尽。

所以调度器通常双重限制:最大活跃序列数 + 每轮最大 token 数(token budget)。当显存不够时,可选择:延迟准入、抢占并重算被踢请求、把 KV 换出到 CPU、或直接拒绝——每种都影响延迟。

四、公平与优先级:避免饿死和队头阻塞

调度策略有内在张力:

  • 总优先短请求 → 平均延迟低,但长请求可能被无限期插队而饿死
  • 严格先来先服务 → 公平,但一个超长请求可能造成队头阻塞,后面的短请求干等。

生产系统需要:优先级队列、等待时间老化(等久了自动提权,防饿死)、租户配额、最大上下文限制。原则是高优先级不能绕过总资源保护(否则拖垮全局)。

五、怎么调优(附方法)

max_num_seqs(最大活跃序列)前,先观察三个信号:GPU 利用率、KV Cache 水位、TPOT

  • 若 GPU 利用率低、KV 还有余 → 可提高并发,吞吐会涨。
  • 若吞吐上升但 P99 的 TTFT/TPOT 超标 → 并发过头了,要降回来,或按 prompt 长度分桶(长短请求分开批),或拆分 Prefill 与 Decode 资源(分离部署)。

压测的铁律:流量必须包含真实的输入/输出长度分布——用清一色短请求测出来的吞吐,上线遇到长请求会崩。

六、易错点

  • 误区:连续批处理只是把 batch 调大。 它的关键是迭代级动态进出,不是单纯增大静态 batch。
  • 误区:只限并发请求数就安全。 必须同时限 token 预算,否则长 prompt 打爆 KV Cache。
  • 误区:吞吐越高越好。 吞吐和尾延迟是跷跷板,要按 SLA(P99 TTFT/TPOT)平衡。
  • 配合 PagedAttention:变长 KV Cache 的高效管理靠 PagedAttention 的分页分配,两者是绝配。

七、加强记忆

连续批处理记「迭代级调度、及时补位」:每轮 Decode 边界重组 batch——完成的请求立即退出、新请求马上补进来,消除静态批处理「被最长请求拖住、短请求空转」的浪费,大幅提升 GPU 利用率和吞吐。代价与要点钉死:必须双重限制(最大序列数 + 每轮 token 预算,防长 prompt 打爆 KV)、需要老化/配额防饿死与队头阻塞、吞吐与尾延迟要按 SLA 平衡、配 PagedAttention 管变长缓存。简要说——静态是「等最慢的人」,连续是「每站上下车」。