使用 T2I-Adapters 对 SDXL 进行高效可控生成
T2I-Adapter 是一个高效的即插即用模型,它能为预训练的文本到图像模型提供额外引导,同时冻结原始大型文本到图像模型。T2I-Adapter 将 T2I 模型中的内部知识与外部控制信号对齐。我们可以根据不同的条件训练各种适配器,实现丰富的控制和编辑效果。
作为同时期工作,ControlNet 具有类似的功能并被广泛使用。然而,它的运行成本可能非常高昂。这是因为在逆向扩散过程的每个去噪步骤中,ControlNet 和 UNet 都需要运行。此外,ControlNet 强调将 UNet 编码器复制为控制模型的重要性,导致参数数量更大。因此,生成过程受 ControlNet 大小的限制(越大,过程越慢)。
在此方面,T2I-Adapters 比 ControlNet 具有竞争优势。T2I-Adapters 尺寸更小,并且与 ControlNet 不同,T2I-Adapters 在整个去噪过程中只需运行一次。
模型类型 | 模型参数 | 存储 (fp16) |
---|---|---|
ControlNet-SDXL | 1251 M | 2.5 GB |
ControlLoRA(秩为 128) | 197.78 M(减少 84.19%) | 396 MB(减少 84.53%) |
T2I-Adapter-SDXL | 79 M(减少 93.69%) | 158 MB(减少 94%) |
在过去几周中,Diffusers 团队和 T2I-Adapter 作者一直在合作,以便在 diffusers
中支持 Stable Diffusion XL (SDXL) 的 T2I-Adapters。在这篇博客文章中,我们分享了从头开始在 SDXL 上训练 T2I-Adapters 的发现,一些引人注目的结果,当然还有各种条件(草图、Canny、线稿、深度和 OpenPose)下的 T2I-Adapter 检查点!
与 T2I-Adapter 的早期版本 (SD-1.4/1.5) 相比,T2I-Adapter-SDXL 仍沿用原始方法,使用一个 79M 的适配器驱动 2.6B 的 SDXL!T2I-Adapter-SDXL 在继承 SDXL 高质量生成的同时,保持了强大的控制能力!
使用 diffusers
训练 T2I-Adapter-SDXL
我们的训练脚本是基于 diffusers
提供的官方示例构建的。
本博客文章中提到的大多数 T2I-Adapter 模型都是在 LAION-Aesthetics V2 的 3M 高分辨率图像-文本对上训练的,具体设置如下:
- 训练步骤:20000-35000
- 批量大小:数据并行,单个 GPU 批量大小为 16,总批量大小为 128。
- 学习率:恒定学习率 1e-5。
- 混合精度:fp16
我们鼓励社区使用我们的脚本来训练自定义且强大的 T2I-Adapters,在速度、内存和质量之间取得竞争性的权衡。
在 diffusers
中使用 T2I-Adapter-SDXL
在这里,我们以线稿条件为例,演示 T2I-Adapter-SDXL 的用法。首先,安装所需的依赖项
pip install -U git+https://github.com/huggingface/diffusers.git
pip install -U controlnet_aux==0.0.7 # for conditioning models and detectors
pip install transformers accelerate
T2I-Adapter-SDXL 的生成过程主要包括以下两个步骤:
- 条件图像首先被准备成适当的控制图像格式。
- 控制图像和提示被传递给
StableDiffusionXLAdapterPipeline
。
让我们看一个使用线稿适配器的简单示例。我们首先初始化 SDXL 的 T2I-Adapter 管道和线稿检测器。
import torch
from controlnet_aux.lineart import LineartDetector
from diffusers import (AutoencoderKL, EulerAncestralDiscreteScheduler,
StableDiffusionXLAdapterPipeline, T2IAdapter)
from diffusers.utils import load_image, make_image_grid
# load adapter
adapter = T2IAdapter.from_pretrained(
"TencentARC/t2i-adapter-lineart-sdxl-1.0", torch_dtype=torch.float16, varient="fp16"
).to("cuda")
# load pipeline
model_id = "stabilityai/stable-diffusion-xl-base-1.0"
euler_a = EulerAncestralDiscreteScheduler.from_pretrained(
model_id, subfolder="scheduler"
)
vae = AutoencoderKL.from_pretrained(
"madebyollin/sdxl-vae-fp16-fix", torch_dtype=torch.float16
)
pipe = StableDiffusionXLAdapterPipeline.from_pretrained(
model_id,
vae=vae,
adapter=adapter,
scheduler=euler_a,
torch_dtype=torch.float16,
variant="fp16",
).to("cuda")
# load lineart detector
line_detector = LineartDetector.from_pretrained("lllyasviel/Annotators").to("cuda")
然后,加载图像以检测线稿
url = "https://huggingface.co/Adapter/t2iadapter/resolve/main/figs_SDXLV1.0/org_lin.jpg"
image = load_image(url)
image = line_detector(image, detect_resolution=384, image_resolution=1024)
然后我们生成
prompt = "Ice dragon roar, 4k photo"
negative_prompt = "anime, cartoon, graphic, text, painting, crayon, graphite, abstract, glitch, deformed, mutated, ugly, disfigured"
gen_images = pipe(
prompt=prompt,
negative_prompt=negative_prompt,
image=image,
num_inference_steps=30,
adapter_conditioning_scale=0.8,
guidance_scale=7.5,
).images[0]
gen_images.save("out_lin.png")
有两个重要的参数需要理解,它们可以帮助您控制条件化的程度。
adapter_conditioning_scale
此参数控制条件化对输入的影响程度。值越高表示条件化效果越强,反之亦然。
adapter_conditioning_factor
此参数控制应该应用条件化的初始生成步骤数。值应设置在 0-1 之间(默认值为 1)。`adapter_conditioning_factor=1` 的值意味着适配器应该应用于所有时间步,而 `adapter_conditioning_factor=0.5` 意味着它只应用于前 50% 的步骤。
有关更多详细信息,欢迎您查阅官方文档。
试用演示
您可以在此空间或下方嵌入的游乐场中轻松试用 T2I-Adapter-SDXL
您还可以尝试使用草图模型构建的 Doodly,它将您的涂鸦转换为逼真的图像(通过语言监督)
更多结果
下面,我们展示了使用不同条件获得的结果。我们还补充了指向其相应预训练检查点的链接。它们的模型卡包含更多关于它们如何训练以及示例用法的信息。
线稿引导
模型来自
TencentARC/t2i-adapter-lineart-sdxl-1.0
草图引导
模型来自
TencentARC/t2i-adapter-sketch-sdxl-1.0
Canny 引导
模型来自
TencentARC/t2i-adapter-canny-sdxl-1.0
深度引导
深度引导模型分别来自
TencentARC/t2i-adapter-depth-midas-sdxl-1.0
和 TencentARC/t2i-adapter-depth-zoe-sdxl-1.0
OpenPose 引导
模型来自
TencentARC/t2i-adapter-openpose-sdxl-1.0
致谢:非常感谢 William Berman 帮助我们训练模型并分享他的见解。