问题:接口2 与接口3/5 乱序调用时耗时抖动(最差 15~22s)。两个根因: 1. GPU 24G 常驻 21.4G,Flux-2(3.9G) 无法完全驻留显存,每次采样动态换页, 速度随空闲显存波动(2s~8s); 2. ComfyUI 单队列 FIFO,接口2 排在接口3/5 批量任务后面。 改动: - hairline/comfyui.py: run() 新增 front 参数,/prompt 带 "front": true 插队到队列最前; redraw.py 透传;service.py 接口2 三处调用(女重绘 + 男有/无遮罩)传 front=True, 接口3/5 仍走普通队列。 - add_hair.json / 0716add-hair-api.json: 节点61 CLIPLoader device default→cpu。 qwen CLIP(4G) 不再占显存(文本条件缓存常年命中),ComfyUI 显存 8.8G→4.5G, Flux-2 完全驻留,采样稳定 ~3-5s。代价:换 prompt 后首次请求 CPU 编码 ~11s(一次性)。 - 提示词全局统一为「填充遮罩区域的头发,皮肤加一点磨皮,再加一点美颜」: app.py 4处默认值、service.py _REDRAW_PROMPT、redraw.py _DEFAULT_PROMPT、 4个工作流节点60内置文案、测试页(test_interface2/3/7/12/12_final)、local_test。 任何两个不同 prompt 交替提交都会打爆 CLIP 编码缓存(--cache-classic 只存最近一次), 之前测试页旧文案与服务端不一致导致交替测试每次 +11s。 - app.py: 接口7 /api/v1/hair/grow-v2 下线(业务弃用;add_hair2.json 的 Klein-9b 会把常驻 Klein-4b 挤出显存)。保留 stub 返回 1007 明确报错,避免裸 404。 实测(1024 档):接口2女 8.5~10s、接口2男 ~5s、接口3 ~7-10s,交替混跑无尖刺。 Co-authored-by: Cursor <cursoragent@cursor.com>
327 lines
4.9 KiB
JSON
327 lines
4.9 KiB
JSON
{
|
|
"16": {
|
|
"class_type": "UNETLoader",
|
|
"inputs": {
|
|
"unet_name": "flux-2-klein-4b-fp8.safetensors",
|
|
"weight_dtype": "fp8_e4m3fn_fast"
|
|
}
|
|
},
|
|
"3": {
|
|
"class_type": "VAELoader",
|
|
"inputs": {
|
|
"vae_name": "flux2-vae.safetensors"
|
|
}
|
|
},
|
|
"61": {
|
|
"class_type": "CLIPLoader",
|
|
"inputs": {
|
|
"clip_name": "qwen_3_4b.safetensors",
|
|
"type": "flux2",
|
|
"device": "cpu"
|
|
}
|
|
},
|
|
"26": {
|
|
"class_type": "LoadImage",
|
|
"inputs": {
|
|
"image": "placeholder.png"
|
|
}
|
|
},
|
|
"60": {
|
|
"class_type": "JjkText",
|
|
"inputs": {
|
|
"text": "填充遮罩区域的头发,皮肤加一点磨皮,再加一点美颜"
|
|
}
|
|
},
|
|
"22": {
|
|
"class_type": "CLIPTextEncode",
|
|
"inputs": {
|
|
"clip": [
|
|
"61",
|
|
0
|
|
],
|
|
"text": [
|
|
"60",
|
|
0
|
|
]
|
|
}
|
|
},
|
|
"31": {
|
|
"class_type": "easy imageSize",
|
|
"inputs": {
|
|
"image": [
|
|
"26",
|
|
0
|
|
]
|
|
}
|
|
},
|
|
"33": {
|
|
"class_type": "Mask Fill Holes",
|
|
"inputs": {
|
|
"masks": [
|
|
"26",
|
|
1
|
|
]
|
|
}
|
|
},
|
|
"36": {
|
|
"class_type": "Convert Masks to Images",
|
|
"inputs": {
|
|
"masks": [
|
|
"33",
|
|
0
|
|
]
|
|
}
|
|
},
|
|
"39": {
|
|
"class_type": "ImageScale",
|
|
"inputs": {
|
|
"image": [
|
|
"36",
|
|
0
|
|
],
|
|
"upscale_method": "nearest-exact",
|
|
"width": [
|
|
"31",
|
|
0
|
|
],
|
|
"height": [
|
|
"31",
|
|
1
|
|
],
|
|
"crop": "disabled"
|
|
}
|
|
},
|
|
"37": {
|
|
"class_type": "Image To Mask",
|
|
"inputs": {
|
|
"image": [
|
|
"39",
|
|
0
|
|
],
|
|
"method": "intensity"
|
|
}
|
|
},
|
|
"32": {
|
|
"class_type": "LayerUtility: ImageScaleByAspectRatio V2",
|
|
"inputs": {
|
|
"image": [
|
|
"26",
|
|
0
|
|
],
|
|
"mask": [
|
|
"37",
|
|
0
|
|
],
|
|
"aspect_ratio": "custom",
|
|
"proportional_width": [
|
|
"31",
|
|
0
|
|
],
|
|
"proportional_height": [
|
|
"31",
|
|
1
|
|
],
|
|
"fit": "letterbox",
|
|
"method": "lanczos",
|
|
"round_to_multiple": "8",
|
|
"scale_to_side": "None",
|
|
"scale_to_length": 1024,
|
|
"background_color": "#000000"
|
|
}
|
|
},
|
|
"44": {
|
|
"class_type": "ImageAndMaskPreview",
|
|
"inputs": {
|
|
"image": [
|
|
"32",
|
|
0
|
|
],
|
|
"mask": [
|
|
"32",
|
|
1
|
|
],
|
|
"mask_opacity": 1,
|
|
"mask_color": "FFFF00",
|
|
"pass_through": true
|
|
}
|
|
},
|
|
"14": {
|
|
"class_type": "GetImageSize+",
|
|
"inputs": {
|
|
"image": [
|
|
"44",
|
|
0
|
|
]
|
|
}
|
|
},
|
|
"13": {
|
|
"class_type": "VAEEncode",
|
|
"inputs": {
|
|
"pixels": [
|
|
"44",
|
|
0
|
|
],
|
|
"vae": [
|
|
"3",
|
|
0
|
|
]
|
|
}
|
|
},
|
|
"2": {
|
|
"class_type": "ModelSamplingFlux",
|
|
"inputs": {
|
|
"model": [
|
|
"16",
|
|
0
|
|
],
|
|
"max_shift": 1.15,
|
|
"base_shift": 0.5,
|
|
"width": [
|
|
"14",
|
|
0
|
|
],
|
|
"height": [
|
|
"14",
|
|
1
|
|
]
|
|
}
|
|
},
|
|
"19": {
|
|
"class_type": "FluxGuidance",
|
|
"inputs": {
|
|
"conditioning": [
|
|
"22",
|
|
0
|
|
],
|
|
"guidance": 1
|
|
}
|
|
},
|
|
"5": {
|
|
"class_type": "ReferenceLatent",
|
|
"inputs": {
|
|
"conditioning": [
|
|
"19",
|
|
0
|
|
],
|
|
"latent": [
|
|
"13",
|
|
0
|
|
]
|
|
}
|
|
},
|
|
"7": {
|
|
"class_type": "EmptySD3LatentImage",
|
|
"inputs": {
|
|
"width": [
|
|
"14",
|
|
0
|
|
],
|
|
"height": [
|
|
"14",
|
|
1
|
|
],
|
|
"batch_size": 1
|
|
}
|
|
},
|
|
"1": {
|
|
"class_type": "BasicScheduler",
|
|
"inputs": {
|
|
"model": [
|
|
"2",
|
|
0
|
|
],
|
|
"scheduler": "simple",
|
|
"steps": 4,
|
|
"denoise": 1
|
|
}
|
|
},
|
|
"20": {
|
|
"class_type": "BasicGuider",
|
|
"inputs": {
|
|
"model": [
|
|
"2",
|
|
0
|
|
],
|
|
"conditioning": [
|
|
"5",
|
|
0
|
|
]
|
|
}
|
|
},
|
|
"6": {
|
|
"class_type": "RandomNoise",
|
|
"inputs": {
|
|
"noise_seed": 0
|
|
}
|
|
},
|
|
"8": {
|
|
"class_type": "KSamplerSelect",
|
|
"inputs": {
|
|
"sampler_name": "euler"
|
|
}
|
|
},
|
|
"9": {
|
|
"class_type": "SamplerCustomAdvanced",
|
|
"inputs": {
|
|
"noise": [
|
|
"6",
|
|
0
|
|
],
|
|
"guider": [
|
|
"20",
|
|
0
|
|
],
|
|
"sampler": [
|
|
"8",
|
|
0
|
|
],
|
|
"sigmas": [
|
|
"1",
|
|
0
|
|
],
|
|
"latent_image": [
|
|
"7",
|
|
0
|
|
]
|
|
}
|
|
},
|
|
"10": {
|
|
"class_type": "VAEDecode",
|
|
"inputs": {
|
|
"samples": [
|
|
"9",
|
|
0
|
|
],
|
|
"vae": [
|
|
"3",
|
|
0
|
|
]
|
|
}
|
|
},
|
|
"62": {
|
|
"class_type": "ColorMatch",
|
|
"inputs": {
|
|
"image_ref": [
|
|
"26",
|
|
0
|
|
],
|
|
"image_target": [
|
|
"10",
|
|
0
|
|
],
|
|
"method": "mkl",
|
|
"strength": 1,
|
|
"multithread": true
|
|
}
|
|
},
|
|
"17": {
|
|
"class_type": "SaveImage",
|
|
"inputs": {
|
|
"images": [
|
|
"62",
|
|
0
|
|
],
|
|
"filename_prefix": "hair_inpaint"
|
|
}
|
|
}
|
|
} |