195 lines
5.2 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 v2.0 API 设计(最小可用)
v2.0 的 API 目标是:把 v1.1 的“脚本提交”变成“服务化提交”,并在服务侧实现队列/重试/状态聚合。
约束:
- 内部 token 鉴权(简单即可)。
- Ray Job 提交必须使用 **Ray Python SDK**`JobSubmissionClient`),不使用 `requests` 手写 HTTP。
- 输出与状态必须落盘到 NFS容器内 `/private`)。
---
## 1. 鉴权
- Header`Authorization: Bearer <INTERNAL_TOKEN>`
- v2.0 不做用户体系与权限隔离token 只是“防误用”。
- 配置建议:复用 `src/mvp/v1.1/py/configs/dev.yaml` 并在 `v2.auth.token_env` 指定 token 环境变量名。
## 1.1 运行位置dev 示例)
- 服务进程运行在 **Ray head 容器**(便于访问 Ray Job server
- 宿主机侧用脚本控制(`docker exec`
- `src/mvp/v2.0/scripts/20_start_api.sh`
- `src/mvp/v2.0/scripts/21_stop_api.sh`
- `src/mvp/v2.0/scripts/22_status_api.sh`
- 远程机目录约定(示例):`argus@h1:/home2/argus/infra/mvp/v2/`,容器内挂载到 `/workspace/mvp/v2/`
---
## 2. 资源与 ID 约定
### 2.1 task_id服务层主 ID
- 格式建议:`mvp2-<workload>-<YYYYMMDD>-<HHMMSS>-<suffix>`
- 示例:`mvp2-ppo-20251223-143201-7f3a`
### 2.2 ray_submission_idattempt 级 ID
- 由 service 派生:`<task_id>--a<NN>`
- 示例:`mvp2-ppo-20251223-143201-7f3a--a01`
好处:
- Ray 的 submission id 自带 task_id可直接从 Ray dashboard 反查到服务侧任务。
- `/private/jobs/<ray_submission_id>/...` 目录天然隔离且可读。
---
## 3. JobSpec请求体
v2.0 **要求 JobSpec 使用 v1.1 同款 YAML**(字段与语义保持一致),服务端接收 YAML 文本并解析后入库(同时原样保存 `jobspec_yaml` 便于审计/复现)。
最小字段(示例 YAML
```yaml
workload: "ppo"
submission_id: "" # v2.0 服务端会忽略/覆盖(由 task_id 派生 ray_submission_id
code_path: "/private/common/code/verl/verl_repo"
model_id: "Qwen/Qwen2.5-0.5B-Instruct"
train_file: "/private/datasets/gsm8k/train.parquet"
val_file: "/private/datasets/gsm8k/test.parquet"
nnodes: 2
n_gpus_per_node: 4
total_epochs: 1
total_training_steps: 10
save_freq: 10
test_freq: -1
trainer_device: null # 仅 sft 使用(通常 "cpu"
```
说明:
- `trainer_device` 仅对 `sft` 生效(通常为 `cpu`,避免 driver 无 GPU
- `val_file` 可为 `null`(例如 SFT
---
## 4. API 端点
### 4.1 提交任务
`POST /api/v2/tasks`
Request body
- **raw JobSpec YAML**(与 v1.1 jobspec YAML 结构一致)
Headers
- `Content-Type: application/yaml`(或 `text/yaml`
Response
```json
{
"task_id": "mvp2-ppo-20251223-143201-7f3a",
"state": "QUEUED"
}
```
### 4.2 查询任务(聚合状态)
`GET /api/v2/tasks/{task_id}`
Response示例
```json
{
"task_id": "mvp2-ppo-20251223-143201-7f3a",
"workload": "ppo",
"state": "RUNNING",
"desired_resources": {"nnodes": 2, "n_gpus_per_node": 4, "total_gpus": 8},
"latest_attempt": {
"attempt_no": 1,
"ray_submission_id": "mvp2-ppo-20251223-143201-7f3a--a01",
"ray_status": "RUNNING",
"start_time": "2025-12-23T14:32:10+08:00"
},
"error_summary": null
}
```
### 4.3 列出 attempts
`GET /api/v2/tasks/{task_id}/attempts`
Response
```json
{
"task_id": "mvp2-ppo-20251223-143201-7f3a",
"attempts": [
{
"attempt_no": 1,
"ray_submission_id": "mvp2-ppo-20251223-143201-7f3a--a01",
"ray_status": "FAILED",
"failure_kind": "INSUFFICIENT_RESOURCES",
"message": "Total available GPUs 0 is less than total desired GPUs 8",
"start_time": "...",
"end_time": "..."
}
]
}
```
### 4.4 取消任务
`POST /api/v2/tasks/{task_id}:cancel`
行为:
- 若 task 处于 `SUBMITTED/RUNNING`:调用 Ray Jobs SDK `stop_job(ray_submission_id)` 并标记 `CANCELED`
- 若处于 `QUEUED/PENDING_RESOURCES`:直接标记 `CANCELED`(不提交)
Response
```json
{"task_id":"...","state":"CANCELED"}
```
### 4.5 获取日志
`GET /api/v2/tasks/{task_id}/logs?attempt=latest&tail=2000`
返回:
- `text/plain`(直接透传 Ray Job logs tail
说明:
- v2.0 先用 Ray SDK `get_job_logs()`
- 若需要更稳定的归档,可在 scheduler 定期抓取并落盘v2.1+)。
### 4.6 列出队列(运维/调试)
`GET /api/v2/queue`
Response
```json
{
"pending": [{"task_id":"...","state":"PENDING_RESOURCES","next_run_at":"..."}],
"running": [{"task_id":"...","ray_submission_id":"..."}]
}
```
---
## 5. 错误码(最小)
- `400`jobspec 缺字段/非法
- `401`token 不正确
- `404`task 不存在
- `409`:状态冲突(例如已终态又 cancel
- `500`:服务内部错误
---
## 6. SQLite 持久化API 可见性)
v2.0 服务端使用 SQLite 持久化保存:
- tasks`task_id``state``jobspec_yaml``next_run_at``latest_attempt_no` 等)
- attempts`ray_submission_id``ray_status`、失败原因等)
因此:
- `GET /api/v2/tasks/{task_id}` 的数据来自 SQLite再叠加 Ray 状态同步的结果)。
- 进程重启后,队列可恢复,`PENDING_RESOURCES` 的任务会在 `next_run_at` 到期后继续尝试提交。