Diffusers 文档

模型文件和布局

Hugging Face's logo
加入 Hugging Face 社区

并获得增强的文档体验

开始使用

模型文件和布局

扩散模型以各种文件类型保存并以不同的布局组织。Diffusers 将模型权重存储为 Diffusers-多文件夹 布局中的 safetensors 文件,它还支持从扩散生态系统中常用的 单文件 布局加载文件(如 safetensors 和 ckpt 文件)。

每种布局都有其自身的优点和用例,本指南将向您展示如何加载不同的文件和布局,以及如何转换它们。

文件

PyTorch 模型权重通常使用 Python 的 pickle 实用程序保存为 ckpt 或 bin 文件。然而,pickle 不安全, pickled 文件可能包含可执行的恶意代码。考虑到模型共享的流行性,这种漏洞是一个严重的问题。为了解决这个安全问题,Safetensors 库被开发为 pickle 的安全替代品,它将模型保存为 safetensors 文件。

safetensors

Safetensors 经审计确认为真正安全并成为默认博客文章中,了解有关设计决策以及为何优先使用 safetensor 文件来保存和加载模型权重的更多信息。

Safetensors 是一种安全快速的文件格式,用于安全地存储和加载张量。Safetensors 限制了头部大小以限制某些类型的攻击,支持延迟加载(对于分布式设置很有用),并且通常具有更快的加载速度。

请确保您已安装 Safetensors 库。

!pip install safetensors

Safetensors 将权重存储在 safetensors 文件中。如果 safetensors 文件可用且 Safetensors 库已安装,Diffusers 默认加载 safetensors 文件。safetensors 文件有两种组织方式:

  1. Diffusers-多文件夹布局:可能有多个独立的 safetensors 文件,每个文件用于一个流水线组件(文本编码器、UNet、VAE),组织在子文件夹中(请参阅 stable-diffusion-v1-5/stable-diffusion-v1-5 仓库作为示例)
  2. 单文件布局:所有模型权重都可以保存在一个文件中(请参阅 WarriorMama777/OrangeMixs 仓库作为示例)
多文件夹
单文件

使用 from_pretrained() 方法加载存储在多个文件夹中的 safetensors 文件的模型。

from diffusers import DiffusionPipeline

pipeline = DiffusionPipeline.from_pretrained(
    "stable-diffusion-v1-5/stable-diffusion-v1-5",
    use_safetensors=True
)

LoRA 文件

LoRA 是一种轻量级适配器,训练快速简便,因此在以特定方式或风格生成图像方面特别受欢迎。这些适配器通常存储在 safetensors 文件中,并在 civitai 等模型共享平台上广泛流行。

LoRA 通过 load_lora_weights() 方法加载到基础模型中。

from diffusers import StableDiffusionXLPipeline
import torch

# base model
pipeline = StableDiffusionXLPipeline.from_pretrained(
    "Lykon/dreamshaper-xl-1-0", torch_dtype=torch.float16, variant="fp16"
).to("cuda")

# download LoRA weights
!wget https://civitai.com/api/download/models/168776 -O blueprintify.safetensors

# load LoRA weights
pipeline.load_lora_weights(".", weight_name="blueprintify.safetensors")
prompt = "bl3uprint, a highly detailed blueprint of the empire state building, explaining how to build all parts, many txt, blueprint grid backdrop"
negative_prompt = "lowres, cropped, worst quality, low quality, normal quality, artifacts, signature, watermark, username, blurry, more than one bridge, bad architecture"

image = pipeline(
    prompt=prompt,
    negative_prompt=negative_prompt,
    generator=torch.manual_seed(0),
).images[0]
image

ckpt

Pickled 文件可能不安全,因为它们可能被利用来执行恶意代码。建议尽可能使用 safetensors 文件,或将权重转换为 safetensors 文件。

PyTorch 的 torch.save 函数使用 Python 的 pickle 实用程序来序列化和保存模型。这些文件保存为 ckpt 文件,其中包含整个模型的权重。

使用 from_single_file() 方法直接加载 ckpt 文件。

from diffusers import StableDiffusionPipeline

pipeline = StableDiffusionPipeline.from_single_file(
    "https://huggingface.co/stable-diffusion-v1-5/stable-diffusion-v1-5/blob/main/v1-5-pruned.ckpt"
)

存储布局

