自从 Stable Diffusion 风靡寰球以来,人们始终在寻求如何更好地管制生成过程的办法。ControlNet 提供了一个简略的迁徙学习办法,可能容许用户在很大水平上自定义生成过程。通过 ControlNet,用户能够轻松地应用多种空间语义条件信息 (例如深度图、宰割图、涂鸦图、关键点等) 来管制生成过程。
具体来说,咱们能够:
将卡通绘图转化为真切的照片,同时放弃极佳的布局连贯性。
写实版的 Lofi Girl (上: 原图,下: 新图)
进行室内设计。
原图 | 新图 |
---|---|
将涂鸦草图变成艺术作品。
原图 | 新图 |
---|---|
甚至拟人化驰名的 logo 形象。
原图 | 新图 |
---|---|
ControlNet,使所有皆有可能 🌠
本文的次要内容:
- 介绍
StableDiffusionControlNetPipeline
- 展现多种管制条件样例
让咱们开启管制之旅!
ControlNet 简述
ControlNet 在 Adding Conditional Control to Text-to-Image Diffusion Models 一文中提被出,作者是 Lvmin Zhang 和 Maneesh Agrawala。它引入了一个框架,反对在扩散模型 (如 Stable Diffusion) 上附加额定的多种空间语义条件来管制生成过程。
训练 ControlNet 包含以下步骤:
- 克隆扩散模型的预训练参数 (文中称为 可训练正本, trainable copy。如 Stable Diffusion 的 latent UNet 局部),同时保留本来的预训练参数 (文中称为 锁定正本, locked copy)。这样能够实现: a) 让锁定正本保留从大型数据集中学到的丰盛常识;b) 让可训练正本学习特定工作的常识。
- 可训练正本和锁定正本的参数通过 “零卷积” 层 (详见 此处) 连贯。“零卷积” 层是 ControlNet 框架的一部分,会在特定工作中优化参数。这是一种训练技巧,能够在新工作条件训练时保留已解冻模型曾经学到的语义信息。
训练 ControlNet 的过程如图所示:
ControlNet 训练集中的其中一种样例如下 (额定的管制条件是 Canny 边缘图):
原始图片 | 利用管制条件 |
---|---|
同样地,如果咱们应用的额定管制条件是语义宰割图,那么 ControlNet 训练集的样例就是这样:
原始图片 | 利用管制条件 |
---|---|
每对 ControlNet 施加一种额定的管制条件,都须要训练一份新的可训练正本参数。论文中提出了 8 种不同的管制条件,对应的管制模型在 Diffusers 中均已反对!
推理阶段须要同时应用扩散模型的预训练权重以及训练过的 ControlNet 权重。如要应用 Stable Diffusion v1-5 以及其 ControlNet 权重推理,其参数量要比仅应用 Stable Diffusion v1-5 多大概 7 亿个,因而推理 ControlNet 须要耗费更多的内存。
因为在训练过程中扩散模型预训练参数为锁定正本,因而在应用不同的管制条件训练时,只须要切换 ControlNet 可训练正本的参数即可。这样在一个应用程序中部署多个 ControlNet 权重就非常简单了,本文会在前面具体介绍。
StableDiffusionControlNetPipeline
在开始之前,咱们要向社区贡献者 Takuma Mori (@takuma104) 示意微小的感激。将 ControlNet 集成到 Diffusers 中,他功不可没 ❤️。
相似 Diffusers 中的 其余 Pipeline,Diffusers 同样为 ControlNet 提供了 StableDiffusionControlNetPipeline
供用户应用。StableDiffusionControlNetPipeline
的外围是 controlnet
参数,它接管用户指定的训练过的 ControlNetModel
实例作为输出,同时放弃扩散模型的预训练权重不变。
本文将介绍 StableDiffusionControlNetPipeline
的多个不同用例。首先要介绍的第一个 ControlNet 模型是 Canny 模型,这是目前最风行的 ControlNet 模型之一,您可能曾经在网上见识过一些它生成的精美图片。在浏览到各个局部的代码时,也欢迎您应用此 Colab 笔记本 运行相干代码片段。
运行代码之前,首先确保咱们曾经装置好所有必要的库:
pip install diffusers==0.14.0 transformers xformers git+https://github.com/huggingface/accelerate.git
为解决不同 ControlNet 对应的多种管制条件,还须要装置一些额定的依赖项:
- OpenCV
- controlnet-aux – ControlNet 预处理模型库
pip install opencv-contrib-python
pip install controlnet_aux
咱们将以驰名的油画作品《戴珍珠耳环的少女》为例,首先让咱们下载这张图像并查看一下:
from diffusers.utils import load_image
image = load_image(
"https://hf.co/datasets/huggingface/documentation-images/resolve/main/diffusers/input_image_vermeer.png"
)
image
而后将图像输出给 Canny 预处理器:
import cv2
from PIL import Image
import numpy as np
image = np.array(image)
low_threshold = 100
high_threshold = 200
image = cv2.Canny(image, low_threshold, high_threshold)
image = image[:, :, None]
image = np.concatenate([image, image, image], axis=2)
canny_image = Image.fromarray(image)
canny_image
如图可见,Canny 实质上是边缘检测器:
接下来,咱们加载 runwaylml/stable-diffusion-v1-5 和 Canny 边缘 ControlNet 模型。设置参数 torch.dtype=torch.float16
能够指定模型以半精度模式加载,可实现内存高效和疾速的推理。
from diffusers import StableDiffusionControlNetPipeline, ControlNetModel
import torch
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
)
这里咱们不应用 Stable Diffusion 默认的 PNDMScheduler 调度器,而应用改良的 UniPCMultistepScheduler (目前最快的扩散模型调度器之一),能够极大地放慢推理速度。经测试,在保障生成图像品质的同时,咱们能将推理阶段的采样步数从 50 降到 20。更多对于调度器的信息能够点击 此处 查看。
from diffusers import UniPCMultistepScheduler
pipe.scheduler = UniPCMultistepScheduler.from_config(pipe.scheduler.config)
咱们通过调用 enable_model_cpu_offload
函数来启用智能 CPU 卸载,而不是间接将 pipeline 加载到 GPU 上。
智能 CPU 卸载是一种升高显存占用的办法。扩散模型 (如 Stable Diffusion) 的推理并不是运行一个独自的模型,而是多个模型组件的串行推理。如在推理 ControlNet Stable Diffusion 时,须要首先运行 CLIP 文本编码器,其次推理扩散模型 UNet 和 ControlNet,而后运行 VAE 解码器,最初运行 safety checker (安全检查器,次要用于审核过滤违规图像)。而在扩散过程中大多数组件仅运行一次,因而不须要始终占用 GPU 内存。通过启用智能模型卸载,能够确保每个组件在不须要参加 GPU 计算时卸载到 CPU 上,从而显著升高显存占用,并且不会显著减少推理工夫 (仅减少了模型在 GPU-CPU 之间的转移工夫)。
留神: 启用 enable_model_cpu_offload
后,pipeline 会主动进行 GPU 内存治理,因而请不要再应用 .to("cuda")
手动将 pipeline 转移到 GPU。
pipe.enable_model_cpu_offload()
最初,咱们要充分利用 FlashAttention/xformers 进行注意力层减速。运行下列代码以实现减速,如果该代码没有起作用,那么您可能没有正确装置 xformers
库,此时您能够跳过该代码。
pipe.enable_xformers_memory_efficient_attention()
根本条件准备就绪,当初来运行 ControlNet pipeline!
跟运行 Stable Diffusion image-to-image pipeline 雷同的是,咱们也应用了文本提醒语来疏导图像生成过程。不过有一些不同的是,ControlNet 容许施加更多品种的管制条件来管制图像生成过程,比方应用方才咱们创立的 Canny 边缘图就能更准确的管制生成图像的构图。
让咱们来看一些乏味的,将 17 世纪的名作《戴珍珠耳环的少女》中的少女一角换为古代的名人会是什么样?应用 ControlNet 就能轻松做到,只须要在提醒语中写上他们的名字即可!
首先创立一个非常简单的帮忙函数来实现生成图像的网格可视化。
def image_grid(imgs, rows, cols):
assert len(imgs) == rows * cols
w, h = imgs[0].size
grid = Image.new("RGB", size=(cols * w, rows * h))
grid_w, grid_h = grid.size
for i, img in enumerate(imgs):
grid.paste(img, box=(i % cols * w, i // cols * h))
return grid
而后输出名字提醒语,并设置随机种子以便复现。
prompt = ", best quality, extremely detailed"
prompt = [t + prompt for t in ["Sandra Oh", "Kim Kardashian", "rihanna", "taylor swift"]] # 别离为: 吴珊卓、金·卡戴珊、蕾哈娜、泰勒·斯威夫特
generator = [torch.Generator(device="cpu").manual_seed(2) for i in range(len(prompt))]
最初运行 pipeline,并可视化生成的图像!
output = pipe(
prompt,
canny_image,
negative_prompt=["monochrome, lowres, bad anatomy, worst quality, low quality"] * 4,
num_inference_steps=20,
generator=generator,
)
image_grid(output.images, 2, 2)
咱们还能轻松地将 ControlNet 与微调联合应用!例如应用 DreamBooth 对模型进行微调,而后应用 ControlNet 减少管制信息,将其渲染到不同的场景中。
本文将以咱们最爱的土豆学生为例,来介绍怎么联合应用 ControlNet 和 DreamBooth。
相较于上文,pipeline 中应用的 ControlNet 局部放弃不变,然而不应用 Stable Diffusion 1.5,而是从新加载一个 土豆学生 模型 (应用 Dreambooth 微调的 Stable Diffusion 模型) 🥔。
尽管 ControlNet 没变,但依然须要从新加载 pipeline。
model_id = "sd-dreambooth-library/mr-potato-head"
pipe = StableDiffusionControlNetPipeline.from_pretrained(
model_id,
controlnet=controlnet,
torch_dtype=torch.float16,
)
pipe.scheduler = UniPCMultistepScheduler.from_config(pipe.scheduler.config)
pipe.enable_model_cpu_offload()
pipe.enable_xformers_memory_efficient_attention()
当初来让土豆学生摆一个《戴珍珠耳环的少女》的姿态吧!
generator = torch.manual_seed(2)
prompt = "a photo of sks mr potato head, best quality, extremely detailed"
output = pipe(
prompt,
canny_image,
negative_prompt="monochrome, lowres, bad anatomy, worst quality, low quality",
num_inference_steps=20,
generator=generator,
)
output.images[0]
看得出来土豆学生尽力了,这场景着实不太适宜他,不过他依然抓住了精华🍟。
ControlNet 还有另一个独特利用: 从图像提取人体姿势,用姿势信息管制生成具备雷同姿势的新图像。因而在下一个示例中,咱们将应用 Open Pose ControlNet 来教超级英雄如何做瑜伽!
首先,咱们须要收集一些瑜伽动作图像集:
urls = "yoga1.jpeg", "yoga2.jpeg", "yoga3.jpeg", "yoga4.jpeg"
imgs = [
load_image("https://huggingface.co/datasets/YiYiXu/controlnet-testing/resolve/main/" + url)
for url in urls
]
image_grid(imgs, 2, 2)
通过 controlnet_aux
提供的 OpenPose 预处理器,咱们能够很不便地提取瑜伽姿势。
from controlnet_aux import OpenposeDetector
model = OpenposeDetector.from_pretrained("lllyasviel/ControlNet")
poses = [model(img) for img in imgs]
image_grid(poses, 2, 2)
瑜伽姿势提取实现后,咱们接着创立一个 Open Pose ControlNet pipeline 来生成一些雷同姿势的超级英雄图像。Let’s go 🚀
controlnet = ControlNetModel.from_pretrained(
"fusing/stable-diffusion-v1-5-controlnet-openpose", torch_dtype=torch.float16
)
model_id = "runwayml/stable-diffusion-v1-5"
pipe = StableDiffusionControlNetPipeline.from_pretrained(
model_id,
controlnet=controlnet,
torch_dtype=torch.float16,
)
pipe.scheduler = UniPCMultistepScheduler.from_config(pipe.scheduler.config)
pipe.enable_model_cpu_offload()
超级英雄的瑜伽工夫!
generator = [torch.Generator(device="cpu").manual_seed(2) for i in range(4)]
prompt = "super-hero character, best quality, extremely detailed"
output = pipe(
[prompt] * 4,
poses,
negative_prompt=["monochrome, lowres, bad anatomy, worst quality, low quality"] * 4,
generator=generator,
num_inference_steps=20,
)
image_grid(output.images, 2, 2)
通过以上示例,咱们对 StableDiffusionControlNetPipeline
的多种用法有了直观的意识,也学会了如何应用 Diffusers 玩转 ControlNet。不过,还有一些 ControlNet 反对的其余类型的管制条件示例,因为篇幅起因本文不再开展,如想理解更多信息,能够点击以下链接查看相应的模型文档页面:
- lllyasviel/sd-controlnet-depth
- lllyasviel/sd-controlnet-hed
- lllyasviel/sd-controlnet-normal
- lllyasviel/sd-controlnet-scribble
- lllyasviel/sd-controlnet-seg
- lllyasviel/sd-controlnet-openpose
- lllyasviel/sd-controlnet-mlsd
- lllyasviel/sd-controlnet-mlsd
咱们十分欢迎您尝试组合不同的管制组件来生成精美的图像,并在 Twitter 上与 @diffuserslib 分享您的作品。如果您还没有运行上述代码段,这里再次建议您查看方才提到的 Colab 笔记本,亲自运行代码体验示例的成果!
在上文中,咱们介绍了减速生成过程、缩小显存占用的一些技巧,它们包含: 疾速调度器、智能模型卸载、xformers
。如果联合应用这些技巧,单张图像的生成过程仅须要: V100 GPU 上约 3 秒的推理工夫以及约 4 GB 的 VRAM 占用;收费 GPU 服务 (如 Google Colab 的 T4) 上约 5 秒的推理工夫。如果没有实现这些技巧,同样的生成过程可达 17 秒!现已集成至 Diffusers 工具箱,来应用 Diffusers 吧,它真的十分强力!💪
结语
本文介绍了 StableDiffusionControlNetPipeline
的多个用例,十分乏味!咱们也十分期待看到社区在此 pipeline 的根底上能构建出什么好玩的利用。如果您想理解更多 Diffusers 反对的对于管制模型的其余 pipeline 和技术细节,请查看咱们的 官网文档。
如果您想间接尝试 ControlNet 的管制成果,咱们也能满足!只需点击以下 HuggingFace Spaces 即可尝试管制生成图像:
- Canny ControlNet Spaces
- OpenPose ControlNet Spaces
原文链接: https://huggingface.co/blog/controlnet
作者: Sayak Paul、YiYi Xu、Patrick von Platen
译者: SuSung-boy
审校、排版: zhongdongy (阿东)
发表回复