大模型推理服务里的连续批处理,是一种让请求随时加入、随时离开的调度方式。同一批请求不必齐步走,谁先生成完谁先退出,空出的位置立刻让给排队中的新请求,显卡的利用率因此被明显拉开,这是推理服务提吞吐的基本功。
静态批处理的老问题
早期的做法是把一批请求凑齐,一起开始解码,一起结束。问题是每个请求的输出长度不同,短请求早就写完了,只能干等最慢的那个,算力白白空转,利用率被最慢的请求拖死。
再延伸一点:静态批处理的浪费还随输出长度差异放大。一批里有人只要五个字、有人要五百个字,差距越大,干等的算力越多;连续批处理正是把这种差异变成进出名单的节奏,差异越大,它相对静态方案的优势越明显。遇到服务性能公告里的利用率数字,背后指的就是这类调度带来的提升。
| 浪费来源 | 静态批处理 | 连续批处理 |
|---|---|---|
| 短请求先写完 | 干等最慢的那个,算力空转 | 写完即退出,位置让给排队请求 |
| 输出长度差异大 | 差距越大,干等的算力越多 | 差异变成进出名单的节奏 |
| 显存水位变化 | 固定编制,腾不出余量 | 紧张时缩编,宽裕时扩编 |
这就像一桌人点菜,必须等最慢的那道菜上齐才能开席,先好的菜放在后厨慢慢凉掉。客人等的是最长的那道菜,饭店赔的是空转的灶眼,两头都难受。
连续批处理怎么随时进出
连续批处理把批次从固定编制改成动态名单。每个解码步结束后,调度器检查名单:写完的请求退出,排队中的请求补入,下一步接着算,名单永远保持满员或接近满员。名单的容量也动态调整,显存紧张时缩编,宽裕时扩编,调度器始终盯着显存这条水位线行事,批次再流动也不能漫过它。
进出按步进行,每一步都可能有人来、有人走。对单个请求来说体验没变,对整个系统来说,空转的算力被新请求填上了,吞吐自然上升。
调度要平衡的两件事
调度器要同时看两件事:一是算力别闲着,尽量让每个解码步都满载;二是别让新请求饿死,排队太久用户会直接放弃,白占一轮排队成本。
实践中常用优先级、时间片、配额等手段做平衡。追求满载会让队列变长,追求低延迟会让利用率下降,调度策略就是在两者之间找位置,没有免费的午餐。观察调度效果可以看两个数:单步耗时是否平稳、队列长度是否收敛。两者都稳,说明批次规模配得合适;单步耗时抖动大,多半是批次编得太大,挤占了显存。
从用户侧看到的效果
这套机制对用户的直接意义是高峰期也能分到算力。请求进入的是一个流动的批次,而不是排一条看不到头的长队,等待时间的方差明显变小,体验更可预期。对普通用户而言,感受不到批次的存在恰恰说明调度在正常工作,一切波动都被消化在了后台,用户只需要专心提问。
在 DeepSeek、讯飞星火等推理服务的公开资料中,这类动态调度是提升吞吐的常见手段。想了解调度周边的机制,可以读解码的循环、请求队列怎么排和投机解码的采纳率。
速查表:
- 解决什么问题?静态批处理里短请求等慢请求的空转
- 怎么进出?每个解码步结束后,退一批、补一批
- 平衡什么?算力满载与排队延迟之间的位置
- 用户得到什么?高峰期也能分到算力,等待更可预期
关于连续批处理再多问三句
- 连续批处理会让我的请求变慢吗?:可能略微排队,但整体吞吐上升,高峰期的总等待通常比静态批处理更稳,个体波动更小。
- 它和并发调用是一回事吗?:不是,并发是客户端同时发多个请求,连续批处理是服务端把在途请求编成一个流动批次,一个在门外一个在门内。
- 为什么高峰期偶尔感觉更快了?:批次里有人退出后空位被补上,你的请求可能因此更早进入计算,这是动态调度的红利。