模型文件有两种组织方式,要么是 Diffusers-多文件夹布局,要么是单文件布局。Diffusers-多文件夹布局是默认的,每个组件文件(文本编码器、UNet、VAE)都存储在单独的子文件夹中。Diffusers 还支持从将所有组件捆绑在一起的单文件布局加载模型。

Diffusers-多文件夹

Diffusers-多文件夹布局是 Diffusers 的默认存储布局。每个组件(文本编码器、UNet、VAE)的权重都存储在单独的子文件夹中。权重可以存储为 safetensors 或 ckpt 文件。

多文件夹布局
UNet 子文件夹

要从 Diffusers-多文件夹布局加载,请使用 from_pretrained() 方法。

from diffusers import DiffusionPipeline

pipeline = DiffusionPipeline.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0",
    torch_dtype=torch.float16,
    variant="fp16",
    use_safetensors=True,
).to("cuda")

使用 Diffusers-多文件夹布局的优点包括:

  1. 更快地单独或并行加载每个组件文件。

  2. 减少内存使用,因为您只加载所需的组件。例如,像 SDXL TurboSDXL LightningHyper-SD 这样的模型除了 UNet 之外,具有相同的组件。您可以使用 from_pipe() 方法重用它们的共享组件,而无需消耗任何额外的内存(请参阅 重用流水线 指南),并且只加载 UNet。这样,您无需下载冗余组件并避免不必要的内存使用。

    import torch
    from diffusers import StableDiffusionXLPipeline, UNet2DConditionModel, EulerDiscreteScheduler
    
    # download one model
    sdxl_pipeline = StableDiffusionXLPipeline.from_pretrained(
        "stabilityai/stable-diffusion-xl-base-1.0",
        torch_dtype=torch.float16,
        variant="fp16",
        use_safetensors=True,
    ).to("cuda")
    
    # switch UNet for another model
    unet = UNet2DConditionModel.from_pretrained(
        "stabilityai/sdxl-turbo",
        subfolder="unet",
        torch_dtype=torch.float16,
        variant="fp16",
        use_safetensors=True
    )
    # reuse all the same components in new model except for the UNet
    turbo_pipeline = StableDiffusionXLPipeline.from_pipe(
        sdxl_pipeline, unet=unet,
    ).to("cuda")
    turbo_pipeline.scheduler = EulerDiscreteScheduler.from_config(
        turbo_pipeline.scheduler.config,
        timestep+spacing="trailing"
    )
    image = turbo_pipeline(
        "an astronaut riding a unicorn on mars",
        num_inference_steps=1,
        guidance_scale=0.0,
    ).images[0]
    image
  3. 减少存储需求,因为如果一个组件(例如 SDXL VAE)在多个模型之间共享,您只需下载和存储它的一个副本,而不是多次下载和存储它。对于 10 个 SDXL 模型,这可以节省约 3.5GB 的存储空间。对于 PixArt Sigma 等新模型,存储节省量甚至更大,其中 文本编码器 单独就有约 19GB!

  4. 灵活地用更新或更好的版本替换模型中的组件。

    from diffusers import DiffusionPipeline, AutoencoderKL
    
    vae = AutoencoderKL.from_pretrained("madebyollin/sdxl-vae-fp16-fix", torch_dtype=torch.float16, use_safetensors=True)
    pipeline = DiffusionPipeline.from_pretrained(
        "stabilityai/stable-diffusion-xl-base-1.0",
        vae=vae,
        torch_dtype=torch.float16,
        variant="fp16",
        use_safetensors=True,
    ).to("cuda")
  5. 有关模型组件的更多可见性和信息,这些组件存储在每个组件子文件夹中的 config.json 文件中。

单文件

单文件布局将所有模型权重存储在一个文件中。所有模型组件(文本编码器、UNet、VAE)的权重都打包在一起,而不是分别存储在子文件夹中。这可以是 safetensors 或 ckpt 文件。

要从单文件布局加载,请使用 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",
    torch_dtype=torch.float16,
    variant="fp16",
    use_safetensors=True,
).to("cuda")

使用单文件布局的优点包括:

  1. 与通常使用单文件布局的扩散接口(如 ComfyUIAutomatic1111)轻松兼容。
  2. 更易于管理(下载和共享)单个文件。

DDUF

DDUF 是一种实验性文件格式,其相关 API 将来可能会发生变化。

