argus-cluster/specs/mvp/v1.1/mvp_plan.md
2025-12-23 14:22:15 +08:00

170 lines
8.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# MVP v1.1 计划Hardening + 多 Workload 可行性验证)
本目录是 `specs/mvp/v1/` 的下一步迭代:在 v1 已经跑通Ray head + 2 workerPPO on Ray持久化落盘的基础上把它升级为**可长期回归**的最小系统,并扩展至少一个新 workload 的可行性闭环。
> v1.1 的目标不是做平台服务化API/队列/多用户)——那是 v2/v3 的工作v1.1 聚焦“工程化 + 可行性边界验证 + 可观测/可排障基础”。
---
## 1. v1 基线回顾(已完成)
- 拓扑1 head无 GPUCPU/GPU=0+ 2 worker各 4 GPU
- 提交方式:必须用 head 上的 `ray job submit`
- driver 调度:通过 `worker_node` 自定义资源 + `--entrypoint-resources` 强制 driver 在 worker
- 输出:按 `submission_id` 组织到共享目录NFS
相关实现参考:
- 脚本:`src/mvp/v1/`
- 验收动作:`specs/mvp/v1/v1_action.md`
- Roadmap`specs/mvp/mvp_roadmap.md`
---
## 2. v1.1 目标(必须达成)
### 2.1 工程化Hardening
1) **JobSpec 标准化(最小)**
- 把“提交 job 需要的参数”收敛成结构化文件:
- Ray 基础配置YAMLcluster 地址、entrypoint 资源约束、runtime_env 等
- 训练 JobSpecYAMLworkload 语义与训练参数
- 至少覆盖:`submission_id`、workload 类型、资源需求、共享根路径、模型/数据路径、输出目录、超时、环境变量注入。
- v1.1 实现落点(已在 repo 里提供SDK 方式):
- RayConfig 示例:`src/mvp/v1.1/py/configs/dev.yaml`
- JobSpec 示例:`src/mvp/v1.1/py/jobspecs/{ppo,grpo,sft}.yaml`
- 提交入口:`src/mvp/v1.1/py/run.py`(在 head 容器内执行,使用 Ray Python SDK 提交)
- 设计文档:`specs/mvp/v1.1/sdk_submit_refactor.md`
2) **共享根路径抽象dev/prod 一致)**
- 引入 `SHARED_ROOT` 作为唯一共享根路径:
- dev建议也用 `/private`docker compose 把宿主机 shared 挂到容器内 `/private`,模拟生产)
- prod固定 `/private`(算力平台容器内 NFS
- 任何代码/脚本不得写死 `/mnt/shared`(允许兼容旧路径但不得作为主路径)。
3) **共享目录分层(新增 `common/` 与 `user/`**
-`datasets/hf/jobs/outputs` 之外,新增一个所有用户可读写的共享区:
- `${SHARED_ROOT}/common/`:共享模型/数据/代码快照(多版本 verl / 公共数据)
- `${SHARED_ROOT}/user/`:用户自定义代码(例如 `reward_fn_path` 指向这里)
- v1.1 默认策略:先假设“所有用户可写”(后续 v3 再做权限与隔离)。
4) **可排障基础**
- 每个 job 目录必须有:
- `config/`提交命令、JobSpec 快照、关键 env_vars
- `logs/`Ray job logs + hydra logs如有
- `checkpoints/`:按 `save_freq` 控制频率(默认每 10 step
- 提供“失败快照”能力:收集 `ray status` / `ray job list` / `ray list nodes` / `ray list actors`(最少其中 2 项)写入 job 目录。
- v1.1 submitter 默认落盘:
- `${SHARED_ROOT}/jobs/<id>/config/job_spec.json`
- `${SHARED_ROOT}/jobs/<id>/config/runtime_env.json`
- `${SHARED_ROOT}/jobs/<id>/config/submit_cmd.txt`
- `${SHARED_ROOT}/jobs/<id>/logs/ray_job_submit.out`
- `${SHARED_ROOT}/jobs/<id>/debug/ray_status_{pre,post}.txt`
- `${SHARED_ROOT}/jobs/<id>/debug/ray_job_list_post.txt`
### 2.2 Workload 扩展(至少新增 1 个)
v1.1 需要新增并验收通过两个 workload都要跑通闭环
- **GRPO on Ray**(推荐优先,复用 PPO 入口,通过算法配置切换)
- 基于 `python -m verl.trainer.main_ppo`
- 通过配置覆盖:`algorithm.adv_estimator=grpo`(以及必要的 rollout 参数)
- **SFT on RayRay-native**
- 入口:`python -m verl.trainer.sft_trainer_ray`
- 参考实现:`verl/verl/trainer/sft_trainer_ray.py`(内部会 `ray.init()`
- 需要确保 `ray.init()` 连接已有集群:
- 优先:`runtime_env.env_vars.RAY_ADDRESS=auto`(配合 `ray job submit`
- 兜底:在 v1.1 的 launcher 脚本里显式 `ray.init(address="auto")` 再调用 trainer避免依赖 Ray 的 env var 行为差异)
- 重要细节Ray Job 的 entrypointdriver默认不分配 GPU因此 SFT driver 侧不要强依赖 CUDA
- 推荐:`trainer.device=cpu`driver 只做 orchestration训练由 Ray workers 占 GPU
---
## 3. v1.1 关键设计点
### 3.1 多版本代码与自定义逻辑(为 v3.1 铺路,但 v1.1 先做最小验证)
已确定优先方案A通过 **Ray Job 的 `runtime_env.env_vars`** 注入 `PYTHONPATH`
- `code_path`(例如 `${SHARED_ROOT}/common/code/verl/<commit>`
- 提交 job 时设置:
- `runtime_env.env_vars.PYTHONPATH = "<code_path>:$PYTHONPATH"`
并约定:
- `reward_fn_path` 可指向 `${SHARED_ROOT}/user/code/...` 下用户自定义代码
-`code_path` 一样,必须通过 `runtime_env.env_vars` 确保该路径可被 import例如把 `${SHARED_ROOT}/user/code` 也加入 `PYTHONPATH`
v1.1 中至少做一次“代码覆盖验证”:
- 在 code_path 下放一个可识别的 `verl` 版本标识(例如 `verl.__version__` 打印差异)
- 提交 job 并在日志中确认 import 的是 code_path 的版本(而不是镜像内默认安装)
v1.1 的最小落地方式(已实现):
- 提供代码快照脚本:`src/mvp/v1.1/scripts/31_snapshot_verl_code.sh`
- 会把 `/workspace/verl`(挂载的 repo复制到 `${SHARED_ROOT}/common/code/verl/<code_id>/`
- 并写入 `${code_path}/mvp_marker.py`,用于在 Ray job logs 中验证“选用的是哪份 code_path”
- submitter 会在 entrypoint 前运行 preflight
- 打印 `verl.__file__``mvp_marker.MARKER`
- 由此确认 job 粒度的 PYTHONPATH 生效,且不同 job 可指向不同 `code_path`(多版本共存)
### 3.2 Checkpoint 策略(磁盘保护)
- 默认:`save_freq=10`(每 10 step 保存一次)
- 对于 step 数已知的短任务(例如 29 steps可以通过配置把 `save_freq` 调整为 10/15/29按需求权衡
- 作业目录按 `submission_id` 隔离,方便清理与归档
---
## 4. v1.1 交付物清单(代码 + 文档)
### 4.1 代码(建议落点)
`src/mvp/` 下新增 v1.1 级别的提交器与模板(或在 `src/mvp/v1` 原地演进但要保持 v1 可回归):
- `src/mvp/v1.1/`
- `docker-compose.yaml`(与 v1 互不干扰的容器名/网络名)
- `scripts/`Ray 启动/prepare 保留 bashsubmit 通过 SDK 工具执行)
- `py/`工程化提交层YAML + Ray Python SDK
- `py/configs/`Ray 基础配置)
- `py/jobspecs/`(训练 JobSpec
- `py/run.py`(入口)
此外,为了对齐 dev 环境约束(远程机固定目录):
- 远程机目录必须新增:`argus@h1:/home2/argus/infra/mvp/v1.1/`
- 该目录内需包含 v1.1 的全部内容compose + scripts + README可由本 repo 的 `src/mvp/v1.1/` 同步过去
### 4.2 文档
- `specs/mvp/v1.1/v1.1_action.md`:开发、部署、测试、验收流程(可复现)
- 更新 `specs/mvp/mvp_roadmap.md`:保持路线图与落地一致(按需)
---
## 5. v1.1 验收标准DoD
### 5.1 Hardening DoD
- [ ] 所有提交均由 head 执行 `ray job submit`,且显式 `--submission-id=<id>`
- [ ] 共享根路径由 `SHARED_ROOT` 控制dev/prod 可切换),脚本无硬编码
- [ ] 每个 job 的输出目录为:`${SHARED_ROOT}/jobs/<submission_id>/`
- [ ] checkpoint 不会“每 step 保存”导致爆盘:默认 `save_freq=10`
- [ ] job 失败时,`${SHARED_ROOT}/jobs/<id>/config/` 中有足够信息定位命令、env、ray 状态快照)
- [ ] v1.1 测试前会清理 v1 的遗留容器/进程避免端口、容器名、Ray session 干扰)
### 5.2 Workload DoDGRPO + SFT 都必须)
GRPO必须
- [ ] `algorithm.adv_estimator=grpo` 的 job 可提交并进入 RUNNING
- [ ] job 能跑完最小训练步数(可设 `total_epochs=1``total_training_steps`
- [ ] 输出目录内有日志与至少 1 次 checkpoint或明确不保存并说明原因
SFT必须
- [ ] `sft_trainer_ray` 可连接集群并跑到至少 1 个 step推荐最小训练步数/epoch
- [ ] 输出目录与 checkpoint 策略同 v1.1 规范(落盘到 `${SHARED_ROOT}/jobs/<id>/...`