前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >用于Stable Diffusion的 ControlNet 简介

用于Stable Diffusion的 ControlNet 简介

作者头像
buzzfrog
发布2023-10-24 14:31:29
7631
发布2023-10-24 14:31:29
举报
文章被收录于专栏:云上修行云上修行

更好地控制文本到图像的生成

本教程介绍了使用 HuggingFace 的 diffusers 包通过 ControlNet 生成文本到图像的技术指南。

ControlNet 是一种通过添加额外条件来控制 Stable Diffusion 模型的神经网络结构。它提供了一种在文本到图像生成过程中通过条件输入(例如 涂鸦、边缘图、分割图、姿势关键点 等)增强 Stable Diffusion 的方法。因此,生成的图像将更加接近 ControlNet 中的输入图像的要求,这比图像到图像生成等传统方法有很大改进。

此外,可以使用消费级 GPU 上的小型数据集来训练 ControlNet 模型。然后,可以使用任何预先训练的Stable Diffusion模型来增强该模型,以生成文本到图像。

ControNet 的初始版本带有以下checkpoint:

让我们继续下一部分的设置和安装。

安装

强烈建议在安装 diffusers 包之前创建一个新的虚拟环境。

diffusers

激活虚拟环境并运行以下命令安装稳定版本的diffusers模块:

代码语言:txt
复制
pip install diffusers

PS: ControlNet 需要 diffusers>=0.14.0

对于最新版本的 diffusers 软件包,请按如下方式安装:

代码语言:txt
复制
pip install git+https://github.com/huggingface/diffusers

accelerate

您可以 accelerate 按如下方式安装该模块:

代码语言:txt
复制
pip install accelerate

本教程包含一些依赖于 的代码片段 accelerate>=0.17.0 ,在撰写本文时尚未在 PyPi 上发布。安装最新版本如下:

代码语言:txt
复制
pip install git+https://github.com/huggingface/accelerate

OpenCV-Python

请注意,根据不同的 ControlNet,预处理器和依赖项会有所不同。为简单起见,本教程将介绍 canny edge 处理器,该处理器取决于软件包 opencv-python 。

opencv-python 有 4 种不同的依赖包。官方文档推荐使用 opencv-contrib-python 依赖包,但可以使用以下任何依赖包来完成推理:

  • opencv-python — 主包
  • opencv-contrib-python — 完整包(附带 contrib/额外模块)
  • opencv-python-headless — 没有 GUI 的主包
  • opencv-contrib-python-headless — 没有 GUI 的完整包

通过以下命令安装它(可以根据您的喜好替换依赖包名称):

代码语言:txt
复制
pip install opencv-contrib-python

controlnet-aux

另一方面,OpenPose 处理器需要 controlnet-aux 依赖包。运行以下命令来安装它:

代码语言:txt
复制
pip install controlnet-aux

xformers(可选)

xformers 依赖包显着提高了推理速度。最新版本附带了对 PyTorch 1.13.1 的pip wheels 支持。

Pip install (win/linux)

对于那些使用 torch==1.13.1 的工程师,只需运行以下命令即可安装 xformers :

代码语言:txt
复制
pip install -U xformers

Conda (linux)

对于 conda 用户,安装支持torch==1.12.1或torch==1.13.1

代码语言:txt
复制
conda install xformers

从源头构建

对于其他工程师,请考虑 xformers 直接从源代码构建:

代码语言:shell
复制
# (Optional) Makes the build much faster
pip install ninja

# Set TORCH_CUDA_ARCH_LIST if running and building on different GPU types
pip install -v -U git+https://github.com/facebookresearch/xformers.git@main#egg=xformers
# (this can take dozens of minutes)

实现

让我们探讨如何利用 canny edge ControlNet 进行图像生成。它需要 canny edge 图像作为输入。

Canny

创建一个名为 canny_inference.py 的新文件,并添加以下import语句:

代码语言:txt
复制
import cv2
import numpy as np
from PIL import Image

然后,继续添加以下代码片段,从现有图像创建 canny edge 图像

代码语言:txt
复制
import cv2
import numpy as np
from PIL import Image

image = Image.open('input.png')
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.save('canny.png')

保存文件并运行以下命令将图像转换为 canny edge 图像:

代码语言:txt
复制
python canny_inference.py

看一下如下例子:

下一步是使用 canny 图像作为条件输入来执行推理。修改导入语句如下:

代码语言:txt
复制
import cv2
+import torch
import numpy as np
from PIL import Image
+from diffusers import StableDiffusionControlNetPipeline, ControlNetModel, DPMSolverMultistepScheduler

通过初始化 ControlNet 和 Stable Diffusion pipelines 来更新代码:

代码语言:txt
复制
...

canny_image = Image.fromarray(image)
# canny_image.save('canny.png')

# for deterministic generation
generator = torch.Generator(device='cuda').manual_seed(12345)
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
)
# change the scheduler
pipe.scheduler = DPMSolverMultistepScheduler.from_config(pipe.scheduler.config)
# enable xformers (optional), requires xformers installation
pipe.enable_xformers_memory_efficient_attention()
# cpu offload for memory saving, requires accelerate>=0.17.0
pipe.enable_model_cpu_offload()

运行推理并保存生成的图像:

代码语言:txt
复制
...

# cpu offload for memory saving, requires accelerate>=0.17.0
pipe.enable_model_cpu_offload()

image = pipe(
    "a beautiful lady, celebrity, red dress, dslr, colour photo, realistic, high quality",
    negative_prompt="cropped, out of frame, worst quality, low quality, jpeg artifacts, ugly, blurry, bad anatomy, bad proportions",
    num_inference_steps=20,
    generator=generator,
    image=canny_image,
    controlnet_conditioning_scale=0.5
).images[0]
image.save('output.png')

