"vscode:/vscode.git/clone" did not exist on "790212f4d992641f2cb17d2d6c4eaeff0c91e741"
loading.md 25.9 KB
Newer Older
1
<!--Copyright 2024 The HuggingFace Team. All rights reserved.
Nathan Lambert's avatar
Nathan Lambert committed
2
3
4
5
6
7
8
9
10
11
12

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.
-->

Steven Liu's avatar
Steven Liu committed
13
# Load pipelines
Patrick von Platen's avatar
Patrick von Platen committed
14

15
16
[[open-in-colab]]

Steven Liu's avatar
Steven Liu committed
17
Diffusion systems consist of multiple components like parameterized models and schedulers that interact in complex ways. That is why we designed the [`DiffusionPipeline`] to wrap the complexity of the entire diffusion system into an easy-to-use API. At the same time, the [`DiffusionPipeline`] is entirely customizable so you can modify each component to build a diffusion system for your use case.
18

19
This guide will show you how to load:
20

21
22
- pipelines from the Hub and locally
- different components into a pipeline
Steven Liu's avatar
Steven Liu committed
23
- multiple pipelines without increasing memory usage
24
- checkpoint variants such as different floating point types or non-exponential mean averaged (EMA) weights
25

Steven Liu's avatar
Steven Liu committed
26
27
28
29
## Load a pipeline

