【训练】VLM Qwen2.GRPO训练微调 EasyR1 多机多卡训练(2)
2025-05-02
GRPO
000

在之前博客进行了简单的训练尝试:https://www.dong-blog.fun/post/2060

在本博客,将会深入进行多机多卡训练,以及调整训练奖励函数。

之前构建了镜像: docker build . -t kevinchina/deeplearning:r1

展开代码
FROM hiyouga/verl:ngc-th2.6.0-cu126-vllm0.8.4-flashinfer0.2.2-cxx11abi0 WORKDIR /workplace RUN git clone https://github.com/hiyouga/EasyR1.git WORKDIR /workplace/EasyR1 RUN pip install -e . -i https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple RUN pip install swanlab -i https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple

多机多卡的rbma通信条件在这个镜像也具备: apt-get install libibverbs1 -y

verl 依托于 Ray, 所以多机多卡使用需要使用Ray进行训练,Ray和torchrun的原理也差不多。Ray在master节点启动head,在子节点启动服务,然后由Ray统一任务调度。

所以官网教程有:

展开代码
Start the Ray head node. 启动 Ray 主节点。 ray start --head --port=6379 --dashboard-host=0.0.0.0 Start the Ray worker node and connect to the head node. 启动 Ray 工作节点并连接到头节点。 ray start --address=<head_node_ip>:6379 Check the Ray resource pool. 检查 Ray 资源池。 ray status Run training script on the Ray head node only. 运行训练脚本仅在 Ray 主节点上。 bash examples/qwen2_5_vl_7b_geo3k_grpo.sh

在一般的多机多卡调度里,有这三个环境变量:

展开代码
${MASTER_ADDR} ${MASTER_PORT} ${RANK}

这是一个用于分布式训练的Bash脚本,主要功能是配置和启动Ray集群来运行Qwen2-5-VL-7B模型的训练任务。脚本首先设置分布式训练参数(如节点数、GPU数量、主节点IP等),然后根据当前节点的RANK值区分主节点和工作节点:主节点启动Ray head服务并等待所有工作节点连接,工作节点则连接到主节点。当集群就绪后,主节点会启动训练脚本(qwen2_5_vl_7b_grpo_train.sh),同时集成了SwanLab实验跟踪工具,支持云端和本地训练日志记录。脚本最后通过sleep infinity保持Ray服务持续运行,确保分布式训练环境稳定。该脚本特别适用于多节点GPU集群上的大规模模型训练场景:

bash
展开代码
#!/bin/bash cp /config/qwen2_5_vl_7b_grpo_train.sh /workplace/EasyR1/examples/ # 参数设置(可以改成从环境变量读取) TOTAL_NODES=2 # 总节点数 GPU_PER_NODE=8 # 每台机器的 GPU 数量 #RAY_HEAD_IP="${MASTER_ADDR}" # 主节点 IP RAY_PORT="${MASTER_PORT}" # Ray 默认端口 NODE_RANK="${RANK}" # 当前节点 rank(0 是主节点) RAY_HEAD_IP=$(getent hosts "${MASTER_ADDR}" | awk '{print $1}') echo "RAY_HEAD_IP: $RAY_HEAD_IP" echo "NODE_RANK: $NODE_RANK" echo "TOTAL_NODES: $TOTAL_NODES" echo "GPU_PER_NODE: $GPU_PER_NODE" echo "RAY_PORT: $RAY_PORT" export SWANLAB_API_KEY=xxxxx # 设置在线跟踪模式API export SWANLAB_LOG_DIR=/swanlab_log # 设置本地日志存储路径 export SWANLAB_MODE=cloud # 包含四种模式:cloud云端跟踪模式(默认)、cloud-only仅云端跟踪本地不保存文件、local本地跟踪模式、disabled完全不记录用于debug # 检查是否是主节点 if [ "$NODE_RANK" -eq 0 ]; then echo "Starting Ray HEAD node on $(hostname -I | awk '{print $1}')" ray start --head --port="$RAY_PORT" --dashboard-host=0.0.0.0 --num-gpus="$GPU_PER_NODE" sleep 20 else sleep 10 echo "Starting Ray WORKER node #$NODE_RANK, connecting to $RAY_HEAD_IP:$RAY_PORT" ray start --address="$RAY_HEAD_IP:$RAY_PORT" --num-gpus="$GPU_PER_NODE" fi # 等待所有节点加入(主节点检查) if [ "$NODE_RANK" -eq 0 ]; then echo "Waiting for all nodes to join..." while true; do echo "Checking connected nodes..." LIVE_NODES=$(ray status | grep -c " 1 node_") echo "Current connected nodes: $LIVE_NODES / $TOTAL_NODES" # 打印ray status的完整输出以便调试 echo "Ray cluster status:" ray status if [ "$LIVE_NODES" -eq "$TOTAL_NODES" ]; then echo "All $TOTAL_NODES nodes connected successfully!" break fi echo "Waiting 5 seconds before next check..." sleep 5 done # 在主节点上启动训练脚本 echo "Launching training script..." echo "Setting up SwanLab environment variables..." export SWANLAB_API_KEY=pM7Xvs5OS2EeXPO5gKXfJ # 设置在线跟踪模式API export SWANLAB_LOG_DIR=/swanlab_log # 设置本地日志存储路径 export SWANLAB_MODE=cloud # 包含四种模式:cloud云端跟踪模式(默认)、cloud-only仅云端跟踪本地不保存文件、local本地跟踪模式、disabled完全不记录用于debug echo "Starting training with qwen2_5_vl_7b_grpo_train.sh..." cd /workplace/EasyR1 && bash examples/qwen2_5_vl_7b_grpo_train.sh fi # 保持 Ray 运行(防止脚本退出) sleep infinity

训练脚本/config/qwen2_5_vl_7b_grpo_train.sh:

bash
展开代码
#!/bin/bash set -x export PYTHONUNBUFFERED=1 export SWANLAB_API_KEY=xxxxx # 设置在线跟踪模式API export SWANLAB_LOG_DIR=/swanlab_log # 设置本地日志存储路径 export SWANLAB_MODE=cloud # 包含四种模式:cloud云端跟踪模式(默认)、cloud-only仅云端跟踪本地不保存文件、local本地跟踪模式、disabled完全不记录用于debug MODEL_PATH=/Qwen2.5-VL-3B-Instruct python3 -m verl.trainer.main \ config=examples/config.yaml \ data.train_files=hiyouga/geometry3k@train \ data.val_files=hiyouga/geometry3k@test \ worker.actor.model.model_path=${MODEL_PATH} \ trainer.experiment_name=qwen2_5_vl_7b_geo_grpo \ trainer.logger=['console','swanlab'] \ trainer.n_gpus_per_node=8 \ trainer.nnodes=2
如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:Dong

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC。本作品采用《知识共享署名-非商业性使用 4.0 国际许可协议》进行许可。您可以在非商业用途下自由转载和修改,但必须注明出处并提供原作者链接。 许可协议。转载请注明出处!