连续批处理 Continuous Batching 是什么?

连续批处理 Continuous Batching 是什么?为什么能提升并发能力?
连续批处理(Continuous Batching)是大模型推理中的核心优化技术。它解决的是"静态批处理"导致的GPU资源浪费问题——通过动态调度,实现序列完成即替换,让GPU始终保持高效运转。
1. 连续批处理是什么?
大白话讲,连续批处理就是动态翻台。
想象餐厅翻台的场景:客人吃完一道菜走了,服务员马上收拾桌子、迎接新客人。而不是等所有客人吃完、全部离席后,才统一翻下一批。
静态批处理呢?是所有客人吃完才翻台——哪怕有一桌早就吃完了,也得干坐着等最后一桌。
ORCA论文第一次把这个思想引入LLM推理。它的核心就一句话:一旦批处理中某个序列生成完毕,立刻用新序列替换它。

2. 为什么静态批处理效率低?
先理解LLM推理的特点。推理分两个阶段:
- Prefill:处理输入prompt,生成第一个token(一次性计算)
- Decode:逐个生成后续token(逐次迭代)
静态批处理的问题出在Decode阶段。
不同请求的生成长度差异巨大。问"今天天气怎么样"可能生成20个token,问"写一篇800字作文"可能生成800个token。
但GPU是批量执行的——所有序列必须同步推进。
一个序列生成完毕了,对不起,你得等着。等谁呢?等那个生成800个token的序列慢慢磨。

这就好比奶茶店:一个人买10杯奶茶,后面买1杯的人也得排队,而且奶茶店不能接待新客人。买10杯的人占着柜台不动,后面的人干着急,柜台资源白白浪费。
结果就是:GPU算完一批token后,必须停下来等最慢的序列。显存被完成序列占着,新请求进不来。GPU大部分时间在"等"。
3. 连续批处理如何提升并发能力?
核心思想很简单:不等。
GPU每生成一个token,调度器就检查一遍——有没有序列完成了?有,马上腾位置,塞新请求进来。
三个立竿见影的效果:
① GPU空闲时间大幅减少
GPU始终有活干。完成一个序列,马上安排下一个。计算资源不再空转。
② 显存即时释放
序列生成完毕,显存马上腾出来。不需要等整批完成才能释放。
③ 新请求快速入队
新任务来了就能进批处理,不用排队等到天荒地老。

还是ETC收费站的例子:传统做法是一辆车过完,后面整队车等着,等所有车都过完才抬下一批闸口。连续批处理呢?一辆车通过后闸口立刻抬起,下一辆跟上——车辆流转效率飙升。
4. ORCA迭代级调度机制
具体怎么实现?ORCA的设计思路是:每个推理步骤之后,scheduler和engine交互一次,检查batch里有没有做完的请求。
流程是这样的:
- GPU执行一次推理(可能是prefill一个batch,也可能是decode一个token)
- Scheduler检查batch中每个序列的状态
- 发现完成的序列 → 标记释放显存
- 发现有待处理的请求 → 加入batch
- 继续下一轮推理
这个"每步都检查"的机制,就是迭代级调度。它的本质是在GPU推理的间隙插入调度操作,实现Batch样本的动态增删。

有个很形象的类比:老师批改作业。不是等全班都交齐才发下一批作业——每改完一份,立刻发下去、收新作业上来。流水线始终在运转。
面试怎么答?
基础版(100字左右)
连续批处理是一种LLM推理优化技术,核心是动态批处理——序列完成即替换。静态批处理的问题是不同序列生成长度差异大,完成的序列占着显存和GPU等待最慢的序列,导致资源闲置。连续批处理通过迭代级调度,每步推理后检查并替换完成序列,让GPU始终有任务,从而提高利用率、即时释放显存、提升整体吞吐量。
加分版(200字左右)
连续批处理由ORCA论文首次提出,核心思想是动态批处理——一旦批处理中某个序列完成生成,立即用新序列替换。静态批处理的本质问题是LLM推理是内存-IO受限的,加载模型参数的时间远大于计算时间,因此批处理能更有效利用内存带宽。但当序列生成长度差异大时,GPU会产生大量"气泡"(idle time)。连续批处理通过迭代级调度,在每个推理步骤后检查并替换完成序列,实现显存的动态分配释放。需要强调的是,连续批处理不需要修改模型结构,它是一种调度优化,与PagedAttention是互补关系。
一句话总结
连续批处理就是让GPU"不等"——序列完成就替换,保持GPU始终有任务,从而大幅提升并发能力。
