# MVP 计划(V1) 本文档目标:把当前“口述/实验记录”整理成**可复现、可验收**的 MVP 计划,并明确下一步最小闭环。 ## 1. 背景与目标 我们要验证的最小闭环是: 1) 在“Head(CPU 容器)+ Worker(GPU 容器)”的 Ray Cluster 上,能够跑通一次 `verl` 的 PPO 训练。 2) 训练所需的 **数据集 / 模型缓存 / 训练产物(checkpoint)/ 日志** 不落在容器临时文件系统里,而是落在**共享存储(NFS)**,容器重启后可继续使用。 3) 所有步骤能写成一套**清晰命令/脚本**,新人可照着复现。 ## 2. 环境与假设 - 机器:H20 机器(具体规格由算力平台提供) - 访问方式:通过 `ssh h1a` 远程登录(进入算力平台/宿主访问入口) - 容器:算力平台可申请 CPU 容器(对外暴露端口)与若干 GPU 容器(可 SSH 互通) - 共享存储:所有容器可挂载同一套 NFS(在 `specs/hl_design_v2.md` 中假设为 `/mnt/shared`) ## 3. 已验证现状(现有实验) 目录 `ray_in_docker/` 已经做过一次可运行的实验(偏“本地/示例级别”): - 用 `docker-compose` 起了 2 个 `verl` 镜像容器: - `verl-head`:作为 Ray Head(Dashboard 端口 `8265`) - `verl-worker`:作为 Ray Worker - 在容器中执行: - 下载 GSM8K 数据集(`examples/data_preprocess/gsm8k.py`) - 拉取 HuggingFace 模型(示例:`Qwen/Qwen2.5-0.5B-Instruct`) - `ray start --head` + `ray start --address=...` - 通过 `ray job submit ... python -m verl.trainer.main_ppo ...` 提交 PPO 训练任务(见 `ray_in_docker/ray_example/ppo_train.sh`) 结论:**训练脚本可以跑通**。 ## 4. 当前主要问题(从实验到平台化 MVP 的差距) 1) **数据 / 模型 / 输出落在容器内**:容器重启/替换后不可复用;也不利于多人共享与审计。 2) **缓存路径不规范**:HuggingFace cache、Ray 临时目录、Hydra 输出目录等可能分散在容器默认路径。 3) **可复现不足**:缺少明确的目录规范、统一的启动/提交流程、验收口径。 4) Ray 节点**打标签/亲和性调度**的方法未固化:需要明确是否统一用 `ray start --resources`,以及命名规范如何设计。 ## 5. MVP V1:最小闭环定义 以 `specs/hl_design_v2.md` 的方向为准,但 V1 **只做最小可运行原型**,暂不做完整 Web/调度系统。 ### 5.1 目录规范(统一落到 NFS) 约定所有容器统一挂载 NFS 到 `/mnt/shared`,并在其中固定目录结构: - `/mnt/shared/code/`:代码(可选:按版本/分支隔离) - `/mnt/shared/datasets/`:数据集(如 `gsm8k/`) - `/mnt/shared/hf/`:HuggingFace 缓存(设置 `HF_HOME=/mnt/shared/hf`) - `/mnt/shared/ray/`:Ray 运行期临时目录(可选:设置 `RAY_TMPDIR=/mnt/shared/ray/tmp`) - `/mnt/shared/outputs/`:训练输出根目录(Hydra/日志/ckpt 统一落这里) - `/mnt/shared/outputs/logs//` - `/mnt/shared/outputs/checkpoints//` ### 5.2 最小集群形态 - 1 个 Head(CPU 容器) - 跑 `ray start --head --dashboard-host=0.0.0.0` - 暴露 `8265` 给 Desktop/用户查看 Job 状态 - 1~2 个 Worker(GPU 容器) - 跑 `ray start --address=:6379` 加入集群 - (可选)通过 `--resources='{\"gpu_pool_a\": 1}'` 给节点打标签 ### 5.3 最小训练任务 - 目标任务:跑通一次 `verl.trainer.main_ppo`(以 GSM8K 为例) - 要求: - `data.train_files` / `data.val_files` 指向 `/mnt/shared/datasets/...` - HuggingFace 模型下载缓存落到 `/mnt/shared/hf` - 训练输出(Hydra outputs、checkpoint、stdout/stderr)落到 `/mnt/shared/outputs/...` 建议在提交命令里显式覆盖 Hydra 输出目录(示例,具体目录名按需调整): - `hydra.run.dir=/mnt/shared/outputs/logs/${JOB_TAG}` ## 6. 实施步骤(Checklist) ### 6.1 一次性准备 - [ ] 确认所有容器已挂载 NFS 到同一路径:`/mnt/shared` - [ ] 在 `/mnt/shared/` 下创建目录:`datasets/ hf/ outputs/ ray/` - [ ] 在所有容器中设置/注入环境变量(推荐写入统一脚本): - `HF_HOME=/mnt/shared/hf` - `HF_ENDPOINT=https://hf-mirror.com`(如需) - `RAY_TMPDIR=/mnt/shared/ray/tmp`(可选) ### 6.2 启动集群(Head + Worker) - [ ] 在 Head 容器启动 Ray Head(并记录 `head_ip:6379`) - [ ] 在每个 Worker 容器执行 `ray start --address=...` 加入集群 - [ ] 在 Head 上通过 `ray status` / Dashboard 验证节点已注册 ### 6.3 准备数据与模型 - [ ] 数据集下载到:`/mnt/shared/datasets/gsm8k/` - [ ] 模型缓存落到:`/mnt/shared/hf/`(拉取一次即可多任务复用) ### 6.4 提交训练任务 - [ ] 用 `ray job submit --address=http://:8265 ...` 提交 PPO 训练 - [ ] 训练日志与 checkpoint 在 `/mnt/shared/outputs/` 可见 ## 7. 验收标准(V1) - [ ] Ray Head/Worker 能稳定加入同一集群(Dashboard 可见) - [ ] PPO 训练任务可提交并跑通(至少完成若干 step/epoch) - [ ] 数据集、HF 缓存、训练输出均在 `/mnt/shared/` 下可复用(容器重启后仍在) - [ ] 有一份“从零到跑通”的命令清单(或脚本)可复现 ## 8. 未决问题(记录待补齐) - [ ] Ray 节点标签/亲和性调度:是否统一用 `ray start --resources`,以及命名规范如何设计 - [ ] RL workload 的 Driver 放置策略:先按 `verl` 默认即可,后续再按 `specs/hl_design_v2.md` 收敛到“Driver-on-Head / Placement Group”等模式 ## 9. 下一步(进入 V2) 当 V1 达到“可复现 + 产物可落盘”的验收标准后,下一阶段工作见:`specs/mvp_plan_v2.md`。