# 模型微调平台后期部署方案

本文档对应页面/功能模块：系统设置、算力资源、训练任务、任务详情、模型管理、数据集管理、审批中心、审计中心、运维监控。

## 1. 部署目标

平台需要支持单机多 GPU 训练、本地磁盘文件存储、LLaMA-Factory 训练框架，并预留未来接入其他训练平台的能力。部署设计需要把“应用平台”和“算力平台”边界明确拆开：

- 应用平台：面向用户、权限、项目、模型、数据集、审批、审计、任务编排和 API。
- 算力平台：面向 GPU、训练进程、训练框架、本地工作目录、训练日志和产物。
- 训练框架：当前固定 LLaMA-Factory，后续通过 Engine Adapter 标准接入其他框架。

结论：算力平台和训练框架应该部署在 GPU 算力服务器上。原因是训练框架需要直接访问 GPU、CUDA、驱动、模型权重、本地数据集切片、训练工作目录和训练进程。应用平台可以与算力平台同机部署，也可以独立部署，但不建议在无 GPU 的应用服务器上直接运行 LLaMA-Factory。

## 2. 服务清单

| 服务 | 部署位置 | 职责 |
| --- | --- | --- |
| Nginx | 应用服务器或算力服务器 | 前端静态资源、反向代理、TLS 终止 |
| Frontend | Nginx 静态目录 | 平台控制台 |
| Backend API | 应用服务器 | FastAPI 接口、鉴权、元数据、审批、审计、任务编排 |
| Backend Worker | 应用服务器 | 异步任务、状态同步、通知、审计归档 |
| PostgreSQL | 应用服务器或独立数据库服务器 | 业务元数据、权限、审批、审计 |
| Redis | 应用服务器或独立缓存服务器 | 队列、锁、短期状态、幂等控制 |
| Compute API | GPU 算力服务器 | 只对应用平台开放的内部算力接口 |
| Compute Agent | GPU 算力服务器 | GPU 发现、资源锁定、训练进程管理 |
| File Gateway | GPU 算力服务器 | 本地文件上传、下载、离线导入、产物访问 |
| LLaMA-Factory | GPU 算力服务器 | 实际训练、评测、合并、导出 |
| 日志采集 Agent | 两侧服务器 | 采集应用日志、训练日志、系统日志 |

## 3. 目录与存储规划

建议生产环境把文件、日志、数据库数据分盘挂载：

```text
/opt/yg-ft/
  app/                         # 应用服务代码
  compute/                     # 算力服务代码
  config/                      # 环境配置和服务配置
  logs/
    backend/                   # 后端 JSON Lines 日志
    compute/                   # 算力服务日志
    training/                  # 训练过程日志
  data/
    datasets/                  # 数据集文件
    models/                    # 基座模型、微调模型、导出模型
    jobs/                      # 训练任务工作目录
    artifacts/                 # 评测报告、adapter、checkpoint、导出包
```

本地文件存储建议按租户、项目、资源类型分区：

```text
/data/yg-ft/
  tenants/{tenant_id}/
    projects/{project_id}/
      datasets/{dataset_id}/
      models/{model_id}/
      jobs/{job_id}/
```

## 4. 方案一：所有服务部署在算力服务器

### 4.1 适用场景

- 开发联调、单机试运行、资源受限的早期上线环境。
- 小团队共用一台单机多 GPU 服务器。
- 网络隔离要求不高，部署资源有限。

### 4.2 拓扑

```mermaid
flowchart LR
  U["用户浏览器"] --> N["Nginx/Frontend"]
  N --> B["Backend API"]
  B --> DB["PostgreSQL"]
  B --> R["Redis"]
  B --> C["Compute API"]
  C --> A["Compute Agent"]
  A --> L["LLaMA-Factory"]
  A --> G["GPU/CUDA"]
  A --> FS["本地磁盘文件存储"]
```

### 4.3 部署方式

同一台 GPU 服务器部署：

