loading.md 25.7 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

Steven Liu's avatar
Steven Liu committed
44
pipeline = DiffusionPipeline.from_pretrained("runwayml/stable-diffusion-v1-5", use_safetensors=True)
45
46
```

Steven Liu's avatar
Steven Liu committed
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
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

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

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

Steven Liu's avatar
Steven Liu committed
67
pipeline = StableDiffusionPipeline.from_pretrained("runwayml/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

Steven Liu's avatar
Steven Liu committed
75
pipeline = StableDiffusionImg2ImgPipeline.from_pretrained("runwayml/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
84
85
86
87
88
89
90
91
92
93
94
95
96
97

<div class="block dark:hidden">
	<iframe 
        src="https://diffusers-compute-pipeline-size.hf.space?__theme=light"
        width="850"
        height="1600"
    ></iframe>
</div>
<div class="hidden dark:block">
    <iframe 
        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
105
git clone https://huggingface.co/runwayml/stable-diffusion-v1-5
```
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
141
142
143
144
145
146
147
pipeline = StableDiffusionXLPipeline.from_pretrained(
  "stabilityai/stable-diffusion-xl-base-1.0", 
  scheduler=scheduler, 
  vae=vae, 
  torch_dtype=torch.float16, 
  variant="fp16", 
  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
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. To switch between tasks, 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).
158

Steven Liu's avatar
Steven Liu committed
159
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.
160
161
162
163
164
165
166
167
168
169

```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
170
pipe_sd = DiffusionPipeline.from_pretrained("SG161222/Realistic_Vision_V6.0_B1_noVAE", torch_dtype=torch.float16)
171
172
173
174
175
176
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
177
178
    prompt="bear eats pizza",
    negative_prompt="wrong white balance, dark, sketches,worst quality,low quality", 
179
    ip_adapter_image=image,
Steven Liu's avatar
Steven Liu committed
180
    num_inference_steps=50,
181
182
    generator=generator,
).images[0]
Steven Liu's avatar
Steven Liu committed
183
out_sd
184
185
186
187
188
189
```

<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
190
191
For reference, you can check how much memory this process consumed.

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

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

Steven Liu's avatar
Steven Liu committed
201
202
203
204
> [!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`].
205
206
207

```python
pipe_sag = StableDiffusionSAGPipeline.from_pipe(
Steven Liu's avatar
Steven Liu committed
208
    pipe_sd
209
210
211
212
)

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

<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
228
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.
229

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

Steven Liu's avatar
Steven Liu committed
235
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`]).
236

Steven Liu's avatar
Steven Liu committed
237
```py
238
239
240
from diffusers import AnimateDiffPipeline, MotionAdapter, DDIMScheduler
from diffusers.utils import export_to_gif

Steven Liu's avatar
Steven Liu committed
241
pipe_sag.unload_ip_adapter()
242
243
244
245
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
246
# load IP-Adapter and LoRA weights again
247
248
249
250
251
252
253
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
254
    prompt="bear eats pizza",
255
    num_frames=16,
Steven Liu's avatar
Steven Liu committed
256
257
    num_inference_steps=50,
    ip_adapter_image=image,
258
259
260
261
    generator=generator,
).frames[0]
export_to_gif(out, "out_animate.gif")
```
Steven Liu's avatar
Steven Liu committed
262

263
264
265
266
<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
267
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).
268

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

Steven Liu's avatar
Steven Liu committed
274
### Modify from_pipe components
275

Steven Liu's avatar
Steven Liu committed
276
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.
277

Steven Liu's avatar
Steven Liu committed
278
279
```py
pipe.sag_unload_ip_adapter()
280
281

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

Steven Liu's avatar
Steven Liu committed
292
### Memory usage of from_pipe
293

Steven Liu's avatar
Steven Liu committed
294
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.
295

Steven Liu's avatar
Steven Liu committed
296
297
298
299
300
301
302
| 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.
303

Steven Liu's avatar
Steven Liu committed
304
## Safety checker
305

Steven Liu's avatar
Steven Liu committed
306
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.
307

