news 2026/2/8 3:05:11

保姆级教学:在AMD集群运行verl全过程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
保姆级教学:在AMD集群运行verl全过程

保姆级教学:在AMD集群运行verl全过程

1. 为什么选择verl?它到底能做什么

你可能已经听说过强化学习(RL)在大模型后训练中的重要性——比如让Qwen、Llama这类模型更懂人类偏好、更会拒绝有害请求、更擅长数学推理。但真正动手跑一次RL训练,很多人卡在第一步:环境太复杂、框架不兼容、GPU支持不友好。

verl就是为解决这些问题而生的。它不是另一个学术玩具,而是字节跳动火山引擎团队在HybridFlow论文基础上开源的生产级RL训练框架,专为大型语言模型(LLMs)的PPO、DPO等后训练任务设计。更重要的是,它从底层就考虑了AMD GPU集群的实际部署需求。

简单说,verl帮你把三件难事变简单了:

  • 算法灵活:不用重写整个训练循环,几行配置就能切换PPO、KTO、Rejection Sampling等流程;
  • 框架友好:不强制你换掉已有的vLLM推理服务或FSDP训练栈,而是“插件式”集成;
  • AMD原生支持:不像很多RL框架只认NVIDIA CUDA,verl通过ROCm生态深度适配MI300系列GPU,通信、显存、算子全链路优化。

如果你正在AMD集群上做模型对齐、奖励建模或函数调用微调,又不想自己从零搭分布式RL流水线——verl很可能就是你现在最需要的那个“开箱即用”的答案。

2. 环境准备:AMD集群上的必要基础组件

在AMD集群上运行verl,不是简单pip install verl就能完事。它依赖一套协同工作的底层设施。我们按实际部署顺序,一项一项理清楚。

2.1 确认ROCm与驱动版本

首先确认你的节点已安装ROCm 6.2+和对应内核驱动。MI300系列GPU必须使用ROCm 6.2或更高版本,低版本会出现NCCL通信失败、HIP kernel launch timeout等典型报错。

检查命令:

rocm-smi --version hipconfig --version

预期输出应类似:

ROCm Version: 6.2.0 HIP version: 6.2.22222

注意:不要混用不同ROCm小版本(如6.2.0和6.2.1),容器内外版本需严格一致。建议统一使用官方推荐的rocm/vllm:rocm6.2_mi300_ubuntu20.04_py3.9_vllm_0.6.4基础镜像。

2.2 安装并验证Ray集群管理器

verl使用Ray作为分布式任务调度核心。Ray版本是成败关键——文档明确要求Ray ≥ 2.40,且2.20以下已被弃用。低于2.40会导致ray job submit命令不可用、Actor生命周期管理异常等问题。

安装命令(在宿主机和容器内均需执行):

pip uninstall -y ray pip install "ray[default] >= 2.40.0" --upgrade

验证是否正常:

ray start --head --dashboard-host=0.0.0.0 --port=6379 --dashboard-port=8265 ray status

你应该看到类似输出:

======== Cluster status: 2025-04-05 10:23:45 ======== Node IP address: 10.124.46.192 Ray runtime context: Dashboard URL: http://10.124.46.192:8265 Node ID: 1a2b3c4d5e6f7g8h9i0j... Is head node: True Workers: 0 Resources: {'CPU': 128.0, 'GPU': 8.0, 'memory': 512.0}

如果ray status报错“Failed to connect to GCS”,大概率是防火墙阻断了6379端口,需联系集群管理员放行。

2.3 配置InfiniBand网络与NCCL参数

AMD集群通常采用InfiniBand互联。verl在多节点训练中高度依赖NCCL进行GPU间梯度同步,因此必须正确识别网卡并设置GID索引。

运行以下命令确认IB设备:

ibstat ibdev2netdev

典型输出:

CA 'mlx5_0' status: active (4) CA 'mlx5_1' status: active (4) ...

然后在环境变量中固定指定这些设备(注意:不是rdma0/rdma1,而是mlx5_*):

export NCCL_IB_HCA=mlx5_0,mlx5_1,mlx5_2,mlx5_3,mlx5_4,mlx5_5,mlx5_8,mlx5_9 export NCCL_IB_GID_INDEX=3 export NCCL_CROSS_NIC=0 export NCCL_PROTO=Simple

小贴士:NCCL_IB_GID_INDEX=3适用于RoCEv2和IB网络混合场景;若纯IB环境,可尝试21,以iblinkinfo显示的GID列表为准。

3. 镜像构建与容器启动:一步到位的AMD适配方案

verl官方未提供预编译的AMD镜像,但提供了完整的Dockerfile.rocm。我们不建议直接在宿主机裸跑——容器化能彻底隔离ROCm、PyTorch、vLLM等组件的版本冲突。

