167 lines
7.8 KiB
Markdown
167 lines
7.8 KiB
Markdown
# MVP v3.0 迭代总结(Ray + SFTPGo + API + WebUI)
|
||
|
||
本文总结 v3.0 迭代最终落地的功能、架构、运行方式、验收点与已知限制,便于后续评审、交接与继续迭代。
|
||
|
||
相关更详细文档:
|
||
- `specs/mvp/v3.0/v3.0_design.md`
|
||
- `specs/mvp/v3.0/v3.0_api.md`
|
||
- `specs/mvp/v3.0/v3.0_dev_plan.md`
|
||
- `specs/mvp/v3.0/v3.0_acceptance.md`
|
||
- `specs/mvp/v3.0/v3.0_progress.md`
|
||
|
||
---
|
||
|
||
## 1. 目标与范围
|
||
|
||
v3.0 作为“第一版可发布”的最小闭环,主要新增:
|
||
- **WebUI**:最小可用的人机界面(登录、任务提交与查看、数据入口、管理员入口)。
|
||
- **用户管理**:基于内部 token 的用户体系(admin 与普通用户),支持创建用户与签发 token。
|
||
- **数据管理入口(SFTPGo)**:用户通过 SFTP/WebClient 上传下载自己的数据;同时暴露只读的共享数据/缓存目录(common)用于复用。
|
||
- **保持训练闭环**:仍通过 Ray Job 提交到集群执行(PPO/GRPO/SFT 三类 workload 都验证)。
|
||
|
||
明确不做(本迭代保持最小):
|
||
- 不支持用户自定义训练代码(TaskSpec 的 `code_path` 固定走 common 下的 verl snapshot 策略)。
|
||
- 不做复杂资源排队优化/多集群/多租隔离策略(目前隔离粒度主要在用户 jobs 目录层)。
|
||
|
||
---
|
||
|
||
## 2. 系统架构(最终形态)
|
||
|
||
核心组件:
|
||
- **Ray 集群(容器)**
|
||
- `argus-ray-head`:head 节点(无 GPU/不跑训练),提供 Ray Dashboard 与 Job Server。
|
||
- `argus-ray-worker-0/1`:worker 节点(有 GPU),承载训练任务。
|
||
- worker 以 “stateless + watchdog 自动连接 head” 的方式加入集群。
|
||
- **API Server(运行在 head 容器内)**
|
||
- 读取 YAML 配置(dev/prod),维护任务队列(sqlite),并周期性调度将任务提交到 Ray。
|
||
- 同时承载 WebUI(`/ui`)。
|
||
- **SFTPGo(容器)**
|
||
- 提供 SFTP(端口 `2022`)与 Web Client/Admin(端口 `8081` 映射到容器 8080)。
|
||
- 用户 home 为 `/private/users/<user>`,默认可读写。
|
||
- 额外提供 `/common/*` 共享只读入口(见第 4 节)。
|
||
- **共享存储(NFS/GPFS 等挂载到容器内 `/private`)**
|
||
- `/private/common`:共享缓存(hf、datasets、models、db、logs 等)。
|
||
- `/private/users/<user>`:用户隔离目录(jobs/datasets/models/code/trash 等)。
|
||
|
||
---
|
||
|
||
## 3. 任务与调度(Task / Ray Job)
|
||
|
||
### 3.1 Task(平台概念)
|
||
- 用户向 API 提交 TaskSpec(YAML),平台分配 `task_id`(可读、包含用户名)。
|
||
- `task_id` 对应内部状态机与重试逻辑;底层每次提交 Ray Job 会产生 attempt 与 `ray_submission_id`。
|
||
|
||
### 3.2 Ray Job(Ray 概念)
|
||
- 真正执行训练的 driver 通过 Ray Job 运行在集群 worker 上(避免 head 承载训练)。
|
||
- head 节点通过 `--num-cpus=0` / 自定义资源等策略避免调度到 head。
|
||
|
||
### 3.3 VERL 资源预检查的处理
|
||
- VERL 在创建资源池时会做 fail-fast 资源预检查(如“可用 GPU 不足”直接报错退出)。
|
||
- v3.0 延续 v2.x 的策略:服务端识别失败原因并按策略重试/回退(具体见 scheduler 实现与 v2.5/3.0 文档)。
|
||
|
||
---
|
||
|
||
## 4. 数据管理(SFTPGo)与 common 只读目录
|
||
|
||
### 4.1 用户目录(读写)
|
||
- 用户通过 SFTP/WebClient 访问自己的 home:`/private/users/<user>`
|
||
- 目录结构(至少):`datasets/ models/ code/ jobs/ trash/ common/`
|
||
|
||
### 4.2 common 只读(方案 A:Virtual Folder)
|
||
本迭代采用 SFTPGo 的 Virtual Folder + 路径权限覆盖,实现用户可读共享目录但不可写。
|
||
|
||
最终对外暴露为:
|
||
- `/common/datasets`(只读)
|
||
- **mapped_path 指向真实目录 `/private/datasets`**(避免 `/private/common/datasets` 中大量 symlink 导致的 WebClient “权限不足/越界”问题)
|
||
- `/common/hf`(只读)
|
||
- mapped_path 指向 `/private/hf`
|
||
|
||
备注:
|
||
- `/private/common/datasets` 内部存在 symlink(如 `gsm8k -> /private/datasets/gsm8k`),如果虚拟目录映射到 symlink 根目录,SFTPGo 会把 symlink 跳转视为“逃逸 root”,导致点击进入时报权限不足;因此选择直接映射到真实目录根。
|
||
|
||
---
|
||
|
||
## 5. WebUI(最小可用)
|
||
|
||
入口:
|
||
- `/ui/login`:粘贴 token(存 browser `localStorage`)
|
||
- `/ui/tasks`:任务列表(Running/Pending/Completed),Completed 支持分页
|
||
- `/ui/tasks/new`:提交任务(PPO/GRPO/SFT 三套样例可一键填充)
|
||
- `/ui/data`:展示当前用户名、支持重置 SFTPGo 密码并复制;提供跳转到 SFTPGo WebClient;提示 FileZilla 等客户端用法
|
||
- `/ui/admin`:管理员入口(创建用户、签发 token、用户列表)
|
||
- 导航栏提供 Ray Dashboard 快捷跳转(当前 IP 的 `:8265`)
|
||
|
||
关于 admin 页面权限:
|
||
- admin 页面本身可访问,但其数据请求必须携带 admin token;否则会在页面内显示 401/403/错误信息(满足“需要先提供 admin token 才能看到内容”)。
|
||
|
||
---
|
||
|
||
## 6. API(v3.0 新增/强化点)
|
||
|
||
核心接口(节选):
|
||
- 认证:
|
||
- Bearer token:`MVP_INTERNAL_TOKEN`(admin)或用户 token(由 admin 签发)
|
||
- 用户管理(admin):
|
||
- `POST /api/v2/users` 创建用户(并初始化用户目录)
|
||
- `GET /api/v2/users` 获取用户列表(包含最新 token、创建/更新时间等)
|
||
- `POST /api/v2/users/{user_id}/tokens` 签发用户 token
|
||
- 任务:
|
||
- `POST /api/v2/tasks` 提交 TaskSpec(YAML)
|
||
- `GET /api/v2/tasks` 任务列表(支持 states/limit/offset,用于 Completed 分页)
|
||
- `GET /api/v2/tasks/{task_id}`、`POST /api/v2/tasks/{task_id}:cancel`、`GET /api/v2/tasks/{task_id}/logs`
|
||
- `GET /api/v2/queue`(运行中/待调度概览)
|
||
- 数据/SFTP:
|
||
- `GET /api/v2/me` 返回用户路径信息、SFTP 连接信息,并 best-effort 对齐 SFTPGo 用户配置
|
||
- `POST /api/v2/me/sftp:reset_password` 用户自助重置 SFTPGo 密码(一次性返回明文)
|
||
|
||
安全取舍说明(当前为内网/开发优先):
|
||
- 为了 Admin WebUI “可查看并复制 token”,数据库持久化存储了 `token_plain`(明文 token)。
|
||
- 这在生产场景通常不建议;未来可改为只展示“重置/重新签发”而不回显明文,或只回显一次。
|
||
|
||
---
|
||
|
||
## 7. 持久化与清理
|
||
|
||
- 任务队列:sqlite(WAL 模式)
|
||
- SFTPGo:自带 sqlite db(容器挂载持久化目录)
|
||
- Jobs 目录清理策略(服务端 janitor):
|
||
- job 结束后 3 天移动到回收目录(trash)
|
||
- 回收目录再保留 7 天后删除
|
||
|
||
---
|
||
|
||
## 8. 运行方式与脚本
|
||
|
||
开发/验收脚本:
|
||
- `src/mvp/scripts/run_all_v30_api.sh`:端到端拉起(Ray + SFTPGo + API),并通过 API 提交 PPO/GRPO/SFT,等待完成并验收
|
||
- 其他脚本用于启动/停止 API、准备数据与模型、探测服务就绪等(详见 scripts 目录与 README)
|
||
|
||
典型端到端(示例参数):
|
||
- `MVP_INTERNAL_TOKEN=my-dev-token`
|
||
- `SFTPGO_ADMIN_PASSWORD=my-dev-sftpgo-admin`
|
||
- 支持 `RESET_DB/RESET_SFTPGO` 用于测试环境重置
|
||
|
||
---
|
||
|
||
## 9. 验证结果(已跑通)
|
||
|
||
在 `argus@h1` 环境中已完成端到端验证:
|
||
- Ray 集群可用(head + 2 worker)
|
||
- API server + WebUI 可用
|
||
- SFTPGo(admin + 普通用户)可用
|
||
- 通过 API 连续提交 PPO/GRPO/SFT 三种任务均能完成(SUCCEEDED)
|
||
- 用户可以登录 SFTPGo WebClient/SFTP,访问自己的目录,并访问 `/common/datasets`、`/common/hf` 的只读内容
|
||
|
||
同时本地单测通过:
|
||
- pytest 全绿
|
||
- 覆盖率阈值 >= 90%
|
||
|
||
---
|
||
|
||
## 10. 已知限制 & 后续可改进
|
||
|
||
- WebUI 当前为最小版,交互与权限提示仍偏“工程化”而非产品化(后续可增强错误提示、搜索筛选、任务详情聚合等)。
|
||
- token 明文持久化仅适合内网/开发场景;生产建议改为一次性展示或支持撤销/轮换策略。
|
||
- SFTPGo 虚拟目录目前保留了历史遗留映射(例如 `/common/models` 可能残留),后续可在升级脚本中做一次性清理与迁移。
|
||
|