Diffusers 多格式兼容实战:加载与转换 .ckpt、KerasCV 与 A1111 LoRA 等 Stable Diffusion 模型格式
【免费下载链接】diffusers🤗 Diffusers: State-of-the-art diffusion models for image, video, and audio generation in PyTorch.项目地址: https://gitcode.com/GitHub_Trending/di/diffusers
Stable Diffusion 模型因训练框架与分发渠道不同,常以 PyTorch.ckpt、Keras.pb/.h5、A1111 LoRA 等多样格式存在。本文基于当前仓库的官方指南(docs/source/ko/using-diffusers/other-formats.md)及其对应实现,系统讲解如何将这些格式转换为 🤗 Diffusers 兼容形式并直接加载使用。读完本文,你将掌握三种主流格式的转换/加载方案、转换脚本的完整参数语义,以及 LoRA 权重加载的底层原理,从而在推理时自由使用 Diffusers 提供的全部能力——如切换多种噪声调度器、构建自定义 pipeline、以及 flash attention、fp16 等推理加速手段。
为什么要做格式转换?
Stable Diffusion 生态中,模型因"训练/保存框架"和"下载来源"不同而呈现多种格式。将它们转换为 🤗 Diffusers 可用的形式后,就能解锁库内所有高级特性:
- 使用各种调度器(scheduler)进行去噪过程定制(步数、随机/确定性、具体算法);
- 自由搭建自定义 pipeline(参考 write_own_pipeline);
- 应用 flash attention、xformers、fp16 等推理优化技术提升速度与显存效率。
[!TIP] 官方明确推荐使用
.safetensors格式:传统的 pickle 序列化文件存在安全漏洞,加载时可能在机器上执行任意恶意代码;而 safetensors 更安全、加载更快。详细原理可阅读安全加载指南。
下面按格式逐一讲解。
加载 PyTorch .ckpt 格式
.ckpt(checkpoint)是最常见的模型存储格式,单个文件包含完整模型权重,通常体积达数 GB。虽然可以通过StableDiffusionPipeline.from_ckpt之类的方法直接加载,但官方更推荐先将其转换为 Diffusers 格式,以获得上述全部能力。转换有两条路径:使用 Space 在线转换与使用仓库内置脚本转换。
方案一:通过 Space 转换
最简单的做法是使用官方 SD → Diffusers 转换 Space,按照页面指引上传.ckpt文件即可完成转换。
需要留意的是:该方案对基础模型(base model)效果很好,但对经过大量自定义微调的模型可能失败——表现为返回空 pull request 或直接报错。遇到这种情况,应改用下面更可靠的脚本方案。
方案二:通过仓库脚本转换
🤗 Diffusers 在 scripts 目录中提供了专门的转换脚本 convert_original_stable_diffusion_to_diffusers.py,比 Space 方案更稳定可控。
准备条件:
- 本地克隆(clone)本仓库,确保能运行
scripts下的脚本; - 登录 Hugging Face 账号,以便后续打开 pull request 并把转换结果推送到 Hub:
hf auth login完整操作流程(以 TemporalNet 这个 SD v1.5 + ControlNet 模型为例):
- 克隆包含待转换
.ckpt文件的仓库:
git lfs install git clone https://huggingface.co/CiaraRowles/TemporalNet- 在目标仓库中为转换结果打开一个 pull request 分支:
cd TemporalNet && git fetch origin refs/pr/13:pr/13 git checkout pr/13确认三个关键脚本参数(详见下文参数详解):
checkpoint_path:待转换.ckpt文件的路径;original_config_file:描述原始架构的 YAML 配置文件。若找不到,可去下载.ckpt的 GitHub 仓库中搜索同名 YAML。例如 TemporalNet 是 SD v1.5 + ControlNet 模型,可直接从 ControlNet 仓库取得cldm_v15.yaml;dump_path:转换后模型的输出路径。
执行转换命令:
python ../diffusers/scripts/convert_original_stable_diffusion_to_diffusers.py --checkpoint_path temporalnetv3.ckpt --original_config_file cldm_v15.yaml --dump_path ./ --controlnet- 转换完成后,将结果上传到 PR 分支并测试:
git push origin pr/13:refs/pr/13转换脚本核心参数详解
对照 convert_original_stable_diffusion_to_diffusers.py 的 argparse 定义,可归纳出以下核心参数及其语义:
| 参数 | 类型 | 默认值 | 作用说明 |
|---|---|---|---|
--checkpoint_path | str | 必填 | 待转换的.ckpt文件路径 |
--original_config_file | str | None | 对应原始架构的 YAML 配置文件;缺省时通过内部启发式自动推断,但对继续微调过的模型易失败,尽量显式提供 |
--config_files | str | None | 架构对应的 YAML 配置(更通用的替代项) |
--dump_path | str | 必填 | 转换后模型的保存路径 |
--scheduler_type | str | pndm | 调度器类型,可选pndm、lms、ddim、euler、euler-ancestral、dpm |
--pipeline_type | str | None | pipeline 类型:FrozenOpenCLIPEmbedder、FrozenCLIPEmbedder、PaintByExample;缺省自动推断 |
--image_size | int | None | 训练时的图像尺寸:SD v1.X 与 SD v2 Base 用 512,SD v2 用 768 |
--prediction_type | str | None | 训练时的预测类型:SD v1.X 与 SD v2 Base 用epsilon,SD v2 用v_prediction |
--extract_ema | bool | False | 对同时含 EMA 与非 EMA 权重的检查点,是否提取 EMA 权重(EMA 推理质量通常更高,非 EMA 更适合继续微调) |
--upcast_attention | bool | False | 是否始终以更高精度计算 attention,运行 SD 2.1 时必需 |
--from_safetensors | bool | False | 输入为 safetensors 格式时以 safetensors 加载 |
--to_safetensors | bool | False | 是否将输出 pipeline 存为 safetensors 格式 |
--device | str | None | 运行设备,如cpu、cuda:0、cuda:1 |
--controlnet | bool | False | 标记该检查点是 ControlNet 检查点(如上例 TemporalNet) |
--half | bool | False | 以半精度(fp16)保存权重 |
--stable_unclip | str | None | 若是 stable unCLIP 模型则指定txt2img或img2img |
--vae_path | str | None | 指定已转换好的 VAE 路径/Hub id,避免重复转换 VAE |
--pipeline_class_name | str | None | 显式指定 pipeline 类名 |
从实现看,该脚本本质上是 convert_from_ckpt.py 中download_from_original_stable_diffusion_ckpt函数的命令行封装。这个底层函数接收checkpoint_path_or_dict(.ckpt路径或直接传入 state dict)、original_config_file、extract_ema、scheduler_type、num_in_channels、upcast_attention、controlnet、vae_path等参数,返回一个组装完成的DiffusionPipeline对象,随后脚本调用pipe.save_pretrained(args.dump_path, safe_serialization=args.to_safetensors)写出 Diffusers 格式的模型目录(若为 ControlNet 则只保存pipe.controlnet)。
值得强调的是,download_from_original_stable_diffusion_ckpt的文档注释明确指出:虽然很多参数可以自动推断,但部分推断依赖对全局步数的脆弱检查,对经过进一步微调的模型很可能会失败,因此只要可能就应提供original_config_file覆盖默认值。
加载 KerasCV 的 .pb / .h5 格式
🧪 该功能为实验性特性,当前 KerasCV 转换 Space 仅支持 Stable Diffusion v1 检查点。
KerasCV 支持训练 Stable Diffusion v1 与 v2,但针对"推理与部署"场景的功能较为有限;相比之下,🤗 Diffusers 提供了更完整的调度器、flash attention 与其他优化手段,因此将 KerasCV 权重转换过来很有价值。
转换方式:使用官方 KerasCV → Diffusers 转换 Space,它会将.pb或.h5权重先转换为 PyTorch,再包装成StableDiffusionPipeline供推理使用,转换结果保存在 Hugging Face Hub 上的新仓库中。
以 textual-inversion 微调过的sayakpaul/textual-inversion-kerasio检查点为例(它用特殊占位符 token<my-funny-cat>把图像个性化成猫)。在 KerasCV 转换 Space 中需要填写:
- Hugging Face 令牌(token);
- UNet 与文本编码器权重的下载路径。根据训练方式,两者不一定都提供——例如 textual-inversion 只需文本编码器中的嵌入,而文本转图像模型转换只需 UNet 权重;
- 占位符 token,仅 textual-inversion 模型需要;
output_repo_prefix:转换结果仓库的名称前缀。
点击Submit后,Space 自动完成转换并返回新仓库链接,仓库中的模型卡片带有一个可直接体验生成效果的推理 widget。要在代码中运行推理,点击模型卡片右上角的Use in Diffusers按钮复制示例代码,或直接:
from diffusers import DiffusionPipeline pipeline = DiffusionPipeline.from_pretrained("sayakpaul/textual-inversion-cat-kerascv_sd_diffusers_pipeline") pipeline.to("cuda") placeholder_token = "<my-funny-cat-token>" prompt = f"two {placeholder_token} getting married, photorealistic, high quality" image = pipeline(prompt, num_inference_steps=50).images[0]加载 A1111(Automatic1111)LoRA 文件
Automatic1111 是 Stable Diffusion 社区广泛使用的 Web UI,并支撑着 Civitai 等模型分享平台。基于 LoRA 技术训练的模型因训练速度快、文件体积远小于全参数微调模型而广受欢迎,因此能否在 Diffusers 中直接加载 A1111 格式的 LoRA 检查点至关重要。
使用 load_lora_weights 加载
Diffusers 通过StableDiffusionLoraLoaderMixin.load_lora_weights原生支持 A1111 LoRA 检查点。完整流程如下:
- 加载基础 pipeline(这里选用
andite/anything-v4.0,并换成UniPCMultistepScheduler调度器):
from diffusers import DiffusionPipeline, UniPCMultistepScheduler import torch pipeline = DiffusionPipeline.from_pretrained( "andite/anything-v4.0", dtype=torch.float16, safety_checker=None ).to("cuda") pipeline.scheduler = UniPCMultistepScheduler.from_config(pipeline.scheduler.config)- 从 Civitai 下载 LoRA 检查点(官方示例用的是 Howl's Moving Castle 风格的 Interior/Scenery LoRA,也可换成任意 LoRA):
!wget https://civitai.com/api/download/models/19998 -O howls_moving_castle.safetensors- 将 LoRA 权重加载进 pipeline:
pipeline.load_lora_weights(".", weight_name="howls_moving_castle.safetensors")- 使用正负提示词与固定随机种子生成图像:
prompt = "masterpiece, illustration, ultra-detailed, cityscape, san francisco, golden gate bridge, california, bay area, in the snow, beautiful detailed starry sky" negative_prompt = "lowres, cropped, worst quality, low quality, normal quality, artifacts, signature, watermark, username, blurry, more than one bridge, bad architecture" images = pipeline( prompt=prompt, negative_prompt=negative_prompt, width=512, height=512, num_inference_steps=25, num_images_per_prompt=4, generator=torch.manual_seed(0), ).images- 用辅助函数把 4 张图拼成网格展示:
from PIL import Image def image_grid(imgs, rows=2, cols=2): w, h = imgs[0].size grid = Image.new("RGB", size=(cols * w, rows * h)) for i, img in enumerate(imgs): grid.paste(img, box=(i % cols * w, i // cols * h)) return grid image_grid(images)load_lora_weights 的底层机制
对照 lora_pipeline.py 中load_lora_weights的实现,可以看清加载链条:
- 首先调用
lora_state_dict解析检查点,得到state_dict、network_alphas与元数据(metadata); - 校验格式:检查所有键名是否包含
lora子串,否则抛出"Invalid LoRA checkpoint"错误; - 分别调用
load_lora_into_unet与load_lora_into_text_encoder,把低秩适配权重注入 UNet 与文本编码器。
StableDiffusionPipeline的类定义(见 pipeline_stable_diffusion.py)同时继承了StableDiffusionLoraLoaderMixin(提供load_lora_weights/save_lora_weights)与FromSingleFileMixin(提供from_single_file直接加载.ckpt),因此这两类加载方式对 SD 系列 pipeline 是开箱即用的。
此外,load_lora_weights还支持adapter_name(为适配器命名以便引用)与hotswap参数:hotswap=True时原地替换已有适配器权重,在torch.compile编译模型场景下可避免重新编译,加载速度与内存占用更优(注意文本编码器暂不支持 hotswap)。
更多格式与转换辅助手段
单文件(single-file)格式
除 Diffusers 目录格式外,社区常见"单文件格式"——把 UNet、Transformer、文本编码器全部权重塞进一个文件。其优点是兼容 ComfyUI / Automatic1111,且便于下载分享。可通过FromSingleFileMixin.from_single_file直接加载,例如:
import torch from diffusers import StableDiffusionXLPipeline pipeline = StableDiffusionXLPipeline.from_single_file( "https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0/blob/main/sd_xl_base_1.0.safetensors", dtype=torch.float16, device_map="cuda" # 或 "mps"、"xpu"、"cpu" )当 Diffusers 格式模型的config.json无法正确推断时,可通过config参数显式指定配置仓库;也可以把config、dtype等参数直接传给from_single_file覆盖默认行为。from_single_file在local_files_only=True时会基于 pipeline 类签名推断组件,但该方式不如显式传入本地模型路径可靠,若联网应使用local_files_only=False让配置下载到本地缓存。
反向转换与 LoRA 格式转换脚本
当前仓库的 scripts 目录还提供了多组配套转换脚本,形成完整的格式生态:
- convert_diffusers_to_original_stable_diffusion.py 与 convert_diffusers_to_original_sdxl.py:把 Diffusers 格式转回原版单文件格式,可用
--use_safetensors指定输出文件类型; - convert_lora_safetensor_to_diffusers.py:将 LoRA safetensors 转换为 Diffusers 可加载形式;
- convert_original_controlnet_to_diffusers.py、convert_original_t2i_adapter.py 等:覆盖 ControlNet、T2I-Adapter 等附加模块的转换。
命名以to_diffusers结尾的脚本即"转换为 Diffusers 格式";每个脚本都有各自独立的参数集,使用前务必查阅其argparse定义。对于标准模型,也可直接使用官方 SD → Diffusers / SD-XL → Diffusers Space:它会自动在模型仓库上打开包含转换文件的 PR,是最省事的方案,但对复杂模型可能失败,此时脚本方案更可靠。
安全提示与最佳实践
- 优先 safetensors:
convert_original_stable_diffusion_to_diffusers.py同时支持--from_safetensors(读取 safetensors 输入)与--to_safetensors(写出 safetensors 输出),建议统一使用 safetensors 规避 pickle 反序列化风险; - 尽量提供原始 YAML 配置:
original_config_file是转换成功率的关键,缺失时自动推断对微调模型不可靠; - ControlNet 等附加模块:转换时务必加上
--controlnet等对应标志,脚本会只保存对应的附加模型(如pipe.controlnet); - 加载 LoRA 前校验格式:
load_lora_weights内部会检查键名是否含lora子串,若报Invalid LoRA checkpoint,说明文件并非标准 LoRA 权重。
通过上述方案,你可以把来自 Civitai、Automatic1111、KerasCV 等生态的模型与适配器无缝接入 Diffusers 的统一推理框架,享受调度器自由切换、pipeline 定制与推理优化的全部能力。
【免费下载链接】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),仅供参考