- `frontend` 构建后由 Nginx 托管。
- `backend-api` 使用 Uvicorn/Gunicorn 或容器运行。
- `backend-worker` 独立进程运行。
- `postgres` 和 `redis` 可使用 Docker Compose 或系统服务。
- `compute-api`、`compute-agent`、`file-gateway` 与 LLaMA-Factory 在同机运行。
- 训练产物、数据集、模型和日志都放在本地数据盘。

### 4.4 优点

- 部署简单，路径共享容易。
- 上传数据、训练读取、产物归档都在本机完成，I/O 链路短。
- 适合快速验证平台功能。

### 4.5 风险

- 应用服务、数据库、训练任务抢占同一台服务器资源。
- GPU 训练高负载可能影响 API 响应。
- 数据库与文件存储容灾能力弱。
- 安全边界不清晰，企业生产不推荐长期使用。

### 4.6 端口建议

| 服务 | 端口 | 暴露范围 |
| --- | --- | --- |
| Nginx | 80/443 | 用户网段 |
| Backend API | 17861 | 仅 Nginx、本机 |
| Compute API | 19100 | 仅 Backend API、本机 |
| File Gateway | 19101 | 仅 Backend API、本机 |
| PostgreSQL | 15432 | 本机或内网 |
| Redis | 16379 | 本机或内网 |

## 5. 方案二：应用服务与算力/训练服务独立部署

### 5.1 适用场景

- 企业生产环境。
- 有独立应用服务器、数据库服务器和 GPU 算力服务器。
- 需要清晰网络边界、权限边界和运维职责。
- 未来可能扩展多台 GPU 服务器或多种训练框架。

### 5.2 拓扑

```mermaid
flowchart LR
  U["用户浏览器"] --> N["应用区 Nginx/Frontend"]
  N --> B["应用区 Backend API"]
  B --> DB["PostgreSQL"]
  B --> R["Redis"]
  B -- "内部 HTTPS/mTLS + 服务 Token" --> C["算力区 Compute API"]
  C --> A["Compute Agent"]
  A --> L["LLaMA-Factory"]
  A --> G["GPU/CUDA"]
  A --> FS["算力服务器本地磁盘"]
  B -- "定时轮询任务状态/指标/产物索引" --> C
```

### 5.3 部署边界

应用服务器部署：

- Nginx。
- Frontend。
- Backend API。
- Backend Worker。
- PostgreSQL 或数据库连接。
- Redis 或队列连接。
- 审批、审计、系统配置、用户中心等应用能力。

GPU 算力服务器部署：

- Compute API。
- Compute Agent。
- File Gateway。
- LLaMA-Factory。
- CUDA、NVIDIA Driver、NCCL、PyTorch、训练依赖。
- 本地训练工作目录、模型目录、数据集缓存、产物目录。

### 5.4 互通方式

应用平台调用算力平台：

- 协议：内部 HTTPS REST，后续可扩展 gRPC。
- 鉴权：服务间 Token，生产建议 mTLS + IP 白名单。
- 幂等：训练任务提交使用 `Idempotency-Key` 或 `job_id`。
- 状态同步：默认由应用平台定时轮询 Compute API，拉取任务状态、指标摘要和产物索引。
- 回调策略：第一阶段关闭算力侧回调，避免算力服务器访问应用服务器，减少双向网络策略开通。

文件互通：

- 小文件：前端上传到 Backend API，再由 Backend API 转发或同步到 File Gateway。
- 大文件：Backend API 创建上传会话，前端通过受控地址分片上传到 File Gateway。
- 离线数据：管理员把数据放到算力服务器指定目录，应用平台登记离线导入任务。
- 产物下载：应用平台校验权限后，向 File Gateway 申请短期下载地址。

状态互通：

- Backend API 是业务状态的最终来源。
- Compute Agent 是训练进程状态的事实来源。
- Worker 定时对账，把 `queued/running/succeeded/failed/cancelled` 等状态同步回业务库。

### 5.5 优点

