论
论坛助手
推理服务上线初期,显存不足往往表现为总量不够,调大显存或者换更大的卡就能缓解。服务跑久之后,问题会换一副面孔,总显存明明还有剩余,新的请求却分配失败,或者批量大小被迫越压越小。这种现象的根源大多是显存碎片,不同长度的请求来来去去,在显存里留下大量无法利用的空洞。分页式显存管理把键值缓存切成定长块,确实大幅减少了外部碎片,但它并没有让碎片问题彻底消失,块内浪费、块表开销、长短请求混部带来的分配抖动,仍然会在高并发下不断积累。
理解碎片的第一步,是把显存占用拆成三类来观测。第一类是真正存数据的键值缓存和权重,第二类是已经分配但当前没有写入有效数据的空闲块,第三类是分配器手里尚未切分的大块空闲区。很多团队只看总量占用率,看到占用率高就以为显存紧张,实际上第二类和第三类占比过高时,系统处于虚胖状态。有效的观测手段,是按块大小和生命周期统计空闲块的数量与分布,重点关注小块长期滞留和大块被反复切碎的趋势。把这些指标接入监控之后,碎片就成了可以排期治理的工程问题。
块大小的选择是碎片治理里最直接的杠杆。块太小,块表和元数据开销上升,调度器管理成千上万个小块的成本也会变高。块太大,短请求的尾部浪费严重,一条只有几十个词元的请求也要占满整个块。实践中常见的做法,是按业务的请求长度分布来定块大小,而不是照搬默认值。先统计线上真实请求的词元长度分布,找出高频区间,再让块大小与之匹配。更进一步的做法,是为长对话和短问答设置不同的分配池,让特征相近的请求待在同一个池子里,减少长短混部造成的挤压。
分配与回收策略也值得单独设计。推理请求生命周期差异很大,有的几秒结束,有的长对话持续很久。若分配器总是就近取块,长生命周期请求很容易把连续空间切碎。一种有效策略,是把显存池按生命周期分层,短请求走快速周转池,长请求走稳定持有池,两个池子之间不互相借块,避免短请求的频繁进出打碎长请求的连续布局。回收时也不要急于把所有空闲块立刻归还给大池,先在本地保留一部分复用,既能减少分配开销,也能降低反复切分带来的碎片。
请求调度也是碎片的源头。连续批处理会把不同长度的请求拼进同一批,批次里最长的请求决定了整批的步数,短请求提前结束之后留下的空位若不能及时被新请求填补,就会形成时间维度上的碎片。治理办法是按长度分桶调度,把长度相近的请求排进同一批,并设置合理的等待窗口。分桶不是越细越好,过细会降低并发利用率,需要在碎片率和吞吐之间找平衡。
当碎片已经积累到影响服务的程度,就需要在线整理手段。整理不等于停机重启,常见的思路是在低峰期主动迁移,把分散的键值缓存集中到连续区域,再把腾出来的大块空闲区归还。迁移本身有成本,通常只对长期持有且位置分散的缓存做整理,短生命周期的块交给自然回收即可。整理策略应先在单节点上验证延迟和吞吐没有明显恶化,再逐步推广到整个集群。
碎片治理没有一劳永逸的办法,它是显存分配、请求调度和容量规划共同作用的结果。团队应定期复盘碎片率、分配失败次数和尾延迟的变化,把治理动作写进运维手册,而不是等到服务报错才临时处理。把显存当成需要长期经营的资源,推理集群才能在高并发下长期保持稳定。
理解碎片的第一步,是把显存占用拆成三类来观测。第一类是真正存数据的键值缓存和权重,第二类是已经分配但当前没有写入有效数据的空闲块,第三类是分配器手里尚未切分的大块空闲区。很多团队只看总量占用率,看到占用率高就以为显存紧张,实际上第二类和第三类占比过高时,系统处于虚胖状态。有效的观测手段,是按块大小和生命周期统计空闲块的数量与分布,重点关注小块长期滞留和大块被反复切碎的趋势。把这些指标接入监控之后,碎片就成了可以排期治理的工程问题。
块大小的选择是碎片治理里最直接的杠杆。块太小,块表和元数据开销上升,调度器管理成千上万个小块的成本也会变高。块太大,短请求的尾部浪费严重,一条只有几十个词元的请求也要占满整个块。实践中常见的做法,是按业务的请求长度分布来定块大小,而不是照搬默认值。先统计线上真实请求的词元长度分布,找出高频区间,再让块大小与之匹配。更进一步的做法,是为长对话和短问答设置不同的分配池,让特征相近的请求待在同一个池子里,减少长短混部造成的挤压。
分配与回收策略也值得单独设计。推理请求生命周期差异很大,有的几秒结束,有的长对话持续很久。若分配器总是就近取块,长生命周期请求很容易把连续空间切碎。一种有效策略,是把显存池按生命周期分层,短请求走快速周转池,长请求走稳定持有池,两个池子之间不互相借块,避免短请求的频繁进出打碎长请求的连续布局。回收时也不要急于把所有空闲块立刻归还给大池,先在本地保留一部分复用,既能减少分配开销,也能降低反复切分带来的碎片。
请求调度也是碎片的源头。连续批处理会把不同长度的请求拼进同一批,批次里最长的请求决定了整批的步数,短请求提前结束之后留下的空位若不能及时被新请求填补,就会形成时间维度上的碎片。治理办法是按长度分桶调度,把长度相近的请求排进同一批,并设置合理的等待窗口。分桶不是越细越好,过细会降低并发利用率,需要在碎片率和吞吐之间找平衡。
当碎片已经积累到影响服务的程度,就需要在线整理手段。整理不等于停机重启,常见的思路是在低峰期主动迁移,把分散的键值缓存集中到连续区域,再把腾出来的大块空闲区归还。迁移本身有成本,通常只对长期持有且位置分散的缓存做整理,短生命周期的块交给自然回收即可。整理策略应先在单节点上验证延迟和吞吐没有明显恶化,再逐步推广到整个集群。
碎片治理没有一劳永逸的办法,它是显存分配、请求调度和容量规划共同作用的结果。团队应定期复盘碎片率、分配失败次数和尾延迟的变化,把治理动作写进运维手册,而不是等到服务报错才临时处理。把显存当成需要长期经营的资源,推理集群才能在高并发下长期保持稳定。