Steven Liu's avatar
Steven Liu committed
308
309
310
311
312
313
314
315
```python
from diffusers import DiffusionPipeline

pipeline = DiffusionPipeline.from_pretrained("runwayml/stable-diffusion-v1-5", safety_checker=None, use_safetensors=True)
"""
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 .
"""
```
316

317
## Checkpoint variants
318

319
A checkpoint variant is usually a checkpoint whose weights are:
320

Steven Liu's avatar
Steven Liu committed
321
322
- 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.
323

Steven Liu's avatar
Steven Liu committed
324
325
> [!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.
326

Steven Liu's avatar
Steven Liu committed
327
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.
328

Steven Liu's avatar
Steven Liu committed
329
330
331
332
333
| **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`                        |
334

Steven Liu's avatar
Steven Liu committed
335
There are two important arguments for loading variants:
336

Steven Liu's avatar
Steven Liu committed
337
- `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.
338

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

Steven Liu's avatar
Steven Liu committed
341
- `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 [runwayml/stable-diffusion-v1-5](https://hf.co/runwayml/stable-diffusion-v1-5/tree/main/unet), set `variant="non_ema"` to download the `non_ema` file.
342

Steven Liu's avatar
Steven Liu committed
343
344
<hfoptions id="variants">
<hfoption id="fp16">
345

Steven Liu's avatar
Steven Liu committed
346
```py
347
from diffusers import DiffusionPipeline
348
import torch
349

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

Steven Liu's avatar
Steven Liu committed
355
356
</hfoption>
<hfoption id="non-EMA">
357

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

Steven Liu's avatar
Steven Liu committed
364
365
</hfoption>
</hfoptions>
366

Steven Liu's avatar
Steven Liu committed
367
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.
368

Steven Liu's avatar
Steven Liu committed
369
370
<hfoptions id="save">
<hfoption id="fp16">
371

372
373
```python
from diffusers import DiffusionPipeline
374

Steven Liu's avatar
Steven Liu committed
375
pipeline.save_pretrained("runwayml/stable-diffusion-v1-5", variant="fp16")
376
377
```

Steven Liu's avatar
Steven Liu committed
378
379
</hfoption>
<hfoption id="non_ema">
380

Steven Liu's avatar
Steven Liu committed
381
382
```py
pipeline.save_pretrained("runwayml/stable-diffusion-v1-5", variant="non_ema")
383
384
```

Steven Liu's avatar
Steven Liu committed
385
386
</hfoption>
</hfoptions>
387

Steven Liu's avatar
Steven Liu committed
388
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.
389

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

401
## DiffusionPipeline explained
402
403
404

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

405
- 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.
406
- 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.
407

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

```python
from diffusers import DiffusionPipeline

413
repo_id = "runwayml/stable-diffusion-v1-5"
414
pipeline = DiffusionPipeline.from_pretrained(repo_id, use_safetensors=True)
415
print(pipeline)
416
417
```

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

420
- `"feature_extractor"`: a [`~transformers.CLIPImageProcessor`] from 🤗 Transformers.
421
422
423
424
425
- `"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`].
426
- `"vae"`: an instance of [`AutoencoderKL`].
427
428

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

461
Compare the components of the pipeline instance to the [`runwayml/stable-diffusion-v1-5`](https://huggingface.co/runwayml/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:
462
463
464

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

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

505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
```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|>",
    },
520
    clean_up_tokenization_spaces=True
521
)
522
```
523

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

- 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
531
{
532
533
534
535
  "_class_name": "StableDiffusionPipeline",
  "_diffusers_version": "0.6.0",
  "feature_extractor": [
    "transformers",
536
    "CLIPImageProcessor"
537
538
539
540
  ],
  "safety_checker": [
    "stable_diffusion",
    "StableDiffusionSafetyChecker"
541
542
543
  ],
  "scheduler": [
    "diffusers",
544
545
546
547
548
    "PNDMScheduler"
  ],
  "text_encoder": [
    "transformers",
    "CLIPTextModel"
549
550
551
  ],
  "tokenizer": [
    "transformers",
552
    "CLIPTokenizer"
553
554
555
556
557
  ],
  "unet": [
    "diffusers",
    "UNet2DConditionModel"
  ],
558
  "vae": [
559
560
561
562
    "diffusers",
    "AutoencoderKL"
  ]
}
563
```