docs: 架构拆分为外网网关+高性能worker(GPU)

- 新增 系统架构-网关与高性能后端.md: 网关薄代理(健康检查/空闲派发/鉴权/
  base64落盘改URL/无后端→1007) + worker(GPU跑完整app)职责划分、配置文件、
  鉴权(共享密码可轮换)、标注图base64流程、部署、安全注意
- 关键约束: 接口文档不变; 每worker并发=1, 总并发=健康worker数; 多worker可配置
- 技术方案: 加运行位置横幅; torch改GPU(CUDA); handler返回annotated_image_base64
- 任务书v1.4: 标注差异说明; 阶段八返base64+鉴权中间件; 阶段十worker(GPU)部署;
  新增§16网关工作流; DoD拆分worker侧/网关侧
- OFFLINE_ASSETS: 区分worker(GPU torch)与网关(轻量)依赖
This commit is contained in:
xsl
2026-06-14 13:55:45 +08:00
parent 7493f48992
commit 2e789d4efa
4 changed files with 387 additions and 43 deletions
@@ -2,6 +2,11 @@
> 基于 MediaPipe Face Mesh468 关键点)测量「眉心以下」+ 人脸解析分割(BiSeNet)获取「真实发际线/头顶」+ 人脸比例先验作为兜底
> 📌 **运行位置**:本文档描述的全部算法逻辑运行在 **高性能 worker(GPU 机)** 上,不在外网网关。系统已拆分为「外网网关 + worker」两层,详见 [`系统架构-网关与高性能后端.md`](系统架构-网关与高性能后端.md)。相对单机版有两处差异:
> 1. **GPU 加速**BiSeNet 改用 CUDA 推理(torch GPU 版),MediaPipe 仍 CPU。
> 2. **标注图返回 base64**worker **不落盘、不拼 URL**,把标注 PNG 以 `annotated_image_base64` 返回;落盘成 `annotated_image_url` 由网关完成(见架构文档 §9)。本文后续 §6/§8 的"保存到 static + 返回 URL"仅适用于单机版,拆分后改为返回 base64。
> 3. **资源宽裕**32G + GPU,无需单机版的 2核4G 并发限制;worker 自身并发=1 由网关保证。
---
## 1. 模型选型
@@ -726,9 +731,13 @@ async def face_measure(image_file: UploadFile = File(...)):
annotated = create_annotated_image(image, result)
buf = BytesIO()
annotated.save(buf, format="PNG")
# ... 保存并返回 URL
return ok(result.to_response())
# 6. 拆分架构下:返回 base64,由网关落盘改写成 annotated_image_url(见架构文档 §9
import base64
data = result.to_response()
data["annotated_image_base64"] = base64.b64encode(buf.getvalue()).decode()
return ok(data)
# —— 单机版(非拆分)才在此保存到 static/ 并返回 annotated_image_url ——
```
---
@@ -810,13 +819,14 @@ Pillow==11.0.0 # 标注图生成(PNG 透明图层)
numpy==1.26.4 # ⚠️ 必须 <2,否则 mediapipe 0.10.x import 崩溃
# 方案 B:头发分割(BiSeNet face-parsing
torch==2.2.2 # CPU 版即可:pip install torch --index-url https://download.pytorch.org/whl/cpu
# 拆分架构:worker 有 GPU → 用 CUDA 版 torch(按 worker 的 CUDA 版本选 whl
torch==2.2.2 # GPU(CUDA)版,例如 cu121--index-url https://download.pytorch.org/whl/cu121
torchvision==0.17.2
```
> ⚠️ **numpy 锁版本**mediapipe 0.10.x 对 numpy 2.x 支持不稳定,务必锁 `numpy<2`(已验证 1.26.4 可用)。先用此组合跑通,再考虑升级。
>
> ⚠️ **torch 体积**CPU 版 torch ~200MB,是本接口最大的依赖。若服务器资源紧张或不想引入 torch,可改用 SegFormer-b0onnxruntime 推理,体积更小),或先只上线方案 A、把方案 B 作为第二期
> ⚠️ **torch GPU/CPU**:拆分架构下 worker 有独立 GPU,用 **CUDA 版 torch**(按 worker 实际 CUDA 版本选对应 whl index,如 cu118/cu121),BiSeNet 推理走 GPU。单机/无 GPU 环境回退 CPU 版(`--index-url .../whl/cpu`~200MB)。BiSeNet 加载时把 `.to('cuda' if torch.cuda.is_available() else 'cpu')`
> MediaPipe 0.10.x 的经典 Solutions API (`mp.solutions.face_mesh`) 仍稳定可用。如需迁移到 Tasks API,后续可平滑升级。