强化学习(RL)已成为大模型从「能用」走向「好用」的核心引擎。但在 RL训练流程中,传统同步训练模式长期受困于「长尾阻塞」——生成阶段的极端耗时反复中断训练,硬件大面积空闲,既拉低吞吐又推高成本。AsyncFlow异步流式RL以训推解耦为核心,通过TransferQueue数据中枢与CheckpointEngine权重引擎,将推理(Rollout)与训练(Trainer)彻底解耦,突破同步模式的性能限制。实测在prompt 2k → response 16k长序列场景下,在昇腾Atlas 900 A3 SuperPoD液冷超节点、Atlas 800 A3风冷超节点等全系列产品训练吞吐从同步方案的59.3提升至226.8,相对提升3.81倍,同时保持收敛精度对齐,目前已支持verl框架。
一个标准的同步RL step,需顺序走完六道工序:Rollout生成 → Reward打分 → Actor前向(old_logprob)→ Reference 前向(ref_logprob)→ Advantage计算 → Actor训练更新。在这样的场景下会出现以下问题:
阶段间相互阻塞:训练必须等整批生成、打分、前向全部结束才能启动,等待期间训练所占算力全程闲置。
长尾拖垮整批:一个batch内绝大多数样本早已生成完毕,仅剩少数超长序列仍在逐token输出;整批必须对齐,已完成样本所在的资源只能陪着空等最慢的一条。
资源画像错配:Rollout访存密集、占用周期长,前向计算量小却与训练共享整机资源。共卡模式下所有角色挤在同一批卡上轮流使用,无法按需分配,也难以横向扩展。
三者叠加的结果是算力利用率低下、训练周期被长尾主导、成本居高不下。
以解耦+数据中枢+可控陈旧
重构流水线
AsyncFlow 的总体思路可概括为三点:
把「一锅煮」拆成独立工位:Rollout、两个前向、Advantage、训练各自拆为独立Worker,运行在自己的事件循环中连续工作,不为彼此的整批进度而等待。
用数据中枢把工位连起来:Worker间不直接通信,只与 TransferQueue(TQ)交互——生产者写入、消费者按需取走,任意环节在物理上彻底解耦。
允许训练用「稍旧」数据:通过staleness机制让推理超前训练若干版本地持续生成、填满空泡;再以FlowControlQueue约束「最多超前多少」,守住精度底线。
之上再以CheckpointEngine在训练更新权重后,将新权重异步广播给推理与前向Worker。
图1 AsyncFlow 整体架构示意图
其性能实验中资源配比52-2-2-8:52张卡给瓶颈所在的 Rollout,两个前向各2张卡,Advantage放CPU,训练独占8张卡。
同步模式下前向、打分、训练被绑死在同一节拍,一环变慢就阻塞全局。AsyncFlow将下游计算拆为四个职责单一的Worker:
四者共享同一套异步循环骨架(取数 → 计算 → 写回),各自运行在独立线程的事件循环中,彼此没有整批同步点。骨架还内置两项保障:一是用「分发策略」抽象屏蔽并行后端差异,Worker主循环无需关心自己跑在何种并行模式;二是取数前先做「全局可用量探测」,所有rank确认数据充足后再一起放行,避免某个 rank 卡住整组的集合通信。由此,多道工序在不同样本上同时推进,流水线真正「流动」起来。
解耦之后系统须回答两个新问题:如何安全使用跨版本混合数据?组内大量重复的prompt如何不浪费存储与带宽?TransferQueue采用控制面与数据面分离的分布式架构——控制面管主题、索引、版本与就绪状态但不存数据,数据面由多个分片承载真实张量。它为异步RL定制了四项能力:
图2 TransferQueue控制面/数据面分离架构
版本即数据属性:version作为每条数据的标签,配合「最新版本 + 允许陈旧度」划出滑动窗口,一次集合运算即可筛出「足够新鲜」的样本,无需为每个版本维护分区。
引用计数去重:GRPO中同一prompt采样n条,组内共享列只传一次、只存一份,大batch、长prompt下显著降内存与带宽。
端到端零拷贝:仅序列化张量元数据,本体经Buffer Protocol + ZMQ零拷贝直传,序列化开销下降95%以上。
索引管理透明化:写入方只提交数据与版本,索引由 TQ 自动分配;消费方只声明数量,TQ按「就绪∩未消费∩版本新鲜」动态分发。每个Worker都与全局进度解耦——这正是异步方案成立的数据底座。
训练每更新一轮权重,都要同步给数十张卡的Rollout与前向Worker,这是异步 RL 中最重的一次通信。CheckpointEngine 统一抽象训推权重同步,底层基于HCCL集合通信广播,叠加三层优化:
图3 CheckpointEngine双缓冲流水线广播
双缓冲流水线:发送与接收并行,以通信/计算重叠隐藏延迟。
分桶传输:小张量按桶批量打包再发,减少通信次数。
主机缓存+懒加载:将「接收权重」与「加载进模型」拆成两步,前向Worker收到新权重先缓存在主机内存,等下一批次开始再加载,使接收对当前计算几乎零干扰。
完整同步流程为:暂停前向与所有Rollout实例 → 准备元数据 → 构建通信拓扑 → 广播更新 → 收尾 → 通知加载并恢复生成。Rollout暂停复用vLLM原生能力,可排空在途请求后再暂停,避免丢弃中间结果。最重的通信被拆解、重叠、缓存,对计算扰动降到最低。
异步若放任不管会失控:推理一路生成、训练来不及消费,TQ中堆积过期数据最终把精度带崩。AsyncFlow用一条带容量上限的FlowControlQueue约束「推理最多可超前多少」,容量为 (staleness + 1) × batch_size。主控注入新prompt前先查容量,将溢出则反压等待;训练每完成一批便释放等量坑位。
图4 FlowControlQueue 陈旧度控制
由此staleness语义清晰可调:=0时严格同步、退化为on-policy;=N时允许推理超前训练N个版本。同时训练侧也在一轮batch等待——训完一个完整GBS才将版本号加一并等待权重同步。数据流全异步、权重更新仍在GBS边界对齐。
1、主控取一批prompt注入生成层;
2、生成层按采样数切分、限流分发给生成Worker调用vLLM,记录 model_version并并行完成reward打分;
3、结果带版本标签写入TransferQueue;
4、Actor/Reference前向Worker分别计算old_logprobs、reference_logprobs写回;Advantage Worker(CPU)凑齐reward、按组算advantage写回;
5、Actor训练Worker发现某样本「全列就绪且版本新鲜」便取走训练,完成后推进版本、释放流控坑位;
6、主控轮询到训练版本前进,触发CheckpointEngine广播新权重。
整条链路上,多道工序在不同样本上并行推进,Rollout仍在为下一批生成——没有任何环节需等待另一环节整批完成。这便是「训推异步流水线」的真正含义。
在Qwen2.5-Math-7B+DAPO-17k、prompt 2k → response 16k场景下:
图5 训练时间线Trace分析
优势核心在于细粒度的角色解耦:把计算量小的两个前向各拆到2张卡、Advantage移至CPU,从而把计算资源更多让给瓶颈所在的Rollout,训练卡也不再被前向挤占。
精度方面,不同陈旧度评测如下:
图6 reward收敛曲线
可以看到:同步与异步(staleness=0)基本一致,差异 2% 以内;适度异步(≤2)可维持甚至微幅提升;过高陈旧度(=4)开始衰退。staleness存在一个「甜点区」——这正是 FlowControlQueue把激进程度约束在收益最大、风险可控区间的意义所在。
AsyncFlow现已在verl框架下可用:
https://github.com/verl-project/verl-recipe/tree/main/async_flow
昇腾开源微信小助手:ascendosc
verl开源社区讨论区:
https://github.com/volcengine/verl/discussions