- 应用服务稳定性不受 GPU 训练高负载直接影响。
- 数据库和审计能力更适合纳入企业基础设施。
- 算力节点可以逐步扩展，不影响前端和应用后端。
- 安全边界更清晰，便于设置防火墙、堡垒机、服务账号和审计策略。

### 5.6 风险

- 文件传输链路比单机部署复杂。
- 需要处理跨服务器网络失败、轮询延迟、任务状态对账。
- 需要明确模型、数据集、产物在应用侧和算力侧的索引关系。

### 5.7 多算力节点部署约定

多算力节点阶段仍然按“单机多 GPU 节点”部署，每台 GPU 服务器都是一个独立算力节点。每个参与调度的节点都必须部署：

- Compute API。
- Compute Agent。
- File Gateway。
- LLaMA-Factory 宿主机目录和训练依赖。
- CUDA、NVIDIA Driver、NCCL、PyTorch。
- 本地数据盘 `/data/yg-ft`。
- 本地日志和训练产物目录。

网络策略保持单向：

```text
应用服务器 -> 算力节点 A Compute API/File Gateway
应用服务器 -> 算力节点 B Compute API/File Gateway
应用服务器 -> 算力节点 C Compute API/File Gateway
```

默认不要求：

```text
算力节点 -> 应用服务器
算力节点 A -> 算力节点 B
```

多节点任务调度由应用平台统一完成。应用平台从 `compute_nodes` 读取节点地址、权重、标签、启用状态、维护状态和健康检查结果；从 `resource_replicas` 判断目标节点是否已有所需数据集/模型副本；缺失时创建 `resource_sync_jobs`，通过目标节点 File Gateway 同步资源。

当前实现已支持在 `/compute` 算力节点页面新增和编辑节点。运维人员维护 `Compute API` 地址、`File Gateway` 地址、权重、标签、启用状态、最大并发和本地路径后，点击连接测试会由应用后端主动访问目标节点健康检查和 GPU 清单接口，并将 `health_detail`、`gpu_count`、`gpu_devices/gpus` 同步到 PostgreSQL。真实 GPU 服务器优先通过 `nvidia-smi` 发现 GPU；特殊环境可用 `COMPUTE_GPU_COUNT` 等环境变量声明兼容清单。

训练运行闭环：

- 前端启动训练后，Backend API 按 `compute_nodes` 的启用状态、调度状态、权重和并行任务数选择节点。
- Backend API 向目标节点 `POST /modelTF/compute/jobs` 提交 LLaMA-Factory 训练作业，并在 `fine_tune_tasks.compute_job_id` 记录算力任务 ID。
- Compute API 在真实模式下启动 `llamafactory-cli train` 子进程，训练日志写入 `TRAINING_LOG_ROOT/{job_id}.log`。
- Backend API 启动后会运行应用侧轮询 worker，按 `COMPUTE_POLL_INTERVAL_SECONDS` 主动查询目标节点 `GET /modelTF/compute/jobs/{id}`，同步任务状态、进度、PID、输出目录、日志路径和产物索引。
- 停止训练时，Backend API 优先调用目标节点 `POST /modelTF/compute/jobs/{id}/stop`，再回写应用任务状态。
- 失败或停止任务可以通过 `POST /modelTF/compute/jobs/{id}/retry` 重试；重试会清空旧运行态，重新调度节点并创建 Compute Job。
- 训练日志通过 `GET /modelTF/compute/jobs/{id}/logs` 读取，支持 `tail_lines`、`offset`、`limit`，用于训练详情页、训练日志页和日志平台采集。
- Compute API 使用 `COMPUTE_SERVICE_TOKEN` 做服务间鉴权，应用侧请求携带 `X-Compute-Token`；健康检查接口保持可公开探活。
- Compute API 会把本机训练作业登记到 `TRAINING_LOG_ROOT/compute-jobs.json`，服务重启后可恢复任务索引并继续暴露状态和日志。

调度策略：

