Files
YG_FT/架构.md
wangjiming 242407b676 update
2026-07-31 16:10:34 +08:00

264 lines
20 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 微调平台架构与现状说明
> 目的:梳理「前端 / 应用后端 / 算力平台」三层当前已实现的功能、哪些是真实可用、哪些是模拟/空壳,
> 并指出与「后端仅做数据/任务调度GPU 计算全部下沉到算力服务」这一架构原则之间的缺口。
>
> 初始生成日期2026-07-30。最近更新2026-07-31。路由前缀统一为 `/modelTF`(前后端、算力 API 共用)。
---
## 0. 更新日志
| 日期 | 变更 |
|---|---|
| 2026-07-30 | 初始版本,梳理三层现状与缺口 |
| 2026-07-31 | 评测/推理后端端点从 `yg_ft1` 移植完成G5 部分解决);更新缺口状态表与路线图 |
| 2026-07-31 | 训练派发改造完成:移植 `process_manager.py`/`adapter.py`/`sync.py`,算力 real 执行器就绪后端轮询线程启动G1/G2/G4 部分解决) |
---
## 1. 三层架构总览
```
┌──────────────┐ HTTP /modelTF ┌──────────────────────┐
│ 前端 │ ───────────────────────▶ │ 应用后端 (backend) │
│ (Vue3+Vite) │ ◀─────────────────────── │ FastAPI + SQLite/PG │
└──────────────┘ └──────────┬───────────┘
│ ✅ 训练派发已打通
│ ✅ 推理代理已打通
│ (需算力 venv 装 llamafactory
┌──────────────────────┐
│ 算力平台 (compute) │
│ FastAPI + LLaMA-Factory│
└──────────────────────┘
```
**关键事实**:应用后端与算力平台是**两个独立部署的服务**。
- 推理路径已打通:后端 `platform.py``ComputeNodeClient._request()` 代理到算力 `/modelTF/inference/*`
- 训练路径已打通:后端 `platform_store.start_task``_dispatch_to_compute``ComputeNodeClient.create_job` 派发到算力;后台轮询线程(`service.start_compute_sync_worker`)经 `sync.poll_compute_jobs_once` 周期回传状态/日志/指标。
- 算力 real 执行器已就绪:`compute/agent/process_manager.py` 真正 `subprocess` 拉起 `llamafactory-cli train`
- **剩余前置**:算力 venv 需安装 `llamafactory`G3基座模型/数据集文件需到达算力节点(阶段 4
### 1.1 职责边界(架构原则)
| 角色 | 职责 | 不得做什么 |
|---|---|---|
| **应用后端** | 数据/任务调度与编排:数据集管理、模型元数据、任务生命周期(创建/状态/日志路由)、审批/审计/租户、对外 REST API | **不得**由自身进程执行任何 GPU 计算;**不得**安装 `llamafactory`/`torch` 等训练运行时。GPU 计算须派发给算力服务进程执行(算力服务可与后端同机部署,也可在独立算力节点,取决于部署形态) |
| **算力服务** | 承载所有 GPU 计算:模型训练(微调)、模型推理、模型评测、数据类型转换等;运行 `llamafactory-cli` 等框架 | 不持有业务元数据;只接收后端派发的作业并回报进度/产物 |
| **前端** | 交互与可视化,纯调用后端 API | 不直连算力(统一经后端中转) |
> **原则**:凡涉及 GPU 的工作负载(训练/推理/评测)一律由后端**派发**给算力服务执行,
> 后端自身只做调度编排与数据流转——即 GPU 计算必须发生在**算力服务进程内**,而非后端进程内。
> 算力服务部署在何处(本机或独立节点)不影响该原则。当前 `fine_tune/runner.py` 由后端进程
> 直接 `subprocess` 跑 `train.py` 属于**违反该原则的临时实现**(见 G1
---
## 2. 前端frontend/src功能清单
菜单来自 `components/AppSidebar.vue`,共 7 组。功能状态取决于后端是否有对应端点。
| 菜单分组 | 功能 | 对应前端视图 | 后端端点 | 状态 |
|---|---|---|---|---|
| 服务看板 | 仪表盘(统计/分布/排行) | `dashboard/` | `platform.dashboard_*` | ✅ 真实 |
| 模型服务 | 模型训练 | `fine-tune/` | `platform.fine-tune*` | ✅ 真实(本地执行,见 G1 |
| 模型服务 | 模型评测 | `eval/` | `/model-eval/*``/dimension/*` | ✅ **已移植**(后端端点+SQL表+Store方法齐备 |
| 模型服务 | 模型推理 | `inference/` | `/model-compare/*``/model-chat/*` | ✅ **已移植**(后端端点+SQL表+Store方法+推理代理齐备) |
| 模型服务 | 模型对比 | `compare/` | `/model-compare/*`(推理/对比共用) | ✅ **已移植**(与推理共用后端) |
| 模型服务 | 模型管理 | `model/` | `platform.model-manage*` | ✅ 真实 |
| 数据治理 | 数据集管理 | `dataset/` | `platform.dataset-manage*` | ✅ 真实 |
| 数据治理 | 数据处理 | `data-process/` | `data_process` 路由 | ✅ 真实 |
| 其他工具 | 数据类型转换 | `data-convert/` | 无端点 | ❌ 空壳 UI纯前端`ElMessage.info('当前仅完成界面设计')` |
| 算力资源 | 算力节点 | `compute/` | `platform.compute*` | ⚠️ 模拟(见 §4 |
| 平台治理 | 租户/项目/审计/审批 | `tenants/ projects/ audit/ approvals/` | tenant/project/approval/audit 模块 | ✅ 真实 |
| 系统设置 | 用户设置/性能/日志 | `system/ hardware/ logs/` | system/users + logs | ✅ 真实 |
**结论**:评测、推理、对比的后端端点已从 `yg_ft1` 移植完成,前端不再 404。
剩余空壳 UI 仅 **数据类型转换**`data-convert/`,纯前端界面,无后端端点)。
---
## 3. 应用后端backend/app真实端点
挂载于 `api/v1/router.py` 的 9 个路由:`health / platform / auth / system / tenant / project / resource / approval / data_process`
其中大量功能集中在 `endpoints/platform.py`(仪表盘、用户、模型、数据集、微调、算力、项目、日志、评测、推理)。
### 3.1 已实现(真实可用)
- **认证**`/login``/logout``/me`(登录写 `sessions` 会话,登出关闭会话)
- **用户/系统**`/users` CRUD、重置密码、`/system-info`
- **租户 / 项目空间 / 审批 / 审计**:各模块路由 + `audit_logs`
- **数据集管理**`/dataset-manage*` 全量 CRUD + 文件版本/上传/下载/预览
- **模型管理**`/model-manage*` 本地/训练模型 CRUD + 合并
- **模型训练(微调)**`/fine-tune*` 全量 CRUD + 启停/暂停/恢复/取消/重试/检查点/事件流/日志
- **数据处理**`data_process` 模块(创建/删除/上传/生成/发布,已补审计埋点)
- **仪表盘**`/dashboard/overview``/dashboard/stats`(含真实登录时长、操作分布)
- **日志**`/log-files``/log-content``/training-log-*`
- **模型评测** ✅ **已移植**`/model-eval`(列表/详情/启动/删除)、`/dimension`CRUD+ `eval_tasks`/`eval_dimensions`
- **模型推理/对比** ✅ **已移植**`/model-compare`CRUD + load/unload + load-status + start-model + chat-with-port + stream-chat+ `/model-chat/*`local chat/stream/preload/unload/status + trained preload + batch+ `compare_tasks`
- **推理代理** ✅ **已打通**`_select_first_online_node()` + `ComputeNodeClient._request()``/model-chat/local/*` 请求代理到算力 `/modelTF/inference/*`
### 3.2 模拟(看似可用,实则未接真实算力)
- **算力资源** `/compute/nodes``/compute/gpus``/compute/queue``/compute/jobs`
- `test-connection` 返回**写死的 success**(不真连)
- `create_compute_job` 仅**落库**,无任何派发逻辑
- `gpus`/`queue` 来自 DB无真实 GPU 采集
### 3.3 ~~缺失~~(前端在调用但后端不存在)
> **2026-07-31 更新**:原 G5 列出的 `/model-eval/*`、`/inference/*`、`/model-compare/*` 已全部移植完成。
> 后端 `modules/eval`、`modules/inference` 目录仍仅有空 `__init__.py`(评测/推理逻辑直接写在 `platform.py` + `platform_store.py` 中,与 `yg_ft1` 架构一致)。
>
> 唯一仍缺后端端点的是 **数据类型转换** `/data-convert/*`,但该前端页面本身也是纯展示(`ElMessage.info('当前仅完成界面设计')`),不发送 API 请求。
---
## 4. 算力平台compute现状
独立 FastAPI 服务,**与应用后端分开部署**README 明确说明)。
### 已实现
- **健康检查**`/modelTF/health``/modelTF/v1/compute/health`
- **作业管理**`POST/GET /modelTF/compute/jobs``.../{id}``.../{id}/stop``.../{id}/logs`
- **GPU 资源**`GET /modelTF/compute/resources/gpus`
- **文件网关**`/modelTF/compute/files/upload``/download`
- **LLaMA-Factory 适配**`engines/llama_factory/adapter.py`
- `build_command()` 生成 `llamafactory-cli train ...`SFT/LoRA/量化等参数)
- `parse_log_line()` 解析 loss/grad_norm/learning_rate/epoch 指标
- **模型推理** ✅ **已移植**`engines/llama_factory/inference.py``InferenceSession`load/unload/chat/chat_stream
- **推理 API 端点** ✅ **已移植**
- `POST /modelTF/inference/load` — 加载模型
- `POST /modelTF/inference/unload` — 卸载模型
- `GET /modelTF/inference/status` — 查询状态
- `POST /modelTF/inference/chat` — 同步对话
- `POST /modelTF/inference/chat/stream` — 流式对话SSE
### 模拟 / 未实现
- **`simulator` 模式**默认开发用作业状态按时间演进queued→running→completed
生成**合成** loss 日志GPU 列表为构造数据。可完整跑通 UI 流程。
- **`real` 模式** ✅ **已实现**`compute/agent/process_manager.py``ProcessManager` 类)真正 `subprocess` 拉起 `llamafactory-cli train`,含日志落盘 / checkpoint / artifacts / GPU 锁定 / stop。
- **依赖缺失**`compute/requirements.txt` 已声明 `llamafactory`
但算力 venv 实际未安装,且 `LLAMA_FACTORY_HOME` 默认指向 `/app/LLaMA-Factory`(运行时需存在)。
---
## 5. 与架构目标的缺口(重点)
架构原则:**后端仅做数据/任务调度与编排,所有涉及 GPU 的计算(训练/推理/评测/转换)一律派发到算力服务执行;应用后端不得安装或本地运行 `llamafactory`/`torch` 等训练运行时。**
| # | 缺口 | 现状 | 影响 |
|---|---|---|---|
| **G1** → ✅ 已解决 | ~~训练未派发到算力~~ | `start_task``_dispatch_to_compute` 派发到算力;`sync.poll_compute_jobs_once` 回传状态;后台轮询线程启动。`runner.py` 本机执行仅保留为无算力节点时的降级 fallback | 训练走算力执行(需 G3 环境就绪) |
| **G2** → ✅ 已解决 | ~~算力真实执行器未实现~~ | `compute/agent/process_manager.py` 已移植;`compute/api/main.py` real 模式调用 `ProcessManager.create_job` 真正 `subprocess` 拉起训练 | 算力可执行真实训练 |
| G3 | llamafactory 未安装 | 已声明于 `compute/requirements.txt`,但算力 venv 未装;按架构**不应**装进后端 venv | 真实训练无法启动 |
| **G4** → ✅ 已解决 | ~~训练前后端算力未连通~~ | 推理路径已通;训练路径已通(`start_task``_dispatch_to_compute``ComputeNodeClient.create_job`→算力 `ProcessManager``sync.poll_compute_jobs_once` 回传) | 训练 GPU 作业数据与算力已连通 |
| ~~G5~~**已解决大部分** | ~~多个前端模块无后端~~ | 评测 ✅ 已移植;推理/对比 ✅ 已移植;数据转换 ❌ 仍空壳 | 仅数据转换功能不可用(纯 UI 占位) |
---
## 6. 数据流现状 vs 应有
### 6.1 训练 ✅ 已打通(待 G3 环境就绪)
```
前端 创建/启动训练 → 后端 /fine-tune/start → platform_store.start_task(payload)
→ schedule_node() 选取在线算力节点
→ _dispatch_to_compute() → ComputeNodeClient.create_job(cfg) 派发到算力
→ 算力 POST /modelTF/compute/jobs → ProcessManager.create_job() → subprocess llamafactory-cli train
→ 后台轮询线程 sync.poll_compute_jobs_once() 周期拉取状态/日志/指标 → apply_compute_job 回写
→ 训练完成 → _ensure_trained_model 登记产物
```
> **降级 fallback**:当无在线算力节点时,`start_task` 降级到 `service.launch_training` → `runner.run_training`(本机 subprocess违反 §1.1,待移除)。
>
> **前置依赖**:算力 venv 需安装 `llamafactory`G3基座模型/数据集文件需到达算力节点(阶段 4
### 6.2 推理 ✅ 已打通
```
前端 新建推理/对话 → 后端 /model-compare/* 或 /model-chat/local/*
→ 后端 _select_first_online_node(store) 选取在线算力节点
→ ComputeNodeClient(api_base_url)._request("POST", "/inference/chat", json_data=payload)
→ 算力平台 POST /modelTF/inference/chat → InferenceSession.chat() → 返回推理结果
→ 流式POST /modelTF/inference/chat/stream → SSE 逐字回传
```
> 推理路径已完全打通:后端代理 → 算力执行 → 结果回传。
> 若算力节点不在线,后端返回降级响应(`"no online compute node available for inference"`)。
---
## 7. 建议的下一步
1. **训练打通**(当前最高优先级缺口):
- 移植 `yg_ft1``compute/agent/process_manager.py`real 执行器)到 `compute/agent/`
- 移植 `yg_ft1``compute_gateway/sync.py`(派发+状态/日志回传)到 `backend/app/modules/compute_gateway/`
- 改造 `fine_tune/service.py``start_task` 改为经 `compute_gateway.dispatch()` 派发,移除本机 `runner.py` subprocess。
2. **环境**(低风险):在算力 venv 安装 `llamafactory`;后端 venv 保持不含它。
3. **联调**:算力平台切 `COMPUTE_EXECUTION_MODE=simulator`,后端改为经算力 API 派发训练,使训练 UI 走通。
4. **数据转换**(低优先级):补齐 `/data-convert/*` 后端端点(当前前端纯 UI 占位,无 API 调用)。
---
## 8. 改造路线图GPU 任务从后端进程派发到算力服务进程
目标:落实 §1.1 职责边界——**后端只做数据/任务调度与编排GPU 计算一律派发给算力服务进程执行**。
当前 `fine_tune/runner.py` 用后端 venv 本机 `subprocess``train.py` 是违反原则的临时实现,需移除并改为「派发 + 回传」。
> **参考实现 `yg_ft1`**:同仓下 `e:/yg_ft/yg_ft1` 是更完整的参考版本,本路线图所需能力大多已实现,应**直接迁移/对齐,而非从零编写**
> - **训练闭环完整**`compute/agent/process_manager.py`real 模式真正 `subprocess` 拉起 `llamafactory-cli train`,含日志落盘 / checkpoint / artifacts / GPU 锁定 / stop、`compute/engines/llama_factory/adapter.py``build_command` / `prepare_runtime_files` / `parse_log_line`)、后端 `compute_gateway/client.py` + `sync.py`(派发 + 状态/日志回传)。
> - **推理真实端点** ✅ 已迁移:`compute/api/main.py` 的 `/inference/*` + `compute/engines/llama_factory/inference.py` 已于 2026-07-31 移植到当前项目。
> - **评测** ✅ 后端端点已迁移:`/model-eval/*` + `/dimension/*` + `eval_tasks`/`eval_dimensions` 表 + Store 方法已于 2026-07-31 移植。**但评测执行器(是否走算力)尚未实现**——当前仅落库,无真实评测执行。
>
> 因此阶段 1/2/3 本质是**把 `yg_ft1` 的训练相关文件迁移到 `yg_ft` 并对齐接口**;推理已完成;评测需另行补全执行器。
> 现状代码支撑:`compute_nodes` 表已带 `api_base_url` 字段(见 `001_platform_runtime.sql`
> 算力 API 已有 `jobs/create/get/stop/logs` 与 `resources/gpus``adapter.build_command` 可生成 `llamafactory-cli train`。
> `ComputeNodeClient` 已有 `headers()`、`_request()` 异步方法(推理代理已验证可用)。
> 缺的是:① 后端 `compute_gateway/sync.py`(派发+回传同步线程);② 训练不走本机;③ 算力 `real` 执行器(`process_manager.py`);④ 数据集/模型文件如何到达算力。
### 阶段 0 — 算力环境就绪(前置)—— **待执行**
- **改动**:在算力服务 venv 安装 `llamafactory`(依赖已声明于 `compute/requirements.txt`),后端 venv 保持不含它。
- **验证**:算力切 `simulator``POST /modelTF/compute/jobs` 能返回 `queued``pip show llamafactory` 在算力环境为已装、在后端为未装。
### 阶段 1 — 后端 `compute_gateway` 桥接 ✅ 已完成
- **已建文件**`backend/app/modules/compute_gateway/sync.py`(从 `yg_ft1` 迁移)。
- **已实现**
- `sync.py``poll_compute_jobs_once()` 周期性同步线程,从算力 API 拉取 job 状态/日志/指标,写回 `PlatformStore.task`
- `client.py` 已有 `create_job`/`get_job`/`stop_job`/`job_logs` 方法(同步)和 `_request`/`headers` 方法(异步,推理已用),直接复用。
- `_select_first_online_node` 已实现(推理代理已验证)。
- 后台轮询线程在 `main.py` lifespan 中自动启动。
### 阶段 2 — 训练改为「派发 + 回传」 ✅ 已完成
- **已改文件**`backend/app/modules/fine_tune/service.py``backend/app/db/platform_store.py``backend/app/main.py`
- **已实现**
- `platform_store.start_task``schedule_node``_dispatch_to_compute``ComputeNodeClient.create_job` 派发到算力。
- 后台轮询线程(`service.start_compute_sync_worker`)启动,周期调 `sync.poll_compute_jobs_once`
- `apply_compute_job` 回写状态/进度/日志/checkpoints/artifacts`record_training_log_metrics` 解析并存储训练指标。
- `stop_task` 改为先通知算力 `stop_job`,再更新 DB + 释放 GPU。
- `runner.py` 本机 `subprocess` 仅保留为无算力节点时的降级 fallback`start_task``elif` 分支)。
### 阶段 3 — 算力 `real` 执行器 ✅ 已移植
- **已建文件**`compute/agent/process_manager.py`(从 `yg_ft1` 迁移)。
- **已改文件**`compute/api/main.py`real 模式调用 `ProcessManager`)。
- **已实现**`ProcessManager` 类——真正 `subprocess` 拉起 `llamafactory-cli train`,含日志落盘 / checkpoint 收集 / artifacts 收集 / GPU 锁定 / stop。`compute/api/main.py` 的 real 模式不再返回 501。
### 阶段 4 — 数据集 / 模型文件到达算力(关键依赖)
- **问题**:派发后算力节点须能读到**基座模型**与**训练数据集**文件。
- **方案(二选一或并存)**
- A推荐生产基座模型与数据集通过**共享存储**NFS / 对象存储)挂载到算力节点,路径随派发 config 传入;
- B已具备雏形经算力文件网关 `POST /compute/files/upload``/download` 传输(当前为占位,需落盘实现)。
- **验证**:算力 `real` 执行时能从指定路径加载模型与数据集,不报「文件不存在」。
### 阶段 5 — 评测执行器 / 数据转换
- **评测**:后端端点已移植(`/model-eval/*` 落库),但**真实评测执行器**未实现(是否走算力待定)。需补全评测执行逻辑——可能经 `compute_gateway` 派发到算力,或后端编排调 API 模型评测。
- **数据转换**:补齐 `/data-convert/*` 后端端点(当前前端纯 UI 占位,无 API 调用)。
- **验证**:评测任务能真实执行并产出分数;数据转换页面功能可用。
### 风险与前置提醒
1. **阶段 4 文件传递是派发可用性的硬前置**——不解决,算力无数据可训(优先级高于阶段 3
2. **暂停/恢复语义缺口**:算力当前仅 `stop`,阶段 2 需先确定 pause/resume 是否必需、如何映射。
3. **共享存储/网络可达性**`compute_nodes.api_base_url` 必须网络可达,且算力与后端时间/路径一致。
4. **回退策略**:阶段 2 上线前保留本机 `runner` 作为可开关的 fallback`DISPATCH_TO_COMPUTE=true/false`),便于灰度。
```