# 模型运行配置与部署说明

## 1. 适用范围

模型运行配置用于管理五类算法能力的实际推理端点和运行资源：

- 可见光目标检测 `vision-detector`
- 场景语义分割 `vision-segmenter`
- 栅格变化检测 `change-detector`
- 点云形变分析 `pointcloud-analyzer`
- 红外温度分析 `thermal-analyzer`

模型版本、制品、参数方案和测试记录仍由模型治理模块维护；运行配置负责将已经登记的模型版本绑定到实际部署端点。同一模型组可以同时保留本地调试、开发、预发布和生产配置，但任意时刻只有一个配置生效。

## 2. 运行架构

```text
业务分析任务 / 模型测试任务
          |
          v
Spring Boot 模型运行路由
          |
          +-- 读取当前模型组的生效配置
          +-- 固化模型版本、参数和部署编号
          +-- 按配置调用推理或测试接口
          |
          v
FastAPI 视觉服务 / 空间分析服务 / 兼容统一契约的外部服务
          |
          +-- 按 model_group + model_version 选择注册制品
          +-- ONNX Runtime CPU/GPU、Open3D 或其他兼容运行时
          v
结构化推理结果、运行快照和业务告警
```

运行配置保存在 `model_runtime_deployments` 表中。切换操作在数据库事务内完成，使用模型组级唯一索引保证不会出现两个同时生效的配置。每次创建、修改、切换和删除都会写入 `model_audit_logs`。

## 3. 页面操作

进入“算法资产 -> 模型管理”，打开任一模型组并选择“运行配置”。

### 3.1 配置内容

| 配置域 | 主要字段 | 用途 |
| --- | --- | --- |
| 基础信息 | 名称、模型版本、环境、制品地址 | 明确配置身份和实际版本 |
| 服务接口 | 根地址、健康、运行时、生产推理、模型测试路径 | 对接本地容器、服务器服务或独立算法集群 |
| 运行资源 | 引擎、执行提供程序、设备、精度、副本、并发、超时、批量 | 描述并约束运行资源 |
| 切换策略 | 期望运行档案、允许基线降级 | 防止本地与生产端点误切换 |
| 安全引用 | 认证密钥引用 | 保存 Vault 或 Kubernetes Secret 名称，不保存明文密钥 |

### 3.2 连接检查与运行检查

“检查连接”只访问配置中的健康接口，用于确认服务地址、端口、网络和进程状态。连接结果单独记录为“已连接”“不可连接”或“待检查”，不会因为模型制品缺失而把网络连接判定为失败。

“运行检查”在连接成功后继续依次验证：

1. 服务根地址和健康接口可访问。
2. 运行时清单接口可访问。
3. 返回的 `profile` 与期望运行档案一致。
4. 运行时已注册当前模型组和模型版本。
5. 当前模型制品已经安装。

运行就绪状态含义：

| 状态 | 含义 | 是否允许切换 |
| --- | --- | --- |
| `healthy` | 服务、档案、版本和制品均正常 | 允许 |
| `degraded` | 服务可用，但制品缺失或运行时清单不完整；页面显示具体缺失路径 | 本地允许降级或管理员明确强制时允许 |
| `unreachable` | 健康接口无法访问 | 禁止 |
| `incompatible` | 运行档案、模型组或版本不匹配 | 禁止 |
| `unknown` | 尚未检查或配置刚被修改 | 检查后再切换 |

### 3.3 切换与回退

选择目标配置并点击“切换”。平台会重新执行健康检查，检查通过后停用原配置并激活目标配置。后续新建的分析和模型测试任务立即使用新的端点与版本，已经开始的推理请求不被中断。

回退使用相同操作：对原配置执行检查并重新切换。生效配置不可编辑或删除，避免绕过健康检查修改生产路由。

## 4. 统一服务契约

自建算法服务或独立推理集群接入页面配置时，应提供以下 HTTP 接口：

