
在《使用 AMD Instinct™ MI355X 上的 verl 扩展 RL》一文中,我们介绍了 AMD Instinct™ MI355X GPU 上 verl 的全异步策略训练器。那篇文章使用的是 ROCm™ 7.0.2 上的 verl 0.7.1.amd0,采用 4+4 GPU 拆分,在 Qwen2.5-VL-7B(Megatron)上运行 GRPO,在 Qwen2.5-Math-7B(FSDP2)上运行 DAPO,并与 NVIDIA B300 进行了单独的同步吞吐量对比。
这篇后续文章介绍的是接下来的技术栈。AMD 已在 ROCm™ 10.0 上启用 verl 0.9.0,发布为 AMD-Ecosystem/verl 的 release/0.9.0.amd0 分支。相同的异步配方仍然可以运行,但运行时现在是一流的 ROCm™ 平台:原生 PlatformROCm 检测、专用的 Dockerfile.rocm(在同一镜像中提供 vLLM 0.27.0 和 SGLang)、Megatron-Core 0.18,以及 0.7.1 之后落地的上游 0.9.0 训练器/rollout 功能。
如果你已经按照 MI355X 演练操作过,可以继续使用 GRPO 和 DAPO 脚本。变化的是容器、主机 ROCm™ 驱动,以及一组 AMD 特定的启动修复,这些修复使 0.9.0 在 AMD Instinct™ GPU 上达到生产就绪状态。
| 项目 | 上一篇博客(2026 年 8 月) | 本次发布 | | --- | --- | --- | | verl | 0.7.1.amd0 | 0.9.0.amd0(release/0.9.0.amd0) | | ROCm™ | 7.0.2 | 10.0.0 | | Docker(容器化平台) | rocm/verl:verl-0.7.1.amd0_rocm7.0.2_ubuntu22.04_py3.12_vllm0.20.2 | 基于 rocm/primus:v26.7 从 docker/rocm/Dockerfile.rocm 构建 | | 硬件 | 在 8× MI355X(gfx950)上验证 | 面向 MI300 系列(gfx942)和 MI350 系列(gfx950) | | PyTorch | PyTorch 2.9.1、Megatron-Core 0.16.0 | Primus v26.7 训练栈,包含 PyTorch 2.12.0 + Megatron-Core 0.18.0 | | Rollout | vLLM 0.20.2 | 同一镜像中提供 vLLM 0.27.0 和源码构建的 SGLang | | 编排 | 0.7.1 镜像中的 Ray | Ray 2.58.0,接入 amdsmi 使 Ray 能识别 AMD Instinct™ GPU | | 训练器 | 实验性全异步策略 | 上游 V1 训练器为默认,外加相同的全异步 GRPO/DAPO 脚本 | | 平台层 | 围绕 CUDA(NVIDIA 并行计算平台和编程模型) 风格 API(应用程序编程接口) 的 ROCm™ 补丁 | 一流的 PlatformROCm 后端 |
上一篇博客解释了何时使用同步与异步,以及如何运行那两个 MI355X 示例。本文是启用说明:0.9.0.amd0 如何为 ROCm™ 10.0 构建、上游 0.9.0 为 AMD GPU 带来了什么,以及如何启动容器。
上游 verl v0.9.0(2026 年 8 月 14 日)是一次大规模更新:统一的 V1 训练器、以 Megatron-Bridge 作为默认 Megatron 路径、仅支持 vLLM ≥ 0.18、增量分片权重同步,以及硬件插件层。AMD 分支承接了这次更新,使其能在 ROCm™ 10.0 上运行,而不是让团队停留在上一篇博客中的 0.7.1 / ROCm™ 7.0.2 镜像上。
对 ROCm™ 用户来说,最重要的有三个主题。
0.9.0 引入了 verl.plugin.platform:设备 API、Ray 资源环境变量以及 rollout 引擎默认值都通过注册表管理,而不再是分散的 torch.cuda 调用。在 AMD 上,该后端为 PlatformROCm。
它继承自 CUDA 平台(ROCm™ 上的 PyTorch 仍通过 hipify 暴露 torch.cuda),仅覆盖有差异的部分:
可用性检查 torch.version.hip,并可在纯 CPU 的 Ray actor 中回退到 rocm-smi。
Rollout worker 可设置 SGLANG_USE_AITER,使 SGLang 的非注意力内核(RMSNorm、RoPE、MoE、量化)走 AITER。PlatformROCm 仍默认开启该标志;Dockerfile.rocm 将其覆盖为 SGLANG_USE_AITER=0,并使用打过补丁的非 AITER fused_add_rms_norm 路径,该路径在此 Primus 栈上稳定。注意力仍走 Triton(SGLANG_ATTENTION_BACKEND=triton)。若想改用 AITER 内核,可在运行时设置 SGLANG_USE_AITER=1。
告知 Ray 不要覆盖 HIP_VISIBLE_DEVICES 或 ROCR_VISIBLE_DEVICES——这与我们最初为 AMD Instinct™ 在 Ray 中修复的问题属于同一类,现在在平台层表达,而非作为一次性补丁。
你可以通过 VERL_PLATFORM=amd 强制指定后端,但自动检测才是预期路径。
SGLang 在 AMD 快速入门矩阵中不再处于“进行中”状态,也不再是单独安装。上游 0.9.0 通过平台默认值和 Ray 初始化环境变量落地了 ROCm™ SGLang 支持。Dockerfile.rocm 现在在 vLLM 旁边从源码构建 SGLang,因此共置和完全异步运行可通过 actor_rollout_ref.rollout.name=vllm 或 sglang 选择引擎。
来自上游 0.9.0,现已进入 AMD 分支:
V1 PPO 训练器为默认。sync、colocate_async 和 separate_async 共享同一控制流、回放缓冲区和指标面。上一篇博客中的实验性 Fully Async Policy 脚本仍位于 verl/experimental/fully_async_policy/ 下。
Megatron-Bridge 是 Megatron 默认(上游已弃用 vanilla mBridge)。AMD geo3k Megatron 配方仍有少量 ROCm™ 侧调整(vanilla mBridge、关闭动态批大小、微批提升至 2),以便 MI355X 4+4 演练继续运行。
低于 0.18 的 vLLM 被移除。ROCm™ 10.0 镜像构建 vLLM 0.27.0,已超过该截止版本,并包含混合 RL 所需的 sleep/wake 和 MoE 修复。同一 Dockerfile 还构建 SGLang(固定提交、ROCm™ sgl-kernel、--no-deps,因此不会替换 Primus PyTorch 或 vLLM)。
delta_sharded 检查点引擎将每个 actor 分片与固定的 CPU 快照进行差异比较,仅将变更对发送到 rollout。这是在分离式异步训练中实现更廉价权重同步的路径。
AMD 上的 DeepSeek-V4-Flash GRPO。上游在 ROCm™ 上启用了该功能,并为 DSA 提供了纯 PyTorch 的 fast_hadamard_transform 回退,因此内核路径不依赖仅 CUDA 的库。
MI300 端到端 PPO CI 已进入代码树,因此 AMD 平台由 AMD Instinct™ 回归工作流覆盖,而非“在我们集群上可用”。
之前的镜像是完整的 rocm/verl:…0.7.1… 标签。0.9.0.amd0 新增了 docker/rocm/Dockerfile.rocm,它基于 rocm/primus:v26.7(训练栈:PyTorch、TransformerEngine、AITER)构建,并叠加 Primus 未提供的 RL 组件。
该 Dockerfile 在做真正的启用工作,而不仅仅是 pip install verl:
| 关注点 | 10.0 配方做了什么 | | --- | --- | | Ray 看到 0 个 GPU | Primus 的 TheRock SDK 提供 amd_smi,但不提供 amdsmi Python 包。即使 torch 和 rocm-smi 正常,Ray 的 AMD 加速器管理器也会报告 0 个 GPU。镜像从捆绑的 SDK 安装 amdsmi,并将 rocm_sdk 库预加载从 RTLD_GLOBAL 切换为 RTLD_LOCAL,使 torch.cuda.device_count() 不会坍缩为 0。 | | 无 rollout 引擎 | Primus 仅用于训练。镜像在同一镜像中从源码构建 vLLM 0.27.0(VLLM_TARGET_DEVICE=rocm)和 SGLang。verl 在运行时选择引擎(rollout.name=vllm 或 sglang)。 | | ROCm™ 上的 SGLang | 固定一个在 Primus + vLLM ROCm™ 上验证过的 SGLang 提交,应用 ROCm™ layernorm / Qwen3-ASR 注册补丁,为 gfx942 和 gfx950 构建 sgl-kernel,并设置镜像默认值 SGLANG_USE_AITER=0 和 SGLANG_ATTENTION_BACKEND=triton。训练器 rollout.yaml 为 vLLM 和 SGLang 都设置 disable_custom_all_reduce: True,并为 SGLang 设置 attention_backend: triton。 | | AMD Instinct™ 内核 | PYTORCH_ROCM_ARCH / AMDGPU_TARGETS 为 gfx942;gfx950。vLLM AITER 标志(VLLM_ROCM_USE_AITER、FP8 padding)为镜像默认值。 | | Qwen3.5 / GDN | 安装 flash-linear-attention、megatron-core 0.18.0、mbridge、transformers ≥ 5.12,以及 libz3.so.4.15 符号链接,以便 tilelang/TVM 可以 dlopen(Gated Delta Net 所需)。 | | 检查点引擎 | 安装 cupy-rocm-7-0,以便 NCCL/RCCL 检查点后端注册。 | | 可复现的 verl | 在 release/0.9.0.amd0 克隆 https://github.com/AMD-Ecosystem/verl.git。 | | Ray | 固定 ray[default,serve]==2.58.0。 |
RCCL 相关环境默认值已在镜像中设置(NCCL_MIN_NCHANNELS=112、HSA_NO_SCRATCH_RECLAIM=1、HIP_FORCE_DEV_KERNARG=1),可在多节点场景中覆盖。
0.9.0.amd0 / ROCm™ 10.0 的启动矩阵:
| 组件 | 版本 / PIN | | --- | --- | | 主机驱动 | ROCm™ 10.0.0 | | 基础镜像 | rocm/primus:v26.7 | | verl | AMD-Ecosystem release/0.9.0.amd0 | | Python | 3.12 | | GPU 架构 | gfx942 (MI300X / MI300A / MI325X), gfx950 (MI350X / MI355X) | | vLLM | 0.27.0 (源码) | | SGLang | 从源码构建(在 Dockerfile.rocm 中固定提交;与 vLLM 共存) | | Ray | 2.58.0 | | Megatron-Core | 0.18.0 | | CuPy | cupy-rocm-7-0 | | Rollout 环境 | vLLM: VLLM_ROCM_USE_AITER=1, VLLM_USE_V1=1(在示例脚本中)。SGLang: SGLANG_USE_AITER=0, SGLANG_ATTENTION_BACKEND=triton(镜像默认值) |
此分支上的功能支持:
| 类别 | 状态 | | --- | --- | | 运行时模式 | 完全异步,colocate(V1 sync / colocate_async / separate_async) | | 推理引擎 | vLLM 和 SGLang(两者均安装在 Dockerfile.rocm 中) | | 训练器后端 | FSDP, FSDP2, Megatron | | 硬件 | MI300 系列(gfx942),MI350 系列(gfx950) |
已安装 ROCm™ 10.0 主机驱动栈且运行正常。
Docker 可以访问 /dev/kfd 和 /dev/dri。
数据集和模型存储路径已就绪(如果要下载模型,需要 Hugging Face token)。
克隆 AMD 发布分支并构建。需要 BuildKit。
git clone --recursive -b release/0.9.0.amd0 https://github.com/AMD-Ecosystem/verl.git cd verl DOCKER_BUILDKIT = 1 docker build \ -f docker/rocm/Dockerfile.rocm \ --build-arg GPU_ARCH = "gfx942;gfx950" \ --build-arg VLLM_TAG = v0.27.0 \ --build-arg VERL_BRANCH = release/0.9.0.amd0 \ -t verl-rocm:0.9.0.amd0-rocm \ .
同一个 Dockerfile 会在 vLLM 之后克隆并安装 SGLang(固定 SGLANG_TAG;如果要重新验证更新的提交,可用 --build-arg SGLANG_TAG=… 覆盖)。为了在单一架构上缩短编译时间,可设置 --build-arg GPU_ARCH=gfx950 (MI355X) 或 gfx942 (MI300X)。如果 vLLM 或 sgl-kernel 构建受内存限制,可降低 --build-arg MAX_JOBS=64。
启动(与上一篇博客相同的 device、shm 和 ulimit 模式):
NAME = verl_0_9_0_amd0 DOCKER = verl-rocm:0.9.0.amd0-rocm docker run -it --name $NAME \ --device /dev/kfd --device /dev/dri \ --privileged --network = host \ --group-add video --cap-add = SYS_PTRACE --security-opt seccomp = unconfined \ --shm-size = 2048g \ --ulimit memlock = -1 --ulimit stack = 67108864 \ -w /workspace \ $DOCKER \ /bin/bash
在容器内:
python - <=1.14.0' export HF_TOKEN = your_token cd /workspace/verl bash verl/experimental/fully_async_policy/shell/data_model_preparation/prepare_dapo_7b_math_fsdp2_4_4.sh mkdir -p /workspace/logs bash verl/experimental/fully_async_policy/shell/dapo_7b_math_fsdp2_4_4.sh \ 2 > & 1 | tee /workspace/logs/dapo_ $( date +%Y%m%d_%H%M%S ) .log
Qwen2.5-Math-7B 在下载后仍然需要在 config.json 中将 max_position_embeddings 提高到 32768;准备脚本会完成这一操作。
正常启动看起来与之前相同:rollout HTTP 服务器捕获 HIP 图,然后 FullyAsyncTrainer 开始从队列中收集样本。运行期间执行 rocm-smi 快照应显示训练 GPU 受计算限制,而 rollout GPU 占用 KV-cache 显存。
关于算法参数(clip-higher、无 KL 的 DAPO、超长缓冲区、GRPO 组大小),请参阅之前的博客。它们并未为 10.0 重新设计;它们在新镜像上运行。
除了两个异步演示之外,0.9.0.amd0 还记录了以下共置 / 完全异步矩阵(vLLM 或 SGLang):
| 运行时 | 引擎 | 训练器 | 示例 | | --- | --- | --- | --- | | 共置 | vLLM | FSDP | examples/grpo_trainer/run_qwen3_8b_fsdp.sh | | 共置 | vLLM | Megatron | examples/grpo_trainer/run_qwen3_5_35b_megatron.sh | | 完全异步 | vLLM | FSDP2 | verl/experimental/fully_async_policy/shell/dapo_7b_math_fsdp2_4_4.sh | | 完全异步 | vLLM | Megatron | verl/experimental/fully_async_policy/shell/geo3k_qwen25vl_7b_megatron_4_4.sh |
SGLang 已包含在 10.0 镜像中。使用相同的脚本,只需将 rollout 名称从 vLLM 切换为 SGLang(在启动脚本中设置 actor_rollout_ref.rollout.name=sglang 或 rollout_name="sglang")。在 ROCm™ 上保持 attention_backend=triton —— 镜像环境和训练器 rollout.yaml 已设置该项。
Qwen3.5-35B Megatron GRPO 示例是 0.9 时代的工作负载,10.0 Dockerfile 明确为其做了预置(GDN / flash-linear-attention / transformers 5.x)。将其视为“新模型”路径;VL-7B 和 Math-7B 脚本仍是上一篇文章中的回归路径。
对于 Qwen2.5-Math-7B,下载后 max_position_embeddings 必须为 32768。
使用 PYTORCH_ALLOC_CONF=expandable_segments:True 来降低 OOM 风险,但它可能与 vLLM 自定义 all-reduce 冲突。默认配置设置 vllm.disable_custom_all_reduce=True,直到该 ROCm™ 冲突消除。
SGLang 的 attention_backend 必须为 triton。
一些 vLLM/SGLang 的 ROCm™ 修复仍应用在 Dockerfile 中,而不仅仅在已发布的 wheel 中。10.0 配方将 vLLM 固定为 v0.27.0 而非 main,因为更新的代码树需要 torch::stable::Tensor API。SGLang 固定为在此 Primus + vLLM ROCm™ 栈上验证过的提交(并在源码树中为 fused_add_rms_norm 和幂等 Qwen3-ASR 配置注册打了补丁)。如果你升级 PRIMUS_TAG 或 VLLM_TAG,请重新验证 SGLANG_TAG。
verl 0.9.0.amd0 通过 Dockerfile.rocm 和 release/0.9.0.amd0 分支在 ROCm™ 10.0 上启用。该镜像现在同时包含 vLLM 0.27.0 和 SGLang。
MI355X 完全异步 GRPO 和 DAPO 演练是兼容性目标:相同的 4+4 拆分、相同的 staleness / sync / partial-rollout 参数、新的容器和驱动。
PlatformROCm 使 HIP 可见性、Ray GPU 发现以及 SGLang/vLLM 的 ROCm™ 默认值成为 verl 的一部分,而非树外补丁。10.0 镜像随后将 SGLang 固定为 Triton attention 和打过补丁的非 AITER RMSNorm 路径。
上游 0.9.0 已进入 AMD 代码树:V1 训练器默认、Megatron-Bridge、vLLM 0.27、delta-sharded 权重同步、AMD 上的 DeepSeek-V4-Flash GRPO、MI300 PPO CI。
在基于 TheRock 的 Primus 镜像上 Ray 报告零 GPU 是此 Dockerfile 中已解决的启动缺陷(amdsmi + RTLD_LOCAL)。在调试 verl 资源池之前,请检查 torch.cuda.device_count()。
在本博客中,你探索了 verl 0.9.0.amd0 如何在 ROCm™ 10.0 和 AMD Instinct™ GPU 上运行。你了解了自 0.7.1.amd0 / ROCm™ 7.0.2 栈以来的变化,以及新的 PlatformROCm 后端如何使 ROCm™ 成为 verl 的一等平台,而非一组 CUDA 形式的变通方案。你构建了一个单一的 Dockerfile.rocm 镜像,同时提供 vLLM 0.27.0 和 SGLang,确认了 Ray、PyTorch 和两个 rollout 引擎都能看到你的 GPU,并在新栈上重新运行了完全异步 GRPO(Qwen2.5-VL-7B、Megatron)和 DAPO(Qwen2.5-Math-7B、FSDP2)演练。
在《在 AMD Instinct™ MI355X 上使用 verl 扩展 RL》中,我们展示了在 AMD Instinct™ GPU 上进行完全异步 RL 是可行的:分离的 rollout 和训练集群、RCCL 权重同步,以及在 GRPO 和 DAPO 上较高的训练器利用率。本文延续了这项工作。你可以保留相同的 4+4 脚本和异步参数,并获得上游 0.9.0 特性:V1 训练器、Megatron-Bridge、delta-sharded 权重同步,以及 Qwen3.5 GDN 和 DeepSeek-V4-Flash 等新模型路径。你还避免了以前在新镜像上耗费时间的启动问题,例如 Ray 报告零 GPU 或缺少 rollout 引擎。从 docker/rocm/Dockerfile.rocm 构建,将其指向 release/0.9.0.amd0,你就拥有了在 MI300 和 MI350 系列 GPU 上进行 RL 后训练的可复现起点。
这不是终点。我们的团队计划继续优化和扩展 ROCm™ 支持。未来文章的重点是随着 Verl 中新功能的探索和现有功能的优化,继续提供性能洞察和操作指南。请关注 ROCm™ 博客并留意 AMD-Ecosystem/verl 仓库的新版本发布,同时您可以在自己的 AMD Instinct™ GPU 上尝试这些配方。
感谢 AMD ROCm™、verl 和 Primus 的工程师们实现了 PlatformROCm、ROCm™ Dockerfiles、vLLM/SGLang AITER 集成和 AMD Instinct™ CI,也感谢 verl 社区发布了本 AMD 分支所基于的 0.9.0 版本。
第三方内容由拥有该内容的第三方直接向您授权,AMD 未向您授予许可。所有链接的第三方内容均按“原样”提供,不附带任何形式的保证。使用此类第三方内容完全由您自行决定,AMD 在任何情况下均不对任何第三方内容向您承担责任。您承担所有风险,并对因使用第三方内容而可能产生的任何损害承担全部责任。
本文所含信息按“原样”提供,仅供参考,如有更改,恕不另行通知。尽管在编写本文档时已采取一切预防措施,但其中仍可能包含技术不准确、遗漏和排版错误,AMD 没有义务更新或以其他方式更正此信息。Advanced Micro Devices, Inc. 对本文档内容的准确性或完整性不作任何陈述或保证,并且对本文所述 AMD 硬件、软件或其他产品的操作或使用不承担任何形式的责任,包括对不侵权、适销性或特定用途适用性的默示保证。本文档不授予任何知识产权许可,包括默示许可或因禁止反言而产生的许可。适用于 AMD 产品购买或使用的条款和限制以双方签署的协议或 AMD 的标准销售条款和条件为准。GD-18u。
©2026 Advanced Micro Devices, Inc. 保留所有权利。AMD、AMD Arrow 标志、AMD Instinct™、ROCm™ 及其组合是 Advanced Micro Devices, Inc. 的商标。本出版物中使用的其他产品名称仅用于识别目的,可能是其各自所有者的商标。某些 AMD 技术可能需要第三方启用或激活。支持的功能可能因操作系统而异。有关具体功能,请与系统制造商确认。没有任何技术或产品可以完全安全。
转载声明:本文为转载整理,原文版权归原作者及原站点所有。
原文来源:AMD ROCm Blog
原创地址:https://rocm.blogs.amd.com/artificial-intelligence/verl_0.9.0_rocm7.15/README.html
原文作者:Tiffany Mintz, Yao Liu, Phani Vaddadi, Vish Vadlam;如有侵权,请联系管理员删除。