Files
hair/docs/optimization_plans_v2.md
T
2026-07-18 15:30:31 +08:00

299 lines
8.7 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.
# 优化方案 V2 — 修订版(约束:保留 swapHair + 保留所有服务)
> 日期:2026-07-18
> 约束:不能去掉 swapHair、不能停止 hair_service_sd 和 SD WebUI
---
## 根因总结
**ComfyUI 未启用 `--gpu-only`,默认在每次请求后卸载模型到 CPU。**
9B FP8 模型(8.8GB) + 文本编码器(7.7GB) + VAE(0.3GB) = **16.8GB 模型显存**,可用 20GB 中仅剩 3.2GB 给 KSampler 执行 → ComfyUI 自动部分卸载模型 → 下次请求重新加载 → **每次浪费 8-15 秒**
### 关键发现
| 项目 | 值 |
|------|-----|
| GPU | RTX 5090 (32GB) |
| PyTorch | 2.7.1+cu128 (**已支持 sm_120**) |
| ComfyUI 启动参数 | `--listen 127.0.0.1 --port 8188`(无 --gpu-only |
| 当前模型 | 9B FP8 (8.8GB) |
| **4B FP8 模型已在磁盘** | **3.8GB**`diffusion_models/flux-2-klein-4b-fp8.safetensors` |
| 4B 文本编码器已在磁盘 | 7.5GB(`text_encoders/qwen_3_4b.safetensors` |
| 可用显存(ComfyUI | ~20GB32GB - 8GB hair - 3.2GB SD WebUI - 0.7GB Hair |
### 两种工作流对比
| 维度 | 0716add-hair-api.json (接口2女) | add_hair.json (接口2男/接口3) |
|------|------|------|
| 节点数 | 27 | 29 |
| 模型 | flux-2-klein-9b-fp8 | flux-2-klein-9b-fp8 (相同) |
| 文本编码器 | qwen_3_8b_fp8mixed | qwen_3_8b_fp8mixed (相同) |
| VAE | flux2-vae | flux2-vae (相同) |
| KSampler steps | **4** | **6** |
| 输出文件名 | hair_inpaint_XXXXX | ComfyUI_XXXXX |
**两个工作流加载完全相同的模型,仅 steps 不同。模型换出的根因是 ComfyUI 的默认卸载策略,不是工作流切换。**
---
## 方案 A--gpu-only + 统一 steps=4(最小改动)
### 思路
给 ComfyUI 加 `--gpu-only` 标志,禁止模型在 GPU↔CPU 之间转移。同时统一两个工作流的 steps 为 4,减少推理时间。
### 具体改动
#### A1. ComfyUI 启动加 --gpu-only
```bash
# 修改 ComfyUI 启动命令
python main.py --listen 127.0.0.1 --port 8188 --gpu-only
```
`--gpu-only` 让 ComfyUI 启动后将所有模型权重保留在 GPU 显存中,不自动卸载到 CPU。
#### A2. 统一 add_hair.json 的 steps 为 4
```json
// add_hair.json 节点 9 (SamplerCustomAdvanced)
// 将 steps 从 6 改为 4
```
#### A3. 显存验证
| 组件 | 显存 |
|------|------|
| 9B FP8 模型 | 8.8 GB |
| 文本编码器 (8B FP8) | 7.7 GB |
| VAE | 0.3 GB |
| KSampler 执行 | ~3-4 GB |
| **ComfyUI 总需求** | **~20-21 GB** |
| **可用** | **~20 GB** |
| **余量** | **-1 ~ 0 GB** ⚠ |
**风险**9B 模型 + --gpu-only 可能刚好 OOM。需要实测。
### 预期耗时
| 接口 | 当前 | 方案A | 达标 |
|------|------|-------|------|
| 接口2-女 | 17.6s | ~11sswapHair 4.6s + ComfyUI 4s + 预处理 1.5s + 余量 1s | ❌ 差1s |
| 接口2-男 | 8.1s | ~6sComfyUI 4s + 预处理 2s | ✅ |
| 接口3 | 22.9s | ~6sComfyUI 4s + 预处理 1.6s | ✅ |
### 优点
- 改动极小(1行启动参数 + 1个JSON值)
- 不换模型,质量不变
- 可快速验证
### 缺点
- **9B 模型可能 OOM**(仅 0-1GB 余量)
- 接口2女仍 ~11sswapHair 是硬瓶颈)
- `--gpu-only` 在显存不足时可能导致 ComfyUI 崩溃
---
## 方案 B:换 4B FP8 模型 + --gpu-only(推荐)
### 思路
9B FP88.8GB)换成 4B FP83.8GB),省 5GB 显存。模型+编码器从 16.8GB 降到 11.6GBKSampler 有 8.4GB 余量,彻底消除模型换出。4B 模型同样用 4 步推理,速度相当或更快。
### 磁盘上已有模型
```
ComfyUI/models/diffusion_models/flux-2-klein-4b-fp8.safetensors 3.8 GB ✅已存在
ComfyUI/models/text_encoders/qwen_3_4b.safetensors 7.5 GB ✅已存在
ComfyUI/models/vae/flux2-vae.safetensors 0.3 GB ✅已存在
```
**无需下载任何新文件!**
### 具体改动
#### B1. 修改两个工作流的模型加载节点
```python
# 0716add-hair-api.json 和 add_hair.json
# 节点 16 (UNETLoader): unet_name
"flux2.0/flux-2-klein-9b-fp8.safetensors"
"flux-2-klein-4b-fp8.safetensors"
# 节点 61 (CLIPLoader): clip_name
"qwen_3_8b_fp8mixed.safetensors"
"qwen_3_4b.safetensors"
```
#### B2. ComfyUI 启动加 --gpu-only
```bash
python main.py --listen 127.0.0.1 --port 8188 --gpu-only
```
#### B3. 统一 steps 为 4
add_hair.json 的 steps 从 6 改为 4。
#### B4. 显存验证
| 组件 | 显存 |
|------|------|
| 4B FP8 模型 | 3.8 GB |
| 文本编码器 (4B BF16) | 7.5 GB |
| VAE | 0.3 GB |
| KSampler 执行 | ~3-4 GB |
| **ComfyUI 总需求** | **~15-16 GB** |
| **可用** | **~20 GB** |
| **余量** | **+4-5 GB** ✅ 安全 |
### 预期耗时
| 接口 | 当前 | 方案B | 达标 |
|------|------|-------|------|
| 接口2-女 | 17.6s | ~11sswapHair 4.6s + ComfyUI 3s + 预处理 1.5s + 余量 2s | ❌ 差1s |
| 接口2-男 | 8.1s | ~5sComfyUI 3s + 预处理 2s | ✅ |
| 接口3 | 22.9s | ~5sComfyUI 3s + 预处理 1.6s | ✅ |
### 4B vs 9B 质量差异
根据公开资料:
- 4B 模型设计目标是"在消费级 GPU 上实现实时生成"
- 4 步推理,与 9B 相同
- 4B 是 Apache 2.0 开源,9B 是非商用许可
- 质量差异:4B 在复杂场景和细节上略逊于 9B,但对头发补全这类局部重绘任务影响可能较小
- **需要实际对比测试验证**
### 优点
- 模型已在磁盘,无需下载
- 显存余量充足(+4-5GB),不会 OOM
- 4B 模型推理速度更快
- 可彻底消除模型换出
- 不影响其他服务
### 缺点
- 需要质量验证(4B vs 9B
- 需修改两个工作流 JSON
- 接口2女仍 ~11sswapHair 是硬瓶颈)
---
## 方案 C4B FP8 + --gpu-only + SegFormer→GPU + steps=2(激进优化)
### 思路
在方案B基础上进一步优化:
1. SegFormer 移到 GPUtorch 已是 cu128,支持 5090
2. steps 降到 2(需质量验证)
3. swapHair 与预处理并行
### 具体改动
#### C1-C3:同方案B
#### C4. SegFormer 移到 GPU
```python
# hairline/face_parsing.py 或环境变量
# 当前 SegFormer 跑 CPU~0.9s/张)
# torch 2.7.1+cu128 已支持 RTX 5090 (sm_120)
export SEG_DEVICE=cuda
# 预期:0.9s → 0.05s
```
#### C5. steps 降到 2
```json
// add_hair.json + 0716add-hair-api.json
// KSampler steps: 4 → 2
```
Flux-2 Klein 是 step-distilled 模型,设计为 4 步。降到 2 步会有质量损失,需验证。
#### C6. swapHair 与预处理并行
```
当前流程:
预处理(1.5s) → swapHair(4.6s) → ComfyUI(3s) = 9.1s
优化后(并行):
预处理(1.5s) ─┐
├→ ComfyUI(3s) = 6.1s
swapHair(4.6s) ┘
```
### 显存验证
| 组件 | 显存 |
|------|------|
| 4B FP8 模型 | 3.8 GB |
| 文本编码器 (4B) | 7.5 GB |
| VAE | 0.3 GB |
| SegFormer (GPU) | ~0.5 GB |
| KSampler 执行 | ~2-3 GBsteps=2 更少) |
| **ComfyUI 总需求** | **~14-15 GB** |
| **可用** | **~20 GB** |
| **余量** | **+5-6 GB** ✅ |
### 预期耗时
| 接口 | 当前 | 方案C | 达标 |
|------|------|-------|------|
| 接口2-女 | 17.6s | ~7sswapHair 4.6s ∥ 预处理 0.6s + ComfyUI 2s | ✅ |
| 接口2-男 | 8.1s | ~4sComfyUI 2s + 预处理 1s | ✅ |
| 接口3 | 22.9s | ~4sComfyUI 2s + 预处理 0.7s | ✅ |
### 优点
- 所有接口达标(<10s
- SegFormer GPU 化(torch cu128 已支持)
- swapHair 并行化进一步优化接口2女
### 缺点
- steps=2 质量需验证
- SegFormer GPU 需修改代码
- swapHair 并行需重构 service.py
- 改动量最大
---
## 三方案对比
| 维度 | A (--gpu-only+steps=4) | B (4B FP8+--gpu-only) | C (4B+GPU SegFormer+steps=2) |
|------|----------------------|----------------------|------------------------------|
| 改动量 | 极小 | 小 | 中 |
| 需下载 | 无 | 无 | 无 |
| 接口2-女 | ~11s ❌ | ~11s ❌ | ~7s ✅ |
| 接口2-男 | ~6s ✅ | ~5s ✅ | ~4s ✅ |
| 接口3 | ~6s ✅ | ~5s ✅ | ~4s ✅ |
| 显存安全 | ⚠ 紧张(0-1GB) | ✅ 安全(+4GB) | ✅ 宽裕(+5GB) |
| 质量风险 | 无 | 中(4B vs 9B | 高(4B+steps=2 |
| OOM 风险 | 高 | 低 | 极低 |
---
## 建议
### 第一阶段:先做方案B
1. 修改两个工作流 JSON:换 4B FP8 模型 + 4B 文本编码器
2. ComfyUI 加 `--gpu-only`
3. 统一 steps=4
4. 跑一轮质量对比(4B vs 9B 的生发效果)
5. 跑轮换测试验证耗时
**如果接口3和接口2男达标(<10s),接口2女接近(~11s),则进入第二阶段。**
### 第二阶段:方案C 追加优化(解决接口2女)
6. SegFormer 移到 GPU(环境变量 SEG_DEVICE=cuda
7. swapHair 与预处理并行化
8. 如果质量允许,steps 降到 2-3
### 需要你确认
1. **是否先用方案B4B FP8 + --gpu-only)做一轮测试?**
2. **4B 模型质量是否需要先对比验证,还是可以直接切换后看效果?**
3. **方案C 的 steps=2 是否可以接受(需要质量验证)?**