Diffusers 文档

加载适配器

Hugging Face's logo
加入 Hugging Face 社区

并获取增强的文档体验

开始使用

加载适配器

有几种 训练 技术可以将扩散模型个性化,以生成特定主题的图像或特定风格的图像。这些训练方法中的每一种都会生成不同类型的适配器。一些适配器生成全新的模型,而其他适配器仅修改较小的嵌入集或权重集。这意味着每种适配器的加载过程也不同。

本指南将向您展示如何加载 DreamBooth、textual inversion 和 LoRA 权重。

您可以随意浏览 Stable Diffusion ConceptualizerLoRA the ExplorerDiffusers Models Gallery,以查找要使用的 checkpoints 和 embeddings。

DreamBooth

DreamBooth 在少量的主题图像上微调整个扩散模型,以生成该主题在新风格和设置中的图像。此方法通过在 prompt 中使用一个特殊词来实现,模型学习将该词与主题图像关联起来。在所有训练方法中,DreamBooth 生成的文件大小最大(通常为几个 GB),因为它是一个完整的 checkpoint 模型。

让我们加载 herge_style checkpoint,它仅在 Hergé 绘制的 10 张图像上进行训练,以生成该风格的图像。为了使其工作,您需要在 prompt 中包含特殊词 herge_style 以触发 checkpoint

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

Textual inversion

Textual inversion 与 DreamBooth 非常相似,它也可以个性化扩散模型,以仅从几张图像中生成某些概念(风格、对象)。此方法通过训练和查找新的 embeddings 来表示您提供的图像,并在 prompt 中使用特殊词。因此,扩散模型权重保持不变,训练过程产生一个相对较小的文件(几 KB)。

由于 textual inversion 创建 embeddings,因此它不能像 DreamBooth 那样单独使用,并且需要另一个模型。

from diffusers import AutoPipelineForText2Image
import torch

pipeline = AutoPipelineForText2Image.from_pretrained("stable-diffusion-v1-5/stable-diffusion-v1-5", torch_dtype=torch.float16).to("cuda")

现在您可以使用 load_textual_inversion() 方法加载 textual inversion embeddings 并生成一些图像。让我们加载 sd-concepts-library/gta5-artwork embeddings,您需要在 prompt 中包含特殊词 <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

Textual inversion 也可以在不需要的事物上进行训练,以创建负面 embeddings,以阻止模型生成包含这些不需要的事物的图像,例如模糊的图像或手上的多余手指。这可以是一种快速改进 prompt 的简单方法。您也可以使用 load_textual_inversion() 加载 embeddings,但这次您需要两个额外的参数

  • weight_name:指定要加载的权重文件,如果该文件以特定的名称保存在 🤗 Diffusers 格式中,或者该文件存储在 A1111 格式中
  • token:指定在 prompt 中使用的特殊词以触发 embeddings

让我们加载 sayakpaul/EasyNegative-test embeddings

pipeline.load_textual_inversion(
    "sayakpaul/EasyNegative-test", weight_name="EasyNegative.safetensors", token="EasyNegative"
)

现在您可以使用 token 生成带有负面 embeddings 的图像

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

Low-Rank Adaptation (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 适配器,请使用 ~PeftAdapterMixin.load_lora_adapter,它构建并准备适配器所需的模型配置。与 load_lora_weights() 类似,PeftAdapterMixin.load_lora_adapter 可以为 UNet 和文本编码器加载 LoRA。例如,如果您要为 UNet 加载 LoRA,PeftAdapterMixin.load_lora_adapter 将忽略文本编码器的键。

使用 weight_name 参数指定特定的权重文件,并使用 prefix 参数过滤要加载的适当状态字典(在本例中为 "unet")。

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_lora_adapter("jbilcke-hf/sdxl-cinematic-1", weight_name="pytorch_lora_weights.safetensors", prefix="unet")

# 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

使用 ~PeftAdapterMixin.save_lora_adapter 保存适配器。

要卸载 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 有其他部分(例如,resnet 或下采样/上采样器),它们将保持 1.0 的比例。

Kohya 和 TheLastBen

社区中其他流行的 LoRA 训练器包括 KohyaTheLastBen。这些训练器创建的 LoRA checkpoints 与 🤗 Diffusers 训练的 checkpoints 不同,但它们仍然可以以相同的方式加载。

Kohya
TheLastBen

要加载 Kohya LoRA,让我们从 Civitai 下载 Blueprintify SD XL 1.0 checkpoint 作为示例

!wget https://civitai.com/api/download/models/168776 -O blueprintify-sd-xl-10.safetensors

使用 load_lora_weights() 方法加载 LoRA checkpoint,并在 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 一起使用的一些限制包括

  • 图像可能看起来不像 UIs(如 ComfyUI)生成的图像 - 这有很多原因,此处 解释了这些原因。
  • LyCORIS checkpoints 未完全支持。load_lora_weights() 方法加载带有 LoRA 和 LoCon 模块的 LyCORIS checkpoints,但不支持 Hada 和 LoKR。

IP-Adapter

IP-Adapter 是一种轻量级适配器,可为任何扩散模型启用图像 prompt。此适配器的工作原理是将图像和文本特征的交叉注意力层解耦。所有其他模型组件都被冻结,并且仅训练 UNet 中嵌入的图像特征。因此,IP-Adapter 文件通常只有约 100MB。

您可以在 IP-Adapter 指南中了解有关如何将 IP-Adapter 用于不同任务和特定用例的更多信息。

Diffusers 目前仅支持一些最流行的 pipelines 的 IP-Adapter。如果您有很酷的用例并希望将 IP-Adapter 与不受支持的 pipeline 集成,请随时打开功能请求!官方 IP-Adapter checkpoints 可从 h94/IP-Adapter 获取。

首先,加载 Stable Diffusion checkpoint。

from diffusers import AutoPipelineForText2Image
import torch
from diffusers.utils import load_image

pipeline = AutoPipelineForText2Image.from_pretrained("stable-diffusion-v1-5/stable-diffusion-v1-5", torch_dtype=torch.float16).to("cuda")

然后加载 IP-Adapter 权重,并使用 load_ip_adapter() 方法将其添加到 pipeline。

pipeline.load_ip_adapter("h94/IP-Adapter", subfolder="models", weight_name="ip-adapter_sd15.bin")

加载后,您可以将 pipeline 与图像和文本 prompt 一起使用,以指导图像生成过程。

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 子文件夹,则会自动加载图像编码器并将其注册到 pipeline。否则,您需要使用 CLIPVisionModelWithProjection 模型显式加载图像编码器,并将其传递给 pipeline。

IP-Adapter Plus checkpoints 的情况就是如此,它们使用 ViT-H 图像编码器。

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 Face ID 模型

IP-Adapter FaceID 模型是实验性的 IP 适配器,它使用由 insightface 而不是 CLIP 图像 embeddings 生成的图像 embeddings。其中一些模型还使用 LoRA 来提高 ID 一致性。您需要安装 insightface 及其所有要求才能使用这些模型。

由于 InsightFace 预训练模型可用于非商业研究目的,因此 IP-Adapter-FaceID 模型专门为研究目的而发布,不用于商业用途。
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 FaceID Plus 模型之一,则还必须加载 CLIP 图像编码器,因为这些模型同时使用 insightface 和 CLIP 图像 embeddings 以实现更好的照片真实感。

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(
    "stable-diffusion-v1-5/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")
< > 在 GitHub 上更新