仓库源文站点原文


author: 路边的阿不 title: 在本地跑一个AI模型(7) - 你打草稿,模型来画 slug: run-stable-diffusion-locally3-guide-image-generation description: Unlock the power of guided image generation with Stable Diffusion! Learn how to control image output using ControlNet and Adapter technologies, and explore practical examples and comparisons of various detectors and adapters. Discover how to generate high-quality images that meet your specific requirements. date: 2024-04-22 14:36:03 draft: false ShowToc: true TocOpen: true tags:


本文是Stable Diffusion系列第三篇。

前两篇文章我们介绍了在本地运行Stable Diffusion模型的方法,以及使用LoRA对模型生成的图片进行微调。

本篇文章中,我们将介绍两种技术来控制图像的生成过程,对模型图像生成进行引导,使得生成的图像更符合我们的需求。这样生成的图片,更具有商业价值。

图像生成引导技术

Stable Diffusion等文本转图像模型中,"对模型图像生成进行引导"是指通过提供额外的信息来控制图像生成过程,使其生成更符合预期的图像。引导的方法有多种,比如前两篇文章提及的“引导词”和LoRA都是引导技术的一种。在本篇文章中,重点介绍的是“使用参考图像”进行引导的方法,也就是Image to Image。试想一下:你先用草稿将绘画元素勾勒出来,然后利用该技术即可让AI对作品细节进行补充。

ControlNetAdapter

这个表格展示了这两种技术的工作原理及优缺点:

特性 Adapter ControlNet
工作原理 基于提示嵌入 基于神经网络
优点 易于使用、灵活 效果好、可控性强
缺点 效果可能不佳、需要额外的训练数据 使用复杂、需要训练数据

controlnet-aux

在开始前,我们先下载一个工具:

pip install controlnet-aux mediapipe

controlnet-aux提供了多种辅助模型,称为Detector。这些 Detector可以分析图像并提取特定的信息,然后将这些信息作为条件传递给 ControlNet,从而更精细地控制图像生成过程。这一步骤我们称之为生成“引导图”。以下是一些常见的Detector模型及其简介:

要使用这些Detector,需要先下载模型,地址:https://huggingface.co/lllyasviel/Annotators。你需要哪些Detector就下载哪些模型。省事的话就全部下载。

各种Detector对比

首先写一段代码运行Detector

from controlnet_aux import HEDdetector
from diffusers.utils import load_image, make_image_grid

device = 'mps'
original_image = load_image("data/3.jpg")
hed = HEDdetector.from_pretrained("your/path/controlnet-annotators").to(device)

hed_image = hed(original_image)
image_grid = make_image_grid([original_image, hed_image], rows=1, cols=2)
image_grid.save("data/out.jpg")

代码很简单,就不做解释了,下面是各种Detector的效果演示:

各种Controlnet对比

以上我们使用Detector生成了各种“引导图”,接下来我们使用Controlnet对引导图进行创作。老规矩,先去hugging face下载模型,我们这次测试的Controlnet都是sdxl的,具体原因参考前两篇文章:

编写代码:

from diffusers import StableDiffusionXLControlNetPipeline, ControlNetModel, DPMSolverSinglestepScheduler
from diffusers.utils import load_image, make_image_grid
from controlnet_aux import CannyDetector


device = 'mps'
original_image = load_image("data/3.jpg")
canny = CannyDetector()
canny_image = canny(original_image)

controlnet = ControlNetModel.from_pretrained(
    "your/path/controlnet-canny-sdxl-1.0",
    use_safetensors=True
)

pipe = StableDiffusionXLControlNetPipeline.from_single_file(
    "your/path/dreamshaperXL_v21TurboDPMSDE.safetensors",
    controlnet=controlnet,
    use_safetensors=True
).to(device)
pipe.scheduler = DPMSolverSinglestepScheduler.from_config(pipe.scheduler.config, use_karras_sigmas=True)
# pipe.enable_model_cpu_offload()

prompt = "masterpiece, 1girl, long hair, asian, sundress, cartoon"
negative_prompt = 'low quality, bad quality, sketches'

image = pipe(
    prompt,
    negative_prompt=negative_prompt,
    image=canny_image,
    # controlnet_conditioning_scale=0.5,
    height=1024,
    width=576,
    num_inference_steps=6,
    guidance_scale=2,
).images[0]
image_grid = make_image_grid([original_image, image], rows=1, cols=2)
image_grid.save("data/out.jpg")

提示词与上一篇文章一模一样,让我们来看一下生成的图片。

各种Adapter对比

Contronet一样,先去hugging face上下载模型,这次我们使用腾讯的t2i-adapter进行测试:

编写代码:

from diffusers import T2IAdapter, StableDiffusionXLAdapterPipeline, DPMSolverSinglestepScheduler
from diffusers.utils import load_image, make_image_grid
from controlnet_aux import CannyDetector

device = 'mps'
original_image = load_image("data/3.jpg")
canny = CannyDetector()
canny_image = canny(original_image)

adapter = T2IAdapter.from_pretrained("your/path/t2i-adapter-canny-sdxl-1.0")

pipe = StableDiffusionXLAdapterPipeline.from_single_file(
    "your/path/dreamshaperXL_v21TurboDPMSDE.safetensors",
    # controlnet=controlnet,
    adapter=adapter,
    use_safetensors=True
).to(device)
pipe.scheduler = DPMSolverSinglestepScheduler.from_config(pipe.scheduler.config, use_karras_sigmas=True)
# pipe.enable_model_cpu_offload()

prompt = "masterpiece, 1girl, long hair, asian, sundress, cartoon"
negative_prompt = 'low quality, bad quality, sketches'

image = pipe(
    prompt=prompt,
    negative_prompt=negative_prompt,
    image=canny_image,
    # controlnet_conditioning_scale=0.5,
    height=1024,
    width=576,
    num_inference_steps=6,
    guidance_scale=2,
).images[0]
image_grid = make_image_grid([original_image, image], rows=1, cols=2)
image_grid.save("data/out.jpg")

总结

从图片质量可以看出,ControlNet对于引导图的遵循和生成图片的质量都较Adapter高,具体使用情况如何,大家在使用前还是自己测试一下。