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