久流
出图出多了,废图也攒得多。十张里往往有七八张构图、人设、氛围都在线,偏偏手崩了、眼花了、脸歪了一点。整图重抽等于把对的部分一起扔掉,成本太高。局部重绘解决的就是这个问题:只动出问题的区域,其余像素原样保留。
这篇文档整理我目前常用的两套局部重绘模板。两套的修复链路完全一样,差别只有一处:模型加载区。一套跑 Illustrious 系的单文件 checkpoint,一套跑 Anima 系的三件套,正好借这两个例子把 ComfyUI 里两种模型加载方式一次讲清楚。
局部重绘的两条路
ComfyUI 里做局部重绘,常见的有两条路。
一条是手动蒙版。加载图片,自己涂 mask,接 Set Latent Noise Mask(或 VAE Encode for Inpainting)再跑采样。想改哪改哪,自由度最高,代价是每张图都要动手涂,蒙版边缘处理不好还会留一圈色差。适合偶尔修一两张、或者要大改构图的场合。
另一条是自动检测修复。用目标检测模型把脸、眼、手、脚这些部位自动框出来,裁切放大后各自跑一次低重绘幅度的采样,再羽化贴回原图。全程不涂蒙版,批量丢一沓图进去也能挂机跑完。这两套模板走的是这条路,骨架是 Impact Pack 的 Detailer 系列。
原理一句话就能说清:把检测到的区域裁下来放大到工作分辨率,当成一张独立小图做一次 img2img,重绘幅度压得很低,只修细节不动结构,完成后贴回原位。整个流程串起来是:
载入图片 → 检测脸部 → 裁切放大 → 低幅度重绘 → 贴回原图 → 检测眼睛 → 重复 → 检测手 → 重复 → 检测脚 → 重复 → NSFW 分区 → 保存两套模板里这段链重复了五轮,每一轮只换检测器和区域提示词,其余完全一致。
模型区:两套模板唯一的分叉
这是两份工作流真正不同的地方,值得单独拆开讲。
IL 版:单文件 checkpoint,一个节点全包
IL 版跑的是 waiIllustriousSDXL_v170.safetensors。WAI 系是标准的 Illustrious/SDXL checkpoint,单文件里打包了 UNet、CLIP、VAE 三样东西。所以加载只需要一个 CheckpointLoaderSimple 节点,三个输出口各接各的:MODEL 和 CLIP 进 LoRA 挂载位,VAE 拉一根长线直接分给五段修复。SDXL、Illustrious、Pony 这类以 checkpoint 形式发布的模型,都是这个接法。
Anima 版:三件套,三个 loader 各管各的
Anima 版跑的是 chosenIrisesMix_v20Anima。这里的 Anima 指 CircleStone Labs 和 Comfy Org 合作的 2B 参数动漫模型,底子是 NVIDIA Cosmos-Predict2 的 DiT 架构。这个系的东西官方就不发布单文件 checkpoint,而是拆成三个文件,各归各位:
- 扩散模型放 models/diffusion_models,用 UNETLoader 加载,模板里是 chosenIrisesMix_v20Anima.safetensors;
- 文本编码器放 models/text_encoders,用 CLIPLoader 加载,模板里是 chosenIrisesMix_v20Anima_txt.safetensors。Anima 原生的文本编码器基于 Qwen3-0.6B,个头只有 1GB 出头,比 SDXL 那对双编码器轻不少;
- VAE 用 qwen_image_vae.safetensors,放 models/vae,用 VAELoader 加载。这个 VAE 和 Qwen-Image 通用。
chosenIrisesMix 这个合并包跟着 Anima 的发布形态走,同样拆成了三份。三个 loader 的输出最后汇到同一个地方,下游链路感知不到上游是单文件还是三件套。
两条路怎么选
判断标准看下载页。标 Checkpoint 的单文件,用 CheckpointLoaderSimple;标 Diffusion Model、按 diffusion_models / text_encoders / vae 三个目录分别发布的,用 UNETLoader 加 CLIPLoader 加 VAELoader。把 Anima 系的扩散模型塞进 CheckpointLoaderSimple 会直接报错——那个节点要从文件里同时找到 UNet、CLIP、VAE 三套权重,三件套里它什么都凑不齐。反过来,把 SDXL checkpoint 拆开加载纯属自找麻烦。
对照表放这里,换模型的时候对着看:
| IL 版 | Anima 版 | |
|---|---|---|
| 模型文件 | waiIllustriousSDXL_v170.safetensors | chosenIrisesMix_v20Anima 三件套 |
| 架构 | SDXL(Illustrious 系) | Cosmos-Predict2 底子的 2B DiT |
| 加载节点 | CheckpointLoaderSimple 一个 | UNETLoader、CLIPLoader、VAELoader 各一个 |
| 文件落位 | models/checkpoints | diffusion_models、text_encoders、vae 三个目录 |
| 文本编码器 | 内置 CLIP-G/L | Qwen3-0.6B 底子,独立文件 |
| VAE | 内置 | 独立 qwen_image_vae |
共同的汇合点
两套模板里,MODEL 和 CLIP 都先过 rgthree 的 Power Lora Loader 再往下走,VAE 不经 LoRA 直接分发。把 LoRA 挂载位放在最上游,五段修复共用一次挂载,不用每段重复接。模板里预置了几个画风和角色 LoRA 的槽位,默认全部关闭——局部重绘多数时候用底模就够,除非修的就是特定角色的图。
检测器:五段修复五双眼睛
五段修复各配一个检测模型,都通过 Impact Subpack 的 UltralyticsDetectorProvider 加载,文件放 models/ultralytics/bbox,分割模型放 segm:
| 修复段 | 检测器 | 说明 |
|---|---|---|
| 脸 | bbox/face_yolov9c.pt | 通用人脸检测 |
| 眼 | bbox/Eyeful_v2-Individual.pt | 专门盯眼睛 |
| 手 | bbox/hand_yolov9c.pt | 手部检测 |
| 脚 | bbox/FootYolov8x_v20.pt | 脚部检测 |
| NSFW | bbox/ntd11_anime_nsfw_segm_v3_all.pt | 分割模型,按部位出标签 |
前四个是 bbox 模型,只负责框。NSFW 这一个是 segm 分割模型,能按部位给出标签和形状,配合后面要说的标签语法,可以做到检测到哪个部位就只补哪个部位的词。
每段还各挂一个 SAMLoader(sam_vit_b_01ec64.pth,放 models/sams)。检测框框住的是"这一片",SAM 在框内再勾一遍"这一块"的实际轮廓,贴回时的边缘明显更准。五段各配一个 SAM 而不是共用,是 DetailerPipe 的打包结构决定的,这点开销不心疼。
组装与串联
打包:ToDetailerPipe 与 EditDetailerPipe
ToDetailerPipe 是个打包节点,把一次修复需要的原料捆成一根管道:model、clip、vae、正面词、反面词、bbox 检测器、SAM 模型。五段修复各打各的包,互不干扰。
model 在进包之前先过一个 DifferentialDiffusion。这个节点让噪声的施加考虑蒙版的软硬过渡,重绘区域和保留区域的衔接更平滑,贴回痕迹更轻。它不开白不开,所以每段都串了。
EditDetailerPipe 接在 ToDetailerPipe 后面,负责往管道里注入区域提示词,用 [CONCAT] 前缀把区域词拼到底稿正面词的后面。脸部段填的是 [CONCAT] {face|face,detailed face},大括号是通配符,每次执行随机二选一,给修复留一点变化。手段直接写死:[CONCAT] hand, perfect hands。脚段同理。
NSFW 段的写法特殊一点,用的是标签语法:
[LAB][ALL] nsfw[NIPPLES] nsfw, nipples[PUSSY] nsfw, pussy[ANUS] nsfw, (anus)[PENIS] nsfw, penis[TESTICLES] nsfw, testicles方括号里的标签对应分割模型输出的部位名,检测命中哪个部位,就只把对应的行拼进提示词,不是无脑全上。
执行链与收尾
五段 FaceDetailerPipe 头尾相接。载入的图先过脸部段,出来的图进眼部段,之后依次是手、脚、NSFW,最后出图。任何一段没检测到目标,图就原样穿过去,不会报错。
每两段之间挂一个 rgthree 的 Image Comparer,把这一段修之前和修之后的图摆在一起。哪段帮了忙、哪段帮了倒忙,一眼就能看出来,调阈值和 denoise 全靠它。
IL 版的收尾多一个开关节点:关着直接保存,打开就先过一遍 4x-AnimeSharp 超分再保存。修完的图细节密度上来了,配合超分出图更干净,要不要超分按图而定。Anima 版没有这一层,修完直接保存。
另外说一句 IL 模板里的遗留物:EmptyLatentImage 和图片宽高两个设置,是文生图模板改过来时留下的,现在的纯修复链路用不到。哪天想做出图到修复一条龙,把 KSampler 接回来就能用。
关键参数
五段修复的参数完全一致,没有给某段单独开小灶:
| 参数 | 值 | 说明 |
|---|---|---|
| guide_size | 512 | 裁切区域放大的目标边长 |
| max_size | 4096 | 裁切图的上限,防大图吃显存 |
| steps | 14 | 小图小任务,够收敛 |
| CFG | 6 | 动漫模型常规值 |
| 采样器 | euler_ancestral / normal | 跟出图模型的常用搭配保持一致 |
| denoise | 0.26 | 全链的核心参数 |
| feather | 16 | 贴回时的羽化宽度 |
| bbox_threshold | 0.4 | 检测置信度阈值,低一点漏检少 |
| bbox_dilation | 8 | 检测框向外扩的像素 |
| bbox_crop_factor | 3 | 裁切范围是检测框的三倍,给上下文 |
| drop_size | 16 | 太小的检测目标直接丢弃 |
| cycle | 1 | 每段只跑一遍 |
denoise 单独展开说。0.26 是这套模板的定海神针:只允许模型在原有结构上做修正,不允许它重新发明。崩掉的眼、错的手指能被压下去,画风、线条、配色基本不动。代价是一次修不干净,崩得狠的图要再跑一遍,或者把那一段单独拎出来提到 0.35 到 0.4。超过 0.5 就开始"重画"了,画风漂移会非常明显。宁可多次低幅度,不要一次高幅度。
提示词的组织
底稿是两个 PrimitiveStringMultiline,一个正面一个反面,标题里都写了"需要打开开关"。这是 Primitive 节点的一个小坑:改完内容还要把节点上的开关打开,值才会传给下游,不然改了等于没改。
正面词出来先过一个正则替换节点,用 ^,|,$ 把首尾多余的逗号清掉。通配符拼接经常留下悬空逗号,清一下干净。反面词五段共用一份,Illustrious 系照常规写:lowres、bad anatomy、画质崩坏那一类。Anima 系的提示词风格和 Illustrious 不同,底稿留空按需填。
IL 版底稿的正面词供参考,是完整的 Danbooru 风格 tag 组:画质词(masterpiece、best quality、very aesthetic 一类)打底,人物和特征词居中,动作和场景词收尾。
用下来的一些经验
- 某段没动静,先看 Image Comparer。框都没框出来是检测问题,动 bbox_threshold 或换检测器;框到了但没修好是 denoise 问题。
- 手是最难的部位。hand_yolov9c 命中率可以,但 0.26 的幅度对严重错指基本无能为力,烂得狠的图我会把手段单独调到 0.4 左右再跑。
- feather 别调太小。羽化太窄,贴回的地方会有一圈隐约的边界;16 在多数图上刚好,还不行就往 24 加。
- 两套模型切换只动模型区这一小块,修复链一根线都不用动。换 checkpoint 就换 CheckpointLoaderSimple 里的文件名,换三件套就三个 loader 各换各的。
- 显存压力主要在单段生成。max_size 4096 意味着极端大图的裁切区域会被压回来,注意这个上限的存在。
这套东西搭完之后基本是挂机用的。思路比节点重要:检测、裁切、低幅度、羽化贴回,四步拆开用什么节点实现都行,Impact Pack 只是把这条链封装得顺手,检测器也是现成的。剩下的活是拿自己的废图喂它,找到自己图库里"修"和"换"的那条分界线。
暂无评论