diff --git a/README.md b/README.md index 5d0b07c..5987b6a 100644 --- a/README.md +++ b/README.md @@ -1,279 +1,59 @@ # YG_FT 模型微调平台 -YG_FT 是一个面向企业治理场景的模型微调平台,覆盖用户中心、多租户、项目隔离、数据集管理、模型管理、训练任务、评测、推理、审批流、审计留存、算力调度和训练引擎适配。 +YG_FT 是面向多用户、多租户和多算力节点的模型训练与推理平台,提供数据集、模型、训练、权重合并、推理、评测、算力节点、项目隔离、权限和审计能力。 -当前前端已有基础页面,后端与算力平台已按多人协作开发方式建立工程骨架,并开始实现正式系统主链路能力。当前代码和 SQL 均作为后续生产演进基线维护,不再以一次性演示或静态 Mock 为开发准则。 - -## 总体架构 +## 架构 ```text -YG_FT/ - frontend/ # 前端控制台 - backend/ # FastAPI 应用平台后端 - app/ - api/v1/ # 对前端暴露的 REST API - core/ # 配置、日志、中间件、权限等基础能力 - db/ # 数据库连接、迁移、事务工具 - modules/ # 业务模块目录 - schemas/ # Pydantic 入参/出参模型 - services/ # 跨模块应用服务 - workers/ # 后台任务入口 - requirements.txt # 后端 Python 第三方依赖 - compute/ # 算力平台与训练框架适配层 - api/ # 内部 Compute API - agent/ # 单机多 GPU 调度与进程管理 - engines/llama_factory/ # LLaMA-Factory 适配器 - file_gateway/ # 本地文件上传、下载、导入、产物管理 - docs/ # 需求、接口、数据库、开发计划和部署文档 - docker/ # 容器化配置 +浏览器 -> Frontend Nginx:16801 -> Backend API:17861 + |-> PostgreSQL(元数据、权限、审计、任务状态) + |-> Redis(缓存及任务辅助状态) + |-> MinIO:19000(模型和数据唯一对象源) + |-> Compute API:19100 + |-> Compute Agent/GPU/LLaMA-Factory + `-> File Gateway:19101 ``` -## 平台分层 +Backend、MinIO 和 Compute 节点可以部署在不同服务器,不依赖跨服务器 Docker 网络,通过 IP、DNS 或负载均衡地址通信。Compute 节点只保存按需准备的本地缓存,MinIO 是模型、数据集、权重、评测报告和训练产物的唯一数据源。 -| 层级 | 职责 | 主要目录 | -| --- | --- | --- | -| 前端控制台 | 用户操作入口、任务看板、项目/模型/数据集/训练/审批/审计页面 | `frontend/` | -| 应用平台后端 | 用户中心、多租户、RBAC/ABAC、项目隔离、元数据、审批流、审计、API 编排 | `backend/` | -| 算力平台 | GPU 发现、资源锁定、训练进程管理、日志采集、产物归档、任务状态同步 | `compute/` | -| 训练引擎 | 当前固定接入 LLaMA-Factory,预留其他训练平台适配标准 | `compute/engines/` | -| 数据层 | PostgreSQL、Redis、本地文件存储、日志归档 | `docs/postgres-schema.sql` | +## 目录 -## 当前开发基线 +| 目录 | 作用 | +| --- | --- | +| `frontend/` | Vue 3、TypeScript、Element Plus 控制台 | +| `backend/app/api/v1/` | 平台 REST API | +| `backend/app/core/` | 配置、认证、权限和日志 | +| `backend/app/db/` | PostgreSQL 访问和初始化 SQL | +| `backend/app/modules/` | 系统、资源、审批、数据处理和存储模块 | +| `backend/app/workers/` | 节点轮询、任务对账和资源同步 | +| `compute/` | Compute API、Agent、GPU 和训练引擎 | +| `docker/` | 应用、MinIO、算力服务部署文件 | +| `docs/` | 架构、权限、部署和测试文档 | -- 使用 FastAPI 提供统一 API 响应结构 `{ code, message, data }`。 -- 本地运行阶段统一使用 PostgreSQL,后端启动时会在 PG 中初始化当前运行表和系统内置账号;模型、数据集、算力节点、GPU、微调任务等业务数据必须通过页面、接口或正式导入流程产生。 -- 支持登录、模型管理、数据集管理、微调任务创建/启动/停止/进度轮询。 -- 支持训练日志、loss 指标、checkpoint 和训练产物接口;真实训练执行器接入前,联调状态机必须通过显式环境变量开启。 -- 支持多算力节点、GPU、任务队列、资源副本和资源同步状态接口。 -- 前端新增 `/compute` 算力节点页面,展示节点地址、权重、标签、启用状态、GPU、队列和资源副本。 -- `compute/engines/llama_factory/adapter.py` 提供 LLaMA-Factory 参数校验、命令生成和日志解析基础能力。 +## 端口 -## 前后端一键启动 +| 服务 | 主机端口 | 容器端口 | +| --- | ---: | ---: | +| Frontend | 16801 | 80 | +| Backend API | 17861 | 8000 | +| Redis | 16379 | 6379 | +| MinIO API/Console | 19000/19001 | 9000/9001 | +| Compute API/File Gateway | 19100/19101 | 9100 | -首次使用前请确保前端依赖已安装、PostgreSQL 已可用。之后在项目根目录执行: +## 启动 ```bash -bash ./start.sh -``` - -脚本会自动补装后端 `requirements.txt`,然后同时启动前端 `http://localhost:16801` 和后端 -`http://127.0.0.1:17861`,按 `Ctrl+C` 会同时停止两个服务。脚本不会自动安装 -前端依赖,也不会启动 PostgreSQL、Redis 或算力服务。 - -仅检查依赖和端口而不启动服务: - -```bash -bash ./start.sh --check -``` - -本地启动推荐只配置数据库主机。脚本会复用 `docker/app/.env` 中已有的 -`POSTGRES_USER`、`POSTGRES_PASSWORD` 和 `POSTGRES_DB`,端口默认使用 -PostgreSQL 标准端口 `5432`: - -```bash -DATABASE_HOST='www.caoxiaozhu.com' bash ./start.sh -``` - -也可以在 `docker/app/.env` 中增加: - -```env -DATABASE_HOST=www.caoxiaozhu.com -``` - -需要使用非标准端口时再设置 `DATABASE_PORT`。`DATABASE_URL` 仍可作为完整连接串 -高级覆盖项;终端环境变量优先级最高。脚本不会输出数据库密码。 - -## 后端启动 - -```bash -cd backend -python -m venv .venv -.venv\Scripts\activate -pip install -r requirements.txt -uvicorn app.main:app --reload --port 17861 -``` - -默认接口前缀为 `/modelTF`,例如: - -```text -GET /modelTF/health -POST /modelTF/login -GET /modelTF/model-manage -GET /modelTF/dataset-manage -GET /modelTF/fine-tune -GET /modelTF/compute/nodes -GET /modelTF/data-convert -``` - -### 数据库配置 - -后端通过 `backend/.env` 文件配置数据库连接(自动加载,`override=True`): - -```env -DATABASE_URL=postgresql+psycopg://用户:密码@数据库地址:端口/库名 -COMPUTE_SERVICE_TOKEN=change_me -``` - -支持远程数据库。连接池参数已针对远程库优化(`connect_timeout=30`、`max_size=20`、`max_waiting=50`)。 - -### 环境变量 - -| 变量 | 默认值 | 说明 | -|---|---|---| -| `DATABASE_URL` | `postgresql+psycopg://yg_ft:change_me@localhost:15432/yg_ft` | 数据库连接串 | -| `COMPUTE_SERVICE_TOKEN` | `""` | 算力服务认证 token,需与 compute 一致 | -| `COMPUTE_STATUS_SYNC_MODE` | `polling` | `off` 禁用轮询(远程库慢时推荐) | -| `COMPUTE_POLL_INTERVAL_SECONDS` | `3` | 轮询间隔秒数 | -| `COMPUTE_REQUEST_TIMEOUT_SECONDS` | `5` | 调 compute 的超时秒数 | - -### 推荐启动命令(远程数据库) - -```cmd -cd /d E:\yg_ft\backend -set COMPUTE_STATUS_SYNC_MODE=off -.\.venv\Scripts\python.exe -m uvicorn app.main:app --reload --port 17861 -``` - -开发阶段内置登录账号: - -| 角色 | 账号 | 密码 | 说明 | -| --- | --- | --- | --- | -| 超级管理员 | `admin` | `admin123` | 拥有当前全部页面权限 | -| 操作员 | `operator` | `operator123` | 拥有业务操作相关页面权限 | - -以上账号仅用于本地开发和联调。生产环境初始化后应立即修改密码,或改为企业统一身份认证/管理员初始化流程。 - -## 前端启动 - -```bash -cd frontend -npm install -npm run dev -``` - -前端开发服务默认运行在 `http://localhost:16801`,并通过 Vite proxy 将 `/modelTF` 转发到 `http://localhost:17861`。 - -## 算力服务启动 - -算力服务是一个 FastAPI 应用,同时承载 Compute API(模型训练/推理/GPU 管理)和 File Gateway(文件上传下载)路由。Docker 部署时对外暴露两个端口(19100 和 19101)均指向同一服务,方便应用平台分别配置 `api_base_url` 和 `file_gateway_url`。本地开发只需启动一个进程。 - -### 方式一:Docker 启动(推荐) - -**1. 构建镜像**(首次或依赖变更后): - -```cmd -cd /d E:\yg_ft +cd frontend && npm ci && npm run build && cd .. +docker build -f docker/app/Dockerfile.backend -t yg-ft-backend-api:latest . +docker build -f docker/app/Dockerfile.frontend -t yg-ft-frontend-runtime:latest . docker build -f docker/compute/Dockerfile.compute -t yg-ft-compute-api:latest . +cd docker/minio && docker compose up -d +cd ../app && docker compose up -d +cd ../compute && docker compose up -d ``` -**2. 启动容器**: +## 权限与性能 -```cmd -cd docker/compute -cp .env.example .env -docker compose up -d -``` +系统使用角色权限、资源 ACL、用户/项目/租户归属联合校验;删除为软删除,关键操作写入审计。模型合并前准备 base model 和 adapter,结果归档 MinIO;推理前按选择节点准备缓存。远程 PostgreSQL 延迟会影响全量列表和看板,页面慢时应检查浏览器 Network、Nginx、Backend 日志、连接池和节点可达性。 -**3. 验证**: - -```cmd -curl http://localhost:19100/health -``` - -> 注意:构建上下文必须是项目根目录 `E:\yg_ft`(`docker build` 最后的 `.`),因为 Dockerfile 需要 `COPY compute/requirements.txt`。 - -### 方式二:本地开发启动 - -**Windows (cmd):** - -```cmd -cd /d E:\yg_ft\compute -set PYTHONPATH=E:\yg_ft -.\.venv\Scripts\python.exe -m uvicorn api.main:app --reload --host 0.0.0.0 --port 19100 -``` - -> `PYTHONPATH=E:\yg_ft` 是必需的,因为代码使用 `from compute.agent...` 绝对导入。 -> `--host 0.0.0.0` 让其他机器可以通过 IP 访问(算力节点测试需要)。 - -**Linux / macOS:** - -```bash -cd compute -PYTHONPATH=.. uvicorn api.main:app --reload --host 0.0.0.0 --port 19100 -``` - -### 算力节点配置 - -在平台的「算力节点」页面新增节点,填入: -- **Compute API**:`http://你的IP:19100` -- **File Gateway**:`http://你的IP:19101` - -本机测试用 `http://localhost:19100`。 - -### 环境变量说明 - -| 变量 | 默认值 | 说明 | -|---|---|---| -| `COMPUTE_MODE` | `real` | `real` / `simulator`,仅隔离联调用 simulator | -| `COMPUTE_EXECUTION_MODE` | `real` | 训练执行模式 | -| `COMPUTE_SERVICE_TOKEN` | `change_me` | 服务间认证 token,需与 backend 一致 | -| `COMPUTE_AUTH_ENABLED` | `true` | 是否开启 token 认证 | -| `MODELTF_ROUTE_PREFIX` | `/modelTF` | API 路由前缀 | - -应用平台通过数据库 `compute_nodes` 表中的 `api_base_url` 和 `file_gateway_url` 主动轮询算力节点状态。 - -## 日志 - -后端日志模块位于 `backend/app/core/logging.py`,说明文档见: - -- `docs/backend-logging.md` - -默认输出: - -```text -logs/backend-YYYY-MM-DD.log -logs/error-YYYY-MM-DD.log -``` - -日志格式为 JSON Lines,单个文件不超过 20MB,只保留最近 10 天。 - -## 主要文档 - -- `docs/platform-architecture-requirements.md`:平台需求、功能模块、页面补全建议。 -- `docs/menu-functional-requirements.md`:当前菜单、二级路由、规划菜单、功能需求、接口和数据库映射。 -- `docs/backend-api-design.md`:FastAPI 接口分组、参数定义、权限说明。 -- `docs/postgres-schema.sql`:PostgreSQL 数据库脚本,包含权限、用户中心、多租户、审批、审计等模型。 -- `docs/system-development-plan.md`:多人协作开发计划,按前端、后端、DB、部署拆分。 -- `docs/team-development-plan.md`:3-4 人并行开发分工计划,按人员边界标注页面、接口、数据库和交付节奏。 -- `docs/first-version-development-plan.md`:当前系统主链路开发计划,覆盖前端、后端、DB、Compute API、GPU 和 LLaMA-Factory 适配。 -- `docs/backend-logging.md`:后端日志模块使用说明。 -- `docs/deployment-plan.md`:后期部署方案,覆盖单机算力服务器部署与应用/算力分离部署。 -- `docker/README.md`:Docker 部署入口,包含应用服务器和算力服务器两套 Compose 使用方式。 - -## Docker 部署入口 - -应用服务器: - -```bash -cd docker/app -cp .env.example .env -docker compose up -d -``` - -算力服务器: - -```bash -cd docker/compute -cp .env.example .env -docker compose up -d -``` - -两套 Compose 均采用代码外挂方式运行,镜像只包含运行时环境和第三方依赖。项目根目录不再保留 `Dockerfile` 和 `docker-compose.yml`,部署时统一进入 `docker/app` 或 `docker/compute` 目录执行。 - -## 后续开发原则 - -- 接口实现优先遵循 `docs/backend-api-design.md`。 -- 数据库实现优先遵循 `docs/postgres-schema.sql`,后续通过 Alembic 迁移管理变更。 -- 前端页面与后端接口、数据库表之间的映射以文档中的“对应页面/功能模块”为准。 -- 训练引擎适配必须通过 `compute/engines/` 下的标准接口,不在应用平台后端直接拼接训练命令。 -- 敏感信息不得写入日志,生产环境密钥通过环境变量或密钥管理系统注入。 +详细部署见 `docker/README.md`,测试见 `测试用例.md`,本次快照见 `docs/20260812/`。 diff --git a/docker/README.md b/docker/README.md index 355cc46..130f3f9 100644 --- a/docker/README.md +++ b/docker/README.md @@ -1,313 +1,58 @@ # Docker 部署说明 -## 跨服务器部署 +## 部署边界 -MinIO、Backend API 和 Compute API 使用各自服务器上的独立 Docker 网络,不能使用跨服务器的容器名称互访。当前 WSL 联调地址为 `172.25.179.69`: +生产规划分为应用服务器、存储服务器和算力服务器。应用服务器运行 Frontend Nginx、Backend API、Redis;存储服务器运行 MinIO;算力服务器运行 Compute API、Compute Agent、GPU 和训练引擎。三类服务器不共享 Docker 网络,通过可路由地址通信。 + +当前 WSL 联调地址为 `172.25.179.69`,拆分部署时必须替换为真实服务器地址。 + +## 配置 + +应用服务器 `docker/app/.env`: ```env -# docker/app/.env MINIO_ENABLED=true MINIO_ENDPOINT=http://172.25.179.69:19000 COMPUTE_API_BASE_URL=http://172.25.179.69:19100 FILE_GATEWAY_BASE_URL=http://172.25.179.69:19101 -``` - -拆分到不同服务器后,将 `172.25.179.69` 替换为对应服务器 IP。MinIO 容器内部仍使用 `9000/9001`,对外使用 `19000/19001`;Backend 和 Compute API 通过外部 IP 访问 MinIO,不加入 MinIO 的 Docker 网络。 - -本目录按应用服务器和算力服务器拆分 Dockerfile 与 Docker Compose 文件。Compose 文件不包含 `build:`,不会在 `docker compose up` 时自动构建业务镜像。所有业务镜像需要先通过手动 `docker build` 构建,再由 Compose 启动。 - -## 基础镜像 - -| 镜像 | 用途 | -| --- | --- | -| `python:3.12-slim` | 应用后端基础镜像,后端运行环境要求 Python 3.12 及以上 | -| `nginx:1.27-alpine` | 前端静态资源与 `/modelTF` 反向代理运行镜像 | -| `hiyouga/llamafactory:latest` | 算力服务基础镜像,基于 LLaMA-Factory 官方镜像扩展 Compute API | -| `postgres:16-alpine` | 开发阶段内置 PostgreSQL | -| `redis:7-alpine` | 开发阶段内置 Redis | - -一键拉取基础镜像: - -```bash -docker pull python:3.12-slim && \ -docker pull nginx:1.27-alpine && \ -docker pull hiyouga/llamafactory:latest && \ -docker pull postgres:16-alpine && \ -docker pull redis:7-alpine -``` - -Windows PowerShell: - -```powershell -$images = @( - "python:3.12-slim", - "nginx:1.27-alpine", - "hiyouga/llamafactory:latest", - "postgres:16-alpine", - "redis:7-alpine" -) -$images | ForEach-Object { docker pull $_ } -``` - -如果部署环境不能访问外网,需要提前在可联网环境执行上述拉取命令,再用 `docker save` / `docker load` 导出导入。 - -## 业务镜像 - -| 镜像 | Dockerfile | 构建命令 | -| --- | --- | --- | -| `yg-ft-backend-api:latest` | `docker/app/Dockerfile.backend` | `docker build -f docker/app/Dockerfile.backend -t yg-ft-backend-api:latest .` | -| `yg-ft-frontend-runtime:latest` | `docker/app/Dockerfile.frontend` | `docker build -f docker/app/Dockerfile.frontend -t yg-ft-frontend-runtime:latest .` | -| `yg-ft-compute-api:latest` | `docker/compute/Dockerfile.compute` | `docker build -f docker/compute/Dockerfile.compute -t yg-ft-compute-api:latest .` | - -## 对外端口 - -所有宿主机对外端口统一使用 5 位端口。容器内部端口保持镜像默认端口,便于容器内服务和健康检查稳定。 - -| 服务 | 宿主机对外端口 | 容器内部端口 | 说明 | -| --- | --- | --- | --- | -| 前端 Nginx | `16801` | `80` | 前端页面入口 | -| 后端 API | `17861` | `8000` | FastAPI 服务 | -| PostgreSQL | `15432` | `5432` | 开发阶段内置数据库 | -| Redis | `16379` | `6379` | 开发阶段内置缓存 | -| Compute API | `19100` | `9100` | 算力服务器 API | -| File Gateway | `19101` | `9100` | 当前由 Compute API 暴露文件网关契约,后续可拆为独立服务 | - -注意:`8000` 是后端容器内部端口,不作为宿主机对外访问端口。宿主机或浏览器应访问 `http://:17861/modelTF/health`;前端 Nginx 容器在 Docker 网络内部访问 `http://backend-api:8000/modelTF/...`。 - -对应配置文件: - -- `docker/app/.env.example` - - `FRONTEND_PORT=16801` - - `BACKEND_API_PORT=17861` - - `POSTGRES_PORT=15432` - - `REDIS_PORT=16379` -- `docker/compute/.env.example` - - `COMPUTE_API_PORT=19100` - - `FILE_GATEWAY_PORT=19101` - -## 运行模式 - -- 应用侧默认 `COMPUTE_MODE=real`,任务状态必须由真实算力同步逻辑更新。 -- 算力侧默认 `COMPUTE_EXECUTION_MODE=real`,真实执行器未完成前不会伪造训练作业。 -- 仅隔离联调时可显式设置 `COMPUTE_MODE=simulator` 或 `COMPUTE_EXECUTION_MODE=simulator`,该模式不得用于测试环境、生产环境或生产升级基线。 - -## 应用服务器部署 - -应用服务器包含前端 Nginx、Backend API、PostgreSQL、Redis。 - -当前 Compose 内置 PostgreSQL 使用 `backend/app/db/sql/001_platform_runtime.sql` 初始化运行库。`docs/postgres-schema.sql` 是完整目标架构设计,不应直接挂载为当前运行库初始化脚本,否则会与当前后端代码的运行表结构不兼容。 - -首次部署: - -```bash -cd - -# 1. 使用当前 Windows/宿主机 npm 构建前端静态产物 -cd frontend -npm ci -npm run build -cd .. - -# 2. 手动构建业务镜像 -docker build -f docker/app/Dockerfile.backend -t yg-ft-backend-api:latest . -docker build -f docker/app/Dockerfile.frontend -t yg-ft-frontend-runtime:latest . - -# 3. 启动应用服务 -cd docker/app -cp .env.example .env -docker compose up -d -``` - -后端镜像构建过程中会执行依赖导入自检,确认 `fastapi`、`uvicorn`、`psycopg`、`sqlalchemy`、`redis` 等运行依赖已安装。构建后也可以手动检查: - -```bash -docker run --rm yg-ft-backend-api:latest python -c "import psycopg; print(psycopg.__version__)" -``` - -默认访问地址: - -```text -http://:16801 -``` - -应用侧代码和数据外挂: - -```text -../../backend -> /app -../../frontend/dist -> /usr/share/nginx/html -../../runtime/app/logs/backend -> /opt/yg-ft/logs/backend -../../runtime/app/data -> /data/yg-ft -``` - -前端容器启动前必须确保 `../../frontend/dist/index.html` 已存在。若前端 Nginx 日志出现 `directory index of "/usr/share/nginx/html/" is forbidden` 或 `rewrite or internal redirection cycle while internally redirecting to "/index.html"`,通常表示当前执行 `docker compose` 的项目目录下没有构建好的 `frontend/dist`,或挂载路径不是同一份代码目录。 - -```bash -# 在执行 docker compose 的同一份代码目录中检查 -cd /frontend -npm run build -test -f dist/index.html && ls -lh dist/index.html - -cd ../docker/app -docker compose up -d --force-recreate frontend -docker compose logs --tail=80 frontend -``` - -如果使用 Windows npm 构建、WSL 中运行 Docker Compose,需要确认 Windows 路径和 WSL 路径指向同一份仓库。例如在 `D:\...\YG_FT\frontend` 构建不会自动生成 `/mnt/d/wuyongtao/Code/YG_FT/frontend/dist` 下的产物,除非二者本就是同一个目录。 - -如果使用企业统一 PostgreSQL/Redis,修改 `docker/app/.env`: - -如果前端 Nginx 日志出现 `open() "/usr/share/nginx/html/modelTF/login" failed` 或 `open() "/usr/share/nginx/html/login" failed`,说明当前容器没有加载项目的 Nginx 代理配置,`/modelTF/*` 被当成静态文件查找。处理方式: - -```bash -cd /docker/app -docker compose up -d --force-recreate frontend -docker compose exec frontend nginx -T | grep -n "location.*modelTF" -A12 -``` - -正常配置中应存在 `location ^~ /modelTF/`,并代理到 `BACKEND_PROXY_PASS`,默认是 `http://backend-api:8000`。 - -```env -DATABASE_URL=postgresql+psycopg://:@:15432/ -REDIS_URL=redis://:16379/0 -USE_BUILTIN_POSTGRES=false -USE_BUILTIN_REDIS=false -``` - -生产环境如完全使用外部基础设施,可以删除或注释 Compose 中的 `postgres`、`redis` 服务及 `backend-api.depends_on` 中对应依赖。 - -## 算力服务器部署 - -算力服务器包含 Compute API、后续 Compute Agent、File Gateway、GPU runtime、本地训练数据目录和 LLaMA-Factory。`Dockerfile.compute` 基于 LLaMA-Factory 官方镜像: - -```dockerfile -FROM hiyouga/llamafactory:latest -``` - -部署前需要安装: - -- NVIDIA Driver -- NVIDIA Container Toolkit -- Docker Engine 和 Docker Compose Plugin -- 本地训练数据目录,默认 `/data/yg-ft` - -首次部署: - -```bash -cd - -# 手动构建算力业务镜像 -docker build -f docker/compute/Dockerfile.compute -t yg-ft-compute-api:latest . - -# 启动算力服务 -cd docker/compute -cp .env.example .env -docker compose up -d -``` - -健康检查: - -```text -GET http://:19100/modelTF/health -GET http://:19100/modelTF/v1/compute/health -``` - -算力侧代码和数据外挂: - -```text -../../compute -> /app/compute -${YG_FT_DATA_ROOT_HOST} -> /data/yg-ft -${YG_FT_MODEL_ROOT_HOST} -> /data/yg-ft/models -${YG_FT_DATASET_ROOT_HOST} -> /data/yg-ft/datasets -${YG_FT_OUTPUT_ROOT_HOST} -> /data/yg-ft/outputs -${COMPUTE_LOG_ROOT_HOST} -> /opt/yg-ft/logs/compute -${TRAINING_LOG_ROOT_HOST} -> /opt/yg-ft/logs/training -``` - -算力服务器启动前必须先在宿主机创建持久化目录,基座模型、训练数据、训练产物和训练日志都应落在宿主机磁盘上,不能只写入容器层。推荐默认目录: - -```bash -cd /docker/compute -mkdir -p data/yg-ft/models \ - data/yg-ft/datasets \ - data/yg-ft/outputs \ - data/yg-ft/logs/compute \ - data/yg-ft/logs/training -``` - -默认 `docker/compute/.env.example` 使用 `./data/yg-ft`,该相对路径以 `docker/compute/docker-compose.yml` 所在目录为基准,因此实际宿主机目录是 `/docker/compute/data/yg-ft`。如企业环境模型盘、数据盘、产物盘分盘挂载,可在 `docker/compute/.env` 中分别调整 `YG_FT_MODEL_ROOT_HOST`、`YG_FT_DATASET_ROOT_HOST`、`YG_FT_OUTPUT_ROOT_HOST`、`COMPUTE_LOG_ROOT_HOST`、`TRAINING_LOG_ROOT_HOST`,容器内路径建议保持 `/data/yg-ft/models`、`/data/yg-ft/datasets`、`/data/yg-ft/outputs`,避免训练参数和节点配置复杂化。 - -页面上传数据集时,文件先进入 Backend API,再由 Backend API 调用目标算力节点的 `POST /modelTF/compute/files/upload`,写入容器内 `/data/yg-ft/datasets/{dataset_id}/`。在默认开发配置下,宿主机可在 `/docker/compute/data/yg-ft/datasets/{dataset_id}/` 看到对应文件。仅创建 bind mount 不会自动让应用侧上传文件出现在算力目录,必须通过这条 File Gateway 链路同步。 - -## 应用与算力分离部署 - -应用服务器只需要主动访问算力服务器,不要求算力服务器回调应用服务器。 - -在 `docker/app/.env` 中配置: - -```env -COMPUTE_API_BASE_URL=http://:19100 -FILE_GATEWAY_BASE_URL=http://:19101 -COMPUTE_SERVICE_TOKEN=change_me COMPUTE_STATUS_SYNC_MODE=polling COMPUTE_POLL_INTERVAL_SECONDS=3 -COMPUTE_POLL_BATCH_SIZE=100 ``` -交互链路: +MinIO 不需要额外安装 Python 包;Backend 的 MinIO 兼容访问依赖随 `backend/requirements.txt` 安装。生产环境应使用固定 DNS/IP、内网访问和防火墙白名单。 -```text -Frontend - -> Backend API - -> Compute API - -> Compute Agent / LLaMA-Factory - -> 本地数据目录 / 模型目录 / 训练产物 - <- Backend Worker 定时轮询 Compute API -``` - -算力服务默认开启服务间鉴权。`docker/compute/.env` 中保持 `COMPUTE_AUTH_ENABLED=true`,并确保 `COMPUTE_SERVICE_TOKEN` 与 `docker/app/.env` 一致;健康检查路径仍可用于容器探活。 - -## 多算力节点部署 - -多算力节点仍按“单机多 GPU 节点”部署。每台 GPU 服务器都独立部署一套 `docker/compute`: - -```text -gpu-node-01: docker/compute + /data/yg-ft + 19100/19101 -gpu-node-02: docker/compute + /data/yg-ft + 19100/19101 -gpu-node-03: docker/compute + /data/yg-ft + 19100/19101 -``` - -节点之间默认不互访。应用平台主动访问每个节点的 Compute API/File Gateway,并通过 `compute_nodes`、`resource_replicas`、`resource_sync_jobs` 统一调度和同步。 - -节点地址、权重、标签、启用状态和本地路径在前端“算力节点”页面动态维护。新增或编辑节点后,点击“测试”会由 Backend API 主动访问该节点的 `GET /modelTF/v1/compute/health` 和 `GET /modelTF/compute/resources/gpus`,并把健康信息与 GPU 清单同步到 PostgreSQL。 - -## 常用命令 - -重新构建应用镜像: +## 构建和启动 ```bash docker build -f docker/app/Dockerfile.backend -t yg-ft-backend-api:latest . docker build -f docker/app/Dockerfile.frontend -t yg-ft-frontend-runtime:latest . -``` - -重新构建算力镜像: - -```bash docker build -f docker/compute/Dockerfile.compute -t yg-ft-compute-api:latest . +cd docker/minio && docker compose up -d +cd ../app && docker compose up -d +cd ../compute && docker compose up -d ``` -启动服务: +验证命令:`docker compose ps`、`curl http://:17861/modelTF/health`、`curl http://:19100/modelTF/health`、`curl http://:19000/minio/health/live`。 -```bash -cd docker/app -docker compose up -d +## 端口 -cd ../compute -docker compose up -d -``` +| 服务 | 主机端口 | 容器端口 | +| --- | ---: | ---: | +| Frontend | 16801 | 80 | +| Backend API | 17861 | 8000 | +| Redis | 16379 | 6379 | +| MinIO API/Console | 19000/19001 | 9000/9001 | +| Compute API/File Gateway | 19100/19101 | 9100 | -查看服务: +## 数据和安全 -```bash -docker compose ps -docker compose logs -f -``` +算力主机应持久化 `/data/yg-ft/models`、`datasets`、`trained_models`、`outputs`、`cache` 以及训练日志目录。上述目录是 Compute Agent 的本地缓存和运行目录,权威对象必须归档 MinIO。 + +- Compute API 和 File Gateway 开启 token 认证。 +- MinIO 不直接暴露公网,使用内网或安全组限制访问。 +- 不在镜像和 Git 中提交数据库、Redis、MinIO 密码或服务 token。 +- 当前 Compute API 默认 root 仅适用于开发阶段,生产环境需评估非 root 和 GPU/挂载目录权限改造。 + +## 拆分验证 + +从 Backend 容器验证 MinIO 和每个 Compute API 的 health;上传数据集、训练、权重合并、推理和节点断网重试均需完成一次联调。 diff --git a/docs/20260812/README.md b/docs/20260812/README.md new file mode 100644 index 0000000..5987b6a --- /dev/null +++ b/docs/20260812/README.md @@ -0,0 +1,59 @@ +# YG_FT 模型微调平台 + +YG_FT 是面向多用户、多租户和多算力节点的模型训练与推理平台,提供数据集、模型、训练、权重合并、推理、评测、算力节点、项目隔离、权限和审计能力。 + +## 架构 + +```text +浏览器 -> Frontend Nginx:16801 -> Backend API:17861 + |-> PostgreSQL(元数据、权限、审计、任务状态) + |-> Redis(缓存及任务辅助状态) + |-> MinIO:19000(模型和数据唯一对象源) + |-> Compute API:19100 + |-> Compute Agent/GPU/LLaMA-Factory + `-> File Gateway:19101 +``` + +Backend、MinIO 和 Compute 节点可以部署在不同服务器,不依赖跨服务器 Docker 网络,通过 IP、DNS 或负载均衡地址通信。Compute 节点只保存按需准备的本地缓存,MinIO 是模型、数据集、权重、评测报告和训练产物的唯一数据源。 + +## 目录 + +| 目录 | 作用 | +| --- | --- | +| `frontend/` | Vue 3、TypeScript、Element Plus 控制台 | +| `backend/app/api/v1/` | 平台 REST API | +| `backend/app/core/` | 配置、认证、权限和日志 | +| `backend/app/db/` | PostgreSQL 访问和初始化 SQL | +| `backend/app/modules/` | 系统、资源、审批、数据处理和存储模块 | +| `backend/app/workers/` | 节点轮询、任务对账和资源同步 | +| `compute/` | Compute API、Agent、GPU 和训练引擎 | +| `docker/` | 应用、MinIO、算力服务部署文件 | +| `docs/` | 架构、权限、部署和测试文档 | + +## 端口 + +| 服务 | 主机端口 | 容器端口 | +| --- | ---: | ---: | +| Frontend | 16801 | 80 | +| Backend API | 17861 | 8000 | +| Redis | 16379 | 6379 | +| MinIO API/Console | 19000/19001 | 9000/9001 | +| Compute API/File Gateway | 19100/19101 | 9100 | + +## 启动 + +```bash +cd frontend && npm ci && npm run build && cd .. +docker build -f docker/app/Dockerfile.backend -t yg-ft-backend-api:latest . +docker build -f docker/app/Dockerfile.frontend -t yg-ft-frontend-runtime:latest . +docker build -f docker/compute/Dockerfile.compute -t yg-ft-compute-api:latest . +cd docker/minio && docker compose up -d +cd ../app && docker compose up -d +cd ../compute && docker compose up -d +``` + +## 权限与性能 + +系统使用角色权限、资源 ACL、用户/项目/租户归属联合校验;删除为软删除,关键操作写入审计。模型合并前准备 base model 和 adapter,结果归档 MinIO;推理前按选择节点准备缓存。远程 PostgreSQL 延迟会影响全量列表和看板,页面慢时应检查浏览器 Network、Nginx、Backend 日志、连接池和节点可达性。 + +详细部署见 `docker/README.md`,测试见 `测试用例.md`,本次快照见 `docs/20260812/`。 diff --git a/docs/20260812/docker-readme.md b/docs/20260812/docker-readme.md new file mode 100644 index 0000000..130f3f9 --- /dev/null +++ b/docs/20260812/docker-readme.md @@ -0,0 +1,58 @@ +# Docker 部署说明 + +## 部署边界 + +生产规划分为应用服务器、存储服务器和算力服务器。应用服务器运行 Frontend Nginx、Backend API、Redis;存储服务器运行 MinIO;算力服务器运行 Compute API、Compute Agent、GPU 和训练引擎。三类服务器不共享 Docker 网络,通过可路由地址通信。 + +当前 WSL 联调地址为 `172.25.179.69`,拆分部署时必须替换为真实服务器地址。 + +## 配置 + +应用服务器 `docker/app/.env`: + +```env +MINIO_ENABLED=true +MINIO_ENDPOINT=http://172.25.179.69:19000 +COMPUTE_API_BASE_URL=http://172.25.179.69:19100 +FILE_GATEWAY_BASE_URL=http://172.25.179.69:19101 +COMPUTE_STATUS_SYNC_MODE=polling +COMPUTE_POLL_INTERVAL_SECONDS=3 +``` + +MinIO 不需要额外安装 Python 包;Backend 的 MinIO 兼容访问依赖随 `backend/requirements.txt` 安装。生产环境应使用固定 DNS/IP、内网访问和防火墙白名单。 + +## 构建和启动 + +```bash +docker build -f docker/app/Dockerfile.backend -t yg-ft-backend-api:latest . +docker build -f docker/app/Dockerfile.frontend -t yg-ft-frontend-runtime:latest . +docker build -f docker/compute/Dockerfile.compute -t yg-ft-compute-api:latest . +cd docker/minio && docker compose up -d +cd ../app && docker compose up -d +cd ../compute && docker compose up -d +``` + +验证命令:`docker compose ps`、`curl http://:17861/modelTF/health`、`curl http://:19100/modelTF/health`、`curl http://:19000/minio/health/live`。 + +## 端口 + +| 服务 | 主机端口 | 容器端口 | +| --- | ---: | ---: | +| Frontend | 16801 | 80 | +| Backend API | 17861 | 8000 | +| Redis | 16379 | 6379 | +| MinIO API/Console | 19000/19001 | 9000/9001 | +| Compute API/File Gateway | 19100/19101 | 9100 | + +## 数据和安全 + +算力主机应持久化 `/data/yg-ft/models`、`datasets`、`trained_models`、`outputs`、`cache` 以及训练日志目录。上述目录是 Compute Agent 的本地缓存和运行目录,权威对象必须归档 MinIO。 + +- Compute API 和 File Gateway 开启 token 认证。 +- MinIO 不直接暴露公网,使用内网或安全组限制访问。 +- 不在镜像和 Git 中提交数据库、Redis、MinIO 密码或服务 token。 +- 当前 Compute API 默认 root 仅适用于开发阶段,生产环境需评估非 root 和 GPU/挂载目录权限改造。 + +## 拆分验证 + +从 Backend 容器验证 MinIO 和每个 Compute API 的 health;上传数据集、训练、权重合并、推理和节点断网重试均需完成一次联调。 diff --git a/docs/20260812/测试用例.md b/docs/20260812/测试用例.md new file mode 100644 index 0000000..8df82c4 --- /dev/null +++ b/docs/20260812/测试用例.md @@ -0,0 +1,99 @@ +# YG_FT 平台测试用例 + +## 测试范围 + +覆盖部署、登录会话、权限、租户与项目隔离、算力节点、GPU 分配、数据集、MinIO、训练、权重合并、模型推理、模型评测、审计、日志、异常重试和性能。 + +测试地址:前端 `http://localhost:16801`,Backend `http://localhost:17861/modelTF`,Compute `http://localhost:19100/modelTF`,File Gateway `http://localhost:19101/modelTF`,MinIO `http://localhost:19000`。 + +## 前置条件 + +1. 前端已执行 `npm run build`。 +2. Backend、Frontend、Redis、MinIO、Compute 容器均为 healthy。 +3. PostgreSQL 表结构与 `backend/app/db/sql/000_full_init.sql` 一致。 +4. 准备管理员、普通用户、不同项目和租户测试账号。 +5. 准备 JSON、JSONL、空文件和非法格式数据集。 +6. 准备 base model、adapter 和可推理模型。 + +## 用例 + +| 编号 | 场景 | 操作 | 预期 | +| --- | --- | --- | --- | +| DEP-001 | 容器启动 | 执行各 compose 的 `up -d` | 所有服务启动并 healthy | +| DEP-002 | Backend 健康 | 访问 `/health` | HTTP 200,依赖状态正常 | +| DEP-003 | Compute 健康 | 访问 Compute health | 返回节点服务正常 | +| DEP-004 | MinIO 健康 | 访问 `/minio/health/live` | 返回存活状态 | +| DEP-005 | 前端入口 | 打开 `:16801` | 无白屏、无外部 CDN 请求 | +| DEP-006 | 跨服务器 | 配置远程 MinIO/Compute 地址 | Backend 可访问远程服务 | +| AUTH-001 | 正常登录 | 输入正确账号密码 | 登录成功并保存 token | +| AUTH-002 | 错误密码 | 连续输入错误密码 | 返回 401,达到阈值后限流 | +| AUTH-003 | 过期会话 | 使用过期 token 请求接口 | 返回 401 并回登录页 | +| AUTH-004 | 退出登录 | 退出后再次请求业务接口 | token 失效 | +| AUTH-005 | 管理员 | 访问用户、节点、审计功能 | 可执行授权操作 | +| AUTH-006 | 普通用户 | 访问管理员功能 | 按钮隐藏,后端返回 403 | +| AUTH-007 | 项目隔离 | 用户 A 访问用户 B 项目 | 列表不显示,接口拒绝 | +| AUTH-008 | 租户隔离 | 租户 A 请求租户 B 数据 | 不返回跨租户数据 | +| AUTH-009 | ACL | 授予模型 read/execute | read 只能看,execute 才能运行 | +| AUTH-010 | 软删除 | 删除模型或数据集 | 列表隐藏,保留删除审计字段 | +| NODE-001 | 新增节点 | 填写 API、文件网关和标签 | 节点保存并显示 | +| NODE-002 | 节点测试 | 点击测试 | health/GPU 信息同步 | +| NODE-003 | 不可达节点 | 使用错误地址测试 | 快速失败并显示原因 | +| NODE-004 | 删除节点 | 点击删除 | 节点从可用列表消失 | +| NODE-005 | 多 GPU | 节点有多张卡 | 显示编号、显存和状态 | +| NODE-006 | 指定 GPU | 训练选择 GPU 0 | 只占用 GPU 0 | +| NODE-007 | GPU 冲突 | 两任务申请同卡 | 后者排队或拒绝,不抢占 | +| NODE-008 | 剩余 GPU | 节点有空闲卡 | 其他任务可继续选择该节点 | +| NODE-009 | 释放 GPU | 停止训练/卸载推理 | GPU 恢复可用 | +| DATA-001 | JSON 统计 | 上传 3 条 JSON 数据 | 列表和详情均为 3 条 | +| DATA-002 | JSONL 统计 | 上传 3 行 JSONL | 列表和详情均为 3 条 | +| DATA-003 | 非法文件 | 上传空或错误格式 | 返回明确错误 | +| DATA-004 | MinIO 归档 | 上传数据集 | 产生对象和 checksum | +| DATA-005 | 节点同步 | 选择算力节点上传 | 文件进入目标节点缓存 | +| DATA-006 | 同步断网 | 同步时阻断节点 | 进入重试或失败,不无限等待 | +| DATA-007 | 数据权限 | 用户查看数据集 | 只显示有权限的数据 | +| TRAIN-001 | 创建训练 | 选择项目、数据集、节点和 GPU | 任务关联完整 | +| TRAIN-002 | 启动训练 | 启动任务 | 进入 queued/running | +| TRAIN-003 | 日志轮询 | 打开训练日志 | 约 3 秒更新,不刷屏 | +| TRAIN-004 | 训练曲线 | 产生 loss/metric | 页面显示曲线 | +| TRAIN-005 | 停止训练 | 点击停止 | 进程停止且资源释放 | +| TRAIN-006 | 训练失败 | 模拟引擎失败 | 显示原因和日志 | +| MERGE-001 | 自动准备 | 执行权重合并 | 自动准备 base model/adapter | +| MERGE-002 | 节点一致 | 权重在训练节点 | 合并请求发往训练节点 | +| MERGE-003 | 合并归档 | 合并成功 | 结果上传 MinIO 并登记 | +| MERGE-004 | 合并权限 | 无 execute 用户操作 | 返回 403 | +| INF-001 | 列表加载 | 点击模型推理 | 列表快速显示,不长时间等待 | +| INF-002 | 指定节点 | 多节点时选择节点 B | 模型只在 B 加载 | +| INF-003 | 训练节点优先 | 未重新指定节点 | 优先使用训练节点 | +| INF-004 | 推理缓存 | 启动未缓存模型 | 从 MinIO 下载到目标节点 | +| INF-005 | 加载超时 | 模拟加载超过 15 分钟 | 失败并显示原因 | +| INF-006 | 对话推理 | 发送消息 | 返回推理结果 | +| INF-007 | 释放推理 | 点击释放 | 卸载模型并释放 GPU | +| INF-008 | 删除推理 | 删除任务记录 | 记录删除成功并释放资源 | +| EVAL-001 | 创建评测 | 选择模型、数据集、指标 | 任务创建成功 | +| EVAL-002 | 数据集权限 | 选择无权数据集 | 不出现在选择列表 | +| EVAL-003 | 指标保存 | 选择具体指标 | 结果不错误显示 custom | +| EVAL-004 | 评测报告 | 等待任务完成 | 返回非空报告和明细 | +| EVAL-005 | 页面轮询 | 打开评测页面 | 不刷屏,loading 可结束 | +| OPS-001 | 审计 | 登录、创建、删除、执行资源 | 记录 actor/action/resource/time | +| OPS-002 | 轮询日志 | 观察 Backend 日志 | 成功轮询不高频输出 INFO | +| OPS-003 | 错误日志 | 模拟依赖异常 | 保留 WARNING/ERROR 和 request_id | +| OPS-004 | 推理接口耗时 | 请求 `/model-compare` | 正常环境目标小于 1 秒 | +| OPS-005 | 看板耗时 | 请求 `/dashboard/stats` | 有短缓存且不无限等待 | +| OPS-006 | 并发访问 | 10 用户同时打开列表 | 无连接池耗尽和 5xx | +| OPS-007 | 数据库断开 | 临时阻断 PostgreSQL | 页面明确显示依赖异常 | + +## 回归命令 + +```bash +cd frontend +npm run build +cd .. +python -m compileall backend/app compute +git diff --check +docker compose -f docker/app/docker-compose.yml ps +docker compose -f docker/compute/docker-compose.yml ps +curl http://localhost:17861/modelTF/health +curl http://localhost:19100/modelTF/health +``` + +失败用例必须附接口响应、容器日志、request_id 和复现步骤。 diff --git a/测试用例.md b/测试用例.md new file mode 100644 index 0000000..8df82c4 --- /dev/null +++ b/测试用例.md @@ -0,0 +1,99 @@ +# YG_FT 平台测试用例 + +## 测试范围 + +覆盖部署、登录会话、权限、租户与项目隔离、算力节点、GPU 分配、数据集、MinIO、训练、权重合并、模型推理、模型评测、审计、日志、异常重试和性能。 + +测试地址:前端 `http://localhost:16801`,Backend `http://localhost:17861/modelTF`,Compute `http://localhost:19100/modelTF`,File Gateway `http://localhost:19101/modelTF`,MinIO `http://localhost:19000`。 + +## 前置条件 + +1. 前端已执行 `npm run build`。 +2. Backend、Frontend、Redis、MinIO、Compute 容器均为 healthy。 +3. PostgreSQL 表结构与 `backend/app/db/sql/000_full_init.sql` 一致。 +4. 准备管理员、普通用户、不同项目和租户测试账号。 +5. 准备 JSON、JSONL、空文件和非法格式数据集。 +6. 准备 base model、adapter 和可推理模型。 + +## 用例 + +| 编号 | 场景 | 操作 | 预期 | +| --- | --- | --- | --- | +| DEP-001 | 容器启动 | 执行各 compose 的 `up -d` | 所有服务启动并 healthy | +| DEP-002 | Backend 健康 | 访问 `/health` | HTTP 200,依赖状态正常 | +| DEP-003 | Compute 健康 | 访问 Compute health | 返回节点服务正常 | +| DEP-004 | MinIO 健康 | 访问 `/minio/health/live` | 返回存活状态 | +| DEP-005 | 前端入口 | 打开 `:16801` | 无白屏、无外部 CDN 请求 | +| DEP-006 | 跨服务器 | 配置远程 MinIO/Compute 地址 | Backend 可访问远程服务 | +| AUTH-001 | 正常登录 | 输入正确账号密码 | 登录成功并保存 token | +| AUTH-002 | 错误密码 | 连续输入错误密码 | 返回 401,达到阈值后限流 | +| AUTH-003 | 过期会话 | 使用过期 token 请求接口 | 返回 401 并回登录页 | +| AUTH-004 | 退出登录 | 退出后再次请求业务接口 | token 失效 | +| AUTH-005 | 管理员 | 访问用户、节点、审计功能 | 可执行授权操作 | +| AUTH-006 | 普通用户 | 访问管理员功能 | 按钮隐藏,后端返回 403 | +| AUTH-007 | 项目隔离 | 用户 A 访问用户 B 项目 | 列表不显示,接口拒绝 | +| AUTH-008 | 租户隔离 | 租户 A 请求租户 B 数据 | 不返回跨租户数据 | +| AUTH-009 | ACL | 授予模型 read/execute | read 只能看,execute 才能运行 | +| AUTH-010 | 软删除 | 删除模型或数据集 | 列表隐藏,保留删除审计字段 | +| NODE-001 | 新增节点 | 填写 API、文件网关和标签 | 节点保存并显示 | +| NODE-002 | 节点测试 | 点击测试 | health/GPU 信息同步 | +| NODE-003 | 不可达节点 | 使用错误地址测试 | 快速失败并显示原因 | +| NODE-004 | 删除节点 | 点击删除 | 节点从可用列表消失 | +| NODE-005 | 多 GPU | 节点有多张卡 | 显示编号、显存和状态 | +| NODE-006 | 指定 GPU | 训练选择 GPU 0 | 只占用 GPU 0 | +| NODE-007 | GPU 冲突 | 两任务申请同卡 | 后者排队或拒绝,不抢占 | +| NODE-008 | 剩余 GPU | 节点有空闲卡 | 其他任务可继续选择该节点 | +| NODE-009 | 释放 GPU | 停止训练/卸载推理 | GPU 恢复可用 | +| DATA-001 | JSON 统计 | 上传 3 条 JSON 数据 | 列表和详情均为 3 条 | +| DATA-002 | JSONL 统计 | 上传 3 行 JSONL | 列表和详情均为 3 条 | +| DATA-003 | 非法文件 | 上传空或错误格式 | 返回明确错误 | +| DATA-004 | MinIO 归档 | 上传数据集 | 产生对象和 checksum | +| DATA-005 | 节点同步 | 选择算力节点上传 | 文件进入目标节点缓存 | +| DATA-006 | 同步断网 | 同步时阻断节点 | 进入重试或失败,不无限等待 | +| DATA-007 | 数据权限 | 用户查看数据集 | 只显示有权限的数据 | +| TRAIN-001 | 创建训练 | 选择项目、数据集、节点和 GPU | 任务关联完整 | +| TRAIN-002 | 启动训练 | 启动任务 | 进入 queued/running | +| TRAIN-003 | 日志轮询 | 打开训练日志 | 约 3 秒更新,不刷屏 | +| TRAIN-004 | 训练曲线 | 产生 loss/metric | 页面显示曲线 | +| TRAIN-005 | 停止训练 | 点击停止 | 进程停止且资源释放 | +| TRAIN-006 | 训练失败 | 模拟引擎失败 | 显示原因和日志 | +| MERGE-001 | 自动准备 | 执行权重合并 | 自动准备 base model/adapter | +| MERGE-002 | 节点一致 | 权重在训练节点 | 合并请求发往训练节点 | +| MERGE-003 | 合并归档 | 合并成功 | 结果上传 MinIO 并登记 | +| MERGE-004 | 合并权限 | 无 execute 用户操作 | 返回 403 | +| INF-001 | 列表加载 | 点击模型推理 | 列表快速显示,不长时间等待 | +| INF-002 | 指定节点 | 多节点时选择节点 B | 模型只在 B 加载 | +| INF-003 | 训练节点优先 | 未重新指定节点 | 优先使用训练节点 | +| INF-004 | 推理缓存 | 启动未缓存模型 | 从 MinIO 下载到目标节点 | +| INF-005 | 加载超时 | 模拟加载超过 15 分钟 | 失败并显示原因 | +| INF-006 | 对话推理 | 发送消息 | 返回推理结果 | +| INF-007 | 释放推理 | 点击释放 | 卸载模型并释放 GPU | +| INF-008 | 删除推理 | 删除任务记录 | 记录删除成功并释放资源 | +| EVAL-001 | 创建评测 | 选择模型、数据集、指标 | 任务创建成功 | +| EVAL-002 | 数据集权限 | 选择无权数据集 | 不出现在选择列表 | +| EVAL-003 | 指标保存 | 选择具体指标 | 结果不错误显示 custom | +| EVAL-004 | 评测报告 | 等待任务完成 | 返回非空报告和明细 | +| EVAL-005 | 页面轮询 | 打开评测页面 | 不刷屏,loading 可结束 | +| OPS-001 | 审计 | 登录、创建、删除、执行资源 | 记录 actor/action/resource/time | +| OPS-002 | 轮询日志 | 观察 Backend 日志 | 成功轮询不高频输出 INFO | +| OPS-003 | 错误日志 | 模拟依赖异常 | 保留 WARNING/ERROR 和 request_id | +| OPS-004 | 推理接口耗时 | 请求 `/model-compare` | 正常环境目标小于 1 秒 | +| OPS-005 | 看板耗时 | 请求 `/dashboard/stats` | 有短缓存且不无限等待 | +| OPS-006 | 并发访问 | 10 用户同时打开列表 | 无连接池耗尽和 5xx | +| OPS-007 | 数据库断开 | 临时阻断 PostgreSQL | 页面明确显示依赖异常 | + +## 回归命令 + +```bash +cd frontend +npm run build +cd .. +python -m compileall backend/app compute +git diff --check +docker compose -f docker/app/docker-compose.yml ps +docker compose -f docker/compute/docker-compose.yml ps +curl http://localhost:17861/modelTF/health +curl http://localhost:19100/modelTF/health +``` + +失败用例必须附接口响应、容器日志、request_id 和复现步骤。