Diffusers 模型格式与单文件加载完全指南:从 Diffusers 目录格式到 safetensors/ckpt 的转换实战
【免费下载链接】diffusers🤗 Diffusers: State-of-the-art diffusion models for image, video, and audio generation in PyTorch.项目地址: https://gitcode.com/GitHub_Trending/di/diffusers
导读:本文是围绕 Hugging Face Diffusers 官方文档《Model formats》整理的技术指南,核心解决两类工程问题:一是理解"格式(format)"与"文件类型(file)"的区别——前者指权重以目录结构存储还是单文件存储,后者指 safetensors 或 ckpt 等文件封装;二是掌握
from_single_file加载单文件权重、config参数覆盖默认配置、LoRA 元数据保存,以及借助 转换脚本 与save_pretrained在两种格式间互转的完整方案。读完本文,你将能在不依赖 Diffusers 目录结构的情况下,直接加载社区流传的 .safetensors / .ckpt 检查点,并安全地在各生态格式间迁移模型。
引言:理解"格式"与"文件类型"
在 Diffusion 模型生态中,模型权重的存储方式常常让人混淆。Diffusers 官方文档用一个简明的 Tip 点破了本质:
Format 指的是权重以目录结构存储还是单文件存储;File 指的是文件的具体封装类型(safetensors 或 ckpt)。
- 格式(Format):分为 Diffusers 格式(每个组件一个子目录)与单文件格式(所有组件权重塞进一个文件)。
- 文件类型(File):safetensors、ckpt(基于 Python pickle)、以及其他社区封装。
这两条轴彼此正交:一个单文件格式的模型,既可以是.safetensors,也可以是.ckpt;一个 Diffusers 格式的模型仓库,内部组件也各自以 safetensors 存储。本文后续所有章节都围绕这两条轴展开。
Diffusers 格式:目录化的组件存储
Diffusers 格式将 UNet、Transformer、文本编码器等每个模型组件分别存放在独立的子文件夹中,每个组件目录下都有对应的权重文件与config.json。官方文档总结了这种存储方式的四重收益:
- 更快的整体管线初始化:可以只加载需要的单个模型,也可以并行加载全部组件;
- 更低的内存占用:当只需要某个模型时,不必把整条管线的组件全部加载进内存;
- 更低的存储需求:多个管线共享的公共模型只需下载一次;
- 更高的灵活性:可以在管线中自由替换更新或更优的模型组件。
这种格式与 [~DiffusionPipeline.from_pretrained] 天然配套。模型仓库根目录的config.json记录了各组件(unet、vae、text_encoder、scheduler 等)的类名与子目录位置,from_pretrained据此逐组件实例化。你可以在 加载指南 中看到更完整的加载细节(如"多管线复用模型"的用法)。
单文件格式:一个文件装下整条管线
单文件格式将所有模型权重(UNet、Transformer、文本编码器等)打包进单个文件。其优势同样明显:
- 与 ComfyUI、Automatic1111(stable-diffusion-webui)等生态工具兼容性更好,社区模型常以此形态分发;
- 更易下载与分享,一个文件即可分发完整模型。
加载单文件格式的标准入口是 [~loaders.FromSingleFileMixin.from_single_file],其底层实现位于 src/diffusers/loaders/single_file.py。从源码 docstring 可知,该方法支持两种输入:Hub 上.ckpt/.safetensors文件的直链,或本地包含全部管线权重的单文件路径;加载完成后管线默认处于model.eval()评估模式。
基础用法:加载 SDXL 单文件检查点
官方文档给出的最小示例,直接把模型链接与设备/精度参数传给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" # or "mps", "xpu", "cpu" )这里dtype=torch.float16将管线权重以半精度加载以节省显存,device_map指定设备分发策略。从源码看(single_file.py),该方法还接受force_download、cache_dir、proxies、token、local_files_only、revision、disable_mmap等 huggingface_hub 风格参数;disable_mmap=True在网络挂载盘或机械硬盘上加载 safetensors 时可能获得更好性能。
单组件加载:为管线替换新模型
from_single_file同样支持只加载某个组件(如新的 Transformer),再组装进已有管线——这正是"Diffusers 格式下灵活替换组件"思想的延伸:
import torch from diffusers import FluxPipeline, FluxTransformer2DModel transformer = FluxTransformer2DModel.from_single_file( "https://huggingface.co/Kijai/flux-fp8/blob/main/flux1-dev-fp8.safetensors", dtype=torch.bfloat16 ) pipeline = FluxPipeline.from_pretrained( "black-forest-labs/FLUX.1-dev", transformer=transformer, dtype=torch.bfloat16, device_map="cuda" # or "mps", "xpu", "cpu" )此例先用FluxTransformer2DModel.from_single_file单独加载 FP8 量化的 Flux Transformer,再通过FluxPipeline.from_pretrained将其注入完整管线。由于量化模型通常要求更低的数值精度,这里使用torch.bfloat16。这种"组件级单文件加载 + 管线级目录加载"的组合,是生产环境中处理量化/蒸馏/微调组件的常见姿势。
配置选项:config 参数的自动推断与手动覆盖
Diffusers 格式的模型仓库中都有config.json,记录层数、注意力头数等关键结构属性。from_single_file会自动从检查点推断合适的 config——源码中的fetch_diffusers_config(checkpoint)通过检查点内的 key 识别模型类型(single_file.py),例如任何基于 SDXL base 模型的单文件检查点都会被配置为stabilityai/stable-diffusion-xl-base-1.0。
但在少数情况下自动推断会失败,此时应显式传入config参数;当管线中的模型与原实现不同、或检查点缺少判断 config 所需的元数据时,同样必须手动指定:
from diffusers import StableDiffusionXLPipeline ckpt_path = "https://huggingface.co/segmind/SSD-1B/blob/main/SSD-1B.safetensors" pipeline = StableDiffusionXLPipeline.from_single_file(ckpt_path, config="segmind/SSD-1B")config参数既可以是 Hub 上的 repo id,也可以是本地 Diffusers 格式目录路径。源码(single_file.py)展示了完整的解析逻辑:若config不是本地目录,则视为 repo id 并尝试下载其配置;若本地无缓存且local_files_only=True,则会回退下载配置(除非同时提供original_config走旧版推断路径)。
关于original_config有一个官方文档强调的坑:当使用original_config且local_files_only=True时,Diffusers 会基于管线类的签名类型推断组件配置(源码中的_infer_pipeline_config_dict,single_file.py),此时不会从 Hub 下载配置文件以避免断网时产生向后不兼容变更。但这种推断不如显式传入本地模型目录的config可靠,可能报错——建议先以local_files_only=False运行一次,让配置文件下载到本地缓存,之后再离线使用。
覆盖默认配置:管线级与模型级示例
from_single_file还允许把额外的参数直接传给管线或模型的__init__,从而覆盖默认配置。官方文档给出两个典型场景:
管线级覆盖——以 COSXL 编辑模型为例:
from diffusers import StableDiffusionXLInstructPix2PixPipeline ckpt_path = "https://huggingface.co/stabilityai/cosxl/blob/main/cosxl_edit.safetensors" pipeline = StableDiffusionXLInstructPix2PixPipeline.from_single_file( ckpt_path, config="diffusers/sdxl-instructpix2pix-768", is_cosxl_edit=True )这里同时做了两件事:用config指定与 COSXL 结构匹配的 InstructPix2Pix 配置,用is_cosxl_edit=True告诉管线这是一个 COSXL 编辑模型(触发对应分支逻辑)。
模型级覆盖——以 0.9 VAE 的 UNet 为例:
from diffusers import UNet2DConditionModel ckpt_path = "https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0/blob/main/sd_xl_base_1.0_0.9vae.safetensors" model = UNet2DConditionModel.from_single_file(ckpt_path, upcast_attention=True)upcast_attention=True覆盖了 UNet 默认的注意力上转型配置,对兼容旧版 VAE 训练权重很有用。从源码看,多余的 kwargs 会通过passed_class_obj机制传递到组件构造器(single_file.py)。
本地文件:用 huggingface_hub 工具预先下载
如果希望完全离线操作,可以先用 [~huggingface_hub.snapshot_download] 下载配置文件、用 [~huggingface_hub.hf_hub_download] 下载检查点,再传入本地路径。默认会下载到缓存目录,也可通过local_dir指定目录:
from huggingface_hub import hf_hub_download, snapshot_download from diffusers import StableDiffusionXLPipeline my_local_checkpoint_path = hf_hub_download( repo_id="segmind/SSD-1B", filename="SSD-1B.safetensors" ) my_local_config_path = snapshot_download( repo_id="segmind/SSD-1B", allow_patterns=["*.json", "**/*.json", "*.txt", "**/*.txt"] ) pipeline = StableDiffusionXLPipeline.from_single_file( my_local_checkpoint_path, config=my_local_config_path, local_files_only=True )注意snapshot_download的allow_patterns只拉取 json/txt 配置类文件而避开大权重文件——这正是"配置文件来自 Diffusers 仓库、权重文件来自单文件检查点"这一混合策略的精髓。local_files_only=True保证加载阶段绝不联网。
符号链接(Symlink)与不支持符号链接的文件系统
HuggingFace Hub 的缓存机制默认使用符号链接。若你工作的文件系统(如某些网络盘、Windows 老式文件系统、容器挂载卷)不支持符号链接,则应在下载时就通过local_dir参数落地到本地目录——使用local_dir会自动禁用符号链接:
from huggingface_hub import hf_hub_download, snapshot_download from diffusers import StableDiffusionXLPipeline my_local_checkpoint_path = hf_hub_download( repo_id="segmind/SSD-1B", filename="SSD-1B.safetensors", local_dir="my_local_checkpoints", ) print("My local checkpoint: ", my_local_checkpoint_path) my_local_config_path = snapshot_download( repo_id="segmind/SSD-1B", allow_patterns=["*.json", "**/*.json", "*.txt", "**/*.txt"] ) print("My local config: ", my_local_config_path)随后照常传入from_single_file:
pipeline = StableDiffusionXLPipeline.from_single_file( my_local_checkpoint_path, config=my_local_config_path, local_files_only=True )文件类型:safetensors 与 ckpt
无论采用哪种格式,模型权重最终都要落到某种文件封装中。Hub 与社区里最常见的是 safetensors,但也会遇到 ckpt。
safetensors:默认且推荐的文件类型
Safetensors 是一种安全、快速的张量存储格式:
- 安全:严格限制文件头大小,抵御特定类型的恶意攻击;
- 快速:一般加载速度优于 pickle 系格式;
- 支持惰性加载(lazy loading):对分布式部署尤其有用。
Diffusers 将 safetensors 作为默认加载格式(也是必需的依赖),只要 Safetensors 库已安装且文件可用,就会优先加载 safetensors。无论目录格式还是单文件格式,加载入口都是一致的:
import torch from diffusers import DiffusionPipeline pipeline = DiffusionPipeline.from_pretrained( "stabilityai/stable-diffusion-xl-base-1.0", torch.dtype=torch.float16, device_map="cuda" # or "mps", "xpu", "cpu" ) pipeline = DiffusionPipeline.from_single_file( "https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0/blob/main/sd_xl_base_1.0.safetensors", dtype=torch.float16, )LoRA 元数据是 safetensors 的重要特性:若检查点由 Diffusers 训练脚本产出,LoRA 配置等元数据会自动写入文件;加载时 Diffusers 解析这些元数据以正确配置 LoRA,避免配置缺失或错误。可在 Hub 上点击文件旁的 safetensors logo 查看元数据。
对非 Diffusers 训练产出的 LoRA,需要手动保存元数据:Transformer/UNet 分别用transformer_lora_adapter_metadata或unet_lora_adapter_metadata;文本编码器则用text_encoder_lora_adapter_metadata与text_encoder_2_lora_adapter_metadata传给 [~loaders.FluxLoraLoaderMixin.save_lora_weights]。该功能仅支持 safetensors 文件。Flux 管线的完整示例:
import torch from diffusers import FluxPipeline pipeline = FluxPipeline.from_pretrained( "black-forest-labs/FLUX.1-dev", dtype=torch.bfloat16 ).to("cuda") # or "mps", "xpu", "cpu" pipeline.load_lora_weights("linoyts/yarn_art_Flux_LoRA") pipeline.save_lora_weights( text_encoder_lora_adapter_metadata={"r": 8, "lora_alpha": 8}, text_encoder_2_lora_adapter_metadata={"r": 8, "lora_alpha": 8} )源码层面,src/diffusers/loaders/lora_base.py 定义了LORA_ADAPTER_METADATA_KEY = "lora_adapter_metadata",并强制约束:指定了lora_adapter_metadata时safe_serialization必须为 True(即只能存为 safetensors),且该参数必须是 dict;最终会以"组件名前缀 + 元数据"的形式打包进文件的 header。各管线类(如 SDXL、Flux、SD3 等)的save_lora_weights实现分布在 src/diffusers/loaders/lora_pipeline.py 中,分别接受unet_lora_adapter_metadata、text_encoder_lora_adapter_metadata、text_encoder_2_lora_adapter_metadata、transformer_lora_adapter_metadata等参数(见该文件 L471-L509、L896-L916、L1182 附近),加载时据此还原 LoRA 的 rank、alpha 等关键配置。
ckpt:历史遗留但需警惕
较老的权重常用 Python 的 pickle 序列化进.ckpt文件。pickle 存在安全隐患——恶意文件可借此执行任意代码,官方文档明确建议优先使用 safetensors,或将 ckpt 权重转换为 safetensors。
若确需加载 ckpt,同样走from_single_file:
from diffusers import DiffusionPipeline pipeline = DiffusionPipeline.from_single_file( "https://huggingface.co/stable-diffusion-v1-5/stable-diffusion-v1-5/blob/main/v1-5-pruned.ckpt" )务必只从可信来源获取 ckpt 文件,并在隔离环境中先验证其安全性。
格式与文件类型互转:脚本、API 与 Space
Diffusers 提供了多层次的转换能力,以覆盖整个扩散生态。
转换脚本:scripts 目录
仓库的 scripts 目录汇集了大量转换脚本。命名规律是:以to_diffusers结尾的脚本将模型转换为 Diffusers 格式(例如convert_original_stable_diffusion_to_diffusers.py、convert_sd3_to_diffusers.py、convert_flux_to_diffusers.py等)。每个脚本都有一套专属参数,使用前务必查看其具体参数说明。
反向转换(Diffusers 格式 → 单文件格式)的官方示例使用convert_diffusers_to_original_sdxl.py:
python convert_diffusers_to_original_sdxl.py --model_path path/to/model/to/convert --checkpoint_path path/to/save/model/to --use_safetensors其中--model_path指向待转换的 Diffusers 格式模型,--checkpoint_path是转换产物的保存路径,--use_safetensors可选地指定输出为 safetensors(不指定则输出 ckpt)。类似地,仓库还提供了convert_diffusers_to_original_stable_diffusion.py等脚本覆盖其他架构,你可以按需选择。
save_pretrained:代码内一键转 Diffusers 格式
[~DiffusionPipeline.save_pretrained] 负责将模型保存为 Diffusers 格式,自动为每个组件创建子目录,默认以 safetensors 落盘。结合from_single_file即可完成"单文件 → Diffusers 目录"的纯代码转换:
from diffusers import DiffusionPipeline pipeline = DiffusionPipeline.from_single_file( "https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0/blob/main/sd_xl_base_1.0.safetensors", ) pipeline.save_pretrained()零代码方案:SD To Diffusers 等 Space
若不想写代码,还可以使用社区提供的转换 Space(如 SD To Diffusers、SD-XL To Diffusers):上传模型后,Space 会在你的模型仓库上自动打开一个包含转换产物的 PR。这是最省事的方案,但对结构较复杂的模型可能失败——此时使用转换脚本更可靠。
小结与选型建议
| 维度 | Diffusers 格式 | 单文件格式 |
|---|---|---|
| 存储形态 | 每组件独立子目录 + config.json | 全部权重打包进一个文件 |
| 加载入口 | from_pretrained | from_single_file |
| 初始化速度 | 可按需/并行加载,更快 | 一次载入全部 |
| 内存占用 | 按需加载,更低 | 需整载 |
| 生态兼容 | Diffusers 原生 | ComfyUI / A1111 友好 |
| 典型文件类型 | safetensors | safetensors / ckpt |
实际工程中的推荐路径:
- 新训练/新发布模型:优先采用 Diffusers 格式 + safetensors,享受按需加载与安全默认;
- 消费社区单文件检查点:使用
from_single_file,必要时用config显式指定结构配置; - 需要与 WebUI 生态互换:用 scripts 下的转换脚本(如
convert_diffusers_to_original_sdxl.py)导出单文件; - 离线/特殊文件系统环境:先通过
hf_hub_download/snapshot_download配合local_dir落地文件,再以local_files_only=True加载; - 安全底线:对 ckpt 文件保持警惕,优先转换或使用 safetensors。
如需进一步了解模型加载的完整话题(包括多管线复用、组件卸载等),可继续阅读 加载指南。
【免费下载链接】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),仅供参考