5.3 KiB
5.3 KiB
MVP v2.5 迭代总结(已落地)
本文档总结 v2.5 在 v2.0/v2.1/v2.2…基础上完成的能力、实现点、验收方式与已知限制,便于回顾与后续版本迭代对齐。
目标与边界
v2.5 的核心目标:
- 引入 User Management(用户管理):基于 token 的鉴权与任务级隔离(“只隔离 jobs”)。
- 引入 Stateless Ray Node Pool(无状态 Ray worker 池):worker 不依赖平台下发 head 地址,自动发现并连接/自愈。
- 保持 TaskSpec(v1.1 同款 YAML 格式)不扩展:本迭代不支持 reward function、自定义 verl 代码等。
明确不做(v2.5 约束):
- 不支持 TaskSpec 扩展(例如
reward_fn_path等)。 - 不支持用户自定义 verl/hf/dataset 的隔离或自定义路径:统一使用
/private/common/...的公共资源。 - 用户隔离仅覆盖 任务与产物目录(jobs),不覆盖 HF cache、datasets 等公共缓存。
关键能力(对外表现)
1) 多用户鉴权与任务隔离
- API 仍使用内部
Authorization: Bearer <token>方式:- 管理员 token 来自环境变量
MVP_INTERNAL_TOKEN(admin)。 - 业务用户 token 由管理员通过 API 下发并持久化到 SQLite。
- 管理员 token 来自环境变量
- 用户隔离策略:
- 非管理员用户只能查询/取消/拉取日志 自己的 task;跨用户访问返回 404(不泄露存在性)。
- 训练产物落盘隔离:Ray job 目录统一写入
/private/users/<user_id>/jobs/<ray_submission_id>/...。
2) task_id / submission_id 带用户名
- 新任务 ID 规则:
mvp2-<user>-<workload>-<YYYYMMDD-HHMMSS>-<suffix> - Ray submission id(attempt)规则:
<task_id>--aNN,因此自然包含用户名。 - 作用:Dashboard/日志/落盘目录可读性更强,便于按用户追踪和审计。
3) “无状态 worker 池”与 head 地址发现
- Head 在共享存储写入 head 地址文件(例如
head.json),worker 通过 watchdog:- 轮询发现 head 地址
- 自动
ray start --address ...加入集群 - 掉线后自动重连(watchdog 自愈)
- 达成效果:在生产环境中,即使 worker 容器由算力平台创建(只提供 SSH 纳管),也能通过共享存储实现连接与自愈。
4) 任务调度:队列 + Ray Job 提交 + 状态回传
- API 提交任务后进入 SQLite 队列,由后台 scheduler 逐个提交到 Ray(默认
max_running_tasks=1)。 - Scheduler 持续轮询 Ray job 状态并回写任务状态(RUNNING/SUCCEEDED/FAILED/CANCELED)。
- 资源不足的“可重试失败”处理:
- 针对 VERL 的 fail-fast(
Total available GPUs ... is less than total desired GPUs ...)或集群资源不足, 任务进入PENDING_RESOURCES并设置next_run_at,按retry_interval_s周期重试。
- 针对 VERL 的 fail-fast(
关键实现点(工程化落地)
存储与目录约定(容器内视角)
- 共享根路径统一为
/private(对齐生产挂载)。 - v2.5 强约束:TaskSpec 的以下字段必须以
/private/common/开头:code_path/train_file/val_file
- 公共目录(示例):
/private/common/hf:HF 缓存/private/common/datasets:训练数据(必要时通过 symlink 指向已有缓存目录复用下载)/private/common/db/mvp.sqlite3:队列与用户信息(SQLite)/private/common/logs:API / watchdog 日志/private/users/<uid>/jobs/...:用户作业产物(隔离)
Ray 拓扑与“head 不跑训练”
- Head 启动为管理节点(CPU/GPU=0),避免训练任务落到 head。
- Worker 节点具备 GPU(示例:2 个 worker * 每个 4 GPU)。
- driver 通过
entrypoint_resources(例如worker_node: 1)强制落 worker。
部署脚本与可重复执行
提供完整脚本链路,覆盖:
- 清理 legacy 环境、起停容器、启动 Ray head
- head discovery publisher、worker watchdog 启动与状态检查
- 数据/模型/代码准备(幂等、可复用已有下载)
- 启动 API server(并支持 RESET_DB)
- API 方式连续提交 PPO/GRPO/SFT 并等待完成
代表性脚本:
src/mvp/scripts/run_all_v25_api.sh:v2.5 happy-path 端到端(含重建集群、准备资源、起 API、提交 3 类任务)src/mvp/scripts/run_e2e_v25_cases.sh:在 happy-path 基础上增加鉴权/隔离/输入校验/资源不足/取消等用例
验收与测试(已通过)
单元测试(本机 venv)
.venv/bin/python -m pytest- 覆盖率阈值:>= 90%
远端端到端(h1)
- 在
argus@h1:/home2/argus/infra/mvp/src/mvp/scripts执行:MVP_INTERNAL_TOKEN=mvp-dev-token RESET_DB=1 ./run_e2e_v25_cases.sh
- 结果:happy-path(PPO/GRPO/SFT)完成,且异常/边界用例验证通过(鉴权、跨用户隔离、输入校验、资源不足转 PENDING_RESOURCES、取消任务等)。
已知问题与后续建议
max_running_tasks=1会让队列中的任务在前序 RUNNING 时保持 QUEUED,这在“资源不足”边界测试里需要显式清空/取消前序任务,或接受该行为作为设计的一部分。- 当前仍是 SQLite 单点;后续若要 HA/水平扩展,可在 v2.6+ 引入更强的持久化与多副本(例如 Postgres/etcd)。
- API server / watchdog 目前以脚本方式守护;后续可进一步统一为 systemd/supervisor(或平台侧守护)并补齐健康检查与告警。