Stable Diffusion ControlNet详解

1 人参与

说起 ControlNet,大多数人第一反应是“哦,就是那个能控制姿势和构图的插件”。但真到了实际项目里,你就会发现,它远不止“加个控制”这么简单。很多设计师对着同一张白模图反复抽卡,不是手歪了,就是材质跑偏,归根结底是没搞懂 ControlNet 到底在底层干了什么事。

Stable Diffusion ControlNet详解

它到底是怎么“控制”的?

ControlNet 的本质,不是往 SD 模型里硬塞一个新功能,而是在原有 UNet 结构上平行地加了一条“指挥通道”。它复制了 UNet 的编码器前几层,并且用零卷积(zero convolution)初始化——这也就意味着,初始状态下它对原模型毫无影响。只有当你输入了一张条件图(比如 Canny 边缘、深度图或姿态骨架),这条通道才会逐渐学会“在哪个时间步、哪个空间位置去干预特征图”。

换句话说,SD 原本像一个自由发挥的画家,而 ControlNet 就是在他耳边轻声提示“这里线条应该更硬一些”,但绝不动他握笔的手。这种训练方式保证了原始模型的风格和多样性几乎不受损,同时又能精准响应外部信号。

不同的“提示方式”各有脾气

  • Canny 模型吃的是白底黑线的边缘图。但它有个小秘密:边缘检测时的阈值如果设得太低,连木纹的细碎花纹都会被当成轮廓,导致生成结果杂乱得像一团毛线;设得太高,又会把墙的转角直接抹掉。室内设计里,我一般把下阈值设在 100,上阈值设在 200,这样既能保留主结构,又不会让软装细节被“框死”。

  • Depth 模型更看重虚实关系。如果你用 MiDaS 直接估算深度,遇到透明玻璃或镂空隔断时,往往会出错——玻璃会被当成一面实墙,深度图直接一片白。这时候需要人工在深度图上把玻璃区域涂成中间灰,告诉模型“这是半透的”。

  • Segmentation (语义分割) 模型是室内工作流的硬通货。原文课程里反复提到“把 Rhino/3DMax 调成纯色窗口”,其实就是为了让分割图颜色纯粹,避免因为模型训练时使用的 ADE20K 数据集颜色映射混乱而误判。一个常见坑:米黄色墙面在分割图里很容易被识别为“地板”,解决方法是在调色阶段把相近色块的距离拉大,比如墙面用 RGB(150, 0, 0),地板用 RGB(0, 150, 0)。

权重、Control Mode 和“打架”

很多人以为 ControlNet 权重越高越听话,实际上权重超过 1.2 后,模型反而容易“死板”——所有细节都被挤压成条件图的翻版,毫无光影灵气。更关键的是 Control Mode 里的“均衡”“偏向原图”“更偏向控制”三个选项。Mode 决定的是当 ControlNet 与 Prompt 冲突时谁说了算。比如你写了一个“皮革沙发”,但 ControlNet 传入了木纹桌子的一张图,Mode 设成“更偏向控制”后,模型会强行生成木纹桌子,哪怕 prompt 写了沙发。所以复杂场景里,我通常先用“平衡”,等主体轮廓稳定了,再单独对某个元素用“偏向原图”微调。

别被“模型数量”骗了

ControlNet 1.1 版本后,官方把 Canny、MLSD、Lineart 等合并成了一套更紧凑的架构,但社区里依然流传着各种“.pth”和“.safetensors”。实际上日常出图真正高频使用的无非三个:Canny(控制轮廓)、OpenPose(控制人物姿势)、Tile(用于放大和修复细节)。Tile 模型尤其有意思——它通过把原图切成小块并随机遮挡来学习局部修复,相当于给 SD 装了一个“局部重绘增强器”,门槛比用 Inpainting 低得多。

严格来说,ControlNet 不是魔法,而是一种“聪明的约束”。理解了它怎么读图、怎么干预、怎么与 prompt 博弈,你手里那个“始终抽不到理想图”的 SD 才算真正活了过来。下次再遇到生成结果翻车,别急着改 prompt,先看看 ControlNet 输入的那张图是不是已经在出卖你。

参与讨论

1 条评论