- 后端新增 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>
7.6 KiB
MinIO + Compute Agent 本地缓存方案与开发计划
1. 方案结论
本方案用 MinIO 作为模型、数据集、checkpoint、评测结果和训练产物的唯一正式存储,算力节点不挂载 NFS,也不要求安装 NFS 客户端。
算力节点只保留任务运行所需的本地缓存:
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 存储服务器或专用存储节点:
9000 S3 API
9001 MinIO Console(仅管理员网络开放)
建议创建 bucket:
yg-ft-resources
对象前缀建议:
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 镜像即可:
minio/minio
Backend API
建议增加 Python SDK:
minio>=7.2.0
Backend 用 SDK 生成预签名上传、下载 URL,并负责 bucket、对象元数据和权限控制。
Compute API / Compute Agent
推荐第一版只使用现有 httpx 访问预签名 URL,不额外安装 MinIO SDK。流程是:
Backend -> 返回预签名 URL
Compute Agent -> httpx 下载/上传
这样算力节点不需要 MinIO 客户端、AWS CLI 或 NFS 客户端。
如果后续需要 Agent 直接操作 bucket、列目录或分片上传,再增加:
minio>=7.2.0
但不建议第一阶段让算力节点持有 MinIO 管理密钥。
5. 权限模型
继续沿用当前项目的:
projects;project_members;acls。
MinIO 只负责对象访问凭证,Backend 负责业务授权:
- 用户请求模型或数据集;
- Backend 校验项目成员关系和资源 ACL;
- 校验通过后生成短时预签名 URL;
- Compute Agent 使用 URL 下载;
- URL 过期后自动失效。
MinIO bucket 不直接向前端或普通算力节点开放长期 Access Key。
6. 本地缓存目录
Compute API 容器继续以 root 运行,本地缓存挂载到:
/data/yg-ft/cache/models
/data/yg-ft/cache/datasets
/data/yg-ft/cache/adapters
/data/yg-ft/cache/outputs
每个缓存资源必须包含:
resource_id
version_id
sha256
byte_size
last_used_at
status
缓存状态:
missing:本地不存在;downloading:正在下载;ready:校验成功;corrupted:校验失败;evicting:正在清理。
任务只能使用 ready 状态的缓存。
7. 任务流程
7.1 训练
校验项目/用户权限
-> 获取基座模型版本和数据集版本
-> 检查本地缓存
-> 缺失则下载并校验 SHA256
-> 启动 LLaMA-Factory
-> checkpoint 写入本地临时目录
-> 任务完成后上传 outputs 到 MinIO
-> MinIO 上传完成并校验后更新数据库
7.2 推理
校验模型权限
-> 下载或复用本地模型缓存
-> 使用本地模型路径加载
-> 推理服务只绑定当前节点缓存
7.3 权重合并
下载 base model 和 adapter/checkpoint
-> 在指定节点执行 CPU 合并
-> 上传 merged model 到 MinIO
-> 数据库记录新的模型版本
7.4 NFS 故障规则对应关系
MinIO 不可达时,节点不再依赖本地残留文件直接启动新任务:
- 已有完整缓存且资源版本仍有效:允许继续执行当前任务;
- 新任务无法确认资源版本:等待 MinIO 恢复;
- 等待超过配置窗口:任务失败;
- 产物无法上传:任务不得标记为最终成功,进入
storage_error。
如果严格执行“共享存储故障时节点不能正常工作”,则即使本地缓存完整,也应禁止启动新任务。建议当前项目采用这一严格规则。
8. 数据库建议
现有 resource_replicas 可扩展为缓存索引,建议增加:
storage_backend -- minio
storage_bucket
storage_object_key
version_id
cache_path
cache_status
last_used_at
download_progress
resource_sync_jobs 可继续用于下载和上传任务,但建议增加方向字段:
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. 预计工作量
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 增加
minioPython SDK; - Compute Agent 第一阶段继续使用现有
httpx,不增加 MinIO SDK; - 算力节点不安装 NFS 客户端;
- Compute API 继续以 root 运行;
- 训练、推理和权重合并继续使用本地路径,改造风险低于直接让训练框架读取对象存储。