本文将要介绍整合 HuggingFace 的 diffusers 包和 ControlNet 调节生成文本到图像,能够更好地管制文本到图像的生成
ControlNet 是一种通过增加额定条件来管制扩散模型的神经网络构造。它提供了一种加强稳固扩散的办法,在文本到图像生成过程中应用条件输出,如涂鸦、边缘映射、宰割映射、pose 关键点等。能够让生成的图像将更靠近输出图像,这比传统的图像到图像生成办法有了很大的改良。
ControlNet 模型能够在应用小数据集进行训练。而后整合任何预训练的稳固扩散模型来加强模型,来达到微调的目标。
- ControNet 的初始版本带有以下预训练权重:
- Canny edge — 彩色背景上带有红色边缘的单色图像。
- Depth/Shallow areas — 灰度图像,彩色代表深区域,红色代表浅区域。
- Normal map — 法线贴图图像。
- Semantic segmentation map——ADE20K 的宰割图像。
- HED edge — 彩色背景上带有红色软边缘的单色图像。
- Scribbles — 彩色背景上带有红色轮廓的手绘单色涂鸦图像。
- OpenPose(姿态关键点)— OpenPose 骨骼图像。
- M-LSD — 仅由彩色背景上的红色直线组成的单色图像。
上面咱们开始进行整合:
设置
倡议在安装包之前创立一个新的虚拟环境。
diffusers
激活虚拟环境,执行以下命令:
pip install diffusers
ControlNet 要求 diffusers>=0.14.0
accelerate
pip install accelerate
本教程蕴含一些依赖于 accelerate>=0.17.0,须要应用上面命令装置最新版本:
pip install git+https://github.com/huggingface/accelerate
opencv-python
为了简略起见,咱们应用 canny 边缘处理器,所以它须要 opencv-python 包。
Opencv-python 有 4 个不同的包。官网文档举荐应用 opencv-contrib-python 包,但也能够应用以下任何包进行:
- opencv-python 主包
- opencv-contrib-python - 完整包 (附带 contrib/ 额定模块)
- opencv-python-headless - 没有 GUI 的主包
- opencv-contrib-python-headless - 没有 GUI 的完整包
所以咱们这里应用完整包:
pip install opencv-contrib-python
controlnet-aux
OpenPose 处理器须要 controlnet-aux 包。执行如下命令装置:
pip install controlnet-aux
xformers(可选)
xformers 包能够进步了推理速度。最新版本为 PyTorch 1.13.1 提供了 pip wheels 反对。
pip install -U xformers
conda 能够装置反对 torch1.12.1 或 torch1.13.1
conda install xformers
好了,这里的环境就设置结束了
canny edge 图像生成
上面就是利用 canny edge ControlNet 进行图像生成。它须要一个精密的边缘图像作为输出。
创立一个名为 canny_inference.py 的新文件,并增加以下导入语句:
import cv2
import numpy as np
from PIL import Image
而后,持续增加以下代码片段,从现有图像创立一个 canny edge 图像
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 图像。
python canny_inference.py
看看上面的例子:
下一步是应用方才生成的 canny 图像作为条件输出执行推理。
import cv2
import torch
import numpy as np
from PIL import Image
from diffusers import StableDiffusionControlNetPipeline, ControlNetModel, DPMSolverMultistepScheduler
初始化 ControlNet 和 Stable Diffusion 管道
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()
运行推理并保留生成的图像:
# 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 的输入增加到原始 unet 的残余局部之前,将它们乘以 controlnet_conditioning_scale。默认为 1.0,承受 0.0-1.0 之间的任何值。
运行脚本,能够失去相似上面输入:
让咱们用不同的输出图像和设置从新运行脚本:
image = pipe(
"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=1.0
).images[0]
image.save('tmp/output.png')
后果如下:
OpenPose
上面能够尝试应用 OpenPose 图像作为条件输出:
controlnet-aux 模块反对将图像转换为 OpenPose 骨骼图像。咱们创立一个名为 pose_inference.py 的新 Python 文件并增加以下导入:
import torch
from PIL import Image
from controlnet_aux import OpenposeDetector
from diffusers import StableDiffusionControlNetPipeline, ControlNetModel, DPMSolverMultistepScheduler
持续增加以下代码
image = Image.open('input.png')
openpose = OpenposeDetector.from_pretrained('lllyasviel/ControlNet')
pose_image = openpose(image)
pose_image.save('pose.png')
执行以下图像转换为 OpenPose 图像:
python pose_inference.py
后果如下
上面咱们开始依据 OpenPose 生成图像
# 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 是一个十分弱小的神经网络构造,通过增加额定的条件来管制扩散模型。目前还不反对 Multi-ControlNet,开源社区有音讯说正在踊跃开发中。这个新性能提供了能够应用多个管制网络,并将他们的输入一起用于图像生成,容许更好地管制整个图像。
https://avoid.overfit.cn/post/0663779d52484d0da5cc946b8f429f36
作者:Ng Wai Foong