ControlNet 通过零卷积分支将空间条件信号注入扩散模型,实现像素级结构控制,解决了传统扩散模型难以精确控制构图、姿态的痛点。
核心原理
架构设计
在 Stable Diffusion 架构中增加"控制分支",解析控制图(如线稿、姿态图),强制生成结果遵循结构约束:
$$F_{out} = F_{base}(z) + \alpha \cdot F_{control}(c)$$
零卷积初始化
1
2
3
4
5
6
| class ZeroConv2d(nn.Module):
def __init__(self, in_ch, out_ch):
super().__init__()
self.conv = nn.Conv2d(in_ch, out_ch, 1)
self.conv.weight.data.zero_()
self.conv.bias.data.zero_()
|
确保训练初期 ControlNet 对原始模型影响为零,保护预训练模型的生成能力。
控制类型
| 条件类型 | 控制功能 | 典型应用 |
|---|
| Canny 边缘图 | 轮廓约束 | 线稿转彩色图像 |
| OpenPose | 人体姿势控制 | 人物插画姿势调整 |
| 深度图 | 空间透视控制 | 建筑场景构图设计 |
| 语义分割图 | 物体类别布局约束 | 室内设计家具摆放 |
| Scribble 草图 | 自由线条引导 | 快速概念图生成 |
使用示例
Canny 边缘检测
1
2
3
4
5
6
7
8
9
10
11
12
| from diffusers import StableDiffusionControlNetPipeline, ControlNetModel
controlnet = ControlNetModel.from_pretrained("lllyasviel/sd-controlnet-canny", torch_dtype=torch.float16)
pipe = StableDiffusionControlNetPipeline.from_pretrained(
"runwayml/stable-diffusion-v1-5", controlnet=controlnet, torch_dtype=torch.float16
).to("cuda")
image = pipe(
prompt="a sleek wireless headphone, futuristic design",
image=canny_image,
controlnet_conditioning_scale=1.0
).images[0]
|
OpenPose 姿势控制
1
2
3
4
| from controlnet_aux import OpenposeDetector
openpose = OpenposeDetector.from_pretrained('lllyasviel/ControlNet')
controlnet = ControlNetModel.from_pretrained("lllyasviel/sd-controlnet-openpose", torch_dtype=torch.float16)
|
性能优化
1
2
| pipe.enable_xformers_memory_efficient_attention() # 启用 xformers 加速
pipe.enable_model_cpu_offload() # 启用 CPU 卸载
|
性能对比
| 指标 | ControlNet v1.1 | SD ControlNet v1.1 |
|---|
| FID↓ | 15.2 | 18.5 |
| CLIPSIM↑ | 0.82 | 0.78 |
未来方向
Comments