DDUF (DDUF Diffusion Unified Format) 是一种文件格式,旨在使扩散模型的存储、分发和使用更加便捷。DDUF 基于 ZIP 文件格式构建,提供了一种标准化、高效且灵活的方式,可将扩散模型的所有部分打包成一个易于管理的单个文件。它在 Diffusers 多文件夹格式和广泛流行的单文件格式之间取得了平衡。

在 Hugging Face Hub 文档上了解更多关于 DDUF 的详细信息。

将检查点传递给 dduf_file 参数以将其加载到 DiffusionPipeline 中。

from diffusers import DiffusionPipeline
import torch

pipe = DiffusionPipeline.from_pretrained(
    "DDUF/FLUX.1-dev-DDUF", dduf_file="FLUX.1-dev.dduf", torch_dtype=torch.bfloat16
).to("cuda")
image = pipe(
    "photo a cat holding a sign that says Diffusers", num_inference_steps=50, guidance_scale=3.5
).images[0]
image.save("cat.png")

要将流水线保存为 .dduf 检查点,请使用 export_folder_as_dduf 实用程序,该实用程序负责所有必要的文件级验证。

from huggingface_hub import export_folder_as_dduf
from diffusers import DiffusionPipeline
import torch 

pipe = DiffusionPipeline.from_pretrained("black-forest-labs/FLUX.1-dev", torch_dtype=torch.bfloat16)

save_folder = "flux-dev"
pipe.save_pretrained("flux-dev")
export_folder_as_dduf("flux-dev.dduf", folder_path=save_folder)

> [!TIP]
> Packaging and loading quantized checkpoints in the DDUF format is supported as long as they respect the multi-folder structure.

## Convert layout and files

Diffusers provides many scripts and methods to convert storage layouts and file formats to enable broader support across the diffusion ecosystem.