3.1 构建verl ROCm镜像

进入verl源码根目录(假设路径为~/projects/verl_upstream),执行:

cd docker docker build -f Dockerfile.rocm -t verl.rocm .

该Dockerfile已预置:

  • PyTorch 2.3.0+rocm6.2
  • vLLM 0.6.4(MI300优化版)
  • verl主仓库代码(git clone + pip install -e .)
  • 必要的HIP、RCCL、MIOpen依赖

构建成功后,用docker images | grep verl确认镜像存在。

3.2 启动带GPU权限的容器

AMD GPU容器需挂载特殊设备与权限。以下命令启动一个交互式调试容器(用于验证):

docker run -it --rm \ --device /dev/kfd --device /dev/dri \ --group-add video \ --cap-add=SYS_PTRACE --security-opt seccomp=unconfined \ --shm-size=128g \ -v $HOME:/workspace \ -w /workspace \ -e HIP_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 \ -e ROCR_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 \ -e CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 \ verl.rocm bash

进入容器后,立即验证关键组件:

# Python内验证 import torch print(torch.__version__) # 应输出 2.3.0+rocm6.2 print(torch.cuda.is_available()) # 应为 True print(torch.cuda.device_count()) # 应为 8(MI300X) import vllm print(vllm.__version__) # 应为 0.6.4 import verl print(verl.__version__) # 应输出类似 0.1.0.dev0

全部通过,说明容器环境已就绪。

4. 多节点Ray集群搭建:SLURM脚本逐行解析

真实训练必然跨节点。我们不再手动ray start,而是用SLURM统一调度——这是HPC集群的标准做法。下面这份slurm_script.sh不是黑盒,我们拆解每一部分的真实作用。

4.1 SLURM作业头配置说明

#SBATCH --nodes=2 #SBATCH --ntasks-per-node=2 #SBATCH --gpus-per-node=8 #SBATCH --cpus-per-task=28 #SBATCH --nodelist=gpu-[0,1]
  • --nodes=2:申请2个计算节点(1个head + 1个worker)
  • --ntasks-per-node=2:每个节点启动2个独立进程(用于后续docker exec并发控制)
  • --gpus-per-node=8:MI300X单卡8 GPU,必须显式声明
  • --nodelist=gpu-[0,1]:精确指定节点名,避免SLURM随机分配到不兼容硬件

4.2 容器启动阶段的关键点

脚本中这一段常被忽略,却是AMD训练稳定的核心:

docker run --rm -d \ -e HIP_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 \ -e ROCR_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 \ -e CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 \ --device /dev/dri \ --device /dev/kfd \ --device /dev/infiniband \ --group-add video \ ...
  • /dev/dri/dev/kfd是AMD GPU访问必需设备节点;
  • --group-add video赋予容器访问GPU视频加速能力(影响vLLM推理性能);
  • 所有VISIBLE_DEVICES必须完全一致,否则vLLM会报HIP_ERROR_INVALID_VALUE

4.3 Ray集群初始化逻辑

脚本自动获取head节点IP并启动:

head_node_ip=$(srun --nodes=1 --ntasks=1 -w "$head_node" hostname --ip-address) srun --nodes=1 --ntasks=1 -w "$head_node" \ docker exec "${CONTAINER_NAME}" \ ray start --head --node-ip-address="$head_node_ip" --port=6379 \ --dashboard-port=8266 \ --num-cpus=28 --num-gpus=8 --block &

这里有两个易错细节:

  • --node-ip-address必须是节点物理IP,不能是127.0.0.1localhost
  • --num-gpus=8必须与--gpus-per-node一致,否则Ray无法正确分配GPU资源。

worker节点启动时,务必等待head完全就绪(脚本中sleep 10很关键),否则worker会因连接超时退出。

4.4 集群连通性自检

脚本末尾的Python测试段不是摆设:

import ray ray.init(address="auto") print("Number of nodes:", len(ray.nodes())) for node in ray.nodes(): print("Node:", node["NodeManagerHostname"], "Alive:", node["Alive"]) ray.shutdown()

它验证三件事:

  • 所有节点是否注册到GCS(Global Control Store);
  • 每个节点的GPU资源是否被正确识别(ray.nodes()中含"resources": {"GPU": 8.0});
  • 跨节点Actor能否通信(为后续PPO rollout打基础)。

如果这里失败,请回查NCCL_IB_HCA、防火墙、ray start日志(位于/tmp/ray/session_latest/logs/)。

5. 数据与模型准备:避开常见陷阱

verl训练前需准备好高质量的SFT+RM数据集和基础模型。AMD环境下有特殊注意事项。

