argus-cluster/src/mvp/v1/README.md

4.9 KiB
Raw Blame History

MVP V1Ray + VERL PPO实验脚本

本目录用于在“宿主机 + Docker 容器”环境下,**用宿主机脚本(docker exec**协调启动 Ray 集群,并通过 **ray job submit(在 head 提交)**跑通一次 verl 的 PPO 训练闭环(total_epochs=1),且数据/模型/日志/ckpt 都持久化到宿主机目录。

1. 运行环境与拓扑

1.1 依赖

  • 宿主机Linux
  • 必需工具:dockerdocker composeCompose v2 插件)、git
  • GPU至少 8 张可用 GPU索引 0-7Docker 的 NVIDIA runtime 可用

1.2 集群拓扑3 个容器)

  • mvp-ray-headRay Head
    • 不挂 GPU(容器内 nvidia-smi 不可用)
    • ray start --head --num-cpus=0 --num-gpus=0head 只做控制面,不参与计算调度
    • 暴露 dashboard宿主机端口 8265
  • mvp-ray-worker-0Ray Worker
    • 4 GPU0,1,2,3
    • ray start ... --resources='{"worker_node": 100}'
  • mvp-ray-worker-1Ray Worker
    • 4 GPU4,5,6,7
    • ray start ... --resources='{"worker_node": 100}'

关键点driver 不在 head

  • 作业通过 head 提交:ray job submit ...
  • 通过 --entrypoint-resources='{"worker_node": 1}' 强制 entrypoint/driver 只能调度到 workerhead 没有该资源)

2. 持久化目录(宿主机 <-> 容器)

在宿主机项目根目录(运行脚本时的 ${PWD})下使用 ./shared 做持久化根目录,并 bind mount 到容器内 /mnt/shared

  • 宿主机:./shared
  • 容器:/mnt/shared

主要内容:

  • 数据集:/mnt/shared/datasets/gsm8k/
  • HF 缓存:/mnt/shared/hf/(脚本会设置 HF_HOME,并尽量幂等跳过重复下载)
  • 每个 Ray Job 的输出(按 submission id 分目录):
    • /mnt/shared/jobs/<submission_id>/logs/
    • /mnt/shared/jobs/<submission_id>/checkpoints/

3. 整体流程(代码逻辑)

脚本都在 src/mvp/v1/scripts/,整体顺序如下:

  1. 00_prereq_check.sh
    • 检查 docker/docker compose/git
  2. 05_ensure_verl_repo.sh
    • 若项目根目录下没有 ./verl,自动 git clone https://github.com/volcengine/verl.git
  3. 01_up.sh
    • 创建持久化目录(./shared/...
    • docker compose up -d 启动 3 个容器
  4. 10_install_verl_editable.sh
    • 在 3 个容器内执行 pip install -e /workspace/verl(确保 python -m verl... 可用且代码与 ./verl 同步)
  5. 20_start_head.sh
    • mvp-ray-head 内启动 Ray headCPU=0、GPU=0
  6. 21_start_workers.sh
    • 在两个 worker 内启动 Ray worker 加入集群
    • 同时给 worker 打 worker_node 自定义资源标签
  7. 30_prepare_data_and_model.sh
    • 数据集:若 train.parquet/test.parquet 已存在则跳过,否则生成
    • 模型:使用 HF cacheHF_HOME=/mnt/shared/hf),存在则跳过,不存在才下载
  8. 40_submit_ppo_epoch1.sh
    • 在 head 容器里执行 ray job submit
    • 显式指定 --submission-id=$SUBMISSION_ID
    • 通过 --entrypoint-resources='{"worker_node": 1}' 强制 driver 在 worker
    • 训练参数:
      • trainer.total_epochs=1
      • trainer.total_training_steps=29GSM8K 该配置下对应 29 steps
      • trainer.save_freq=10(每 10 step 保存一次 checkpoint避免磁盘爆炸
      • trainer.default_local_dir=/mnt/shared/jobs/$SUBMISSION_ID/checkpoints
      • hydra.run.dir=/mnt/shared/jobs/$SUBMISSION_ID/logs/hydra
  9. 50_status.sh
    • 打印 ray status / ray job list / ray job status / ray job logs | tail

4. 运行方法

4.1 一键执行

在项目根目录执行:

  • ./src/mvp/v1/scripts/run_all.sh

4.2 分步执行(推荐)

按顺序执行:

  • ./src/mvp/v1/scripts/01_up.sh
  • ./src/mvp/v1/scripts/10_install_verl_editable.sh
  • ./src/mvp/v1/scripts/20_start_head.sh
  • ./src/mvp/v1/scripts/21_start_workers.sh
  • ./src/mvp/v1/scripts/30_prepare_data_and_model.sh
  • SUBMISSION_ID=ppo_h20_8g_$(date +%Y%m%d_%H%M%S) ./src/mvp/v1/scripts/40_submit_ppo_epoch1.sh
  • ./src/mvp/v1/scripts/50_status.sh

4.3 查看与停止

  • Dashboardhttp://<宿主机IP>:8265
  • 列出作业(在 head 容器内):
    • docker exec mvp-ray-head bash -lc "ray job list --address=http://127.0.0.1:8265"
  • 停止某个 submission id
    • docker exec mvp-ray-head bash -lc "ray job stop --address=http://127.0.0.1:8265 <submission_id>"

4.4 清理

  • 停止并删除容器:./src/mvp/v1/scripts/02_down.sh
  • 清理输出(谨慎,数据量可能很大):删除 ./shared/jobs/<submission_id>/

5. 常见坑

  • 不传 --submission-id 会导致“输出目录难以等于 submission id”:因为 hydra/ckpt 目录需要在提交前确定。当前脚本会显式传 --submission-id=$SUBMISSION_ID,并使用同名目录。
  • checkpoint 太大PPO 的 checkpoint 非常占空间。当前脚本默认 save_freq=10,如仍过大,可调大 save_freq 或减少保存内容/频率。

更多分步操作与验收标准见:specs/mvp/v1_action.md