Miles Sleep/Wake显存共享机制:训练Actor与Rollout引擎如何共用一块GPU
【免费下载链接】milesMiles is an enterprise-facing reinforcement learning framework for LLM and VLM post-training, forked from and co-evolving with slime.项目地址: https://gitcode.com/GitHub_Trending/miles1/miles
Miles 是一个面向企业的大模型强化学习(RL)后训练框架。它的Sleep/Wake 显存共享机制让训练 Actor 与 Rollout 推理引擎轮流使用同一块 GPU:推理生成时,Actor 把权重和状态"睡"到主机内存或本地磁盘;训练前再"唤醒"回显卡。本文用通俗的方式讲清这套机制的原理、流程与实测收益,帮助新手理解 Miles 如何在有限硬件上跑通大模型 RL 训练。
为什么 RL 训练要"两块模型抢一块 GPU" 🤔
强化学习后训练(如 GRPO)有一个绕不开的特点:训练循环里有两个截然不同的角色。
- Rollout 推理引擎:用当前模型权重生成大量样本(回答、代码、推理轨迹),这是计算密集、显存密集的阶段;
- 训练 Actor:拿到奖励信号后计算 log-prob、梯度,并执行优化器更新,这才是"学习"本身。
如果两者各占一块 GPU,集群成本翻倍。Miles 选择了Colocate(同卡部署)模式:把推理引擎和训练 Actor 放在同一批 GPU 上,靠显存的时间片复用来省钱。开启--colocate后,Miles 会自动打开--offload-train——Actor 只在train()阶段驻留显卡,整个 Rollout 窗口期间它都必须"让位"(见 docs/advanced/disk-offload.md)。
Sleep/Wake 的两步流程:如何把模型"请出去"再"请回来"
整个机制只有两个动作,Megatron 后端实现在 miles/backends/megatron_utils/actor.py 的sleep()与wake_up()中:
sleep():把权重、梯度、优化器状态一次性搬走
Rollout 开始前,Actor 调用sleep(),它会做三件事:
- 清空显存碎片,释放量化工作区(如 Transformer Engine 的 FP8 workspace);
- 销毁进程组——NCCL 通信缓冲也一并释放,把显存彻底交还给推理引擎;
- 暂停显存区域:借助底层内存保存器
torch_memory_saver挂钩 CUDA 分配器,把权重、梯度缓冲、优化器状态作为一个整体块搬到备份位置,不关心里面装的是什么。
一个值得注意的细节:sleep()是幂等的,重复调用会直接跳过,这在容错重试场景下非常省心。
wake_up():训练前原地"唤醒"
下一轮train()入口处,若检测到 Actor 仍处于休眠状态,就会先调用wake_up()(见 miles/backends/megatron_utils/actor.py):按 tag 恢复显存区域、重建进程组。由于暂停/恢复都发生在阶段边界,等优化器真正执行一步更新时,所有数据都已回到 HBM,训练过程零等待。
FSDP 后端(miles/backends/fsdp_utils/actor.py)逻辑类似,只是更直白:sleep()把模型和优化器整体.cpu(),wake_up()再.cuda()回来,并用dist.barrier保证所有 rank 同步。
搬去哪里?主机内存还是本地磁盘 💾
--offload-train-target决定备份落点,这是新手最关心的参数:
| 场景 | 参数 | 说明 |
|---|---|---|
| 休眠 Actor 放得进主机内存(默认) | --offload-train-target=cpu | 备份到 pinned host 内存,最快、无需额外空间 |
| 模型太大,主机内存不够 | --offload-train-target=disk | 通过固定大小的 pinned 暂存区流式写入节点本地 NVMe上的 per-rank 文件,主机内存占用被--offload-train-disk-chunk-mb钳制住 |
磁盘模式下有几个实用要点:
- 目录指向真正的节点本地 NVMe(默认
$SCRATCH/miles_train_offload_<uid>),不要用 tmpfs 挂载的/tmp,那会把数据又留在内存里,违背初衷; - 文件每步原地覆盖,Actor 退出时自动清理;
- 它和
--stream-optimizer-state-to-disk(把 fp32 主参数和 Adam 动量按桶流式读改写盘)可以叠加使用:前者管"整个 Rollout 窗口",后者管"训练那一步之内",两者互补。
实测收益:sleep/wake 从 24 秒缩短到 5 秒 ⚡
官方文档给出了真实数据:在 Qwen3-30B-A3B 上,单独开启 Actor offload 时 sleep/wake 分别耗时24s / 8.9s;叠加优化器状态流式后,休眠的 Actor 不再携带 12 字节/参数的 fp32 状态,sleep/wake 直接降到5.2s / 1.3s。对多机集群来说,这部分"空转时间"的省出相当可观。
训练效果层面,Miles 在 DeepSeek-V4.1 等大模型上的 RL 训练奖励曲线稳定爬升,验证了显存轮换机制对训练正确性零干扰:
关键参数与延伸阅读 📚
| 参数 | 作用 |
|---|---|
--colocate | 推理引擎与 Actor 同卡部署,自动启用--offload-train |
--offload-train | Rollout 窗口期间把 Actor 请出 HBM(colocate 下默认开启) |
--offload-train-target=cpu / disk | 选择备份落点:主机内存或本地 NVMe |
--offload-train-disk-dir/--offload-train-disk-chunk-mb | 磁盘目录与 pinned 暂存区大小 |
--stream-optimizer-state-to-disk | 优化器状态按桶流式读写盘,解决"训练那一步"也放不下 |
延伸阅读:
- 磁盘卸载完整机制:docs/advanced/disk-offload.md
- 参数定义与 colocate 默认值逻辑:miles/utils/arguments.py
- 训练后端架构说明:docs/user-guide/training-backend.md
总结
Miles 的 Sleep/Wake 机制本质是一次以阶段边界为节拍的显存时间片调度:sleep()用内存保存器把 Actor 整体请出 HBM、连 NCCL 缓冲一起清空,让推理引擎独占显卡;wake_up()在训练前原地恢复,一步不慢。备份可以选主机内存(快)或本地 NVMe(省内存),再叠加优化器状态流式进一步压缩切换时间。对新手而言,记住一句话即可——在 Miles 里,GPU 从不闲置:推理时 Actor 在睡觉,训练时引擎在让位。
【免费下载链接】milesMiles is an enterprise-facing reinforcement learning framework for LLM and VLM post-training, forked from and co-evolving with slime.项目地址: https://gitcode.com/GitHub_Trending/miles1/miles
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考