RL r3 的超高校级的实现
内容提要
Qwen训练中优化QSA indexer top-k回放:原方案数据量达router百倍,每步耗时增8倍。作者发现中间环节无需理解top-k,改为payload只写一次存共享存储,仅传KB级引用,布局机器改用24字节handle,额外开销降至7%以下。
延伸解读
优化思路:从压缩数据到改变数据流
面对QSA indexer top-k回放数据量达router百倍、每步耗时增8倍的困境,初期尝试分片和压缩收效有限。作者重新审视数据流后发现,中间组件并不需要理解top-k内容,却被迫搬运大张量。真正的优化机会在于让payload只写一次存共享存储,中间环节仅传递KB级引用,从而将数据量从GB级降至KB级,额外开销降至7%以下。
实现关键:引用传递与布局机器复用
优化后,推理端将top-k payload写入共享存储,响应中只携带四元组引用。训练侧收口时生成manifest,调度和packing仅操作KB级清单。布局阶段将manifest展开为每token 24字节的handle,复用router r3的fused unpad和all_gather机器,通信量降低三个数量级。payload仅在消费点物化一次,常驻当前micro-batch,回收由manifest统一管理。
通用性与工程启示
该方案不挑数据类型,任何token粒度状态只要中间环节无需查看内容,都可采用类似拆分:布局信息先行,本体留到消费点。这要求开发者跳出局部实现,从全局视角审视数据通路,明确生产者、消费者和生命周期。在AI辅助编码时代,这种判断力尤为关键,否则可能更快地构建出本可不存在的数据通路。
Q&A
QSA indexer top-k回放为什么会导致训练step耗时增加8倍?
因为QSA top-k的原始字节量是router top-k的100+倍,一条长轨迹的索引就能到GB级别,一个batch再乘上去,数据量巨大,导致传输和处理开销极高,整个step耗时额外增加8倍。
优化后如何将top-k回放的数据量从GB级降到KB级?
优化后,payload(top-k本体)只写一次到共享存储,随响应回家的只有一串四元组(对象uuid、起始行、行数、层数),一条GB级轨迹用几十段这样的区间描述,KB级。中间环节只传递引用,不再搬运payload。
布局机器在优化中是如何处理top-k数据的?
布局机器不再搬运大的top-k张量,而是将manifest展开成每token一个24字节的handle(128bit对象uuid、行内坐标、哨兵值),喂入原有的fused unpad等机器。机器只关心行映射,不关心数据大小,通信量降低三个数量级。
优化后payload在训练侧是如何被消费的?
训练侧将handle按uuid归组,本stage只取自己那几层的对象,把对应行抽出来组装成record,经ContextVar注入Megatron。这是payload全程唯一一次物化,常驻范围只有当前micro-batch。
优化后开启indexer R3的额外耗时是多少?
相对关闭indexer R3的完整step,开启后的额外耗时不足7%。这是整条链路全开起来的总账,包括录制、存储、读取、回放。
这种优化方法可以推广到其他场景吗?
可以。这套拆法不挑数据:任何要从rollout带去train的token粒度状态,只要中间环节不需要看内容做决策,都可以让布局信息先走,本体留到消费点。