Take a look at the [diffusers/scripts](https://github.com/huggingface/diffusers/tree/main/scripts) collection to find a script that fits your conversion needs.

> [!TIP]
> Scripts that have "`to_diffusers`" appended at the end mean they convert a model to the Diffusers-multifolder layout. Each script has their own specific set of arguments for configuring the conversion, so make sure you check what arguments are available!

For example, to convert a Stable Diffusion XL model stored in Diffusers-multifolder layout to a single-file layout, run the [convert_diffusers_to_original_sdxl.py](https://github.com/huggingface/diffusers/blob/main/scripts/convert_diffusers_to_original_sdxl.py) script. Provide the path to the model to convert, and the path to save the converted model to. You can optionally specify whether you want to save the model as a safetensors file and whether to save the model in half-precision.

```bash
python convert_diffusers_to_original_sdxl.py --model_path path/to/model/to/convert --checkpoint_path path/to/save/model/to --use_safetensors

最后,您还可以使用 save_pretrained() 方法将模型保存为 Diffusers-多文件夹布局。如果目录不存在,此方法会为您创建目录,并且默认将文件保存为 safetensors 文件。

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",
)
pipeline.save_pretrained()

最后,还有一些 Space,例如 SD To DiffusersSD-XL To Diffusers,它们提供了更用户友好的界面,用于将模型转换为 Diffusers-多文件夹布局。这是转换布局最简单、最方便的选项,它会在您的模型仓库中打开一个包含转换文件的 PR。然而,此选项不如运行脚本可靠,并且 Space 可能会在更复杂的模型上失败。

单文件布局使用

既然您熟悉了 Diffusers-多文件夹和单文件布局之间的区别,本节将向您展示如何使用 from_single_file() 方法加载模型和流水线组件,自定义加载的配置选项,以及加载本地文件。

加载流水线或模型

将流水线或模型的文件路径传递给 from_single_file() 方法以加载它。

流水线
模型
from diffusers import StableDiffusionXLPipeline

ckpt_path = "https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0/blob/main/sd_xl_base_1.0_0.9vae.safetensors"
pipeline = StableDiffusionXLPipeline.from_single_file(ckpt_path)

通过将组件直接传递给 from_single_file() 方法来定制流水线中的组件。例如,您可以在流水线中使用不同的调度器。

from diffusers import StableDiffusionXLPipeline, DDIMScheduler

ckpt_path = "https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0/blob/main/sd_xl_base_1.0_0.9vae.safetensors"
scheduler = DDIMScheduler()
pipeline = StableDiffusionXLPipeline.from_single_file(ckpt_path, scheduler=scheduler)

或者您可以在流水线中使用 ControlNet 模型。

from diffusers import StableDiffusionControlNetPipeline, ControlNetModel

ckpt_path = "https://huggingface.co/stable-diffusion-v1-5/stable-diffusion-v1-5/blob/main/v1-5-pruned-emaonly.safetensors"
controlnet = ControlNetModel.from_pretrained("lllyasviel/control_v11p_sd15_canny")
pipeline = StableDiffusionControlNetPipeline.from_single_file(ckpt_path, controlnet=controlnet)

自定义配置选项

模型有一个配置文件,用于定义其属性,例如 UNet 中的输入数量。流水线的配置选项可在流水线的类中找到。例如,如果您查看 StableDiffusionXLInstructPix2PixPipeline 类,会有一个选项可以使用 is_cosxl_edit 参数缩放图像潜在空间。

这些配置文件可以在模型的 Hub 仓库或其他配置文件的来源位置(例如,GitHub 仓库或本地设备)中找到。

Hub 配置文件
原始配置文件

from_single_file() 方法会自动将检查点映射到适当的模型仓库,但在某些情况下,使用 config 参数会很有用。例如,如果检查点中的模型组件与原始检查点不同,或者检查点没有必要的元数据来正确确定流水线要使用的配置。

from_single_file() 方法会自动从模型仓库中的配置文件确定要使用的配置。您还可以通过向 config 参数提供仓库 ID 来显式指定要使用的配置。

from diffusers import StableDiffusionXLPipeline

ckpt_path = "https://huggingface.co/segmind/SSD-1B/blob/main/SSD-1B.safetensors"
repo_id = "segmind/SSD-1B"

pipeline = StableDiffusionXLPipeline.from_single_file(ckpt_path, config=repo_id)

模型从仓库中各自的子文件夹加载 UNetVAE文本编码器 的配置文件。

虽然配置文件指定了流水线或模型的默认参数,但您可以通过直接向 from_single_file() 方法提供参数来覆盖它们。模型或流水线类支持的任何参数都可以通过这种方式配置。

流水线
模型

例如,要在 StableDiffusionXLInstructPix2PixPipeline 中缩放图像潜在空间,请传递 is_cosxl_edit 参数。

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)

本地文件

在 Diffusers>=v0.28.0 中,from_single_file() 方法尝试通过检查点文件中的键推断模型类型来配置流水线或模型。推断出的模型类型用于确定 Hugging Face Hub 上适当的模型仓库,以配置模型或流水线。

例如,任何基于 Stable Diffusion XL 基础模型的单文件检查点都将使用 stabilityai/stable-diffusion-xl-base-1.0 模型仓库来配置流水线。

但是,如果您在网络受限的环境中工作,则应使用 snapshot_download 函数下载配置文件,并使用 hf_hub_download 函数下载模型检查点。默认情况下,这些文件会下载到 Hugging Face Hub 缓存目录,但您可以使用 local_dir 参数指定首选的下载目录。

将配置和检查点路径传递给 from_single_file() 方法以在本地加载。

Hub 缓存目录
特定本地目录
from huggingface_hub import hf_hub_download, snapshot_download

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)

不使用符号链接的本地文件

在 huggingface_hub>=v0.23.0 中,hf_hub_downloadsnapshot_download 函数不再需要 local_dir_use_symlinks 参数。

from_single_file() 方法依赖于 huggingface_hub 缓存机制来获取和存储模型和流水线的检查点和配置文件。如果您在不支持符号链接的文件系统上工作,应首先将检查点文件下载到本地目录,并在 hf_hub_download 函数和 snapshot_download 函数中将 local_dir_use_symlink=False 参数设置为禁用符号链接。

from huggingface_hub import hf_hub_download, snapshot_download

my_local_checkpoint_path = hf_hub_download(
    repo_id="segmind/SSD-1B",
    filename="SSD-1B.safetensors"
    local_dir="my_local_checkpoints",
    local_dir_use_symlinks=False
)
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"]
    local_dir_use_symlinks=False,
)
print("My local config: ", my_local_config_path)

然后可以将本地路径传递给 pretrained_model_link_or_pathconfig 参数。

pipeline = StableDiffusionXLPipeline.from_single_file(my_local_checkpoint_path, config=my_local_config_path, local_files_only=True)
< > 在 GitHub 上更新