argus-cluster/specs/mvp/v3.5/v3.5_dev_plan.md

201 lines
8.7 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 v3.5精简版开发计划TDD
> 目标:在 v3.0 已有能力基础上,仅新增两项能力:
> 1) **Advanced TaskSpec自定义 command**
> 2) **Custom Reward方式 A用户自己在 command 里写 `custom_reward_function.*`**
>
> 设计依据:`specs/mvp/v3.5/v3.5_design.md`(本计划不再扩展 scope
---
## 0. 范围与约束
### 0.1 In scope
- 新增 `kind: advanced` 的 TaskSpec用户提供 `command`,平台做 `$HOME` 宏替换与 best-effort 校验,再提交 Ray Job。
- Custom Reward平台仅做 **reward path 校验**(方式 A不新增结构化字段。
- `$HOME/common/*` 路径语义支持(关键):用户在 SFTPGo/WebClient 看到的路径能被训练进程正确读取。
### 0.2 Out of scope本轮不做
- 自定义 verl 版本/代码路径(多版本共存)
- 断点续训resume from checkpoint
- IB/RoCEv2/NCCL 专项支持
- Model Serving
- Node management 改造v3.0 的 stateless head/worker/watchdog/supervisor 机制保持不变)
### 0.3 关键路径映射(必须保持一致)
> 说明SFTPGo 的 `$HOME/common/...` 是 **virtual folder**,训练进程看不到该虚拟路径。
提交 Advanced command 前必须展开/映射:
- `$HOME/common/datasets``/private/datasets`(只读语义)
- `$HOME/common/hf``/private/hf`(只读语义)
- 其余 `$HOME``/private/users/<user_id>`
并且为兼容历史用法v3.0
- Basic TaskSpec 仍接受 `/private/common/datasets/...``/private/common/hf/...`(不强制迁移)。
---
## 1. 测试策略TDD
### 1.1 单元测试优先级
1) **解析与兼容**`kind: advanced` 能解析;无 `kind` 仍按 Basic 解析,旧用法不破坏。
2) **宏替换正确性**`$HOME` / `$HOME/common/*` 映射严格按约定展开。
3) **best-effort 校验**:拒绝明显危险/跨用户路径;对 reward path 做 allowlist。
4) **提交链路**Scheduler 能识别 Advanced spec 并调用对应的提交方法,确保 submission_id/目录规范不变。
5) **WebUI/API**New Task 模板与 `/spec` 展示完整 resolved spec包含展开后的 command
### 1.2 本地运行方式
- 复用已有 `.venv`,执行:`.venv/bin/python -m pytest`
- 若环境没有 pip使用 uv 的方式参考 v3.0 约定(不在本计划重复)。
---
## 2. 里程碑划分(每个里程碑可独立验证)
> 约定:每个里程碑先写测试(失败),再实现代码使测试通过;里程碑结束跑一遍 `pytest`。
### M1 — TaskSpec 模型与解析(兼容优先)
**目标**
- 引入 AdvancedTaskSpec 数据结构与 union parser同时保证 v3.0 Basic 行为不变。
**新增/修改(建议位置)**
- `src/mvp/py/argus/ray/models.py`
- 新增 `AdvancedTaskSpec`
- 新增 `parse_taskspec(obj: dict) -> JobSpec | AdvancedTaskSpec`
- 兼容策略:缺省 `kind` → 走 `JobSpec.from_dict`
**测试(先写)**
- `src/mvp/py/tests/test_models.py`
- `test_parse_taskspec_basic_no_kind_compat()`
- `test_parse_taskspec_advanced_smoke()`
- `test_parse_taskspec_advanced_requires_command_nnodes_gpus()`
**验收**
- `pytest -q` 通过;旧测试不修改或仅做最小必要更新。
---
### M2 — Advanced command 展开与校验(核心能力)
**目标**
- 实现 command 展开(含 `$HOME/common/*` 映射)与 best-effort 强约束校验。
**实现点(建议新增模块)**
- `src/mvp/py/argus/service/command_expand.py`(或放在 `argus/service/validation.py`
- `expand_advanced_command(user_id: str, command: str) -> str`
- `validate_advanced_command(user_id: str, expanded_command: str) -> None`(失败抛 `ValueError`
**强约束(与设计文档一致)**
- 必须包含 `python3` 且包含 `-m verl.trainer.`(否则 400
- 禁止出现 `/private/users/<other>/...`(跨用户路径)
- 若检测到 `data.train_files=`/`data.val_files=`
- 只允许 `/private/users/<me>/datasets/...``/private/datasets/...`
- (兼容)允许 `/private/common/datasets/...`(旧路径)
- 若检测到 `custom_reward_function.path=`
- 只允许 `/private/users/<me>/code/...`(展开后校验)
**测试(先写)**
- 新增:`src/mvp/py/tests/test_advanced_command.py`
- `test_expand_maps_home_common_datasets_to_private_datasets()`
- `test_expand_maps_home_common_hf_to_private_hf()`
- `test_expand_maps_home_to_private_users()`
- `test_validate_rejects_cross_user_paths()`
- `test_validate_requires_verl_trainer_entry()`
- `test_validate_allows_reward_path_under_user_code()`
- `test_validate_rejects_reward_path_outside_user_code()`
**验收**
- 单测覆盖映射/校验的正反例;错误信息可读(用于 API 400 detail
---
### M3 — Ray 提交链路支持 AdvancedBuilder/Tool/Scheduler
**目标**
- Advanced spec 能进入 scheduler 队列并提交为 Ray jobdriver 仍落 worker
**代码改动点(建议)**
- `src/mvp/py/argus/ray/builders.py`
- 新增 `build_advanced_argv(command: str)`:返回 `["bash","-lc", expanded_command]`
- `src/mvp/py/argus/ray/ray_job_tool.py`
- 新增 `submit_advanced(...)`(或统一成内部 submit plan
- runtime_env继续注入公共 verl code path本轮不支持用户自定义 verl 代码)
- 可选:把 `/private/users/<user>/code` 加入 `PYTHONPATH`,提升 reward 代码 `import` 体验
- `src/mvp/py/argus/service/scheduler.py`
- 使用 `parse_taskspec` 分流 Basic/Advanced
- Advanced 调用 `tool.submit_advanced(...)`
**测试(先写)**
- `src/mvp/py/tests/test_builders.py`
- `test_build_advanced_argv_uses_bash_lc()`
- `src/mvp/py/tests/test_scheduler.py`
- 新增一个 `kind: advanced` 的任务,断言 scheduler 调用了 `submit_advanced`
- 断言 job_dir/submission_id 规则不变(仍按 `/private/users/<user>/jobs/<sid>`
- `src/mvp/py/tests/test_ray_job_tool.py`
- 断言 advanced 提交时 entrypoint 是 driver_entrypoint + `bash -lc ...`
**验收**
- 单测跑通Scheduler tick 能完成 Advanced 任务从 QUEUED → SUBMITTEDmock Ray
---
### M4 — API & WebUI最小功能闭环
**目标**
- WebUI/HTTP API 能提交 Advanced Task并在详情页看到 resolved spec含完整 command
**API 改动点**
- `src/mvp/py/argus/service/app.py`
- `POST /api/v2/tasks`:支持 `kind: advanced`
- 保存 raw YAML保持与 Basic 一致)
- 对 Advanced展开 command + 校验(失败返回 400
- `GET /api/v2/tasks/{task_id}/spec`
- 返回 resolved spec建议同时返回 raw + expanded或 YAML 中直接给 expanded
**WebUI 改动点**
- `src/mvp/py/argus/service/ui.py`
- New Task 页面新增 Advanced 模板(含中文注释)
- 文案强调共享目录:`$HOME/common/datasets``$HOME/common/hf`
**测试(先写)**
- `src/mvp/py/tests/test_app.py`
- `test_create_task_advanced_ok()`(最小 valid command
- `test_create_task_advanced_rejects_invalid_command()`
- `test_task_spec_endpoint_includes_expanded_command()`
- `src/mvp/py/tests/test_ui.py`
- 断言页面包含 Advanced 示例块
**验收**
- `pytest` 通过;浏览器可提交 Advanced YAML 并看到 expanded command。
---
### M5 — 端到端验证(远端 argus@h1
**目标**
- 在真实 Ray cluster + VERL 环境下验证 Advanced 与 Custom Reward方式 A
**步骤(手工验收脚本化可选)**
1) 启动 v3.0/v3.5 统一的 compose + API沿用现有 `run_all` 脚本体系)
2) 用户(如 `alice`)通过 SFTP 上传 reward 代码到:
- `$HOME/code/reward.py`(真实路径 `/private/users/alice/code/reward.py`
3) 通过 WebUI 或 curl 提交 Advanced task
- `command` 中包含:
- `custom_reward_function.path=$HOME/code/reward.py`
- `custom_reward_function.name=compute_score`
- `data.train_files=$HOME/common/datasets/gsm8k/train.parquet`
- `data.val_files=$HOME/common/datasets/gsm8k/test.parquet`
4) 检查:
- 任务状态从 QUEUED → RUNNING → SUCCEEDED/FAILED有日志
- driver 不在 head 上跑dashboard 验证)
- 日志出现 “custom reward” 生效的提示(按 VERL 实际日志关键字确认)
5) 回归:提交 Basic ppo/grpo/sft 任务仍可运行(确保兼容性)
**验收**
- Advanced task 能跑至少若干 step且 reward 注入生效。
- Basic 任务兼容不回退。
---
## 3. 风险点与边界(明确写进 PR/变更说明)
- Advanced command 只做 best-effort 校验,不做完整 shell AST 解析;复杂命令可能存在漏检/误判(后续可扩展)。
- `$HOME/common/*` 是“用户侧语义”,服务层必须映射到真实路径,否则训练必然 FileNotFound。
- 校验策略(强约束)如果后续要允许非 VERL 命令,需要调整规则并补测试(本轮默认拒绝)。