Skip to content

Continuous Batching ​

Continuous Batching(连续批处理)是一种按推理迭代重新组批的调度方式:请求完成后立即离开批次,等待队列中的新请求随即补入,而不必等整批请求全部结束。它主要解决生成长度不一致造成的算力空洞,是在线 LLM 服务提升吞吐量和降低排队时间的基础能力。

静态批处理与 Continuous Batching 的迭代槽位对比

静态批处理的问题 ​

传统静态批处理会先凑齐一组请求,再让它们共同运行到全部结束。由于不同请求的输出长度不同,短请求结束后占用的位置无法及时复用:

推理阶段静态批处理Continuous Batching
请求完成等待同批其他请求立即移出批次
新请求到达等当前批次全部完成下一次可调度迭代即可加入
批次大小一批内基本固定随请求状态动态变化

Continuous Batching 也被称为 iteration-level scheduling 或 in-flight batching。它与“去掉 Padding”不是一回事:前者改变请求的调度生命周期,后者只减少一个批次内部的无效计算。

核心原理 ​

设第 t 次迭代的运行批次为 Bt,本轮完成的请求为 Ft,新接纳的请求为 At,下一轮批次可以表示为:

Bt+1=(Bt∖Ft)∪At

调度器通常在每次模型前向计算前执行以下操作:

  1. 接收新请求,并放入等待队列。
  2. 移除已完成或被中止的请求,释放其请求槽位和 KV Cache。
  3. 根据显存、Token 预算和优先级,从等待队列接纳新请求。
  4. 选择新的 Prefill 请求或继续运行 Decode 请求;支持混合执行时,也可把两者组成同一批次。

其中,Decode 请求每轮通常只输入一个新 Token,历史上下文保存在 KV Cache 中。因此,请求可以跨越多个批次持续生成,批次成员也可以在每轮发生变化。

调度时真正受限的资源 ​

Continuous Batching 不是简单地“有空位就塞请求”。调度器至少需要同时考虑:

  • 请求槽位:并发请求数不能超过运行上限。
  • KV Cache 容量:要为已有上下文和后续生成预留空间。
  • 单轮 Token 预算:Prefill 的输入 Token 数远大于 Decode,可能让一次迭代耗时突然增加。
  • 公平性与优先级:持续到来的短请求不应让长请求无限等待。

如果直接把一个超长 Prompt 整体插入正在 Decode 的批次,虽然实现了连续接纳,却可能让所有 Decode 请求等待一次很长的 Prefill 计算。因此调度器还需要限制单轮工作量,在吞吐量与延迟之间取舍。

优势与代价 ​

方面作用
GPU 利用率及时填补已完成请求留下的空位,减少空转
吞吐量在相同硬件上并发服务更多请求
排队时间新请求不必等待最慢的同批请求结束
延迟稳定性仍受长 Prefill、抢占和显存压力影响,需要额外调度策略

它优化的是系统整体效率,但不保证每个请求都更快。批次越大,吞吐量通常越高;同时单轮计算时间和排队竞争也可能增加。因此应同时观察:

  • TTFT(Time To First Token):请求到首个输出 Token 的时间。
  • TPOT(Time Per Output Token):相邻输出 Token 的平均间隔。
  • Goodput:满足延迟目标的有效吞吐量,而不只是每秒处理的总 Token 数。

SGLang 中的实现 ​

SGLang 的调度循环会维护等待队列与运行中的 Decode 批次,在每轮前向计算后过滤已完成请求,再尝试接纳新的 Prefill 请求。接纳过程同时检查请求槽位、KV Cache 和 Prefill Token 等预算。

相关入口:

参考 ​

  1. Orca: A Distributed Serving System for Transformer-Based Generative Models