# MVP v3.6(基于 v3.5)开发计划(TDD) > 设计依据:`specs/mvp/v3.6/v3.6_design.md` > 本计划默认已确认: > 1) W&B host 端口:`8090`;2) project:`_project`;3) evaluation 先做 Advanced 模板;4) 不使用 `WANDB_ENTITY`。 ## 总体原则 - **TDD**:每个里程碑先补齐单测(或契约测试)再实现功能;保证覆盖率门槛不回退。 - **最小闭环**:先做到“可用+可验证”,再做体验优化;不做超出 v3.6 scope 的扩展。 - **配置不落盘敏感信息**:`WANDB_API_KEY` 只能来自运行环境变量,不写入仓库配置文件。 --- ## Milestones ### M1:配置层(tracking.wandb)与解析 **目标** - 在服务配置中新增 `tracking.wandb`,支持开关、base_url、api_key_env。 - 不引入 `WANDB_ENTITY`(保持为空即可)。 **开发任务** - 在 `src/mvp/py/argus/service/config.py`: - 新增 `TrackingConfig/WandbConfig` dataclass(或等价结构)。 - `V2Config.from_root_dict()` 解析 `tracking.wandb.*`(缺省为 disabled)。 - 校验:`enabled=true` 时 `base_url` 不能为空;`api_key_env` 默认 `WANDB_API_KEY`。 **测试(先写)** - `test_config_parses_wandb_defaults`:没有 tracking 字段时,默认 disabled。 - `test_config_parses_wandb_enabled`:enabled=true 能读到 base_url/api_key_env。 - `test_config_rejects_empty_base_url_when_enabled`:enabled=true 且 base_url 空时报错(或记录 warning,取决于实现选择)。 **验收** - 仅通过 config 即能决定是否启用 W&B,且不会破坏 v3.5 现有配置解析。 --- ### M2:Ray Job runtime_env 注入(WANDB_* env) **目标** - 当 `tracking.wandb.enabled=true` 时:平台在 job 粒度注入 `WANDB_BASE_URL/WANDB_API_KEY/WANDB_MODE/WANDB_DIR` 等 env。 - `WANDB_API_KEY` 从 API server 进程环境变量中读取:`os.environ[api_key_env]`。 **开发任务** - 在 scheduler / ray job builder(`src/mvp/py/argus/service/scheduler.py` 或 `src/mvp/py/argus/ray/builders.py`): - 构造 job runtime_env.env_vars 的 merge 逻辑: - 现有 `ray.runtime_env.env_vars` 为基础; - 追加 W&B env(不覆盖用户显式指定的同名变量,或按“平台优先”策略二选一并写清楚)。 - 注入: - `WANDB_BASE_URL=` - `WANDB_API_KEY=` - `WANDB_MODE=online` - `WANDB_DIR=/private/users//jobs//wandb`(本地 run 文件随 job 一起由 janitor 清理) **测试(先写)** - `test_scheduler_injects_wandb_env_when_enabled`: - mock env 中存在 `WANDB_API_KEY`; - 提交一个内置任务(ppo/sft 任意),断言构造出来的 runtime_env 含以上 env_vars。 - `test_scheduler_sets_wandb_dir_under_job_dir`: - 断言 `WANDB_DIR` 位于该 attempt 的 job 目录下(而不是 common 目录),避免无法跟随 job retention 清理。 - `test_scheduler_does_not_inject_wandb_env_when_disabled`。 - `test_scheduler_wandb_missing_api_key_behaviour`: - enabled=true 但缺少 env 时的行为: - 方案 A(推荐):**自动降级**为 console(不注入 wandb),并在 task/attempt message 记录 warning; - 或方案 B:fail-fast(返回 500/400)。 - 需在实现前确认采用哪种策略;建议 v3.6 选 A 提升可用性。 **验收** - 任意内置任务提交后,在 Ray job runtime_env 中能看到 `WANDB_*`。 --- ### M3:内置训练任务自动开启 wandb logger(PPO/GRPO/SFT) **目标** - 当 W&B enabled 时,平台默认把内置训练任务改成 `trainer.logger=["console","wandb"]`,并设置 project/run 命名。 **开发任务** - 在 job 构建(PPO/GRPO/SFT 的 overrides 生成处): - 将 `trainer.logger` 从 `console` 改为 list:`[console,wandb]`(hydra 语法按现有实现方式拼接)。 - `trainer.project_name=_project` - `trainer.experiment_name=` - 保持 v3.5 的 job_dir/checkpoint/log dir 注入方式不变。 **测试(先写)** - `test_job_overrides_include_wandb_logger_when_enabled`: - 断言 entrypoint/overrides 包含 `trainer.logger=[console,wandb]`(或等价写法)。 - 断言包含 `trainer.project_name=_project`、`trainer.experiment_name=`。 - `test_job_overrides_keep_console_only_when_wandb_disabled_or_missing_key`。 **验收** - 训练任务 run 会自动出现在 W&B 对应 project 下(E2E 验证在 M6)。 --- ### M4:API 输出与 WebUI 链接(最小闭环) **目标** - 用户可以在 UI 里“知道去哪看 W&B”,以及知道本 task 对应哪个 project/run。 **开发任务** - API: - `GET /api/v2/me` 增加 `wandb` 信息(仅当 enabled 时返回): - `base_url` - `project_name`(`_project`) - `GET /api/v2/tasks/{task_id}`(或 attempt 结构)增加 `wandb_project` / `wandb_run_name`(run_name=ray_submission_id)。 - WebUI: - Login/Data 页增加 “Open W&B” 链接(跳 `base_url`),展示 project_name + Copy。 - Task detail 增加 wandb 字段展示(project/run/可点击链接或可复制文本)。 **测试(先写)** - `test_me_includes_wandb_when_enabled`(mock config + env)。 - `test_task_detail_contains_wandb_fields_when_enabled`(mock task/attempt)。 - `test_ui_contains_wandb_link`(渲染 HTML 断言包含 base_url/project_name 字样)。 **验收** - WebUI 能一键跳转 W&B;Task detail 能定位到 run。 --- ### M5:New Task 增加 Evaluation 模板(Advanced) **目标** - New Task 页面增加一个 Evaluation 模板按钮/示例(先按 Advanced TaskSpec 提供)。 **开发任务** - 在 `src/mvp/py/argus/service/ui.py`: - YAML 模式增加 “Evaluation example”。 - 表单模式本轮可选(不要求): - 如果要支持:把 evaluation 作为 advanced 模板的一种预填 command(仍 `kind: advanced`)。 - 模板建议使用 verL 自带入口: - `python3 -m verl.trainer.main_eval ... +ray_kwargs.ray_init.address=auto` - `data.path=$HOME/common/datasets/...`(按 v3.5 的宏规则) **测试(先写)** - `test_ui_new_task_contains_evaluation_example`:断言页面包含 `main_eval` 与关键字段。 **验收** - 用户复制 evaluation 模板可提交成功并在 Ray 上运行(E2E 在 M6)。 --- ### M6:端到端(dev/h1)部署与验收流程 > 里程碑 M6 以脚本/手工步骤为主;不强制写 e2e 自动化测试。 **部署任务** - compose 增加 `wandb` 服务: - `wandb/local:latest` - host 端口 `8090:8080` - 数据挂载到 `/private/common/wandb:/vol` 持久化(W&B 元数据/账号/API key/历史 runs) - API 启动方式: - 在宿主机 export:`WANDB_API_KEY=<从 W&B UI 生成的 key>` - 启动 API(确保 env 透传到容器内) - 首次初始化: - 打开 `http://:8090/system-admin` 粘贴 license(管理员操作) **验收用例** 1) **训练类任务自动打点** - 用 alice 提交一个 SFT(或 PPO)任务(内置 workload) - 在 W&B UI 中看到 project:`alice_project` - run name 为 `ray_submission_id`,metrics 可见 2) **Advanced task 可手动打点** - 提交一个 Advanced(用户自己写 command)并在 command 中启用 `trainer.logger=["console","wandb"]`(如需) - 确认 env 注入生效(W&B 记录出现) 3) **Evaluation 模板** - 用 New Task 的 Evaluation example 提交 - 任务成功运行并输出 metrics(stdout/logs) - (可选)如果 evaluation 也启用 wandb,则能出现在对应 project 下 **回归** - v3.5 的三类任务(ppo/grpo/sft)在 W&B disabled 或缺少 key 时仍可跑通(至少 console 输出不受影响)。 **Retention 联动检查** - 提交一个短任务生成 `WANDB_DIR`,结束后确认: - `WANDB_DIR` 位于 `/private/users//jobs//wandb` - janitor 运行后该目录会随 job 一起进入 trash / 被 purge(与 jobs retention 一致) --- ## 交付物清单(v3.6) - 文档: - `specs/mvp/v3.6/v3.6_design.md`(已存在,必要时补充操作流程) - `specs/mvp/v3.6/v3.6_dev_plan.md`(本文) - 代码(预期变更点): - `src/mvp/py/argus/service/config.py` - `src/mvp/py/argus/service/scheduler.py` / `src/mvp/py/argus/ray/builders.py` / `src/mvp/py/argus/ray/ray_job_tool.py` - `src/mvp/py/argus/service/app.py`(/me 与 task detail 输出) - `src/mvp/py/argus/service/ui.py`(Open W&B + Evaluation template) - `src/mvp/docker-compose.yaml`(wandb service) - `src/mvp/configs/dev.yaml`(tracking.wandb 配置) - `src/mvp/scripts/*`(API 启动时 env 透传,必要时补充)