| 接口 | 默认路径 | 要求 |
| --- | --- | --- |
| 健康检查 | `/health` | HTTP 2xx |
| 运行时清单 | `/api/v1/runtime` | 返回档案、执行提供程序和模型列表 |
| 视觉生产推理 | `/api/v1/inference/detect` | 接受资源、场景、模型组和版本 |
| 视觉模型测试 | `/api/v1/inference/test` | 接受模型版本、参数和测试资源 |
| 空间生产分析 | `/api/v1/pointcloud/analyze` | 接受点云或双时相资源 |
| 空间模型测试 | `/api/v1/pointcloud/test` | 接受模型版本、参数和测试资源 |

运行时清单中的模型至少包含：

```json
{
  "profile": "server-gpu",
  "execution_provider": "CUDAExecutionProvider",
  "models": [
    {
      "model_group": "vision-detector",
      "model_version": "v1.0.0",
      "artifact_installed": true,
      "loaded": false,
      "runtime": "onnxruntime-gpu",
      "precision": "FP16"
    }
  ]
}
```

## 5. 本地调试

本地模式使用 CPU、单并发、按需加载和基线降级，适合页面开发、接口联调和单样本验证。

```powershell
.\scripts\start_cpu_stack.cmd
```

访问地址：

- 平台：<http://localhost:8088>
- 模型管理：<http://localhost:8088/algorithm-assets/models>
- 系统运维：<http://localhost:8088/operations>

数据库迁移会为五类模型创建“本地 CPU 调试”和“服务器生产”配置，本地配置默认生效。没有铁路专用 ONNX 制品时，页面会显示降级可用，结果中保留 `execution_mode=baseline` 和降级原因。

安装本地模型：

```powershell
powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\scripts\setup_cpu_models.ps1 `
  -ModelGroup vision-detector `
  -ModelPath C:\models\rail-detector.onnx `
  -LabelsPath C:\models\rail-labels.txt `
  -Restart
```

红外分析由主检测模型和 PatchCore 辅助模型组成，必须同时安装：

```powershell
powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\scripts\setup_cpu_models.ps1 `
  -ModelGroup thermal-analyzer `
  -ModelPath C:\models\thermal-detector.onnx `
  -SecondaryModelPath C:\models\thermal-patchcore.onnx `
  -LabelsPath C:\models\thermal-labels.txt `
  -Restart
```

页面“运行检查”返回的 `/models/...` 是容器内路径，本地对应项目目录 `runtime/models/...`。模型文件安装完成后应重启 `vision-inference` 或 `pointcloud-analysis`，随后重新执行运行检查。

本地前端独立调试可以使用 Vite，API 由 `vite.config.ts` 代理到后端：

```powershell
cd frontend
npm run dev
```

## 6. 服务器生产部署

### 6.1 环境要求

- Linux x86_64 服务器
- Docker Engine 与 Docker Compose v2
- NVIDIA 驱动和 NVIDIA Container Toolkit
- 能够执行 `nvidia-smi`
- 建议视觉服务可用显存 16 GB 以上，空间服务内存 24 GB 以上
- 模型目录使用独立数据盘并只读挂载到推理容器

### 6.2 准备环境变量

```powershell
Copy-Item .\infra\.env.server.example .\infra\.env.server
```

必须替换 PostgreSQL 和 MinIO 密码。`.env.server` 已加入 `.gitignore`，不得提交真实凭据。

### 6.3 安装版本化模型

```powershell
powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\scripts\setup_server_model.ps1 `
  -ModelGroup vision-detector `
  -ModelVersion v1.0.0 `
  -ModelPath D:\rail-models\detector-v100.onnx `
  -LabelsPath D:\rail-models\detector-labels.txt
```

红外组合模型同时提供 `-SecondaryModelPath`。点云 Open3D 几何管线不需要模型文件。服务器模型默认写入 `runtime/server-models/<模型组>/<版本>/`，目录受 `.gitignore` 保护。

Linux 服务器使用：

```bash
sh scripts/setup_server_model.sh vision-detector v1.0.0 \
  /data/source/detector-v100.onnx /data/source/detector-labels.txt
