Diffusers 适配器加载实战指南:DreamBooth、Textual Inversion、LoRA 与 IP-Adapter 完整解析
【免费下载链接】diffusers🤗 Diffusers: State-of-the-art diffusion models for image, video, and audio generation in PyTorch.项目地址: https://gitcode.com/GitHub_Trending/di/diffusers
本篇技术指南以 🤗 Diffusers 项目(当前仓库GitHub_Trending/di/diffusers)的文档《어댑터 불러오기(加载适配器)》为骨架,系统讲解如何为扩散模型加载 DreamBooth 完整检查点、Textual Inversion 文本嵌入、LoRA 权重以及 IP-Adapter 图像适配器。读完本文后,你将掌握每种适配器的加载原理、触发方式、权重缩放与卸载方法,并能直接运行文中的可复现代码。
阅读提示:本仓库源码中
src/diffusers/loaders/目录集中实现了本文涉及的所有加载器 Mixin,文中将结合源码路径进行纵深说明。
一、为什么需要"加载适配器"
要让扩散模型生成特定物体或特定风格的图像,常见做法是先对模型进行个性化训练。仓库文档将其概括为若干种训练方法(参见 训练概览),而不同训练方法会产出不同类型的适配器(adapter):
- 有些适配器是全新的完整模型(例如 DreamBooth 微调后产出的整个 checkpoint);
- 有些适配器只修改一小部分嵌入(embedding)或权重(例如 Textual Inversion 的新嵌入、LoRA 的低秩权重增量)。
由于产物形态不同,每种适配器的加载流程也各不相同。本文即围绕这一核心差异,逐一演示各类适配器的加载方式。
适配器资源可以在社区找到:Stable Diffusion Conceptualizer、LoRA the Explorer、Diffusers Models Gallery 等社区合集收录了大量现成 checkpoint 与嵌入,可直接用于下述代码示例。
二、DreamBooth:加载完整微调检查点
2.1 原理与适用场景
DreamBooth 会对整个扩散模型进行微调,使其学会用新的风格和设定生成特定物体。它的工作方式是:训练时让模型学习把物体图像与提示词中的特殊触发词关联起来。
在所有训练方法中,DreamBooth 产出的文件最大——因为它是完整的 checkpoint 模型,体积通常有数 GB。
2.2 加载示例
下面加载仅用 10 张 Hergé 画作训练出的herge_stylecheckpoint,并生成对应风格的图像。注意:必须把触发词herge_style写进提示词,模型才会生效:
from diffusers import AutoPipelineForText2Image import torch pipeline = AutoPipelineForText2Image.from_pretrained("sd-dreambooth-library/herge-style", 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由于是完整模型,加载方式与普通 pipeline 完全一致——AutoPipelineForText2Image.from_pretrained会读取仓库内的全部组件(UNet、文本编码器、VAE、调度器等)。这里直接用了dtype=torch.float16将权重以半精度加载以节省显存;更规范的写法是传入torch_dtype=torch.float16。
三、Textual Inversion:加载文本嵌入
3.1 原理与适用场景
Textual inversion 与 DreamBooth 类似,同样只需少量图像即可个性化模型(学习某个风格或物体)。区别在于:它不修改扩散模型的任何权重,而是训练并找到一个新的嵌入向量——当提示词中出现特定单词时,模型会查找该单词对应的嵌入并据此生成图像。因此训练产物非常小,通常只有数 KB。
也正因如此,Textual Inversion不能单独使用,必须配合一个已有的扩散模型:
from diffusers import AutoPipelineForText2Image import torch pipeline = AutoPipelineForText2Image.from_pretrained("stable-diffusion-v1-5/stable-diffusion-v1-5", dtype=torch.float16).to("cuda")3.2 加载嵌入并生成图像
使用load_textual_inversion方法(由 TextualInversionLoaderMixin 提供)加载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] image3.3 加载 A1111 格式与指定触发词
Textual Inversion 还能训练负向嵌入(negative embedding)——让模型避免生成模糊图像、多余手指等不良内容,是一种快速改善出图质量的技巧。
加载方式与上面相同,但需要额外传入两个参数:
weight_name:当文件以特定名称保存为 🤗 Diffusers 格式,或文件是A1111(Automatic1111)格式时,用它指定要加载的权重文件名;token:指定在提示词中触发该嵌入的特殊单词。
示例:加载sayakpaul/EasyNegative-test嵌入,权重文件为EasyNegative.safetensors,触发词为EasyNegative:
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] image3.4 源码层面的加载逻辑
从 load_textual_inversion 实现 可以看到完整的处理链路:
- 确定 tokenizer 与 text encoder(默认取 pipeline 自身组件);
- 将输入归一化为列表形式,并校验模型列表与 token 列表长度一致(
_check_text_inv_inputs); - 加载嵌入的 state dict。支持三类来源:Hub 上的模型 id、本地目录、单个权重文件(如
./my_text_inversions.pt)或 torch state dict; - 解析嵌入格式(
_retrieve_tokens_and_embeddings):Diffusers 格式的 dict 只有一个 key(即 token 名);A1111 格式则包含string_to_param字段,此时 token 从state_dict["name"]读取;如果传入的是纯 tensor,则必须显式提供token; - 处理多向量嵌入(
_extend_tokens_and_embeddings):若嵌入张量的第一个维度大于 1,会自动拆分为token_1、token_2…… 等多个 token,并把嵌入逐行展开。配合maybe_convert_prompt(见 textual_inversion.py),加载多向量嵌入后,即使提示词中只写token,推理时也会自动替换为token token_1 token_2 ...序列; - 校验嵌入维度与文本编码器嵌入层维度一致,将 token 加入 tokenizer 词汇表、嵌入写入文本编码器。
四、LoRA:加载低秩适配权重
4.1 原理与适用场景
Low-Rank Adaptation (LoRA) 是目前最流行的训练技术:训练速度快、产物小(通常几十到几百 MB)。原理是向扩散模型中注入新的低秩权重,只训练这些新权重而不是整个模型,因此更易训练、更易存储和分发。
与 Textual Inversion 一样,LoRA 不能独立使用,必须配合一个基础模型。此外 LoRA 可与多种训练方法组合(例如 DreamBooth + LoRA 是常见组合);也常通过加载并合并多个 LoRA 来创造全新风格的图像——多 LoRA 合并不在本文范围内,可参考仓库中的 LoRA 合并专项指南。
4.2 使用 load_lora_weights 加载
先加载基础模型 SDXL:
from diffusers import AutoPipelineForText2Image import torch pipeline = AutoPipelineForText2Image.from_pretrained("stabilityai/stable-diffusion-xl-base-1.0", dtype=torch.float16).to("cuda")然后用load_lora_weights加载ostris/super-cereal-sdxl-lora权重,并通过weight_name指定仓库中的权重文件名:
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] imageload_lora_weights会把 LoRA 权重同时加载到 UNet 和文本编码器,是以下场景的首选方式:
- LoRA 权重中的 UNet 与文本编码器没有独立标识符;
- LoRA 权重中 UNet 与文本编码器有独立标识符。
4.3 只加载到 UNet:load_attn_procs
如果只想把 LoRA 加载到 UNet,可使用load_attn_procs(由 UNet2DConditionLoadersMixin 提供)。例如加载jbilcke-hf/sdxl-cinematic-1LoRA:
from diffusers import AutoPipelineForText2Image import torch pipeline = AutoPipelineForText2Image.from_pretrained("stabilityai/stable-diffusion-xl-base-1.0", dtype=torch.float16).to("cuda") pipeline.unet.load_attn_procs("jbilcke-hf/sdxl-cinematic-1", weight_name="pytorch_lora_weights.safetensors") # 在提示词中使用 cnmt 触发 LoRA prompt = "A cute cnmt eating a slice of pizza, stunning color scheme, masterpiece, illustration" image = pipeline(prompt).images[0] image4.4 卸载 LoRA
调用unload_lora_weights可删除 LoRA 权重,把模型恢复为原始权重:
pipeline.unload_lora_weights()从源码看,load_lora_weights/unload_lora_weights/fuse_lora/unfuse_lora等核心方法定义在 src/diffusers/loaders/lora_pipeline.py 中,且针对 Stable Diffusion、SDXL、Flux、Wan 等不同架构提供了各自的实现版本。加载时还会检查 state dict 中所有键名是否包含lora子串,若格式不合法会直接抛出ValueError。另外需要注意:仓库中名为LoraLoaderMixin的类已标记为弃用(见 lora_pipeline.py),未来版本将移除,请改用StableDiffusionLoraLoaderMixin。
4.5 缩放 LoRA 权重:cross_attention_kwargs
load_lora_weights与load_attn_procs都支持通过cross_attention_kwargs={"scale": 0.5}控制 LoRA 的使用强度:
scale=0:等价于只用基础模型权重;scale=1:等价于完全使用微调后的 LoRA 权重。
4.6 逐层精细控制:set_adapters
若需要对每一层使用多少 LoRA 权重做更细粒度的控制,可使用set_adapters(实现见 src/diffusers/loaders/lora_base.py),传入一个按组件/层级组织的缩放字典:
pipe = ... # 创建 pipeline pipe.load_lora_weights(..., adapter_name="my_adapter") scales = { "text_encoder": 0.5, "text_encoder_2": 0.5, # 仅当 pipeline 有第二个文本编码器时可用 "unet": { "down": 0.9, # down 部分的所有 transformer 使用 0.9 # "mid" # 未指定时,mid 部分的 transformer 使用默认 1.0 "up": { "block_0": 0.6, # up 第 0 个 block 中的 3 个 transformer 全部使用 0.6 "block_1": [0.4, 0.8, 1.0], # up 第 1 个 block 的 3 个 transformer 分别使用 0.4、0.8、1.0 } } } pipe.set_adapters("my_adapter", scales)其源码逻辑会校验传入的组件名是否属于该 pipeline 可加载 LoRA 的模块集合(_lora_loadable_modules),并自动把单个浮点数权重扩展为与 adapter 数量等长的列表;若传入的 adapter 名尚未加载,会抛出明确错误。set_adapters同样支持同时管理多个适配器(可参考 PEFT 推理相关文档了解多适配器强度定制)。
[!WARNING] 当前
set_adapters只支持缩放注意力权重;如果 LoRA 还包含其他部分(如 resnet、down/upsampler),这些部分将保持 1.0 的缩放。
4.7 社区训练器产物:Kohya 与 TheLastBen
社区流行的其他 LoRA 训练器包括 Kohya 与 TheLastBen 的 trainer。它们产出的 LoRA checkpoint 与 🤗 Diffusers 自训练格式不同,但可以用同样的方式加载。
Kohya LoRA 示例:先从 Civitai 下载Blueprintify SD XL 1.0权重:
!wget https://civitai.com/api/download/models/168776 -O blueprintify-sd-xl-10.safetensors然后用load_lora_weights加载本地文件,并通过weight_name指定文件名:
from diffusers import AutoPipelineForText2Image import torch pipeline = AutoPipelineForText2Image.from_pretrained("stabilityai/stable-diffusion-xl-base-1.0", dtype=torch.float16).to("cuda") pipeline.load_lora_weights("path/to/weights", weight_name="blueprintify-sd-xl-10.safetensors")生成图像(提示词中用bl3uprint触发 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[!WARNING] 将 Kohya LoRA 与 🤗 Diffusers 搭配使用时存在一些限制:
- 由于多种原因,生成的图像可能与 ComfyUI 等 UI 中生成的结果略有差异;
- LyCORIS checkpoint 未完全支持:
load_lora_weights可以加载 LyCORIS 的LoRA 与 LoCon模块,但Hada 与 LoKR不支持。
TheLastBen LoRA 示例:加载方式非常相似,例如加载TheLastBen/William_Eggleston_Style_SDXL:
from diffusers import AutoPipelineForText2Image import torch pipeline = AutoPipelineForText2Image.from_pretrained("stabilityai/stable-diffusion-xl-base-1.0", dtype=torch.float16).to("cuda") pipeline.load_lora_weights("TheLastBen/William_Eggleston_Style_SDXL", weight_name="wegg.safetensors") # 在提示词中使用 william eggleston 触发 LoRA prompt = "a house by william eggleston, sunrays, beautiful, sunlight, sunrays, beautiful" image = pipeline(prompt=prompt).images[0] image五、IP-Adapter:加载图像提示适配器
5.1 原理与适用场景
IP-Adapter 是一种轻量级图像提示适配器,可为任意扩散模型引入"以图生图"能力。其原理是:在cross-attention 层中将图像特征与文本特征分离,冻结其余所有模型组件,只训练 UNet 中嵌入的图像特征。因此 IP-Adapter 文件通常只有约 100MB。
关于 IP-Adapter 在不同任务与具体用例中的详细用法,可参考仓库中的 IP-Adapter 专项指南。
[!TIP] Diffusers 目前只对部分最常用的 pipeline 支持 IP-Adapter;如果你有优秀用例但对应 pipeline 尚不支持,可以在仓库中提交 feature request。官方 IP-Adapter 检查点位于
h94/IP-Adapter仓库。
5.2 基本加载流程
首先加载 Stable Diffusion 基础模型:
from diffusers import AutoPipelineForText2Image import torch from diffusers.utils import load_image pipeline = AutoPipelineForText2Image.from_pretrained("stable-diffusion-v1-5/stable-diffusion-v1-5", dtype=torch.float16).to("cuda")然后用load_ip_adapter(由 IPAdapterMixin 提供)加载 IP-Adapter 权重并挂载到 pipeline:
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] images5.3 IP-Adapter Plus:显式加载图像编码器
IP-Adapter 依赖一个图像编码器来生成图像特征。如果 IP-Adapter 仓库中存在image_encoder子文件夹,加载时会自动读取并注册;否则需要用CLIPVisionModelWithProjection显式加载图像编码器并传给 pipeline。
使用ViT-H 图像编码器的IP-Adapter Plus检查点就属于后者:
from transformers import CLIPVisionModelWithProjection image_encoder = CLIPVisionModelWithProjection.from_pretrained( "h94/IP-Adapter", subfolder="models/image_encoder", dtype=torch.float16 ) pipeline = AutoPipelineForText2Image.from_pretrained( "stabilityai/stable-diffusion-xl-base-1.0", image_encoder=image_encoder, dtype=torch.float16 ).to("cuda") pipeline.load_ip_adapter("h94/IP-Adapter", subfolder="sdxl_models", weight_name="ip-adapter-plus_sdxl_vit-h.safetensors")5.4 IP-Adapter Face ID:人脸一致性
IP-Adapter FaceID 是一类实验性适配器,它不使用 CLIP 图像嵌入,而是使用insightface生成的图像嵌入;部分模型还会结合 LoRA 提升 ID 一致性。使用前需要安装insightface及其依赖。
[!WARNING] InsightFace 预训练模型仅可用于非商业研究目的,因此 IP-Adapter-FaceID 系列模型只供研究用途,不可用于商业场景。
SDXL 基础用法:
pipeline = AutoPipelineForText2Image.from_pretrained( "stabilityai/stable-diffusion-xl-base-1.0", 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)两个FaceID Plus模型为了更好的真实感,同时使用insightface与 CLIP 图像嵌入,因此还需要加载 CLIP 图像编码器:
from transformers import CLIPVisionModelWithProjection image_encoder = CLIPVisionModelWithProjection.from_pretrained( "laion/CLIP-ViT-H-14-laion2B-s32B-b79K", dtype=torch.float16, ) pipeline = AutoPipelineForText2Image.from_pretrained( "stable-diffusion-v1-5/stable-diffusion-v1-5", image_encoder=image_encoder, dtype=torch.float16 ).to("cuda") pipeline.load_ip_adapter("h94/IP-Adapter-FaceID", subfolder=None, weight_name="ip-adapter-faceid-plus_sd15.bin")从源码看,load_ip_adapter会依据传入的subfolder、weight_name、image_encoder_folder等参数从 Hub 或本地目录解析权重,将图像编码器与 IP-Adapter 模块注册进 pipeline,并在推理时通过ip_adapter_image参数接收图像输入;卸载对应调用unload_ip_adapter(见 src/diffusers/loaders/ip_adapter.py)。
六、总结:四种适配器加载方式速查
| 适配器类型 | 产物形态 | 文件大小量级 | 加载方法 | 触发方式 |
|---|---|---|---|---|
| DreamBooth | 完整 checkpoint 模型 | 数 GB | AutoPipelineForText2Image.from_pretrained | 提示词中的特殊触发词 |
| Textual Inversion | 文本嵌入向量 | 数 KB | load_textual_inversion | 提示词中的特殊 token(如<gta5-artwork>) |
| LoRA | 低秩权重增量 | 数十~数百 MB | load_lora_weights/unet.load_attn_procs | 提示词中的触发词,可用scale/set_adapters调强度 |
| IP-Adapter | 轻量图像适配器 + 图像编码器 | 约 100 MB | load_ip_adapter | 推理时传入ip_adapter_image |
所有加载器 Mixin 的实现均集中在 src/diffusers/loaders/ 目录下,包括 textual_inversion.py、lora_pipeline.py、lora_base.py、ip_adapter.py 与 unet.py。理解这些源码有助于排查加载失败问题,例如嵌入维度不匹配、token 冲突、state dict 格式非法等——这些场景都会在加载时抛出明确的错误信息。实际使用时,建议始终为 pipeline 传入torch_dtype(如torch.float16)并迁移到 GPU,以获得合理的显存占用与推理速度。
【免费下载链接】diffusers🤗 Diffusers: State-of-the-art diffusion models for image, video, and audio generation in PyTorch.项目地址: https://gitcode.com/GitHub_Trending/di/diffusers
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考