- 后端新增 storage 模块(minio_store),支持 MinIO 预签名 URL 上传与对象管理 - config 新增 MinIO 及存储等待相关配置项 - 算力节点新增 /compute/cache/prepare 缓存预下载接口(带校验和原子落盘) - 算力节点健康接口增加存储可用性探针 - SQL 迁移补充资源存储相关表结构 - Docker 新增 minio 服务与后端 minio 配置 - 补充 minio-compute-cache-plan 设计文档 Co-Authored-By: Claude <noreply@anthropic.com>
288 lines
7.6 KiB
Markdown
288 lines
7.6 KiB
Markdown
# MinIO + Compute Agent 本地缓存方案与开发计划
|
||
|
||
## 1. 方案结论
|
||
|
||
本方案用 MinIO 作为模型、数据集、checkpoint、评测结果和训练产物的唯一正式存储,算力节点不挂载 NFS,也不要求安装 NFS 客户端。
|
||
|
||
算力节点只保留任务运行所需的本地缓存:
|
||
|
||
```text
|
||
MinIO
|
||
-> Backend API 生成资源授权和版本信息
|
||
-> Compute Agent 按任务下载到本地缓存
|
||
-> LLaMA-Factory / 推理 / 合并任务使用本地路径
|
||
-> 任务产物上传回 MinIO
|
||
-> PostgreSQL 更新资源和任务状态
|
||
```
|
||
|
||
MinIO 是唯一正式数据源,本地缓存不是正式资源,节点失效或缓存被清理不会丢失模型和数据。
|
||
|
||
## 2. 为什么适合当前项目
|
||
|
||
当前项目的 Compute API 已经负责:
|
||
|
||
- 训练、评测、推理和权重合并任务启动;
|
||
- 本地文件网关;
|
||
- GPU 和任务状态管理;
|
||
- 训练日志和产物路径管理。
|
||
|
||
因此不需要把 LLaMA-Factory 改成直接读取远程对象,只需要在 Compute Agent 启动任务前准备本地路径,继续把原来的 `model_name_or_path`、`dataset_dir`、`output_dir` 传给训练引擎。
|
||
|
||
## 3. MinIO 部署
|
||
|
||
MinIO 独立部署在 Linux 存储服务器或专用存储节点:
|
||
|
||
```text
|
||
9000 S3 API
|
||
9001 MinIO Console(仅管理员网络开放)
|
||
```
|
||
|
||
建议创建 bucket:
|
||
|
||
```text
|
||
yg-ft-resources
|
||
```
|
||
|
||
对象前缀建议:
|
||
|
||
```text
|
||
models/{model_id}/versions/{version_id}/...
|
||
datasets/{dataset_id}/versions/{version_id}/...
|
||
outputs/{task_id}/...
|
||
evaluations/{task_id}/...
|
||
logs/{task_id}/...
|
||
```
|
||
|
||
MinIO 可以使用官方 Docker 镜像,不需要在 Linux 主机安装 MinIO 软件包。需要持久化挂载 MinIO 的数据目录。
|
||
|
||
## 4. 是否需要额外安装包
|
||
|
||
### MinIO 服务端
|
||
|
||
不需要安装额外系统包,使用 Docker 镜像即可:
|
||
|
||
```text
|
||
minio/minio
|
||
```
|
||
|
||
### Backend API
|
||
|
||
建议增加 Python SDK:
|
||
|
||
```text
|
||
minio>=7.2.0
|
||
```
|
||
|
||
Backend 用 SDK 生成预签名上传、下载 URL,并负责 bucket、对象元数据和权限控制。
|
||
|
||
### Compute API / Compute Agent
|
||
|
||
推荐第一版只使用现有 `httpx` 访问预签名 URL,不额外安装 MinIO SDK。流程是:
|
||
|
||
```text
|
||
Backend -> 返回预签名 URL
|
||
Compute Agent -> httpx 下载/上传
|
||
```
|
||
|
||
这样算力节点不需要 MinIO 客户端、AWS CLI 或 NFS 客户端。
|
||
|
||
如果后续需要 Agent 直接操作 bucket、列目录或分片上传,再增加:
|
||
|
||
```text
|
||
minio>=7.2.0
|
||
```
|
||
|
||
但不建议第一阶段让算力节点持有 MinIO 管理密钥。
|
||
|
||
## 5. 权限模型
|
||
|
||
继续沿用当前项目的:
|
||
|
||
- `projects`;
|
||
- `project_members`;
|
||
- `acls`。
|
||
|
||
MinIO 只负责对象访问凭证,Backend 负责业务授权:
|
||
|
||
1. 用户请求模型或数据集;
|
||
2. Backend 校验项目成员关系和资源 ACL;
|
||
3. 校验通过后生成短时预签名 URL;
|
||
4. Compute Agent 使用 URL 下载;
|
||
5. URL 过期后自动失效。
|
||
|
||
MinIO bucket 不直接向前端或普通算力节点开放长期 Access Key。
|
||
|
||
## 6. 本地缓存目录
|
||
|
||
Compute API 容器继续以 root 运行,本地缓存挂载到:
|
||
|
||
```text
|
||
/data/yg-ft/cache/models
|
||
/data/yg-ft/cache/datasets
|
||
/data/yg-ft/cache/adapters
|
||
/data/yg-ft/cache/outputs
|
||
```
|
||
|
||
每个缓存资源必须包含:
|
||
|
||
```text
|
||
resource_id
|
||
version_id
|
||
sha256
|
||
byte_size
|
||
last_used_at
|
||
status
|
||
```
|
||
|
||
缓存状态:
|
||
|
||
- `missing`:本地不存在;
|
||
- `downloading`:正在下载;
|
||
- `ready`:校验成功;
|
||
- `corrupted`:校验失败;
|
||
- `evicting`:正在清理。
|
||
|
||
任务只能使用 `ready` 状态的缓存。
|
||
|
||
## 7. 任务流程
|
||
|
||
### 7.1 训练
|
||
|
||
```text
|
||
校验项目/用户权限
|
||
-> 获取基座模型版本和数据集版本
|
||
-> 检查本地缓存
|
||
-> 缺失则下载并校验 SHA256
|
||
-> 启动 LLaMA-Factory
|
||
-> checkpoint 写入本地临时目录
|
||
-> 任务完成后上传 outputs 到 MinIO
|
||
-> MinIO 上传完成并校验后更新数据库
|
||
```
|
||
|
||
### 7.2 推理
|
||
|
||
```text
|
||
校验模型权限
|
||
-> 下载或复用本地模型缓存
|
||
-> 使用本地模型路径加载
|
||
-> 推理服务只绑定当前节点缓存
|
||
```
|
||
|
||
### 7.3 权重合并
|
||
|
||
```text
|
||
下载 base model 和 adapter/checkpoint
|
||
-> 在指定节点执行 CPU 合并
|
||
-> 上传 merged model 到 MinIO
|
||
-> 数据库记录新的模型版本
|
||
```
|
||
|
||
### 7.4 NFS 故障规则对应关系
|
||
|
||
MinIO 不可达时,节点不再依赖本地残留文件直接启动新任务:
|
||
|
||
- 已有完整缓存且资源版本仍有效:允许继续执行当前任务;
|
||
- 新任务无法确认资源版本:等待 MinIO 恢复;
|
||
- 等待超过配置窗口:任务失败;
|
||
- 产物无法上传:任务不得标记为最终成功,进入 `storage_error`。
|
||
|
||
如果严格执行“共享存储故障时节点不能正常工作”,则即使本地缓存完整,也应禁止启动新任务。建议当前项目采用这一严格规则。
|
||
|
||
## 8. 数据库建议
|
||
|
||
现有 `resource_replicas` 可扩展为缓存索引,建议增加:
|
||
|
||
```text
|
||
storage_backend -- minio
|
||
storage_bucket
|
||
storage_object_key
|
||
version_id
|
||
cache_path
|
||
cache_status
|
||
last_used_at
|
||
download_progress
|
||
```
|
||
|
||
`resource_sync_jobs` 可继续用于下载和上传任务,但建议增加方向字段:
|
||
|
||
```text
|
||
direction -- download / upload
|
||
```
|
||
|
||
模型、数据集、checkpoint 和评测结果均使用 `resource_id + version_id`,不再把节点本地路径作为唯一资源标识。
|
||
|
||
## 9. 开发计划
|
||
|
||
### 阶段一:MinIO 服务和配置
|
||
|
||
- 增加 `docker/minio/docker-compose.yml`;
|
||
- 配置 MinIO endpoint、bucket、Access Key 和 Secret Key;
|
||
- 增加 Backend `minio` 依赖;
|
||
- 增加 MinIO 健康检查;
|
||
- 创建统一 bucket 和对象前缀规则。
|
||
|
||
### 阶段二:Backend 资源服务
|
||
|
||
- 实现对象上传、下载、删除和 HEAD 校验;
|
||
- 生成短时预签名 URL;
|
||
- 接入项目成员和 ACL 校验;
|
||
- 建立资源版本、SHA256 和大小记录;
|
||
- 上传成功后再更新数据库资源状态。
|
||
|
||
### 阶段三:Compute Agent 缓存服务
|
||
|
||
- 增加缓存目录管理器;
|
||
- 实现预签名 URL 下载;
|
||
- 支持临时文件下载和原子改名;
|
||
- 实现 SHA256 校验、失败重试和断点续传;
|
||
- 增加缓存状态查询和清理接口。
|
||
|
||
### 阶段四:接入业务任务
|
||
|
||
- 训练前准备基座模型和数据集;
|
||
- 推理前准备模型和 adapter;
|
||
- 权重合并前准备 base model 和 checkpoint;
|
||
- 评测前准备模型和数据集;
|
||
- 训练产物、合并模型和评测结果上传 MinIO;
|
||
- MinIO 故障时统一等待并超时失败。
|
||
|
||
### 阶段五:前端和管理员功能
|
||
|
||
- 显示资源版本和对象存储状态;
|
||
- 显示节点缓存状态;
|
||
- 支持手动预热模型;
|
||
- 支持缓存清理;
|
||
- 显示下载、上传和校验失败原因。
|
||
|
||
### 阶段六:测试和切换
|
||
|
||
- 单节点下载和缓存复用测试;
|
||
- 多节点同时下载同一模型测试;
|
||
- MinIO 重启和网络中断测试;
|
||
- SHA256 损坏文件测试;
|
||
- 训练、推理、权重合并全流程测试;
|
||
- 关闭旧的逐节点上传逻辑。
|
||
|
||
## 10. 预计工作量
|
||
|
||
```text
|
||
MinIO 部署和配置 1~2 人日
|
||
Backend 对象存储服务 4~7 人日
|
||
Compute Agent 缓存 6~10 人日
|
||
训练/推理/合并/评测接入 8~15 人日
|
||
权限、数据库和前端 5~10 人日
|
||
故障和回归测试 5~8 人日
|
||
总计 29~52 人日
|
||
```
|
||
|
||
## 11. 推荐结论
|
||
|
||
当前项目建议采用 MinIO + HTTP 预签名 URL + Compute Agent 本地缓存:
|
||
|
||
- MinIO 服务端使用 Docker,不安装主机软件包;
|
||
- Backend 增加 `minio` Python SDK;
|
||
- Compute Agent 第一阶段继续使用现有 `httpx`,不增加 MinIO SDK;
|
||
- 算力节点不安装 NFS 客户端;
|
||
- Compute API 继续以 root 运行;
|
||
- 训练、推理和权重合并继续使用本地路径,改造风险低于直接让训练框架读取对象存储。
|