接受 StableDiffusionControlNetPipeline 以下参数:

  • controlnet_conditioning_scale — controlnet 的输出先乘以 controlnet_conditioning_scale ,然后再添加到原始unet 的残差中。 controlnet_conditioning_scale 默认为 1.0 并接受 0.0 – 1.0 之间的任何值。

运行脚本,您应该得到以下输出:

让我们使用不同的输入图像和设置再次重新运行脚本:

代码语言:txt
复制
...

image = pipe(
-   "a beautiful lady, celebrity, red dress, dslr, colour photo, realistic, high quality",
+   "a beautiful lady wearing blue yoga pants working out on beach, realistic, high quality",
    negative_prompt="cropped, out of frame, worst quality, low quality, jpeg artifacts, ugly, blurry, bad anatomy, bad proportions",
    num_inference_steps=20,
    generator=generator,
    image=canny_image,
-   controlnet_conditioning_scale=0.5
+   controlnet_conditioning_scale=1.0
).images[0]
image.save('tmp/output.png')

输出如下:

OpenPose

让我们尝试使用 OpenPose 骨骼图像作为条件输入。看一下下图作为其外观的参考:

controlnet-aux 模块提供将图像转换为 OpenPose 骨骼图像的支持。创建一个名为 pose_inference.py 的新 Python 文件并添加以下import:

代码语言:txt
复制
import torch
from PIL import Image
from controlnet_aux import OpenposeDetector
from diffusers import StableDiffusionControlNetPipeline, ControlNetModel, DPMSolverMultistepScheduler

继续添加以下代码片段:

代码语言:txt
复制
...

image = Image.open('input.png')
openpose = OpenposeDetector.from_pretrained('lllyasviel/ControlNet')
pose_image = openpose(image)
pose_image.save('pose.png')

保存文件并运行以下命令将图像转换为 OpenPose 骨骼图像:

代码语言:txt
复制
python pose_inference.py

请看以下示例以供参考:

通过附加以下代码行来完成脚本:

代码语言:txt
复制
...

# for deterministic generation
generator = torch.Generator(device='cuda').manual_seed(12345)
controlnet = ControlNetModel.from_pretrained(
    "lllyasviel/sd-controlnet-openpose",
    torch_dtype=torch.float16
)
pipe = StableDiffusionControlNetPipeline.from_pretrained(
    "runwayml/stable-diffusion-v1-5",
    controlnet=controlnet,
    torch_dtype=torch.float16
)
# change the scheduler
pipe.scheduler = DPMSolverMultistepScheduler.from_config(pipe.scheduler.config)
# enable xformers (optional), requires xformers installation
pipe.enable_xformers_memory_efficient_attention()
# cpu offload for memory saving, requires accelerate>=0.17.0
pipe.enable_model_cpu_offload()

# cpu offload for memory saving, requires accelerate>=0.17.0
pipe.enable_model_cpu_offload()

image = pipe(
    "a beautiful hollywood actress wearing black dress attending award winning event, red carpet stairs at background",
    negative_prompt="cropped, out of frame, worst quality, low quality, jpeg artifacts, ugly, blurry, bad anatomy, bad proportions",
    num_inference_steps=20,
    generator=generator,
    image=pose_image,
    controlnet_conditioning_scale=1.0
).images[0]
image.save('output.png')

运行脚本,输出如下:

ControlNet 是一种极其强大的神经网络结构,可以通过添加额外条件来控制扩散模型。

PS:在撰写本文时,开源社区仍在积极开发对 Multi-ControlNet的支持。

新功能提供了一种使用多个 ControlNet 并将输出添加在一起以生成图像的方法,从而可以更好地控制整个图像。只需传入

代码语言:txt
复制
import torch
from diffusers import StableDiffusionControlNetPipeline, ControlNetModel

controlnet_canny = ControlNetModel.from_pretrained("lllyasviel/sd-controlnet-canny", 
                                                   torch_dtype=torch.float16).to("cuda")
controlnet_pose = ControlNetModel.from_pretrained("lllyasviel/sd-controlnet-openpose", 
                                                   torch_dtype=torch.float16).to("cuda")

pipe = StableDiffusionControlNetPipeline.from_pretrained(
 "runwayml/stable-diffusion-v1-5", torch_dtype=torch.float16,
 controlnet=[
  controlnet_pose, 
  controlnet_canny
 ],
).to("cuda")

image = pipe(prompt='...',
             image=[pose_image, canny_image],
        ).images[0]
image.save("output.png")

当使用多个 ControlNet 时,您可以通过controlnet_conditioning_scale传入浮点数列表作为输入参数来控制比例因子,如下所示:

代码语言:txt
复制
controlnet_conditioning_scale=[1.0, 0.5]

结论

让我们回顾一下今天的学习要点。

本文首先简要介绍 ControlNet 和支持的模型列表。

然后,通过 pip install 继续设置和安装步骤。

随后,它继续使用 opencv-python 以获得 canny edge 图像。然后将输出用作文本到图像生成的条件输入。

除此之外,本教程还解释了如何使用 OpenPose 骨骼图像作为条件输入。 controlnet-aux 模块可以方便地将图像转换为 OpenPose 图像。

感谢您阅读这篇文章。祝你有美好的一天!

参考

Github — ControlNet

HuggingFace 文档 — ControlNet

本文系外文翻译,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系外文翻译前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 安装
    • diffusers
      • accelerate
        • OpenCV-Python
          • controlnet-aux
            • xformers(可选)
              • Pip install (win/linux)
              • Conda (linux)
              • 从源头构建
          • 实现
            • Canny
              • OpenPose
              • 结论
              • 参考
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档