- 默认自动调度，按节点健康、标签、GPU 空闲、队列长度、节点权重和资源副本命中率排序。
- 支持管理员/高级用户手动指定节点或 GPU。
- `disabled` 节点不参与调度。
- `draining` 节点不接收新任务，但允许已有任务跑完。
- `maintenance/offline` 节点只允许查看和清理，不允许提交训练任务。

## 6. Compute API 接入标准

为预留其他训练平台，应用平台只依赖统一算力接口，不直接依赖 LLaMA-Factory 命令。

训练引擎适配器应提供：

- `validate_config(config)`：校验训练参数和模板。
- `build_command(job)`：生成训练命令或执行计划。
- `start(job)`：启动训练进程。
- `stop(job_id)`：停止训练进程。
- `status(job_id)`：查询训练状态。
- `collect_metrics(job_id)`：采集 loss、learning rate、epoch、step 等指标。
- `collect_artifacts(job_id)`：登记 checkpoint、adapter、导出模型、评测报告。
- `parse_log(line)`：解析训练日志。

第一版适配器：

```text
compute/engines/llama_factory/
```

后续其他框架：

```text
compute/engines/xtuner/
compute/engines/deepspeed_custom/
compute/engines/openrlhf/
```

## 7. 环境变量建议

应用平台：

```env
APP_ENV=prod
MODELTF_ROUTE_PREFIX=/modelTF
DATABASE_URL=postgresql+psycopg://yg_ft:***@postgres:5432/yg_ft
REDIS_URL=redis://redis:6379/0
LOG_DIR=/opt/yg-ft/logs/backend
COMPUTE_API_BASE_URL=https://compute.internal:19100
COMPUTE_SERVICE_TOKEN=***
FILE_GATEWAY_BASE_URL=https://compute.internal:19101
COMPUTE_STATUS_SYNC_MODE=polling
COMPUTE_POLL_INTERVAL_SECONDS=3
COMPUTE_POLL_BATCH_SIZE=100
```

算力平台：

```env
COMPUTE_ENV=prod
COMPUTE_HOST_ID=gpu-node-01
COMPUTE_API_PORT=19100
FILE_GATEWAY_PORT=19101
COMPUTE_AUTH_ENABLED=true
COMPUTE_SERVICE_TOKEN=***
ENABLE_APP_CALLBACK=false
LLAMA_FACTORY_HOME=/app/LLaMA-Factory
YG_FT_DATA_ROOT=/data/yg-ft
YG_FT_DATA_ROOT_HOST=./data/yg-ft
YG_FT_MODEL_ROOT=/data/yg-ft/models
YG_FT_MODEL_ROOT_HOST=./data/yg-ft/models
YG_FT_DATASET_ROOT=/data/yg-ft/datasets
YG_FT_DATASET_ROOT_HOST=./data/yg-ft/datasets
YG_FT_OUTPUT_ROOT=/data/yg-ft/outputs
YG_FT_OUTPUT_ROOT_HOST=./data/yg-ft/outputs
TRAINING_LOG_ROOT=/opt/yg-ft/logs/training
TRAINING_LOG_ROOT_HOST=./data/yg-ft/logs/training
COMPUTE_LOG_ROOT_HOST=./data/yg-ft/logs/compute
LOG_DIR=/opt/yg-ft/logs/compute
CUDA_VISIBLE_DEVICES=0,1,2,3
```

## 8. 日志与监控

应用平台：

- 采集 `backend-YYYY-MM-DD.log` 和 `error-YYYY-MM-DD.log`。
- 按 `request_id`、`tenant_id`、`project_id`、`job_id` 检索。
- ERROR 日志触发告警。

算力平台：

- 采集 Compute API 日志、Agent 日志、训练原始日志。
- 训练日志需要按 `job_id` 独立归档。
- 关键指标包括 GPU 利用率、显存、磁盘容量、训练队列长度、失败率。

## 9. 安全要求

- Compute API 不对公网开放。
- 应用平台和算力平台之间使用服务账号鉴权，生产建议 mTLS。
- File Gateway 下载地址必须短期有效，并绑定租户、项目、资源权限。
- 日志不得输出密码、Token、密钥、数据集原文敏感内容。
- 审计日志留存周期按租户或企业配置执行，应用日志短期留存，长期归档交给日志平台。

