# 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 运行；
- 训练、推理和权重合并继续使用本地路径，改造风险低于直接让训练框架读取对象存储。
