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

8.3 KiB
Raw Blame History

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
  • Roadmapspecs/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建议也用 /privatedocker 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=cpudriver 只做 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=1total_training_steps
  • 输出目录内有日志与至少 1 次 checkpoint或明确不保存并说明原因

SFT必须

  • sft_trainer_ray 可连接集群并跑到至少 1 个 step推荐最小训练步数/epoch
  • 输出目录与 checkpoint 策略同 v1.1 规范(落盘到 ${SHARED_ROOT}/jobs/<id>/...