326 lines
11 KiB
Markdown
326 lines
11 KiB
Markdown
# 目标:所有接口 < 10 秒 — 三个优化方案
|
||
|
||
> 日期:2026-07-18
|
||
> 基准数据(优化1+2后轮换测试 5轮×4接口)
|
||
|
||
---
|
||
|
||
## 当前性能基线
|
||
|
||
| 接口 | 平均 | 最快 | 最慢 | 目标 | 差距 |
|
||
|------|------|------|------|------|------|
|
||
| 接口1-测量 | 0.1s | 0.1s | 0.1s | <10s | ✅ 已达标 |
|
||
| 接口2-女-椭圆 | 17.6s | 10.0s | 19.7s | <10s | -7.6s |
|
||
| 接口2-男-椭圆 | 8.1s | 7.9s | 8.4s | <10s | ✅ 已达标(余量小) |
|
||
| 接口3-B端生发 | 22.9s | 22.6s | 23.3s | <10s | -12.9s |
|
||
|
||
---
|
||
|
||
## 根因分析
|
||
|
||
### ComfyUI 模型反复换出(最大瓶颈)
|
||
|
||
ComfyUI 服务端日志(`journalctl -u comfyui`)揭示了根因:
|
||
|
||
```
|
||
12:17:14 model_type FLUX
|
||
12:17:16 loaded completely; 17421 MB usable, 15622 MB loaded ← 全量加载(15.6GB)
|
||
12:17:16 Requested to load Flux2
|
||
12:17:23 Unloaded partially: 11904 MB freed, 3718 MB remains ← 部分卸载
|
||
12:17:24 loaded completely; 11832 MB usable, 8996 MB loaded ← 重新加载(8.9GB)
|
||
12:17:27 VAE loaded
|
||
12:17:29 Requested to load Flux2 ← 男性复用(快)
|
||
12:17:31 loaded completely; 11671 MB usable, 8996 MB loaded ← 已加载,6s完成
|
||
12:17:43 Unloaded partially: 8996 MB freed, 0.04 MB remains ← 全部卸载!
|
||
12:17:45 loaded completely; 17567 MB usable, 15622 MB loaded ← 全量重载(15.6GB)
|
||
12:17:52 Unloaded partially: 11904 MB freed, 3718 MB remains ← 再次部分卸载
|
||
12:17:54 loaded completely; 11814 MB usable, 8996 MB loaded ← 再次重载(8.9GB)
|
||
12:17:58 接口3 完成(21.5s)
|
||
```
|
||
|
||
**ComfyUI 在每次执行后都会卸载模型,下次执行时重新加载。** 模型加载耗时 ~8-15s,是接口3和接口2女超时的主因。
|
||
|
||
### 显存分布(32GB GPU)
|
||
|
||
| 进程 | 显存 | 说明 |
|
||
|------|------|------|
|
||
| ComfyUI (Flux-2) | ~10-15 GB | 动态加载/卸载 |
|
||
| hair_service_sd | ~8 GB | GAN 模型常驻 |
|
||
| SD WebUI | ~3.2 GB | SD1.5 + ControlNet |
|
||
| Hair 服务 | ~0.7 GB | uvicorn + 模型 |
|
||
| **合计** | **~22-27 GB** | **仅剩 5-10 GB 可用** |
|
||
|
||
显存不足导致 ComfyUI 无法常驻完整的 Flux-2 模型(~15.6GB 全量或 ~9GB FP8)。
|
||
|
||
### 耗时拆解
|
||
|
||
**接口3(22.9s)**:
|
||
```
|
||
ComfyUI 模型加载: ~15s ← 根因
|
||
ComfyUI 推理(steps=6): ~6s
|
||
预处理(人脸+SegFormer+划线): ~1.6s
|
||
```
|
||
|
||
**接口2女(17.6s)**:
|
||
```
|
||
ComfyUI 模型加载: ~10s ← 根因(模型被接口3卸载后需重载)
|
||
ComfyUI 推理(steps=4): ~4s
|
||
swapHair HTTP: ~4.6s
|
||
预处理(extract_context): ~1.5s(优化2后 SegFormer 只跑一次)
|
||
```
|
||
|
||
**接口2男(8.1s)**:
|
||
```
|
||
ComfyUI 推理(steps=6): ~6s
|
||
预处理: ~2s
|
||
(模型常被前一个女性接口加载好,所以无重载开销)
|
||
```
|
||
|
||
---
|
||
|
||
## 方案 A:释放显存给 ComfyUI(最小改动)
|
||
|
||
### 核心思路
|
||
|
||
ComfyUI 需要 ~15.6GB 显存才能全量加载 Flux-2。当前被 hair_service_sd(8GB)和 SD WebUI(3.2GB)挤占。如果释放足够显存,ComfyUI 就能常驻模型,消除反复加载。
|
||
|
||
### 具体措施
|
||
|
||
#### A1. 接口3不依赖 hair_service_sd
|
||
|
||
接口3 **不调用** change_hair:8801 的 swapHair。但 hair_service_sd 的所有 GAN 模型(8GB)常驻显存只为接口2女服务。
|
||
|
||
**方案**:将 hair_service_sd 改为**按需启动/停止**:
|
||
- 接口2女调用前启动 hair_service_sd
|
||
- 接口2女完成后停止 hair_service_sd(释放 8GB)
|
||
- 接口3和接口2男不启动 hair_service_sd
|
||
|
||
**释放**:8 GB → ComfyUI 可用显存从 ~5GB 增至 ~13GB
|
||
|
||
#### A2. 接口2女改为先启动 hair_service_sd → swapHair → 停止 → 再调 ComfyUI
|
||
|
||
```
|
||
接口2女流程:
|
||
1. 启动 hair_service_sd (8s) ← 可预热
|
||
2. swapHair (4.6s)
|
||
3. 停止 hair_service_sd → 释放 8GB
|
||
4. ComfyUI 重绘 (4-6s, 模型常驻)
|
||
总: ~17s → 仍有问题
|
||
```
|
||
|
||
**问题**:hair_service_sd 启动需要 8s(加载全部 GAN),反而增加耗时。
|
||
|
||
#### A3. 停止 SD WebUI(3.2GB)
|
||
|
||
SD WebUI 只被 change_hair 的 swapHair 使用(接口2女)。如果接口2女改用其他方案(见方案B),可以完全停止 SD WebUI。
|
||
|
||
**释放**:3.2 GB
|
||
|
||
#### A4. 总释放和预期效果
|
||
|
||
| 措施 | 释放 | ComfyUI 可用 |
|
||
|------|------|--------------|
|
||
| 当前 | — | ~5-10 GB |
|
||
| A1 (停 hair_service_sd) | +8 GB | ~13-18 GB |
|
||
| A3 (停 SD WebUI) | +3.2 GB | ~16-21 GB |
|
||
| **合计** | **+11.2 GB** | **~16-21 GB** |
|
||
|
||
Flux-2 全量 15.6GB,释放后 ComfyUI 可常驻模型。
|
||
|
||
### 预期耗时
|
||
|
||
| 接口 | 当前 | 优化后 | 达标 |
|
||
|------|------|--------|------|
|
||
| 接口1 | 0.1s | 0.1s | ✅ |
|
||
| 接口2-女 | 17.6s | ~11s (swapHair 4.6s + ComfyUI 4s + 预处理 1.5s + 启停 1s) | ❌ 差1s |
|
||
| 接口2-男 | 8.1s | ~8s | ✅ |
|
||
| 接口3 | 22.9s | ~8s (ComfyUI 6s + 预处理 1.6s) | ✅ |
|
||
|
||
### 优点
|
||
- 改动最小:主要改服务启停逻辑
|
||
- 不影响算法质量
|
||
- 不需要换 torch 版本
|
||
|
||
### 缺点
|
||
- 接口2女仍可能超 10s(swapHair 4.6s 是硬瓶颈)
|
||
- hair_service_sd 启停增加系统复杂度
|
||
- 需要精确的显存管理
|
||
|
||
---
|
||
|
||
## 方案 B:统一工作流 + 降 steps(中等改动)
|
||
|
||
### 核心思路
|
||
|
||
两个工作流(0716add-hair-api.json 27节点 vs add_hair.json 29节点)加载相同模型但参数不同(steps=4 vs steps=6),切换时触发 ComfyUI 重新初始化。统一为一个工作流 + 降低 steps 可消除切换开销并加速推理。
|
||
|
||
### 具体措施
|
||
|
||
#### B1. 统一为单一工作流
|
||
|
||
将 `add_hair.json` 的 steps 从 6 降到 4,与 `0716add-hair-api.json` 一致。然后所有接口都用同一个工作流。
|
||
|
||
**改动**:
|
||
- `add_hair.json`: KSampler steps 6 → 4
|
||
- 接口2男和接口3统一用修改后的 `add_hair.json`
|
||
- 接口2女也改用 `add_hair.json`(不再用 `0716add-hair-api.json`)
|
||
|
||
**效果**:ComfyUI 不再在工作流间切换,模型可常驻。
|
||
|
||
#### B2. 进一步降低 steps 到 2
|
||
|
||
Flux-2 模型在 steps=2 时仍能生成合理结果(需质量验证)。
|
||
|
||
| steps | 单次推理 | 质量 |
|
||
|-------|---------|------|
|
||
| 6 | ~6s | 最好 |
|
||
| 4 | ~4s | 好 |
|
||
| 2 | ~2s | 可接受(需验证) |
|
||
|
||
#### B3. 接口2女去 swapHair(可选但关键)
|
||
|
||
swapHair 调 change_hair:8801 → webui:57860 SD1.5 img2img,耗时 4.6s。如果去掉 swapHair:
|
||
|
||
- 女性直接用原图 + 遮罩 → ComfyUI Flux-2 重绘
|
||
- 省去 4.6s + 不需要启动 hair_service_sd + SD WebUI
|
||
- 释放 ~11.2GB 显存给 ComfyUI
|
||
|
||
**但**:swapHair 是换发型功能,去掉后女性发型会不同。需要确认产品是否接受。
|
||
|
||
### 预期耗时
|
||
|
||
| 接口 | 当前 | B1(steps=4) | B2(steps=2) | B3(去swapHair) |
|
||
|------|------|-------------|-------------|----------------|
|
||
| 接口2-女 | 17.6s | ~10s | ~8s | ~6s |
|
||
| 接口2-男 | 8.1s | ~6s | ~4s | ~4s |
|
||
| 接口3 | 22.9s | ~8s | ~6s | ~6s |
|
||
|
||
### 优点
|
||
- 消除工作流切换开销
|
||
- 降低推理时间
|
||
- 可与方案A叠加
|
||
|
||
### 缺点
|
||
- steps 降低可能影响质量(需验证)
|
||
- 去 swapHair 改变女性发型效果
|
||
- 需要修改工作流 JSON 和服务代码
|
||
|
||
---
|
||
|
||
## 方案 C:ComfyUI 预热 + 模型常驻(系统级优化)
|
||
|
||
### 核心思路
|
||
|
||
通过 ComfyUI API 和配置,让 Flux-2 模型在启动后常驻显存,不执行后自动卸载。结合预热请求,确保每次调用时模型已在显存。
|
||
|
||
### 具体措施
|
||
|
||
#### C1. 配置 ComfyUI 保持模型加载
|
||
|
||
ComfyUI 有 `--reserve-vram` 和 `--gpu-only` 参数控制 VRAM 管理:
|
||
|
||
```bash
|
||
# 启动 ComfyUI 时禁用模型卸载
|
||
python main.py --listen --gpu-only --reserve-vram 0
|
||
```
|
||
|
||
- `--gpu-only`:禁止将模型卸载到 CPU(保持 GPU 常驻)
|
||
- `--reserve-vram 0`:不预留 VRAM(最大化模型可用空间)
|
||
|
||
**前提**:需要释放足够显存(结合方案A的A1/A3)。
|
||
|
||
#### C2. ComfyUI 预热请求
|
||
|
||
在 hair 服务启动时,发送一个空请求给 ComfyUI,触发模型加载:
|
||
|
||
```python
|
||
# hair 服务启动后
|
||
comfyui.warmup() # 发送最小工作流,触发 Flux-2 加载到 VRAM
|
||
```
|
||
|
||
**效果**:第一次请求不再需要等待模型加载。
|
||
|
||
#### C3. 停止其他占用显存的服务
|
||
|
||
与方案A结合:
|
||
- 停止 hair_service_sd(释放 8GB)
|
||
- 停止 SD WebUI(释放 3.2GB)
|
||
- 仅保留 ComfyUI + Hair 服务
|
||
|
||
**总可用显存**:32GB - 0.7GB(Hair) = ~31GB → 足以常驻 Flux-2(15.6GB)
|
||
|
||
#### C4. ComfyUI 模型管理优化
|
||
|
||
设置环境变量:
|
||
```bash
|
||
export COMFYUI_MODEL_KEEP=true # 保持模型加载
|
||
```
|
||
|
||
或在 ComfyUI 的 `extra_model_paths.yaml` 和 `comfyui/config.yaml` 中配置模型缓存策略。
|
||
|
||
#### C5. 接口2女 swapHair 异步化
|
||
|
||
swapHair(4.6s)是接口2女的独立瓶颈。改为异步流水线:
|
||
|
||
```
|
||
1. 接收请求 → 异步调 swapHair
|
||
2. 同时开始预处理(extract_context + 遮罩)
|
||
3. swapHair 完成 + 预处理完成 → 合并
|
||
4. ComfyUI 重绘
|
||
```
|
||
|
||
**效果**:swapHair 4.6s 与预处理 1.5s 并行,省 1.5s。
|
||
|
||
### 预期耗时
|
||
|
||
| 接口 | 当前 | C方案 |
|
||
|------|------|-------|
|
||
| 接口1 | 0.1s | 0.1s |
|
||
| 接口2-女 | 17.6s | ~9s (swapHair 4.6s ∥ 预处理 1.5s + ComfyUI 4s) |
|
||
| 接口2-男 | 8.1s | ~6s (ComfyUI 4s + 预处理 2s) |
|
||
| 接口3 | 22.9s | ~6s (ComfyUI 4s + 预处理 1.6s) |
|
||
|
||
### 优点
|
||
- 从根本上解决模型换出问题
|
||
- 效果最稳定(模型常驻后不再有抖动)
|
||
- 可与方案B叠加(steps 降到2则接口2女 ~6s)
|
||
|
||
### 缺点
|
||
- 需要停掉 hair_service_sd 和 SD WebUI(影响其他功能)
|
||
- 接口2女仍依赖 swapHair(4.6s)
|
||
- ComfyUI 配置改动需验证不影响稳定性
|
||
- `--gpu-only` 在显存不足时可能导致 OOM 崩溃
|
||
|
||
---
|
||
|
||
## 三方案对比
|
||
|
||
| 维度 | 方案A(释放显存) | 方案B(统一工作流) | 方案C(模型常驻) |
|
||
|------|----------------|------------------|-----------------|
|
||
| 改动量 | 小 | 中 | 中-大 |
|
||
| 接口2女 | ~11s ❌ | ~8s ✅ | ~9s ✅ |
|
||
| 接口3 | ~8s ✅ | ~6s ✅ | ~6s ✅ |
|
||
| 接口2男 | ~8s ✅ | ~4s ✅ | ~6s ✅ |
|
||
| 质量 | 不变 | 需验证 | 不变 |
|
||
| 风险 | 低 | 中(质量) | 中(OOM) |
|
||
| 可叠加 | ✅ | ✅ | ✅ |
|
||
|
||
---
|
||
|
||
## 我的建议
|
||
|
||
**推荐:B + C 组合(统一工作流 + 模型常驻)**
|
||
|
||
理由:
|
||
1. **方案C** 从根本上解决模型换出(最大瓶颈),但需要停掉 hair_service_sd 和 SD WebUI
|
||
2. **方案B** 降低 steps 到 2-4,进一步减少推理时间
|
||
3. **方案B的B3(去swapHair)** 是接口2女达标的关键:去掉 swapHair 后不再需要 hair_service_sd 和 SD WebUI,为方案C释放显存
|
||
4. 组合后所有接口都能稳定在 6-8s
|
||
|
||
**关键决策点**:接口2女是否可以去掉 swapHair(换发型)?如果可以,方案B+C组合是最佳选择。如果不行,需要方案A(hair_service_sd 按需启停)+ 方案C + swapHair 异步化。
|
||
|
||
需要你确认:
|
||
1. 接口2女是否可以去掉 swapHair(直接用原图+遮罩 → ComfyUI)?
|
||
2. 是否可以永久停止 SD WebUI 和 hair_service_sd?
|
||
3. steps 从 6 降到 2 是否可接受(需要质量验证)?
|