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

8.7 KiB
Raw Blame History

优化方案 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.8GBdiffusion_models/flux-2-klein-4b-fp8.safetensors
4B 文本编码器已在磁盘 7.5GBtext_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

# 修改 ComfyUI 启动命令
python main.py --listen 127.0.0.1 --port 8188 --gpu-only

--gpu-only 让 ComfyUI 启动后将所有模型权重保留在 GPU 显存中,不自动卸载到 CPU。

A2. 统一 add_hair.json 的 steps 为 4

// 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. 修改两个工作流的模型加载节点

# 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

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

# 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

// 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女)

  1. SegFormer 移到 GPU(环境变量 SEG_DEVICE=cuda
  2. swapHair 与预处理并行化
  3. 如果质量允许,steps 降到 2-3

需要你确认

  1. 是否先用方案B4B FP8 + --gpu-only)做一轮测试?
  2. 4B 模型质量是否需要先对比验证,还是可以直接切换后看效果?
  3. 方案C 的 steps=2 是否可以接受(需要质量验证)?