# 目标:所有接口 < 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 是否可接受(需要质量验证)?