5.1 数据预处理:Parquet格式是首选

verl默认读取Parquet格式数据(比JSONL快3倍以上,内存占用低50%)。使用官方提供的预处理脚本:

docker exec multinode_verl_training \ python3 examples/data_preprocess/gsm8k.py --local_dir ../data/gsm8k

该脚本会:

  • 下载GSM8K原始数据;
  • 使用datasets库切分train/test;
  • 保存为train.parquettest.parquet,字段包含promptchosenrejected等。

陷阱提醒:不要用pandas.read_json手动转Parquet!verl的DataLoader依赖Arrow schema一致性。务必用官方脚本,或确保schema完全匹配:

# 正确schema示例 schema = pa.schema([ ('prompt', pa.string()), ('chosen', pa.string()), ('rejected', pa.string()), ('reward_chosen', pa.float32()), ('reward_rejected', pa.float32()) ])

5.2 模型加载:HuggingFace模型的AMD适配要点

verl支持任意HF模型,但AMD上需注意:

  • 模型必须支持FlashAttention-2:MI300的矩阵运算加速依赖FA2,Qwen2、Llama3等新架构默认开启;
  • 禁用torch.compile:ROCm 6.2下torch.compile(mode="max-autotune")会导致kernel crash,训练脚本中应注释掉;
  • 权重精度选择:FP16在MI300上不稳定,推荐BF16(需模型本身支持)或FP32(小模型可用)。

验证模型能否加载:

docker exec multinode_verl_training \ python3 -c " from transformers import AutoModelForCausalLM model = AutoModelForCausalLM.from_pretrained( 'Qwen/Qwen2-7B-Instruct', torch_dtype='bfloat16', device_map='auto', trust_remote_code=True ) print('Model loaded successfully on AMD GPU') "

若报错HIP out of memory,说明device_map='auto'未正确识别GPU数量,需显式指定device_map={'': 0}并配合HIP_VISIBLE_DEVICES

6. 启动PPO训练:从配置到监控的完整流程

一切就绪后,最后一步是启动训练。我们以GSM8K数学推理对齐为例,详解关键参数含义。

6.1 核心训练命令拆解

docker exec multinode_verl_training \ python3 -m verl.trainer.main_ppo \ data.train_files=../data/gsm8k/train.parquet \ data.val_files=../data/gsm8k/test.parquet \ actor_rollout_ref.model.path=Qwen/Qwen2-7B-Instruct \ actor_rollout_ref.rollout.name=vllm \ actor_rollout_ref.rollout.gpu_memory_utilization=0.9 \ actor_rollout_ref.rollout.tensor_model_parallel_size=2 \ critic.model.path=Qwen/Qwen2-7B-Instruct \ trainer.nnodes=2 \ trainer.n_gpus_per_node=8 \ trainer.total_epochs=15 \ trainer.logger=['console','wandb']

参数精讲:

  • actor_rollout_ref.rollout.name=vllm:指定使用vLLM作为rollout引擎,而非HuggingFace generate——这是verl在AMD上实现高吞吐的关键;
  • tensor_model_parallel_size=2:将模型按层切分到2个GPU组(每组4卡),缓解单卡显存压力;
  • gpu_memory_utilization=0.9:vLLM显存占用率,MI300X建议0.85~0.92,过高会OOM,过低则浪费算力;
  • trainer.nnodes=2trainer.n_gpus_per_node=8:必须与SLURM申请资源严格一致,否则verl无法正确初始化FSDP。

6.2 训练过程监控与日志定位

训练启动后,实时日志输出到容器标准输出。但更关键的是结构化日志:

  • Ray Dashboard:访问http://<head_node_ip>:8266,查看Actor状态、GPU利用率、任务队列;
  • W&B仪表盘:若启用logger=['console','wandb'],所有loss、KL散度、reward分数自动同步;
  • 本地日志文件:容器内/tmp/verl_logs/目录下生成ppo_train_YYYYMMDD_HHMMSS.log,含详细step级指标。

重点关注三项指标是否收敛:

  • actor/kl_divergence:应缓慢下降至0.01~0.05区间;
  • reward/chosen_mean:随训练逐步上升,表明模型输出更符合人类偏好;
  • rollout/throughput_tokens_per_sec:MI300X双节点理想值>12000 token/s(vLLM + 8卡)。

kl_divergence持续为0,检查algorithm.kl_ctrl.kl_coef是否过小;若throughput低于5000,检查vllm是否启用PagedAttention及gpu_memory_utilization设置。

7. 常见问题排查:AMD集群专属解决方案

即使按上述步骤操作,仍可能遇到AMD特有问题。以下是高频故障与实测有效的解法。