```

模型注册定义位于：

- 本地：`infra/model-registry/cpu-models.json`
- 服务器：`infra/model-registry/server-models.json`

新增版本时应同时登记平台模型版本和服务器注册表，模型组与版本必须完全一致。

### 6.4 启动

```powershell
.\scripts\start_server_stack.cmd
```

Linux 服务器使用：

```bash
sh scripts/start_server_stack.sh
```

首次构建使用 `docker.m.daocloud.io` 获取 NVIDIA CUDA 基础镜像，Python 依赖通过阿里云 PyPI 镜像安装。已经完成镜像构建时使用：

```powershell
.\scripts\start_server_stack.cmd -NoBuild
```

所有生产制品都已经安装时，可以在启动后自动健康检查并激活五个服务器配置：

```powershell
.\scripts\start_server_stack.cmd -NoBuild -ActivateServerProfiles
```

对应的 Linux 命令为 `sh scripts/start_server_stack.sh --no-build --activate-server-profiles`。

也可以在页面逐个检查并切换，便于分阶段上线。

### 6.5 生产配置特点

`infra/docker-compose.server.yml` 在基础编排之上启用：

- CUDA 12.4 与 cuDNN 运行镜像
- ONNX Runtime GPU 和 `CUDAExecutionProvider`
- 视觉与空间服务多进程运行
- 多模型常驻、并发推理和更大的资源上限
- GPU 设备透传和共享内存配置
- 服务自动重启
- 后端模型测试并行资源池
- 版本化模型目录只读挂载

点云配准和几何差分仍使用 Open3D CPU 管线；变化检测的 ONNX 部分使用 GPU。需要进一步水平扩展时，应在 Kubernetes 或负载均衡器后部署多个兼容统一契约的推理实例，并在页面中将服务根地址指向内部服务地址。

## 7. 接口清单

| 方法 | 路径 | 用途 |
| --- | --- | --- |
| GET | `/api/v1/models/{modelGroupId}/runtime-deployments` | 查询模型组运行配置 |
| POST | `/api/v1/models/{modelGroupId}/runtime-deployments` | 新增配置 |
| PUT | `/api/v1/model-runtime-deployments/{id}` | 修改未生效配置 |
| DELETE | `/api/v1/model-runtime-deployments/{id}` | 删除未生效配置 |
| POST | `/api/v1/model-runtime-deployments/{id}/connectivity-check` | 仅检查服务网络与健康接口连通性 |
| POST | `/api/v1/model-runtime-deployments/{id}/health-check` | 执行健康与兼容性检查 |
| POST | `/api/v1/model-runtime-deployments/{id}/activate` | 原子切换运行配置 |
| GET | `/api/v1/model-runtime-deployments/active` | 查询五类模型当前路由 |
| GET | `/api/v1/model-artifacts/runtime-overview` | 查询制品库、安装和加载状态 |
| POST | `/api/v1/model-runtime-deployments/{id}/artifacts` | 上传主模型、辅助模型和标签文件 |
| POST | `/api/v1/model-runtime-deployments/{id}/installations` | 创建制品安装任务 |
| POST | `/api/v1/model-artifact-installations/{id}/load` | 加载模型并重建推理会话 |
| POST | `/api/v1/model-artifact-installations/{id}/unload` | 释放模型运行时资源 |
| GET | `/api/v1/model-artifact-installations/{id}/uninstall-impact` | 检查卸载阻断引用 |
| DELETE | `/api/v1/model-artifact-installations/{id}` | 创建安全卸载任务 |
| GET | `/api/v1/model-artifact-jobs/{id}` | 查询任务阶段、进度和错误 |
| GET | `/api/v1/model-artifact-jobs/{id}/events` | 订阅任务 SSE 事件 |

## 8. 发布检查

生产切换前至少确认：

1. 制品 SHA-256 与发布记录一致。
2. 标签顺序、输入尺寸、归一化和后处理参数与训练导出一致。
3. 目标端点返回 `server-gpu` 档案和正确模型版本。
4. 页面健康状态为“健康”。
5. 模型测试工作台中的固定回归样本集通过验收规则。
6. 推理结果保存部署编号、模型版本和参数快照。
7. 原生产配置仍保留，可在异常时直接切回。
8. Prometheus 已采集服务健康、请求时延和错误率。

## 9. 安全与运维约束

- 页面只保存密钥引用，不保存 Token、密码或私钥明文。
- 服务地址仅允许 HTTP/HTTPS，禁止携带账号信息或路径穿越片段。
- 生产推理端点应部署在内网，并通过网关、NetworkPolicy 或防火墙限制访问。
- 数据库、Redis、Kafka 和 MinIO 端口不应直接暴露到公网。
- 模型目录使用只读挂载，制品变更通过安装脚本或制品发布流水线完成。
- 生产环境禁止允许基线降级，模型制品未就绪时不得切换。
- 配置变更、健康检查、切换和回退应纳入发布审批与审计流程。

## 10. 页面安装与卸载

模型制品页面安装、加载、释放、卸载、回收、权限审批和失败回滚的完整设计见 [模型制品页面安装与卸载功能设计](./model-artifact-installation-uninstallation-design.md)。

该功能采用制品库、异步任务和安装代理架构。浏览器与平台后端不直接修改推理容器目录；生产推理容器继续只读挂载模型目录，由安装代理执行受控写入和原子发布。

### 10.1 页面操作流程

1. 进入“系统运维 > 服务状态”，模型运行时默认显示当前生效的五个模型组；切换“全部环境”可维护未生效的服务器配置。
2. 点击“上传”，为普通视觉模型选择主 ONNX 和标签文件；红外模型还必须选择 PatchCore 辅助 ONNX。
3. 点击“安装”，生产环境填写审批单号，按需选择安装后立即加载。
4. 安装进度窗口显示排队、下载、校验、发布、加载和健康检查事件。关闭页面后可通过当前任务按钮恢复查看。
5. “释放”只清理运行时内存或显存，会保留已安装文件；“加载”会重新创建 ONNX Runtime 会话。
6. “卸载”先检查生效配置、运行中测试和发布记录。存在引用时禁止执行；通过检查后释放会话并删除安装目录中的受管文件，MinIO 原件仍保留。

### 10.2 本地与服务器部署

本地 CPU 启动命令不变：

```powershell
.\scripts\start_cpu_stack.cmd
```

该命令同时启动 `artifact-installer`。推理容器以只读方式挂载 `runtime/models`，安装代理以读写方式挂载同一目录。安装代理只在 Compose 内部网络开放 `8103`，不映射到主机端口；后端通过服务名访问。

服务器部署前必须在 `infra/.env.server` 设置：

```dotenv
ARTIFACT_INSTALLER_TOKEN=<至少 32 字节的随机值>
ARTIFACT_INSTALLER_MEMORY_LIMIT=4g
```

Compose 对缺失的 `ARTIFACT_INSTALLER_TOKEN` 直接拒绝启动。服务器模型目录由 `MODEL_ROOT` 指定，只有安装代理拥有写权限，视觉与空间推理容器保持只读。MinIO 使用独立桶 `rail-model-artifacts` 保存原始制品，安装目录仅保存通过摘要和 ONNX 可加载性校验的发布副本。

### 10.3 故障处理

- 上传失败：文件不会登记为可安装状态，可修正文件后重新上传。
- 摘要或 ONNX 校验失败：安装任务标记失败，正式运行目录不变，任务详情保留根因。
- 发布阶段失败：安装代理从同任务备份目录恢复旧文件。
- 加载失败：制品保留为已安装状态，可修复运行参数后重新加载。
- 安装代理不可用：页面显示明确告警并禁用安装按钮，服务连接检查仍可独立使用。
