章节摘要:显存管好之后,浪费转移到了时间维度:请求什么时候进批、什么时候退出、批满了牺牲谁。本章沿"批的粒度"这条追因线走:静态批为什么让短请求陪跑(4.1),迭代级调度怎么把批的进出从"轮"细化到"步",以及高峰期抢占、交换与重计算这套兜底组合拳(4.2)。读完本章,吞吐曲线上那些"反直觉"的形状都能得到解释。
第 3 章结束时,主线场景的卡上出现了前所未有的富余:并发能力翻了几倍,显存里躺着大量可以容纳新请求的空间。但复盘日志发现了新问题——夜间低峰期吞吐只有白天的几分之一,而卡明明闲着。追查发现:请求不是均匀到达的,一阵稀一阵密;旧部署的批处理方式在"请求稀"的时段把大量 GPU 时间浪费在等待上。
这就是本章的病灶:批的组织粒度。批处理本身不是新闻——把多条请求拼成一个批次一起算,摊薄权重搬运成本,是推理服务的基本功。问题出在"批"的生命周期管理:传统静态批把一批请求捆成命运共同体,同进同出,最先结束的请求要陪到最后一个结束为止。批的粒度是"一轮",而 GPU 时间其实以"步"为单位流逝——粒度错配,浪费就藏在每一步里。
本章两站:4.1 把静态批的等待浪费拆开看,引出迭代级调度的思路;4.2 处理调度器的难题另一面——批满了、显存紧了,让谁等待、让谁让路,抢占、交换与重计算三件套各适用什么场合。
本章的拐点是把"批"从名词变回动词:批不是一次性的分组,而是每个迭代都在重塑的动态集合。这个转变与第 3 章互为因果——PagedAttention 让每条请求的显存开销变得精确可控,调度器才敢随时增减批成员;反过来,批的动态进出让块池的分配回收高频发生,也考验着块管理的效率。两章咬合在一起,才有"高利用率下的稳定吞吐"。
结论落在监控口径上:连续批处理上线后,最能反映调度健康度的指标是"运行中批大小"与"等待队列长度"的时间曲线。批大小长期贴着上限说明该扩容了;等待队列忽长忽短说明流量分布不均或调度参数过紧。第 8 章调优闭环里,这两条曲线是第一现场。
其一,"连续批处理是负载均衡"——不对。负载均衡把请求分到不同实例,连续批处理在单个实例内部决定每一步算哪些请求,两者层次不同、可以叠加。其二,"批越大一定越好"——第 1.2 节的跷跷板在这里再次生效:批的大小受块池容量与延迟目标双重约束,洪峰时的抢占与毛刺(4.2)就是批开过头的样子。带着这两条纠正进入正文,沿途的数字会更容易对上号。
时间和显存的浪费都收拾了,剩下的是重复劳动:相同的提示词前缀被反复计算,解码一步步串行爬行。第 5 章的两件武器——前缀缓存与投机解码——专门对付这两类浪费。