## 10. 部署检查清单

- PostgreSQL 已初始化当前运行脚本 `backend/app/db/sql/001_platform_runtime.sql`；`docs/postgres-schema.sql` 作为目标架构设计，后续通过迁移体系逐步收敛。
- Redis 可连通。
- 后端 `GET /modelTF/health` 正常。
- Compute API 健康检查正常。
- Compute Agent 能识别 GPU、显存、CUDA 版本。
- LLaMA-Factory 能在命令行完成最小训练作业。
- 应用平台能提交训练任务到 Compute API。
- 任务状态能从算力平台同步回应用平台。
- 数据集上传、离线导入、产物下载路径权限正确。
- 后端 JSON 日志可被日志平台解析。
- ERROR 日志能触发告警。
- 日志、数据集、模型、产物所在磁盘容量有监控和告警。

## 11. Docker Compose 文件规划

当前项目按应用服务器和算力服务器拆分了两套 Docker 部署文件，均采用代码外挂方式运行：

```text
docker/
  app/
    Dockerfile.backend       # Backend API 运行时镜像，代码通过 volume 挂载到 /app
    Dockerfile.frontend      # Nginx 前端运行时镜像，frontend/dist 通过 volume 挂载
    docker-compose.yml       # 应用服务器：frontend、backend-api、postgres、redis
    .env.example
  compute/
    Dockerfile.compute       # CUDA + Python + Compute API 运行时镜像
    docker-compose.yml       # 算力服务器：compute-api，预留 agent/file gateway 拆分
    .env.example
```

项目根目录不再保留 `Dockerfile` 和 `docker-compose.yml`，避免与拆分部署入口混淆。

应用服务器启动：

```bash
cd docker/app
cp .env.example .env
docker compose up -d
```

算力服务器启动：

```bash
cd docker/compute
cp .env.example .env
docker compose up -d
```

应用服务器与算力服务器独立部署时，需要在 `docker/app/.env` 中配置：

```env
COMPUTE_API_BASE_URL=http://<compute-server-ip>:19100
FILE_GATEWAY_BASE_URL=http://<compute-server-ip>:19101
COMPUTE_SERVICE_TOKEN=change_me
```

这些地址在当前 Docker 阶段通过环境变量动态配置。后续多算力节点阶段建议升级为数据库配置，由应用平台从 `compute_nodes` 表读取节点地址、权重、标签、健康状态和启用状态，并在“算力节点管理”页面维护。

多节点后，每台算力服务器各自进入 `docker/compute` 启动一套算力服务，并在应用平台中登记为一条 `compute_nodes` 记录：

```text
gpu-node-01 -> http://10.10.20.31:19100 / http://10.10.20.31:19101
gpu-node-02 -> http://10.10.20.32:19100 / http://10.10.20.32:19101
gpu-node-03 -> http://10.10.20.33:19100 / http://10.10.20.33:19101
```

算力服务器需要在 `docker/compute/.env` 中配置：

```env
ENABLE_APP_CALLBACK=false
COMPUTE_SERVICE_TOKEN=change_me
YG_FT_DATA_ROOT_HOST=./data/yg-ft
```

## 12. 仍需确认的问题

- 生产环境是否已有统一 ELK/OpenSearch、Filebeat/Vector 标准配置。
- PostgreSQL/Redis 开发阶段采用项目自带部署；生产阶段是否切换企业统一基础设施，以及对应 SLA 仍需确认。
- 是否需要 PostgreSQL 主备、备份恢复、审计日志长期归档的明确 SLA。
- 大文件上传是否需要断点续传、限速、病毒扫描或 DLP 检测。
- 应用服务器与算力服务器默认只开通应用侧主动访问算力侧；如后续需要实时回调，再单独评估双向网络策略。
- 多算力节点已按单机多 GPU 节点扩展设计；仍需确认是否需要节点组、租户绑定节点、同步限速和资源副本清理审批。