> [!TIP]
> Skip to the [DiffusionPipeline explained](#diffusionpipeline-explained) section if you're interested in an explanation about how the [`DiffusionPipeline`] class works.
30

Steven Liu's avatar
Steven Liu committed
31
There are two ways to load a pipeline for a task:
32

Steven Liu's avatar
Steven Liu committed
33
34
1. Load the generic [`DiffusionPipeline`] class and allow it to automatically detect the correct pipeline class from the checkpoint.
2. Load a specific pipeline class for a specific task.
35

Steven Liu's avatar
Steven Liu committed
36
37
<hfoptions id="pipelines">
<hfoption id="generic pipeline">
38

Steven Liu's avatar
Steven Liu committed
39
The [`DiffusionPipeline`] class is a simple and generic way to load the latest trending diffusion model from the [Hub](https://huggingface.co/models?library=diffusers&sort=trending). It uses the [`~DiffusionPipeline.from_pretrained`] method to automatically detect the correct pipeline class for a task from the checkpoint, downloads and caches all the required configuration and weight files, and returns a pipeline ready for inference.
40
41
42
43

```python
from diffusers import DiffusionPipeline

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

Steven Liu's avatar
Steven Liu committed
47
48
49
50
51
This same checkpoint can also be used for an image-to-image task. The [`DiffusionPipeline`] class can handle any task as long as you provide the appropriate inputs. For example, for an image-to-image task, you need to pass an initial image to the pipeline.

```py
from diffusers import DiffusionPipeline

52
pipeline = DiffusionPipeline.from_pretrained("stable-diffusion-v1-5/stable-diffusion-v1-5", use_safetensors=True)
Steven Liu's avatar
Steven Liu committed
53
54
55
56
57
58
59
60
61
62

init_image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/img2img-init.png")
prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k"
image = pipeline("Astronaut in a jungle, cold color palette, muted colors, detailed, 8k", image=init_image).images[0]
```

</hfoption>
<hfoption id="specific pipeline">

Checkpoints can be loaded by their specific pipeline class if you already know it. For example, to load a Stable Diffusion model, use the [`StableDiffusionPipeline`] class.
63
64

```python
65
66
from diffusers import StableDiffusionPipeline

67
pipeline = StableDiffusionPipeline.from_pretrained("stable-diffusion-v1-5/stable-diffusion-v1-5", use_safetensors=True)
68
69
```

Steven Liu's avatar
Steven Liu committed
70
This same checkpoint may also be used for another task like image-to-image. To differentiate what task you want to use the checkpoint for, you have to use the corresponding task-specific pipeline class. For example, to use the same checkpoint for image-to-image, use the [`StableDiffusionImg2ImgPipeline`] class.
71

Steven Liu's avatar
Steven Liu committed
72
```py
73
74
from diffusers import StableDiffusionImg2ImgPipeline

75
pipeline = StableDiffusionImg2ImgPipeline.from_pretrained("stable-diffusion-v1-5/stable-diffusion-v1-5", use_safetensors=True)
76
77
```

Steven Liu's avatar
Steven Liu committed
78
79
80
81
</hfoption>
</hfoptions>

Use the Space below to gauge a pipeline's memory requirements before you download and load it to see if it runs on your hardware.
82
83

<div class="block dark:hidden">
84
	<iframe
85
86
87
88
89
90
        src="https://diffusers-compute-pipeline-size.hf.space?__theme=light"
        width="850"
        height="1600"
    ></iframe>
</div>
<div class="hidden dark:block">
91
    <iframe
92
93
94
95
96
97
        src="https://diffusers-compute-pipeline-size.hf.space?__theme=dark"
        width="850"
        height="1600"
    ></iframe>
</div>

98
### Local pipeline
99

Steven Liu's avatar
Steven Liu committed
100
To load a pipeline locally, use [git-lfs](https://git-lfs.github.com/) to manually download a checkpoint to your local disk.
101

102
```bash
103
git-lfs install
104
git clone https://huggingface.co/stable-diffusion-v1-5/stable-diffusion-v1-5
105
```
106

Steven Liu's avatar
Steven Liu committed
107
This creates a local folder, ./stable-diffusion-v1-5, on your disk and you should pass its path to [`~DiffusionPipeline.from_pretrained`].
108
109
110
111

```python
from diffusers import DiffusionPipeline

Steven Liu's avatar
Steven Liu committed
112
stable_diffusion = DiffusionPipeline.from_pretrained("./stable-diffusion-v1-5", use_safetensors=True)
113
114
```

Steven Liu's avatar
Steven Liu committed
115
The [`~DiffusionPipeline.from_pretrained`] method won't download files from the Hub when it detects a local path, but this also means it won't download and cache the latest changes to a checkpoint.
116

Steven Liu's avatar
Steven Liu committed
117
## Customize a pipeline
118

Steven Liu's avatar
Steven Liu committed
119
You can customize a pipeline by loading different components into it. This is important because you can:
120

Steven Liu's avatar
Steven Liu committed
121
122
- change to a scheduler with faster generation speed or higher generation quality depending on your needs (call the `scheduler.compatibles` method on your pipeline to see compatible schedulers)
- change a default pipeline component to a newer and better performing one
123

Steven Liu's avatar
Steven Liu committed
124
For example, let's customize the default [stabilityai/stable-diffusion-xl-base-1.0](https://hf.co/stabilityai/stable-diffusion-xl-base-1.0) checkpoint with:
125

Steven Liu's avatar
Steven Liu committed
126
127
- The [`HeunDiscreteScheduler`] to generate higher quality images at the expense of slower generation speed. You must pass the `subfolder="scheduler"` parameter in [`~HeunDiscreteScheduler.from_pretrained`] to load the scheduler configuration into the correct [subfolder](https://hf.co/stabilityai/stable-diffusion-xl-base-1.0/tree/main/scheduler) of the pipeline repository.
- A more stable VAE that runs in fp16.
128

Steven Liu's avatar
Steven Liu committed
129
130
131
```py
from diffusers import StableDiffusionXLPipeline, HeunDiscreteScheduler, AutoencoderKL
import torch
132

Steven Liu's avatar
Steven Liu committed
133
134
scheduler = HeunDiscreteScheduler.from_pretrained("stabilityai/stable-diffusion-xl-base-1.0", subfolder="scheduler")
vae = AutoencoderKL.from_pretrained("madebyollin/sdxl-vae-fp16-fix", torch_dtype=torch.float16, use_safetensors=True)
135
```
136

Steven Liu's avatar
Steven Liu committed
137
Now pass the new scheduler and VAE to the [`StableDiffusionXLPipeline`].
138
139

```py
Steven Liu's avatar
Steven Liu committed
140
pipeline = StableDiffusionXLPipeline.from_pretrained(
141
142
143
144
145
  "stabilityai/stable-diffusion-xl-base-1.0",
  scheduler=scheduler,
  vae=vae,
  torch_dtype=torch.float16,
  variant="fp16",
Steven Liu's avatar
Steven Liu committed
146
147
  use_safetensors=True
).to("cuda")
148
149
```

Steven Liu's avatar
Steven Liu committed
150
## Reuse a pipeline
Steven Liu's avatar
Steven Liu committed
151

Steven Liu's avatar
Steven Liu committed
152
When you load multiple pipelines that share the same model components, it makes sense to reuse the shared components instead of reloading everything into memory again, especially if your hardware is memory-constrained. For example:
153

Steven Liu's avatar
Steven Liu committed
154
155
1. You generated an image with the [`StableDiffusionPipeline`] but you want to improve its quality with the [`StableDiffusionSAGPipeline`]. Both of these pipelines share the same pretrained model, so it'd be a waste of memory to load the same model twice.
2. You want to add a model component, like a [`MotionAdapter`](../api/pipelines/animatediff#animatediffpipeline), to [`AnimateDiffPipeline`] which was instantiated from an existing [`StableDiffusionPipeline`]. Again, both pipelines share the same pretrained model, so it'd be a waste of memory to load an entirely new pipeline again.
156

Steven Liu's avatar
Steven Liu committed
157
158
159
160
With the [`DiffusionPipeline.from_pipe`] API, you can switch between multiple pipelines to take advantage of their different features without increasing memory-usage. It is similar to turning on and off a feature in your pipeline.

> [!TIP]
> To switch between tasks (rather than features), use the [`~DiffusionPipeline.from_pipe`] method with the [AutoPipeline](../api/pipelines/auto_pipeline) class, which automatically identifies the pipeline class based on the task (learn more in the [AutoPipeline](../tutorials/autopipeline) tutorial).
161

Steven Liu's avatar
Steven Liu committed
162
Let's start with a [`StableDiffusionPipeline`] and then reuse the loaded model components to create a [`StableDiffusionSAGPipeline`] to increase generation quality. You'll use the [`StableDiffusionPipeline`] with an [IP-Adapter](./ip_adapter) to generate a bear eating pizza.
163
164
165
166
167
168
169
170
171
172

```python
from diffusers import DiffusionPipeline, StableDiffusionSAGPipeline
import torch
import gc
from diffusers.utils import load_image
from accelerate.utils import compute_module_sizes

image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/load_neg_embed.png")

Steven Liu's avatar
Steven Liu committed
173
pipe_sd = DiffusionPipeline.from_pretrained("SG161222/Realistic_Vision_V6.0_B1_noVAE", torch_dtype=torch.float16)
174
175
176
177
178
179
pipe_sd.load_ip_adapter("h94/IP-Adapter", subfolder="models", weight_name="ip-adapter_sd15.bin")
pipe_sd.set_ip_adapter_scale(0.6)
pipe_sd.to("cuda")

generator = torch.Generator(device="cpu").manual_seed(33)
out_sd = pipe_sd(
Steven Liu's avatar
Steven Liu committed
180
    prompt="bear eats pizza",
181
    negative_prompt="wrong white balance, dark, sketches,worst quality,low quality",
182
    ip_adapter_image=image,
Steven Liu's avatar
Steven Liu committed
183
    num_inference_steps=50,
184
185
    generator=generator,
).images[0]
Steven Liu's avatar
Steven Liu committed
186
out_sd
187
188
189
190
191
192
```

<div class="flex justify-center">
  <img class="rounded-xl" src="https://huggingface.co/datasets/YiYiXu/testing-images/resolve/main/from_pipe_out_sd_0.png"/>
</div>

Steven Liu's avatar
Steven Liu committed
193
194
For reference, you can check how much memory this process consumed.

195
196
197
```python
def bytes_to_giga_bytes(bytes):
    return bytes / 1024 / 1024 / 1024
Steven Liu's avatar
Steven Liu committed
198
199
print(f"Max memory allocated: {bytes_to_giga_bytes(torch.cuda.max_memory_allocated())} GB")
"Max memory allocated: 4.406213283538818 GB"
200
201
```

Steven Liu's avatar
Steven Liu committed
202
Now, reuse the same pipeline components from [`StableDiffusionPipeline`] in [`StableDiffusionSAGPipeline`] with the [`~DiffusionPipeline.from_pipe`] method.
203

Steven Liu's avatar
Steven Liu committed
204
205
206
207
> [!WARNING]
> Some pipeline methods may not function properly on new pipelines created with [`~DiffusionPipeline.from_pipe`]. For instance, the [`~DiffusionPipeline.enable_model_cpu_offload`] method installs hooks on the model components based on a unique offloading sequence for each pipeline. If the models are executed in a different order in the new pipeline, the CPU offloading may not work correctly.
>
> To ensure everything works as expected, we recommend re-applying a pipeline method on a new pipeline created with [`~DiffusionPipeline.from_pipe`].
208
209
210

```python
pipe_sag = StableDiffusionSAGPipeline.from_pipe(
Steven Liu's avatar
Steven Liu committed
211
    pipe_sd
212
213
214
215
)

generator = torch.Generator(device="cpu").manual_seed(33)
out_sag = pipe_sag(
Steven Liu's avatar
Steven Liu committed
216
217
    prompt="bear eats pizza",
    negative_prompt="wrong white balance, dark, sketches,worst quality,low quality",
218
    ip_adapter_image=image,
Steven Liu's avatar
Steven Liu committed
219
    num_inference_steps=50,
220
221
    generator=generator,
    guidance_scale=1.0,
Steven Liu's avatar
Steven Liu committed
222
223
224
    sag_scale=0.75
).images[0]
out_sag
225
226
227
228
229
230
```

<div class="flex justify-center">
  <img class="rounded-xl" src="https://huggingface.co/datasets/YiYiXu/testing-images/resolve/main/from_pipe_out_sag_1.png"/>
</div>

Steven Liu's avatar
Steven Liu committed
231
If you check the memory usage, you'll see it remains the same as before because [`StableDiffusionPipeline`] and [`StableDiffusionSAGPipeline`] are sharing the same pipeline components. This allows you to use them interchangeably without any additional memory overhead.
232

Steven Liu's avatar
Steven Liu committed
233
234
235
```py
print(f"Max memory allocated: {bytes_to_giga_bytes(torch.cuda.max_memory_allocated())} GB")
"Max memory allocated: 4.406213283538818 GB"
236
237
```

Steven Liu's avatar
Steven Liu committed
238
Let's animate the image with the [`AnimateDiffPipeline`] and also add a [`MotionAdapter`] module to the pipeline. For the [`AnimateDiffPipeline`], you need to unload the IP-Adapter first and reload it *after* you've created your new pipeline (this only applies to the [`AnimateDiffPipeline`]).
239

Steven Liu's avatar
Steven Liu committed
240
```py
241
242
243
from diffusers import AnimateDiffPipeline, MotionAdapter, DDIMScheduler
from diffusers.utils import export_to_gif

Steven Liu's avatar
Steven Liu committed
244
pipe_sag.unload_ip_adapter()
245
246
247
248
adapter = MotionAdapter.from_pretrained("guoyww/animatediff-motion-adapter-v1-5-2", torch_dtype=torch.float16)

pipe_animate = AnimateDiffPipeline.from_pipe(pipe_sd, motion_adapter=adapter)
pipe_animate.scheduler = DDIMScheduler.from_config(pipe_animate.scheduler.config, beta_schedule="linear")
Steven Liu's avatar
Steven Liu committed
249
# load IP-Adapter and LoRA weights again
250
251
252
253
254
255
256
pipe_animate.load_ip_adapter("h94/IP-Adapter", subfolder="models", weight_name="ip-adapter_sd15.bin")
pipe_animate.load_lora_weights("guoyww/animatediff-motion-lora-zoom-out", adapter_name="zoom-out")
pipe_animate.to("cuda")

generator = torch.Generator(device="cpu").manual_seed(33)
pipe_animate.set_adapters("zoom-out", adapter_weights=0.75)
out = pipe_animate(
Steven Liu's avatar
Steven Liu committed
257
    prompt="bear eats pizza",
258
    num_frames=16,
Steven Liu's avatar
Steven Liu committed
259
260
    num_inference_steps=50,
    ip_adapter_image=image,
261
262
263
264
    generator=generator,
).frames[0]
export_to_gif(out, "out_animate.gif")
```
Steven Liu's avatar
Steven Liu committed
265

266
267
268
269
<div class="flex justify-center">
  <img class="rounded-xl" src="https://huggingface.co/datasets/YiYiXu/testing-images/resolve/main/from_pipe_out_animate_3.gif"/>
</div>

Steven Liu's avatar
Steven Liu committed
270
The [`AnimateDiffPipeline`] is more memory-intensive and consumes 15GB of memory (see the [Memory-usage of from_pipe](#memory-usage-of-from_pipe) section to learn what this means for your memory-usage).
271

Steven Liu's avatar
Steven Liu committed
272
273
274
275
```py
print(f"Max memory allocated: {bytes_to_giga_bytes(torch.cuda.max_memory_allocated())} GB")
"Max memory allocated: 15.178664207458496 GB"
```
276

Steven Liu's avatar
Steven Liu committed
277
### Modify from_pipe components
278

Steven Liu's avatar
Steven Liu committed
279
Pipelines loaded with [`~DiffusionPipeline.from_pipe`] can be customized with different model components or methods. However, whenever you modify the *state* of the model components, it affects all the other pipelines that share the same components. For example, if you call [`~diffusers.loaders.IPAdapterMixin.unload_ip_adapter`] on the [`StableDiffusionSAGPipeline`], you won't be able to use IP-Adapter with the [`StableDiffusionPipeline`] because it's been removed from their shared components.
280

Steven Liu's avatar
Steven Liu committed
281
282
```py
pipe.sag_unload_ip_adapter()
283
284

generator = torch.Generator(device="cpu").manual_seed(33)
Steven Liu's avatar
Steven Liu committed
285
286
out_sd = pipe_sd(
    prompt="bear eats pizza",
287
    negative_prompt="wrong white balance, dark, sketches,worst quality,low quality",
Steven Liu's avatar
Steven Liu committed
288
289
    ip_adapter_image=image,
    num_inference_steps=50,
290
    generator=generator,
Steven Liu's avatar
Steven Liu committed
291
292
).images[0]
"AttributeError: 'NoneType' object has no attribute 'image_projection_layers'"
293
294
```

Steven Liu's avatar
Steven Liu committed
295
### Memory usage of from_pipe
296

Steven Liu's avatar
Steven Liu committed
297
The memory requirement of loading multiple pipelines with [`~DiffusionPipeline.from_pipe`] is determined by the pipeline with the highest memory-usage regardless of the number of pipelines you create.
298

Steven Liu's avatar
Steven Liu committed
299
300
301
302
303
304
305
| Pipeline | Memory usage (GB) |
|---|---|
| StableDiffusionPipeline | 4.400 |
| StableDiffusionSAGPipeline | 4.400 |
| AnimateDiffPipeline | 15.178 |

The [`AnimateDiffPipeline`] has the highest memory requirement, so the *total memory-usage* is based only on the [`AnimateDiffPipeline`]. Your memory-usage will not increase if you create additional pipelines as long as their memory requirements doesn't exceed that of the [`AnimateDiffPipeline`]. Each pipeline can be used interchangeably without any additional memory overhead.
306

Steven Liu's avatar
Steven Liu committed
307
## Safety checker
308

Steven Liu's avatar
Steven Liu committed
309
Diffusers implements a [safety checker](https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/stable_diffusion/safety_checker.py) for Stable Diffusion models which can generate harmful content. The safety checker screens the generated output against known hardcoded not-safe-for-work (NSFW) content. If for whatever reason you'd like to disable the safety checker, pass `safety_checker=None` to the [`~DiffusionPipeline.from_pretrained`] method.
310

Steven Liu's avatar
Steven Liu committed
311
312
313
```python
from diffusers import DiffusionPipeline

314
pipeline = DiffusionPipeline.from_pretrained("stable-diffusion-v1-5/stable-diffusion-v1-5", safety_checker=None, use_safetensors=True)
Steven Liu's avatar
Steven Liu committed
315
316
317
318
"""
You have disabled the safety checker for <class 'diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.StableDiffusionPipeline'> by passing `safety_checker=None`. Ensure that you abide by the conditions of the Stable Diffusion license and do not expose unfiltered results in services or applications open to the public. Both the diffusers team and Hugging Face strongly recommend keeping the safety filter enabled in all public-facing circumstances, disabling it only for use cases that involve analyzing network behavior or auditing its results. For more information, please have a look at https://github.com/huggingface/diffusers/pull/254 .
"""
```
319

320
## Checkpoint variants
321

322
A checkpoint variant is usually a checkpoint whose weights are:
323

Steven Liu's avatar
Steven Liu committed
324
325
- Stored in a different floating point type, such as [torch.float16](https://pytorch.org/docs/stable/tensors.html#data-types), because it only requires half the bandwidth and storage to download. You can't use this variant if you're continuing training or using a CPU.
- Non-exponential mean averaged (EMA) weights which shouldn't be used for inference. You should use this variant to continue finetuning a model.
326

Steven Liu's avatar
Steven Liu committed
327
328
> [!TIP]
> When the checkpoints have identical model structures, but they were trained on different datasets and with a different training setup, they should be stored in separate repositories. For example, [stabilityai/stable-diffusion-2](https://hf.co/stabilityai/stable-diffusion-2) and [stabilityai/stable-diffusion-2-1](https://hf.co/stabilityai/stable-diffusion-2-1) are stored in separate repositories.
329

Steven Liu's avatar
Steven Liu committed
330
Otherwise, a variant is **identical** to the original checkpoint. They have exactly the same serialization format (like [safetensors](./using_safetensors)), model structure, and their weights have identical tensor shapes.
331

Steven Liu's avatar
Steven Liu committed
332
333
334
335
336
| **checkpoint type** | **weight name**                             | **argument for loading weights** |
|---------------------|---------------------------------------------|----------------------------------|
| original            | diffusion_pytorch_model.safetensors         |                                  |
| floating point      | diffusion_pytorch_model.fp16.safetensors    | `variant`, `torch_dtype`         |
| non-EMA             | diffusion_pytorch_model.non_ema.safetensors | `variant`                        |
337

Steven Liu's avatar
Steven Liu committed
338
There are two important arguments for loading variants:
339

Steven Liu's avatar
Steven Liu committed
340
- `torch_dtype` specifies the floating point precision of the loaded checkpoint. For example, if you want to save bandwidth by loading a fp16 variant, you should set `variant="fp16"` and `torch_dtype=torch.float16` to *convert the weights* to fp16. Otherwise, the fp16 weights are converted to the default fp32 precision.
341

Steven Liu's avatar
Steven Liu committed
342
  If you only set `torch_dtype=torch.float16`, the default fp32 weights are downloaded first and then converted to fp16.
343

344
- `variant` specifies which files should be loaded from the repository. For example, if you want to load a non-EMA variant of a UNet from [stable-diffusion-v1-5/stable-diffusion-v1-5](https://hf.co/stable-diffusion-v1-5/stable-diffusion-v1-5/tree/main/unet), set `variant="non_ema"` to download the `non_ema` file.
345

Steven Liu's avatar
Steven Liu committed
346
347
<hfoptions id="variants">
<hfoption id="fp16">
348

Steven Liu's avatar
Steven Liu committed
349
```py
350
from diffusers import DiffusionPipeline
351
import torch
352

Steven Liu's avatar
Steven Liu committed
353
pipeline = DiffusionPipeline.from_pretrained(
354
    "stable-diffusion-v1-5/stable-diffusion-v1-5", variant="fp16", torch_dtype=torch.float16, use_safetensors=True
355
356
)
```
357

Steven Liu's avatar
Steven Liu committed
358
359
</hfoption>
<hfoption id="non-EMA">
360

Steven Liu's avatar
Steven Liu committed
361
362
```py
pipeline = DiffusionPipeline.from_pretrained(
363
    "stable-diffusion-v1-5/stable-diffusion-v1-5", variant="non_ema", use_safetensors=True
364
)
365
366
```

Steven Liu's avatar
Steven Liu committed
367
368
</hfoption>
</hfoptions>
369

Steven Liu's avatar
Steven Liu committed
370
Use the `variant` parameter in the [`DiffusionPipeline.save_pretrained`] method to save a checkpoint as a different floating point type or as a non-EMA variant. You should try save a variant to the same folder as the original checkpoint, so you have the option of loading both from the same folder.
371

Steven Liu's avatar
Steven Liu committed
372
373
<hfoptions id="save">
<hfoption id="fp16">
374

375
376
```python
from diffusers import DiffusionPipeline
377

378
pipeline.save_pretrained("stable-diffusion-v1-5/stable-diffusion-v1-5", variant="fp16")
379
380
```

Steven Liu's avatar
Steven Liu committed
381
382
</hfoption>
<hfoption id="non_ema">
383

Steven Liu's avatar
Steven Liu committed
384
```py
385
pipeline.save_pretrained("stable-diffusion-v1-5/stable-diffusion-v1-5", variant="non_ema")
386
387
```

Steven Liu's avatar
Steven Liu committed
388
389
</hfoption>
</hfoptions>
390

Steven Liu's avatar
Steven Liu committed
391
If you don't save the variant to an existing folder, you must specify the `variant` argument otherwise it'll throw an `Exception` because it can't find the original checkpoint.
392

393
```python
Steven Liu's avatar
Steven Liu committed
394
395
396
# 👎 this won't work
pipeline = DiffusionPipeline.from_pretrained(
    "./stable-diffusion-v1-5", torch_dtype=torch.float16, use_safetensors=True
397
)
Steven Liu's avatar
Steven Liu committed
398
399
400
# 👍 this works
pipeline = DiffusionPipeline.from_pretrained(
    "./stable-diffusion-v1-5", variant="fp16", torch_dtype=torch.float16, use_safetensors=True
401
402
)
```
403

404
## DiffusionPipeline explained
405
406
407

As a class method, [`DiffusionPipeline.from_pretrained`] is responsible for two things:

408
- Download the latest version of the folder structure required for inference and cache it. If the latest folder structure is available in the local cache, [`DiffusionPipeline.from_pretrained`] reuses the cache and won't redownload the files.
409
- Load the cached weights into the correct pipeline [class](../api/pipelines/overview#diffusers-summary) - retrieved from the `model_index.json` file - and return an instance of it.
410

411
The pipelines' underlying folder structure corresponds directly with their class instances. For example, the [`StableDiffusionPipeline`] corresponds to the folder structure in [`stable-diffusion-v1-5/stable-diffusion-v1-5`](https://huggingface.co/stable-diffusion-v1-5/stable-diffusion-v1-5).
412
413
414
415

```python
from diffusers import DiffusionPipeline

416
repo_id = "stable-diffusion-v1-5/stable-diffusion-v1-5"
417
pipeline = DiffusionPipeline.from_pretrained(repo_id, use_safetensors=True)
418
print(pipeline)
419
420
```

421
422
You'll see pipeline is an instance of [`StableDiffusionPipeline`], which consists of seven components:

423
- `"feature_extractor"`: a [`~transformers.CLIPImageProcessor`] from 🤗 Transformers.
424
425
426
427
428
- `"safety_checker"`: a [component](https://github.com/huggingface/diffusers/blob/e55687e1e15407f60f32242027b7bb8170e58266/src/diffusers/pipelines/stable_diffusion/safety_checker.py#L32) for screening against harmful content.
- `"scheduler"`: an instance of [`PNDMScheduler`].
- `"text_encoder"`: a [`~transformers.CLIPTextModel`] from 🤗 Transformers.
- `"tokenizer"`: a [`~transformers.CLIPTokenizer`] from 🤗 Transformers.
- `"unet"`: an instance of [`UNet2DConditionModel`].
429
- `"vae"`: an instance of [`AutoencoderKL`].
430
431

```json
432
433
434
StableDiffusionPipeline {
  "feature_extractor": [
    "transformers",
435
    "CLIPImageProcessor"
436
437
438
439
  ],
  "safety_checker": [
    "stable_diffusion",
    "StableDiffusionSafetyChecker"
440
441
442
  ],
  "scheduler": [
    "diffusers",
443
444
445
446
447
    "PNDMScheduler"
  ],
  "text_encoder": [
    "transformers",
    "CLIPTextModel"
448
449
450
  ],
  "tokenizer": [
    "transformers",
451
    "CLIPTokenizer"
452
453
454
455
456
  ],
  "unet": [
    "diffusers",
    "UNet2DConditionModel"
  ],
457
  "vae": [
458
459
460
461
462
463
    "diffusers",
    "AutoencoderKL"
  ]
}
```

464
Compare the components of the pipeline instance to the [`stable-diffusion-v1-5/stable-diffusion-v1-5`](https://huggingface.co/stable-diffusion-v1-5/stable-diffusion-v1-5/tree/main) folder structure, and you'll see there is a separate folder for each of the components in the repository:
465
466
467

```
.
468
469
470
471
├── feature_extractor
│   └── preprocessor_config.json
├── model_index.json
├── safety_checker
472
│   ├── config.json
473
474
475
476
|   ├── model.fp16.safetensors
│   ├── model.safetensors
│   ├── pytorch_model.bin
|   └── pytorch_model.fp16.bin
477
478
├── scheduler
│   └── scheduler_config.json
479
480
├── text_encoder
│   ├── config.json
481
482
483
484
|   ├── model.fp16.safetensors
│   ├── model.safetensors
│   |── pytorch_model.bin
|   └── pytorch_model.fp16.bin
485
├── tokenizer
486
│   ├── merges.txt
487
488
│   ├── special_tokens_map.json
│   ├── tokenizer_config.json
489
│   └── vocab.json
490
491
├── unet
│   ├── config.json
492
│   ├── diffusion_pytorch_model.bin
493
494
495
496
497
498
499
500
501
502
503
|   |── diffusion_pytorch_model.fp16.bin
│   |── diffusion_pytorch_model.f16.safetensors
│   |── diffusion_pytorch_model.non_ema.bin
│   |── diffusion_pytorch_model.non_ema.safetensors
│   └── diffusion_pytorch_model.safetensors
|── vae
.   ├── config.json
.   ├── diffusion_pytorch_model.bin
    ├── diffusion_pytorch_model.fp16.bin
    ├── diffusion_pytorch_model.fp16.safetensors
    └── diffusion_pytorch_model.safetensors
504
505
```

506
You can access each of the components of the pipeline as an attribute to view its configuration:
507

508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
```py
pipeline.tokenizer
CLIPTokenizer(
    name_or_path="/root/.cache/huggingface/hub/models--runwayml--stable-diffusion-v1-5/snapshots/39593d5650112b4cc580433f6b0435385882d819/tokenizer",
    vocab_size=49408,
    model_max_length=77,
    is_fast=False,
    padding_side="right",
    truncation_side="right",
    special_tokens={
        "bos_token": AddedToken("<|startoftext|>", rstrip=False, lstrip=False, single_word=False, normalized=True),
        "eos_token": AddedToken("<|endoftext|>", rstrip=False, lstrip=False, single_word=False, normalized=True),
        "unk_token": AddedToken("<|endoftext|>", rstrip=False, lstrip=False, single_word=False, normalized=True),
        "pad_token": "<|endoftext|>",
    },
523
    clean_up_tokenization_spaces=True
524
)
525
```
526

527
Every pipeline expects a [`model_index.json`](https://huggingface.co/stable-diffusion-v1-5/stable-diffusion-v1-5/blob/main/model_index.json) file that tells the [`DiffusionPipeline`]:
528
529
530
531
532
533

- which pipeline class to load from `_class_name`
- which version of 🧨 Diffusers was used to create the model in `_diffusers_version`
- what components from which library are stored in the subfolders (`name` corresponds to the component and subfolder name, `library` corresponds to the name of the library to load the class from, and `class` corresponds to the class name)

```json
534
{
535
536
537
538
  "_class_name": "StableDiffusionPipeline",
  "_diffusers_version": "0.6.0",
  "feature_extractor": [
    "transformers",
539
    "CLIPImageProcessor"
540
541
542
543
  ],
  "safety_checker": [
    "stable_diffusion",
    "StableDiffusionSafetyChecker"
544
545
546
  ],
  "scheduler": [
    "diffusers",
547
548
549
550
551
    "PNDMScheduler"
  ],
  "text_encoder": [
    "transformers",
    "CLIPTextModel"
552
553
554
  ],
  "tokenizer": [
    "transformers",
555
    "CLIPTokenizer"
556
557
558
559
560
  ],
  "unet": [
    "diffusers",
    "UNet2DConditionModel"
  ],
561
  "vae": [
562
563
564
565
    "diffusers",
    "AutoencoderKL"
  ]
}
566
```