【免费下载链接】Relax
An Asynchronous Reinforcement Learning Engine for Omni-Modal Post-Training at Scale
Relax 是一个面向全模态后训练的大规模异步强化学习(Async RL)引擎,其核心组件 DCS(Distributed Checkpoint Service) 通过 NCCL 广播实现训练权重到 SGLang 推理引擎的实时同步。本文将带你深入理解 Relax 中 DCS 权重同步的完整链路:NCCL 广播如何与训练计算重叠、推理引擎如何被"边训边更"地实时更新,以及背后的分桶、流水线与容错设计。
在 Colocate(同步)模式下,训练和推理时间片共享同一批 GPU,权重更新只能串行等待;而 Fully Async 模式下,Actor(训练)、Rollout(SGLang 推理)、ActorFwd/Reference(前向参考)各自独占 GPU 集群并行运行——此时"如何把刚训好的权重快速、无阻塞地送到推理端",就成了决定集群吞吐的关键瓶颈。DCS 就是为解决这个问题而生的高性能分布式权重同步引擎。
为什么权重同步是异步 RL 训练的命门
Fully Async 模式下,六类角色(actor、rollout、actor_fwd、reference、critic、advantages)分布在不同 GPU 集群上同时工作。每完成一次训练更新,Actor 都必须把新权重分发给:
- Rollout(SGLang 推理引擎)——保证下一批采样用上新策略
- ActorFwd——用于当前策略的 log prob 前向计算
- Reference——按
ref_update_interval周期性刷新参考模型(KL 计算用)
如果权重同步采用"训练暂停 → 序列化 → 走网络 → 恢复训练"的朴素方案,大参数 MoE 模型的同步耗时可达数十秒,GPU 利用率会断崖式下跌。DCS 的设计目标是让这条路径几乎零阻塞:权重以分桶 NCCL 异步广播的方式流动,与训练、推理计算充分重叠。
DCS 整体架构:控制面与数据面分离
DCS 采用典型的"控制面 / 数据面"分离设计(完整设计见 docs/draft/distributed_checkpoint_service.md):
| 平面 | 组件 | 职责 |
|---|---|---|
| 控制面 | DCSCoordinator(HTTP REST) | 节点注册、拓扑发现、通信组划分、权重元数据中转、心跳监控 |
| 数据面 | CheckpointEngineClient × N | 每个 rank 一个客户端,负责张量的收发 |
| 通信后端 | DeviceDirectBackend(NCCL/GLOO) | 集群内 GPU 间高速集合通信 |
- 控制面代码:relax/distributed/checkpoint_service/coordinator/
- 数据面客户端:client/engine.py
- NCCL 通信后端:backends/device_direct.py
协调器(Coordinator)只做"指挥":告诉每个节点该和谁组成 NCCL 通信组、下一桶权重的名字/形状/dtype 是什么;真正的权重字节流全部走 NCCL 点对点/广播通道,不经过协调器,因此控制面的 HTTP 开销与 GB 级的数据搬运完全解耦。
NCCL 广播如何与训练重叠:分桶 + 异步句柄
重叠的实现藏在 DeviceDirectBackend.update_weights_for_rollout() 的流水线细节里(device_direct.py#L636-L830):
第一步:TP 聚合 + HF 格式转换。每个参数先在张量并行(TP)组内 all_gather 拼回完整张量,再转换成 HuggingFace 格式。为避免显存峰值,转换是按桶(bucket)进行的——累计字节数超过 update_weight_buffer_size 时才触发一次广播。
第二步:分桶异步广播。拿到一个满桶后,先通过 HTTP 把桶的元数据(names/dtypes/shapes/group_name)扇出给所有 SGLang 引擎,让接收端提前分配好缓冲区;随后所有张量以 async_op=True 的 NCCL 广播并发发起,再统一 wait():
桶 N: [TP gather + HF 转换] ──→ [NCCL 广播(异步)]
桶 N+1: [TP gather + HF 转换] ──→ [NCCL 广播(异步)]
↑ 转换与上一桶的网络传输重叠
由于广播句柄是异步的,当前桶的权重正在网络中飞行时,源 rank 可以继续做下一桶的聚合与转换。同理,Colocate 模式下 Relax 还做了跨块流水线:把 ray.get 推迟到下一块准备完成后再等待,让 IPC 传输与 HF 转换真正并行,整体权重更新时间大约减半(详见 docs/en/guide/update-weights-pipeline.md)。
第三步:双路消费。同一个桶的权重有两条去向——HF 格式版本广播给 Rollout 供 SGLang 加载;原始 Megatron 格式版本走 PP 感知的独立通信组(update_actor_pp_{pp_rank})广播给 ActorFwd/Reference(device_direct.py#L559-L634)。MoE 模型的专家参数(.experts.)则额外经过专家并行(EP)组的 all_gather 再进入同一条流水线。
接收端:长轮询元数据 + 锁步广播
NCCL 集合通信要求收发两端严格"锁步"——发送端遍历张量的同时,接收端必须按相同顺序进入 dist.broadcast 的接收侧。DCS 用协调器解决时序问题:
- 发送端:每刷一个桶,向 Coordinator 的
/send_weight_meta推送该桶元数据 - 接收端(ActorFwd/Reference):在
recv_weight()中对/recv_weight_meta做长轮询(默认等待dcs_recv_weight_meta_wait_timeout_s秒),拿到元数据后立即分配同形状空张量,按序执行dist.broadcast接收(device_direct.py#L1095-L1150) - SGLang 侧:
update_weights_from_distributed接口(sglang_engine.py#L1412-L1427)进入 NCCL 接收路径,把权重直接写入模型显存
为防止多路并发广播死锁,每次桶级广播前会通过 Ray 分布式锁(self.lock.acquire.remote())串行化广播窗口;发送端与接收端在整轮结束前还会通过 GLOO 组做 dist.barrier 对齐,确保任何一边异常时集群不会被"卡死在集合通信里"。
推理引擎如何被"实时更新":暂停-刷新-恢复
对正在服务的 SGLang 引擎,DCS 采用最小停顿策略(device_direct.py#L690-L820):
- 暂停:rank 0 批量调用
/pause_generation,冻结生成(进行中的请求被安全接管) - 清缓存:
/flush_cache清空 KV Cache,避免新旧权重混用 - NCCL 广播:新权重按桶直接落入引擎显存,无需落盘
- 恢复:广播完成后调用
/continue_generation,引擎立即用新策略继续采样
整个过程推理引擎的停顿窗口只有"广播本身",而广播又与源端的转换流水线重叠——这就是"实时更新"的含义:下一批 rollout 几乎无缝切换到新策略。
关键参数速查表
| 参数 | 作用 | 建议 |
|---|---|---|
update_weight_buffer_size | NCCL 广播桶的大小上限 | 越大重叠越好,但注意源端显存峰值 |
max_staleness | Rollout 允许领先 Actor 的步数 | 生产环境推荐 1~2,平衡吞吐与 On-Policy 程度 |
ref_update_interval | Reference 模型刷新周期 | 按 KL 稳定性调整,非每步必须刷新 |
dcs_recv_weight_meta_wait_timeout_s | 接收端长轮询超时 | 网络抖动大的集群可适当调大 |
heartbeat_timeout_seconds | DCS 心跳判死阈值(默认 30s) | 配合故障恢复策略调整 |
配合 max_staleness 让 Rollout 领先训练若干步,"生产数据"与"消费数据"、"权重广播"与"训练计算"三者形成三级流水线,这正是 Fully Async 模式吞吐大幅领先的根本原因(原理详见 docs/en/guide/fully-async-training.md)。
可观测性:一眼看清每次权重同步
DCS 内置 Prometheus 兼容的指标采集(metrics.py):dcs_send_latency_seconds / dcs_recv_latency_seconds 直方图衡量每次广播延迟,dcs_bytes_sent_total 统计流量,dcs_errors_total 捕捉异常。在 GPU 利用率监控面板上,一次权重同步表现为短暂的小幅凹陷,而非同步模式下的长时间空窗:
如果广播耗时异常,可按以下顺序排查:NCCL 拓扑是否跨节点走以太网、桶大小是否过小导致广播次数过多、接收端是否因健康检查掉线而被剪枝(拓扑变化会触发通信组重建)。
小结
DCS 是 Relax 异步训练流水线的心脏:
- 控制面 / 数据面分离——HTTP 管拓扑与元数据,NCCL 管权重字节流,互不拖累
- 分桶 + 异步句柄——广播与张量转换流水线重叠,跨节点同步近乎"免费"
- PP 感知通信组 + 长轮询锁步——大模型多流水线并行下仍能精确对位收发
- 暂停-刷新-恢复——推理引擎停顿窗口被压缩到只剩网络传输本身
理解了这套机制,你就掌握了大规模异步 RL 系统中最难的一环:如何让"训练"与"推理"像两条永不停歇的流水线,在 NCCL 广播的缝隙中彼此重叠、持续加速。
📚 延伸阅读:docs/en/guide/distributed-checkpoint.md · docs/en/guide/fully-async-training.md · 源码总览 relax/distributed/checkpoint_service/
【免费下载链接】Relax
An Asynchronous Reinforcement Learning Engine for Omni-Modal Post-Training at Scale
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考







