3. 批处理基础与动态批处理
在推理服务中,批处理是把多个请求合并成一次前向计算的核心手段。GPU 的算力来自大规模并行,单条请求往往无法填满 SM 与显存带宽,于是把多条请求拼成一个 batch,让矩阵乘法的 M 维变大,单位时间内完成的 token 数就会显著上升。但批处理不是免费的午餐:它把不同请求的等待时间绑在一起,批越大,单条请求从进入到拿到首 token 的延迟通常越高。理解静态、动态、连续三种批处理方式,以及批大小如何同时影响吞吐和延迟,是做好推理服务调优的第一步。
三种批处理方式的概念
静态批处理是最朴素的形式:服务端先攒够固定数量的请求,或者等待一个固定时间窗口,然后把这批请求一次性送入模型,等整批全部生成完毕后再统一返回。它的优点是实现简单、GPU 利用率高、显存占用可预测;缺点是“木桶效应”明显——批内只要有一条请求生成很长,其他已经结束的请求也必须陪着等,尾延迟被最长的那条拖住。此外,如果请求到达稀疏,攒批阶段本身就会引入额外等待。
动态批处理在静态批处理基础上引入时间窗口:服务端不再死等固定条数,而是在一个很短的时间窗(例如 5~20 ms)内收集到达的请求,窗口一到就把当前攒到的请求组成一批。这样在低负载时不必空等,在高负载时又能自然形成较大批次。它缓解了静态批处理的攒批僵化问题,但批内请求仍然要“同进同出”,长序列依旧会拖累短序列。
连续批处理(continuous batching,也称 iteration-level batching)把调度粒度从“整批”降到“单步”。每一轮解码迭代时,调度器都可以把已经完成的请求移出批次,并把新到达的请求插入空出的位置。于是批次成员在每一步都可能变化,GPU 始终维持较高的占用率,短请求完成后立即释放,不必等待同批的长请求。这是当前主流推理框架(如 vLLM、TensorRT-LLM、TGI)默认采用的策略,也是高并发场景下吞吐与延迟平衡的关键。
批大小对吞吐和延迟的直接影响
批大小 B 对两个指标的作用方向相反。吞吐方面,增大 B 让每次前向的矩阵规模变大,权重读取和 kernel 启动开销被更多请求分摊,GPU 利用率上升,单位时间处理的 token 数增加。但收益会递减:当 B 超过某个点后,计算从“访存受限”转为“算力受限”,吞吐曲线趋于平坦,而显存占用(尤其是 KV Cache)继续线性增长,最终触发 OOM 或被迫降低并发。
延迟方面,单条请求的端到端延迟大致由三部分构成:排队等待、首 token 时间(TTFT)、逐 token 生成时间(TPOT)。批越大,排队和 TTFT 通常越长,因为请求要等更久才能凑成一批,且一次前向要处理更多序列。TPOT 的变化更微妙:在访存受限区间,增大批能摊薄权重读取,TPOT 甚至可能下降;但进入算力受限区间后,TPOT 随批增大而上升。
可以用一个简化的示例说明这种权衡。假设某模型在 B=1 时单步耗时 20 ms,其中权重读取占 15 ms、计算占 5 ms;当 B 增大到 8 时,权重读取仍约 15 ms,计算增至 40 ms,单步耗时约 55 ms。此时单请求 TPOT 从 20 ms 升到 55 ms,但整批每步产出 8 个 token,吞吐从 50 token/s 提升到约 145 token/s。这就是典型的“用延迟换吞吐”。实际数值取决于模型、硬件和序列长度,此处仅为说明趋势的假设示例。
典型推理服务中的批处理策略
生产环境通常采用分层策略。第一层是准入控制:限制最大并发请求数 max_num_seqs 和最大批 token 数 max_num_batched_tokens,防止单批过大导致显存溢出。第二层是调度策略:优先填充 prefill 请求还是 decode 请求,常见做法是把 prefill 和 decode 分开调度(chunked prefill),避免长 prompt 的 prefill 阻塞正在解码的请求。第三层是抢占与回收:当显存不足时,按优先级或到达时间抢占部分请求,将其 KV Cache 换出到 CPU 或直接丢弃重算。
一个可参考的配置思路是:先根据显存容量估算 KV Cache 能容纳的最大 token 数,再反推 max_num_seqs;把 max_num_batched_tokens 设为单次前向能高效处理的上限(例如 2048~8192,视模型而定);开启连续批处理并设置合理的调度窗口。上线后观察 TTFT、TPOT、吞吐和 GPU 利用率的 P50/P99,逐步调整批大小上限,直到延迟满足 SLA 且吞吐不再明显增长为止。
| 策略 | 批大小特征 | 吞吐 | 延迟 | 适用场景 |
|---|---|---|---|---|
| 静态批处理 | 固定,攒满即发 | 高且稳定 | 尾延迟高 | 离线批量推理 |
| 动态批处理 | 窗口内浮动 | 较高 | 中等 | 负载波动的一般服务 |
| 连续批处理 | 每步动态变化 | 最高 | 低且可控 | 高并发在线服务 |
需要强调的是,批处理策略没有绝对最优,只有与业务目标匹配。对话类应用对首 token 延迟敏感,应控制批大小并优先调度新请求的 prefill;文档摘要类应用可以接受较长等待,适合用大 batch 提升吞吐。把批大小、调度方式和 SLA 三者放在一起权衡,才是批处理调优的完整视角。