# 模型格式

扩散模型通常以 Diffusers 格式或单文件格式存储。模型文件可以保存为多种文件类型，例如 safetensors 或 ckpt。

> [!TIP]
> Format 指的是权重是否以目录结构存储。File type 指的是这些权重的序列化方式，例如 safetensors 或 ckpt。

```text
Diffusers format                    Single-file format
model/                              model.safetensors   (or .ckpt)
├─ model_index.json                 └─ all components in one file
├─ unet/  (or transformer/)
├─ text_encoder/
├─ vae/
└─ scheduler/
```

本指南将向您展示如何从这些格式和文件中加载管道和模型。

## Diffusers 格式

Diffusers 格式将每个模型（UNet、transformer、text encoder）分别存储在独立的子文件夹中。这种分离存储方式具有多项优势。

- 整体流水线初始化速度更快，因为您可以加载所需的单个模型，或者并行加载所有模型。
- 由于您只需加载一个模型，因此无需加载所有流水线组件，从而降低了内存使用量。[复用](./loading#reusing-models-in-multiple-pipelines)在多个流水线之间共享的模型。
- 由于多个流水线共享的通用模型只需下载一次，因此存储需求更低。
- 在流水线中使用新模型或改进模型的灵活性。

## 单文件格式

单文件格式将*所有*模型权重（UNet、transformer、text encoder）存储在单个文件中。单文件格式的优点包括：

- 与 [ComfyUI](https://github.com/comfyanonymous/ComfyUI) 或 [Automatic1111](https://github.com/AUTOMATIC1111/stable-diffusion-webui) 具有更高的兼容性。
- 下载和共享单个文件更加便捷。

使用 [from_single_file()](/docs/diffusers/v0.43.0/zh/api/loaders/single_file#diffusers.loaders.FromSingleFileMixin.from_single_file) 加载单个文件。

```py
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"
)
```

[from_single_file()](/docs/diffusers/v0.43.0/zh/api/loaders/single_file#diffusers.loaders.FromSingleFileMixin.from_single_file) 方法还支持传入新的模型或调度器。

```py
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"
)
```

### 配置选项

Diffusers 格式的模型在其仓库中包含一个 `config.json` 文件，其中包含层数和注意力头数量等重要属性。[from_single_file()](/docs/diffusers/v0.43.0/zh/api/loaders/single_file#diffusers.loaders.FromSingleFileMixin.from_single_file) 方法会自动从 `config.json` 中确定要使用的合适配置。不过，在少数罕见情况下这可能会失败，此时应使用 `config` 参数。

如果流水线中的模型与原始实现不同，或者缺少确定正确配置所需的元数据，您也应该使用 `config` 参数。

```py
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")
```

当传入 `original_config` 并设置 `local_files_only=True` 时，Diffusers 会根据 pipeline 类的签名推断 pipeline 组件。它不会从 Hub 下载配置文件，从而避免在离线时出现破坏性变更。与为 `config` 提供本地模型路径相比，这种方式可靠性较低，且可能会报错。如果之后需要离线使用，请运行一次 `local_files_only=False`，以便将配置文件保存到本地缓存中。

通过直接将参数传递给 [from_single_file()](/docs/diffusers/v0.43.0/zh/api/loaders/single_file#diffusers.loaders.FromSingleFileMixin.from_single_file) 来覆盖默认配置。以下示例展示了如何在流水线或模型中覆盖配置。

```py
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
)
```

```py
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)
```

### 本地文件

[from_single_file()](/docs/diffusers/v0.43.0/zh/api/loaders/single_file#diffusers.loaders.FromSingleFileMixin.from_single_file) 方法会尝试通过推断检查点文件中的键来配置流水线或模型。例如，任何基于 Stable Diffusion XL 基础模型的单文件检查点都会从 [stabilityai/stable-diffusion-xl-base-1.0](https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0) 进行配置。

如果你正在处理本地文件，请使用 [snapshot_download](https://huggingface.co/docs/huggingface_hub/v2.4.0/en/package_reference/file_download#huggingface_hub.snapshot_download) 方法下载配置文件，并使用 [hf_hub_download](https://huggingface.co/docs/huggingface_hub/v2.4.0/en/package_reference/file_download#huggingface_hub.hf_hub_download) 下载模型检查点。这些文件会下载到你的 [缓存目录](https://huggingface.co/docs/huggingface_hub/en/guides/manage-cache) 中，但你可以通过 `local_dir` 参数将它们下载到指定目录。

```py
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
)
```

### 符号链接

如果您使用的文件系统不支持符号链接，请先使用 `local_dir` 参数将检查点文件下载到本地目录。使用 `local_dir` 参数会自动禁用符号链接。

```py
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()](/docs/diffusers/v0.43.0/zh/api/loaders/single_file#diffusers.loaders.FromSingleFileMixin.from_single_file)。

```py
pipeline = StableDiffusionXLPipeline.from_single_file(
    my_local_checkpoint_path, config=my_local_config_path, local_files_only=True
)
```

## 文件类型

模型可以存储为多种文件类型。Safetensors 是最常见的文件类型，但您可能会在 Hub 或扩散模型社区中遇到其他文件类型。

### safetensors

[Safetensors](https://hf.co/docs/safetensors) 是一种安全且快速的文件类型，用于安全地存储和加载张量。它通过限制头部大小来防范某些类型的攻击，支持延迟加载（在分布式环境中非常有用），并且通常加载速度更快。

如果存在 safetensors 文件且已安装 Safetensors 库，Diffusers 默认会加载 safetensors 文件（这是一个必需的依赖项）。

Use [from_pretrained()](/docs/diffusers/v0.43.0/zh/api/pipelines/overview#diffusers.DiffusionPipeline.from_pretrained) or [from_single_file()](/docs/diffusers/v0.43.0/zh/api/loaders/single_file#diffusers.loaders.FromSingleFileMixin.from_single_file) to load safetensor files.

```py
import torch
from diffusers import DiffusionPipeline, StableDiffusionXLPipeline

pipeline = DiffusionPipeline.from_pretrained(
    "stabilityai/stable-diffusion-xl-base-1.0",
    dtype=torch.float16,
    device_map="cuda",  # or "mps", "xpu", "cpu"
)

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,
)
```

如果您使用的是通过 Diffusers 训练脚本训练的 checkpoint，诸如 LoRA 配置之类的元数据会自动保存。加载该文件时，系统会解析这些元数据，从而正确配置 LoRA。您可以点击 Hub 上文件旁边的  图标来查看 safetensors 文件的元数据。

对于未使用 Diffusers 训练的 checkpoint，可通过将其传递给 [save_lora_weights()](/docs/diffusers/v0.43.0/zh/api/loaders/lora#diffusers.loaders.FluxLoraLoaderMixin.save_lora_weights) 来保存 LoRA 适配器元数据。transformer 使用 `transformer_lora_adapter_metadata`，文本编码器使用 `text_encoder_lora_adapter_metadata`。您还必须传递 `save_directory` 以及 `transformer_lora_layers` 或 `text_encoder_lora_layers` 中的至少一个。此路径仅支持 safetensors 文件。

```py
import torch
from peft.utils import get_peft_model_state_dict
from diffusers import FluxPipeline

pipeline = FluxPipeline.from_pretrained(
    "black-forest-labs/FLUX.1-dev", dtype=torch.bfloat16, device_map="cuda"  # or "mps", "xpu", "cpu"
)
pipeline.load_lora_weights("linoyts/yarn_art_Flux_LoRA")

transformer_lora_layers = get_peft_model_state_dict(pipeline.transformer)
pipeline.save_lora_weights(
    save_directory="path/to/lora",
    transformer_lora_layers=transformer_lora_layers,
    transformer_lora_adapter_metadata={"r": 8, "lora_alpha": 8},
)
```

### ckpt

旧版模型权重通常使用 Python 的 [pickle](https://docs.python.org/3/library/pickle.html) 工具保存在 ckpt 文件中。

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

使用 [from_single_file()](/docs/diffusers/v0.43.0/zh/api/loaders/single_file#diffusers.loaders.FromSingleFileMixin.from_single_file) 加载 ckpt 文件。

```py
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"
)
```

### GGUF

GGUF 将预量化权重存储在单个文件中。Diffusers 通过模型的 [from_single_file()](/docs/diffusers/v0.43.0/zh/api/loaders/single_file#diffusers.loaders.FromSingleFileMixin.from_single_file) 方法并结合 [GGUFQuantizationConfig](/docs/diffusers/v0.43.0/zh/api/quantization#diffusers.GGUFQuantizationConfig) 来加载 GGUF。不支持在 Pipeline 层面加载 GGUF。

有关安装步骤和完整示例，请参阅 [GGUF](../quantization/gguf)。

```py
import torch
from diffusers import FluxTransformer2DModel, GGUFQuantizationConfig

transformer = FluxTransformer2DModel.from_single_file(
    "https://huggingface.co/city96/FLUX.1-dev-gguf/blob/main/flux1-dev-Q2_K.gguf",
    quantization_config=GGUFQuantizationConfig(compute_dtype=torch.bfloat16),
)
```

## 转换格式和文件

Diffusers 提供了脚本和方法，用于转换格式和文件，以便扩散生态系统中的更多工具能够使用它们。

请查看 [diffusers/scripts](https://github.com/huggingface/diffusers/tree/main/scripts) 文件夹以查找转换脚本。文件名末尾带有 `"to_diffusers"` 的脚本用于将模型转换为 Diffusers 格式。每个脚本都有一套特定的参数用于配置转换过程。请务必检查可用的参数。

下面的示例将存储在 Diffusers 格式中的模型转换为单文件格式。请提供要转换的模型的路径以及保存转换后模型的位置。您可以选择性地指定保存模型的文件类型和数据类型。

```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()](/docs/diffusers/v0.43.0/zh/api/pipelines/overview#diffusers.DiffusionPipeline.save_pretrained) 方法同样会以 Diffusers 格式保存模型，并负责为每个模型创建子文件夹。默认情况下，它会将文件保存为 safetensor 文件。

```py
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("path/to/save/model")
```

## 后续步骤

- 有关设计决策以及为何在保存和加载模型权重时优先使用 safetensor 文件的更多信息，请参阅博客文章 [经过审计，Safetensors 确实安全，并成为默认选项](https://blog.eleuther.ai/safetensors-security-audit/)。

