加载适配器
有几种针对个性化扩散模型以生成特定主题的图像或特定风格的图像的训练技术。每种训练方法都会产生不同类型的适配器。一些适配器生成一个全新的模型,而其他适配器只会修改较小的嵌入或权重集。这意味着每个适配器的加载过程也不同。
本指南将向您展示如何加载 DreamBooth、文本反转和 LoRA 权重。
您可以随意浏览Stable Diffusion 概念化器、LoRA 探索者和Diffusers 模型库,查找要使用的检查点和嵌入。
DreamBooth
DreamBooth 对一个完整的扩散模型进行微调,只使用该主题的几张图像,就能生成该主题在新的风格和环境中的图像。这种方法通过在提示中使用一个特殊词来实现,该词被模型学习与主题图像相关联。在所有训练方法中,DreamBooth 产生的文件大小最大(通常为几个 GB),因为它是一个完整的检查点模型。
让我们加载herge_style 检查点,该检查点只使用埃尔热绘制的 10 张图像进行训练,以生成该风格的图像。为了使它生效,您需要在提示中包含特殊词 herge_style
以触发检查点
from diffusers import AutoPipelineForText2Image
import torch
pipeline = AutoPipelineForText2Image.from_pretrained("sd-dreambooth-library/herge-style", torch_dtype=torch.float16).to("cuda")
prompt = "A cute herge_style brown bear eating a slice of pizza, stunning color scheme, masterpiece, illustration"
image = pipeline(prompt).images[0]
image
文本反转
文本反转 与 DreamBooth 非常相似,它也可以个性化扩散模型,以从仅几张图像生成特定概念(风格、物体)。这种方法通过训练和查找新的嵌入来实现,这些嵌入使用提示中的一个特殊词来表示您提供的图像。因此,扩散模型权重保持不变,训练过程产生一个相对较小的文件(几 KB)。
由于文本反转创建了嵌入,因此它不能像 DreamBooth 那样独立使用,需要另一个模型。
from diffusers import AutoPipelineForText2Image
import torch
pipeline = AutoPipelineForText2Image.from_pretrained("runwayml/stable-diffusion-v1-5", torch_dtype=torch.float16).to("cuda")
现在,您可以使用load_textual_inversion() 方法加载文本反转嵌入,并生成一些图像。让我们加载sd-concepts-library/gta5-artwork 嵌入,您需要在提示中包含特殊词 <gta5-artwork>
以触发它
pipeline.load_textual_inversion("sd-concepts-library/gta5-artwork")
prompt = "A cute brown bear eating a slice of pizza, stunning color scheme, masterpiece, illustration, <gta5-artwork> style"
image = pipeline(prompt).images[0]
image
文本反转也可以对不希望出现的东西进行训练,以创建负面嵌入,以阻止模型生成包含这些不希望出现的东西的图像,例如模糊图像或手上的额外手指。这是一种简单的方法,可以快速改进您的提示。您也可以使用load_textual_inversion() 加载嵌入,但这次,您需要两个额外的参数
weight_name
: 如果文件以特定名称保存在 🤗 Diffusers 格式中,或者文件存储在 A1111 格式中,则指定要加载的权重文件。token
: 指定要在提示中使用的特殊词,以触发嵌入。
让我们加载sayakpaul/EasyNegative-test 嵌入
pipeline.load_textual_inversion(
"sayakpaul/EasyNegative-test", weight_name="EasyNegative.safetensors", token="EasyNegative"
)
现在,您可以使用 token
使用负面嵌入生成图像
prompt = "A cute brown bear eating a slice of pizza, stunning color scheme, masterpiece, illustration, EasyNegative"
negative_prompt = "EasyNegative"
image = pipeline(prompt, negative_prompt=negative_prompt, num_inference_steps=50).images[0]
image
LoRA
低秩自适应 (LoRA) 是一种流行的训练技术,因为它速度快,产生的文件大小也更小(几百 MB)。与本指南中的其他方法一样,LoRA 可以训练一个模型,以从仅几张图像中学习新的风格。它的工作原理是将新的权重插入扩散模型,然后只训练新的权重,而不是整个模型。这使得 LoRA 训练起来更快,存储也更容易。
LoRA 是一种非常通用的训练技术,可以与其他训练方法一起使用。例如,使用 DreamBooth 和 LoRA 训练模型很常见。将多个 LoRA 加载和合并以创建新的和独特的图像也越来越常见。您可以在深入的合并 LoRA 指南中了解更多信息,因为合并超出了本加载指南的范围。
LoRA 也需要与另一个模型一起使用
from diffusers import AutoPipelineForText2Image
import torch
pipeline = AutoPipelineForText2Image.from_pretrained("stabilityai/stable-diffusion-xl-base-1.0", torch_dtype=torch.float16).to("cuda")
然后使用load_lora_weights() 方法加载ostris/super-cereal-sdxl-lora 权重,并指定存储库中的权重文件名
pipeline.load_lora_weights("ostris/super-cereal-sdxl-lora", weight_name="cereal_box_sdxl_v1.safetensors")
prompt = "bears, pizza bites"
image = pipeline(prompt).images[0]
image
load_lora_weights() 方法将 LoRA 权重加载到 UNet 和文本编码器中。这是加载 LoRA 的首选方法,因为它可以处理以下情况:
- LoRA 权重没有为 UNet 和文本编码器提供单独的标识符
- LoRA 权重为 UNet 和文本编码器提供单独的标识符
但是,如果您只需要将 LoRA 权重加载到 UNet 中,则可以使用load_attn_procs() 方法。让我们加载jbilcke-hf/sdxl-cinematic-1 LoRA
from diffusers import AutoPipelineForText2Image
import torch
pipeline = AutoPipelineForText2Image.from_pretrained("stabilityai/stable-diffusion-xl-base-1.0", torch_dtype=torch.float16).to("cuda")
pipeline.unet.load_attn_procs("jbilcke-hf/sdxl-cinematic-1", weight_name="pytorch_lora_weights.safetensors")
# use cnmt in the prompt to trigger the LoRA
prompt = "A cute cnmt eating a slice of pizza, stunning color scheme, masterpiece, illustration"
image = pipeline(prompt).images[0]
image
要卸载 LoRA 权重,请使用unload_lora_weights() 方法丢弃 LoRA 权重,并将模型恢复到其原始权重
pipeline.unload_lora_weights()
调整 LoRA 权重比例
对于load_lora_weights() 和load_attn_procs(),您可以传递 cross_attention_kwargs={"scale": 0.5}
参数来调整使用 LoRA 权重的比例。值为 0
与仅使用基础模型权重相同,值为 1
等同于使用完全微调的 LoRA。
要对每层使用的 LoRA 权重数量进行更细粒度的控制,您可以使用 set_adapters()
并传递一个字典,指定每层权重的比例。
pipe = ... # create pipeline
pipe.load_lora_weights(..., adapter_name="my_adapter")
scales = {
"text_encoder": 0.5,
"text_encoder_2": 0.5, # only usable if pipe has a 2nd text encoder
"unet": {
"down": 0.9, # all transformers in the down-part will use scale 0.9
# "mid" # in this example "mid" is not given, therefore all transformers in the mid part will use the default scale 1.0
"up": {
"block_0": 0.6, # all 3 transformers in the 0th block in the up-part will use scale 0.6
"block_1": [0.4, 0.8, 1.0], # the 3 transformers in the 1st block in the up-part will use scales 0.4, 0.8 and 1.0 respectively
}
}
}
pipe.set_adapters("my_adapter", scales)
这也适用于多个适配器 - 请参阅本指南,了解如何操作。
目前,set_adapters()
仅支持缩放注意力权重。如果 LoRA 还有其他部分(例如,残差网络或下采样器/上采样器),它们将保持 1.0 的比例。
Kohya 和 TheLastBen
社区中其他流行的 LoRA 训练者包括 Kohya 和 TheLastBen 的训练者。这些训练者创建的 LoRA 检查点与 🤗 Diffusers 训练的不同,但仍然可以使用相同的方式加载。
要加载 Kohya LoRA,让我们以 Blueprintify SD XL 1.0 检查点为例,从 Civitai 下载它。
!wget https://civitai.com/api/download/models/168776 -O blueprintify-sd-xl-10.safetensors
使用 load_lora_weights() 方法加载 LoRA 检查点,并在 weight_name
参数中指定文件名。
from diffusers import AutoPipelineForText2Image
import torch
pipeline = AutoPipelineForText2Image.from_pretrained("stabilityai/stable-diffusion-xl-base-1.0", torch_dtype=torch.float16).to("cuda")
pipeline.load_lora_weights("path/to/weights", weight_name="blueprintify-sd-xl-10.safetensors")
生成一张图片
# use bl3uprint in the prompt to trigger the LoRA
prompt = "bl3uprint, a highly detailed blueprint of the eiffel tower, explaining how to build all parts, many txt, blueprint grid backdrop"
image = pipeline(prompt).images[0]
image
使用 Kohya LoRA 与 🤗 Diffusers 有些限制,包括
- 由于多种原因,图片可能不像 ComfyUI 等 UI 生成的图片一样,具体说明见 这里。
- LyCORIS 检查点 并不完全受支持。 load_lora_weights() 方法加载带有 LoRA 和 LoCon 模块的 LyCORIS 检查点,但 Hada 和 LoKR 不受支持。
IP-Adapter
IP-Adapter 是一款轻量级的适配器,可为任何扩散模型启用图像提示。此适配器通过解耦图像和文本特征的交叉注意力层来工作。所有其他模型组件都被冻结,只有 UNet 中的嵌入图像特征被训练。因此,IP-Adapter 文件通常只有大约 100MB。
您可以在 IP-Adapter 指南中了解更多有关如何为不同任务和特定用例使用 IP-Adapter 的信息。
Diffusers 目前仅支持一些最流行管道中的 IP-Adapter。如果您有很酷的用例并希望将 IP-Adapter 集成到不受支持的管道中,请随时提出功能请求!官方的 IP-Adapter 检查点可从 h94/IP-Adapter 获取。
首先,加载一个 Stable Diffusion 检查点。
from diffusers import AutoPipelineForText2Image
import torch
from diffusers.utils import load_image
pipeline = AutoPipelineForText2Image.from_pretrained("runwayml/stable-diffusion-v1-5", torch_dtype=torch.float16).to("cuda")
然后加载 IP-Adapter 权重,并使用 load_ip_adapter() 方法将其添加到管道中。
pipeline.load_ip_adapter("h94/IP-Adapter", subfolder="models", weight_name="ip-adapter_sd15.bin")
加载后,您就可以使用图像和文本提示来使用管道,以指导图像生成过程。
image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/load_neg_embed.png")
generator = torch.Generator(device="cpu").manual_seed(33)
images = pipeline(
prompt='best quality, high quality, wearing sunglasses',
ip_adapter_image=image,
negative_prompt="monochrome, lowres, bad anatomy, worst quality, low quality",
num_inference_steps=50,
generator=generator,
).images[0]
images
IP-Adapter Plus
IP-Adapter 依赖于图像编码器来生成图像特征。如果 IP-Adapter 存储库包含 image_encoder
子文件夹,则会自动加载图像编码器并将其注册到管道。否则,您需要使用 CLIPVisionModelWithProjection 模型显式加载图像编码器,并将其传递给管道。
对于使用 ViT-H 图像编码器的 *IP-Adapter Plus* 检查点,情况就是如此。
from transformers import CLIPVisionModelWithProjection
image_encoder = CLIPVisionModelWithProjection.from_pretrained(
"h94/IP-Adapter",
subfolder="models/image_encoder",
torch_dtype=torch.float16
)
pipeline = AutoPipelineForText2Image.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
image_encoder=image_encoder,
torch_dtype=torch.float16
).to("cuda")
pipeline.load_ip_adapter("h94/IP-Adapter", subfolder="sdxl_models", weight_name="ip-adapter-plus_sdxl_vit-h.safetensors")
IP-Adapter 人脸 ID 模型
IP-Adapter 人脸 ID 模型是实验性的 IP 适配器,它们使用由 insightface
生成的图像嵌入,而不是 CLIP 图像嵌入。其中一些模型还使用 LoRA 来提高 ID 一致性。您需要安装 insightface
及其所有依赖项才能使用这些模型。
pipeline = AutoPipelineForText2Image.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
torch_dtype=torch.float16
).to("cuda")
pipeline.load_ip_adapter("h94/IP-Adapter-FaceID", subfolder=None, weight_name="ip-adapter-faceid_sdxl.bin", image_encoder_folder=None)
如果您想使用两种 IP-Adapter 人脸 ID Plus 模型之一,您还必须加载 CLIP 图像编码器,因为此模型使用 insightface
和 CLIP 图像嵌入来实现更好的照片真实感。
from transformers import CLIPVisionModelWithProjection
image_encoder = CLIPVisionModelWithProjection.from_pretrained(
"laion/CLIP-ViT-H-14-laion2B-s32B-b79K",
torch_dtype=torch.float16,
)
pipeline = AutoPipelineForText2Image.from_pretrained(
"runwayml/stable-diffusion-v1-5",
image_encoder=image_encoder,
torch_dtype=torch.float16
).to("cuda")
pipeline.load_ip_adapter("h94/IP-Adapter-FaceID", subfolder=None, weight_name="ip-adapter-faceid-plus_sd15.bin")