8.3 KiB
8.3 KiB
MVP v1.1 计划(Hardening + 多 Workload 可行性验证)
本目录是 specs/mvp/v1/ 的下一步迭代:在 v1 已经跑通(Ray head + 2 worker,PPO on Ray,持久化落盘)的基础上,把它升级为可长期回归的最小系统,并扩展至少一个新 workload 的可行性闭环。
v1.1 的目标不是做平台服务化(API/队列/多用户)——那是 v2/v3 的工作;v1.1 聚焦“工程化 + 可行性边界验证 + 可观测/可排障基础”。
1. v1 基线回顾(已完成)
- 拓扑:1 head(无 GPU,CPU/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)
-
JobSpec 标准化(最小)
- 把“提交 job 需要的参数”收敛成结构化文件:
- Ray 基础配置(YAML):cluster 地址、entrypoint 资源约束、runtime_env 等
- 训练 JobSpec(YAML):workload 语义与训练参数
- 至少覆盖:
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
- RayConfig 示例:
- 把“提交 job 需要的参数”收敛成结构化文件:
-
共享根路径抽象(dev/prod 一致)
- 引入
SHARED_ROOT作为唯一共享根路径:- dev:建议也用
/private(docker compose 把宿主机 shared 挂到容器内/private,模拟生产) - prod:固定
/private(算力平台容器内 NFS)
- dev:建议也用
- 任何代码/脚本不得写死
/mnt/shared(允许兼容旧路径但不得作为主路径)。
- 引入
-
共享目录分层(新增
common/与user/)- 在
datasets/hf/jobs/outputs之外,新增一个所有用户可读写的共享区:${SHARED_ROOT}/common/:共享模型/数据/代码快照(多版本 verl / 公共数据)${SHARED_ROOT}/user/:用户自定义代码(例如reward_fn_path指向这里)
- v1.1 默认策略:先假设“所有用户可写”(后续 v3 再做权限与隔离)。
- 在
-
可排障基础
- 每个 job 目录必须有:
config/:提交命令、JobSpec 快照、关键 env_varslogs/: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
- 每个 job 目录必须有:
2.2 Workload 扩展(至少新增 1 个)
v1.1 需要新增并验收通过两个 workload(都要跑通闭环):
-
GRPO on Ray(推荐优先,复用 PPO 入口,通过算法配置切换)
- 基于
python -m verl.trainer.main_ppo - 通过配置覆盖:
algorithm.adv_estimator=grpo(以及必要的 rollout 参数)
- 基于
-
SFT on Ray(Ray-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 的 entrypoint(driver)默认不分配 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 保留 bash;submit 通过 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 DoD(GRPO + 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>/...)