7.1 NCCL超时与通信失败

现象:训练启动后卡在Initializing process group,日志出现NCCL_TIMEOUTConnection reset by peer

解决方案:

  • slurm_script.sh中添加:
    export NCCL_ASYNC_ERROR_HANDLING=0 export NCCL_SOCKET_TIMEOUT=1200000000 export NCCL_IB_DISABLE=0
  • 确保所有节点时间同步:sudo chronyc makestep
  • 若使用RoCE,关闭ECN:sudo rdma link set dev roce0 eth_pcp 0

7.2 vLLM推理卡死或返回空字符串

现象:rollout阶段vllm进程无响应,或生成结果全为空。

解决方案:

  • 强制指定vLLM后端:export VLLM_ATTENTION_BACKEND=FLASHINFER(MI300X推荐);
  • 降低max_num_seqs:从默认256改为128,缓解显存碎片;
  • 在启动命令中加入--enable-prefix-caching,提升长上下文推理稳定性。

7.3 FSDP训练崩溃:RuntimeError: Expected all tensors to be on the same device

现象:critic模型FSDP初始化时报错,提示GPU设备不一致。

解决方案:

  • verl/trainer/main_ppo.py中找到setup_fsdp函数,强制指定device_id
    fsdp_config = dict( sharding_strategy=ShardingStrategy.FULL_SHARD, cpu_offload=CPUOffload(offload_params=False), auto_wrap_policy=size_based_auto_wrap_policy, device_id=torch.cuda.current_device(), # ← 关键修复行 )
  • 或在启动命令中添加:actor_rollout_ref.actor.fsdp_config.device_id=0

获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/7 2:21:48

ClawdBot惊艳效果展示:Qwen3-4B生成质量对比测试与响应速度实测

ClawdBot惊艳效果展示&#xff1a;Qwen3-4B生成质量对比测试与响应速度实测 1. 什么是ClawdBot&#xff1f;一个真正属于你的本地AI助手 ClawdBot不是云端服务&#xff0c;也不是需要注册账号的SaaS工具。它是一个你可以在自己设备上完整运行的个人AI助手——从模型推理、对话…

作者头像 李华
网站建设 2026/2/5 5:38:31

人脸分析系统(Face Analysis WebUI)在考勤场景中的应用指南

人脸分析系统&#xff08;Face Analysis WebUI&#xff09;在考勤场景中的应用指南 1. 为什么考勤需要更智能的人脸分析能力 你有没有遇到过这样的情况&#xff1a;员工排队打卡&#xff0c;队伍越排越长&#xff1b;有人用照片或视频“代打卡”&#xff0c;考勤数据失真&…

作者头像 李华
网站建设 2026/2/6 3:19:55

Qwen-Image-Edit-2511实战分享:我是怎么省下3天工时的

Qwen-Image-Edit-2511实战分享&#xff1a;我是怎么省下3天工时的 上个月底&#xff0c;我们团队接到一个紧急需求&#xff1a;为即将上线的秋季新品系列&#xff0c;把全部287张产品主图统一更新—— 不是简单换背景&#xff0c;而是要&#xff1a; 把模特身上的浅灰针织衫替…

作者头像 李华
网站建设 2026/2/7 12:48:26

零基础也能用!VibeThinker-1.5B-WEBUI实战AIME难题

零基础也能用&#xff01;VibeThinker-1.5B-WEBUI实战AIME难题 你是不是也试过&#xff1a;看到一道AIME真题&#xff0c;读了三遍还是卡在第一步&#xff1f;翻遍论坛找不到完整推导过程&#xff0c;只有一行答案&#xff1b;想自己写代码解算法题&#xff0c;却总在边界条件…

作者头像 李华
网站建设 2026/2/5 4:28:02

PCAN驱动开发调试技巧超详细版分享

以下是对您提供的博文《PCAN驱动开发调试技巧超详细版技术分析》的 深度润色与结构化重构版本 。本次优化严格遵循您的全部要求: ✅ 彻底去除AI痕迹,语言自然、专业、有“人味”——像一位十年嵌入式老兵在茶水间给你讲干货; ✅ 摒弃所有模板化标题(如“引言”“总结”…

作者头像 李华
网站建设 2026/2/5 19:20:06

本地私有化部署:Live Avatar保障数据安全的用法

本地私有化部署&#xff1a;Live Avatar保障数据安全的用法 1. 为什么选择本地部署数字人——数据不出域的安全刚需 你有没有想过&#xff0c;当企业要用数字人做客服、培训或直播时&#xff0c;把员工的面部图像、声音样本、内部话术甚至客户对话记录上传到公有云&#xff0…

作者头像 李华