"graphbolt/src/vscode:/vscode.git/clone" did not exist on "8568386911075fe9113e4b5e40bfe3b36400831e"
schedulers.md 9.85 KB
Newer Older
1
<!--Copyright 2024 The HuggingFace Team. All rights reserved.
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 schedulers and models
14

15
16
[[open-in-colab]]

Steven Liu's avatar
Steven Liu committed
17
Diffusion pipelines are a collection of interchangeable schedulers and models that can be mixed and matched to tailor a pipeline to a specific use case. The scheduler encapsulates the entire denoising process such as the number of denoising steps and the algorithm for finding the denoised sample. A scheduler is not parameterized or trained so they don't take very much memory. The model is usually only concerned with the forward pass of going from a noisy input to a less noisy sample.
18

Steven Liu's avatar
Steven Liu committed
19
This guide will show you how to load schedulers and models to customize a pipeline. You'll use the [runwayml/stable-diffusion-v1-5](https://hf.co/runwayml/stable-diffusion-v1-5) checkpoint throughout this guide, so let's load it first.
20

Steven Liu's avatar
Steven Liu committed
21
```py
22
import torch
Steven Liu's avatar
Steven Liu committed
23
from diffusers import DiffusionPipeline
24

25
26
pipeline = DiffusionPipeline.from_pretrained(
    "runwayml/stable-diffusion-v1-5", torch_dtype=torch.float16, use_safetensors=True
Steven Liu's avatar
Steven Liu committed
27
).to("cuda")
28
29
```

Steven Liu's avatar
Steven Liu committed
30
You can see what scheduler this pipeline uses with the `pipeline.scheduler` attribute.
31

Steven Liu's avatar
Steven Liu committed
32
```py
33
34
35
pipeline.scheduler
PNDMScheduler {
  "_class_name": "PNDMScheduler",
36
  "_diffusers_version": "0.21.4",
37
38
39
40
41
42
43
44
  "beta_end": 0.012,
  "beta_schedule": "scaled_linear",
  "beta_start": 0.00085,
  "clip_sample": false,
  "num_train_timesteps": 1000,
  "set_alpha_to_one": false,
  "skip_prk_steps": true,
  "steps_offset": 1,
45
  "timestep_spacing": "leading",
46
47
48
49
  "trained_betas": null
}
```

Steven Liu's avatar
Steven Liu committed
50
## Load a scheduler
51

Steven Liu's avatar
Steven Liu committed
52
Schedulers are defined by a configuration file that can be used by a variety of schedulers. Load a scheduler with the [`SchedulerMixin.from_pretrained`] method, and specify the `subfolder` parameter to load the configuration file into the correct subfolder of the pipeline repository.
53

Steven Liu's avatar
Steven Liu committed
54
For example, to load the [`DDIMScheduler`]:
55

Steven Liu's avatar
Steven Liu committed
56
57
```py
from diffusers import DDIMScheduler, DiffusionPipeline
58

Steven Liu's avatar
Steven Liu committed
59
ddim = DDIMScheduler.from_pretrained("runwayml/stable-diffusion-v1-5", subfolder="scheduler")
60
61
```

Steven Liu's avatar
Steven Liu committed
62
Then you can pass the newly loaded scheduler to the pipeline.
63
64

```python
Steven Liu's avatar
Steven Liu committed
65
66
67
pipeline = DiffusionPipeline.from_pretrained(
    "runwayml/stable-diffusion-v1-5", scheduler=ddim, torch_dtype=torch.float16, use_safetensors=True
).to("cuda")
68
69
```

Steven Liu's avatar
Steven Liu committed
70
## Compare schedulers
71

Steven Liu's avatar
Steven Liu committed
72
Schedulers have their own unique strengths and weaknesses, making it difficult to quantitatively compare which scheduler works best for a pipeline. You typically have to make a trade-off between denoising speed and denoising quality. We recommend trying out different schedulers to find one that works best for your use case. Call the `pipeline.scheduler.compatibles` attribute to see what schedulers are compatible with a pipeline.
73

Steven Liu's avatar
Steven Liu committed
74
Let's compare the [`LMSDiscreteScheduler`], [`EulerDiscreteScheduler`], [`EulerAncestralDiscreteScheduler`], and the [`DPMSolverMultistepScheduler`] on the following prompt and seed.
75

Steven Liu's avatar
Steven Liu committed
76
77
78
```py
import torch
from diffusers import DiffusionPipeline
79

Steven Liu's avatar
Steven Liu committed
80
81
82
pipeline = DiffusionPipeline.from_pretrained(
    "runwayml/stable-diffusion-v1-5", torch_dtype=torch.float16, use_safetensors=True
).to("cuda")
83

Steven Liu's avatar
Steven Liu committed
84
prompt = "A photograph of an astronaut riding a horse on Mars, high resolution, high definition."
85
86
87
generator = torch.Generator(device="cuda").manual_seed(8)
```

Steven Liu's avatar
Steven Liu committed
88
To change the pipelines scheduler, use the [`~ConfigMixin.from_config`] method to load a different scheduler's `pipeline.scheduler.config` into the pipeline.
89

Steven Liu's avatar
Steven Liu committed
90
91
<hfoptions id="schedulers">
<hfoption id="LMSDiscreteScheduler">
92

Steven Liu's avatar
Steven Liu committed
93
[`LMSDiscreteScheduler`] typically generates higher quality images than the default scheduler.
94

Steven Liu's avatar
Steven Liu committed
95
```py
96
97
98
99
100
101
102
from diffusers import LMSDiscreteScheduler

pipeline.scheduler = LMSDiscreteScheduler.from_config(pipeline.scheduler.config)
image = pipeline(prompt, generator=generator).images[0]
image
```

Steven Liu's avatar
Steven Liu committed
103
104
</hfoption>
<hfoption id="EulerDiscreteScheduler">
105

Steven Liu's avatar
Steven Liu committed
106
[`EulerDiscreteScheduler`] can generate higher quality images in just 30 steps.
107

Steven Liu's avatar
Steven Liu committed
108
```py
109
110
111
from diffusers import EulerDiscreteScheduler

pipeline.scheduler = EulerDiscreteScheduler.from_config(pipeline.scheduler.config)
Steven Liu's avatar
Steven Liu committed
112
image = pipeline(prompt, generator=generator).images[0]
113
114
115
image
```

Steven Liu's avatar
Steven Liu committed
116
117
</hfoption>
<hfoption id="EulerAncestralDiscreteScheduler">
118

Steven Liu's avatar
Steven Liu committed
119
[`EulerAncestralDiscreteScheduler`] can generate higher quality images in just 30 steps.
120

Steven Liu's avatar
Steven Liu committed
121
```py
122
123
124
from diffusers import EulerAncestralDiscreteScheduler

pipeline.scheduler = EulerAncestralDiscreteScheduler.from_config(pipeline.scheduler.config)
Steven Liu's avatar
Steven Liu committed
125
image = pipeline(prompt, generator=generator).images[0]
126
127
128
image
```

Steven Liu's avatar
Steven Liu committed
129
130
</hfoption>
<hfoption id="DPMSolverMultistepScheduler">
131

Steven Liu's avatar
Steven Liu committed
132
[`DPMSolverMultistepScheduler`] provides a balance between speed and quality and can generate higher quality images in just 20 steps.
133

Steven Liu's avatar
Steven Liu committed
134
```py
135
136
137
from diffusers import DPMSolverMultistepScheduler

pipeline.scheduler = DPMSolverMultistepScheduler.from_config(pipeline.scheduler.config)
Steven Liu's avatar
Steven Liu committed
138
image = pipeline(prompt, generator=generator).images[0]
139
140
141
image
```

Steven Liu's avatar
Steven Liu committed
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
</hfoption>
</hfoptions>

<div class="flex gap-4">
  <div>
    <img class="rounded-xl" src="https://huggingface.co/datasets/patrickvonplaten/images/resolve/main/diffusers_docs/astronaut_lms.png" />
    <figcaption class="mt-2 text-center text-sm text-gray-500">LMSDiscreteScheduler</figcaption>
  </div>
  <div>
    <img class="rounded-xl" src="https://huggingface.co/datasets/patrickvonplaten/images/resolve/main/diffusers_docs/astronaut_euler_discrete.png" />
    <figcaption class="mt-2 text-center text-sm text-gray-500">EulerDiscreteScheduler</figcaption>
  </div>
</div>
<div class="flex gap-4">
  <div>
    <img class="rounded-xl" src="https://huggingface.co/datasets/patrickvonplaten/images/resolve/main/diffusers_docs/astronaut_euler_ancestral.png" />
    <figcaption class="mt-2 text-center text-sm text-gray-500">EulerAncestralDiscreteScheduler</figcaption>
  </div>
  <div>
    <img class="rounded-xl" src="https://huggingface.co/datasets/patrickvonplaten/images/resolve/main/diffusers_docs/astronaut_dpm.png" />
    <figcaption class="mt-2 text-center text-sm text-gray-500">DPMSolverMultistepScheduler</figcaption>
  </div>
</div>
165

Steven Liu's avatar
Steven Liu committed
166
Most images look very similar and are comparable in quality. Again, it often comes down to your specific use case so a good approach is to run multiple different schedulers and compare the results.
167

Steven Liu's avatar
Steven Liu committed
168
### Flax schedulers
169

Steven Liu's avatar
Steven Liu committed
170
To compare Flax schedulers, you need to additionally load the scheduler state into the model parameters. For example, let's change the default scheduler in [`FlaxStableDiffusionPipeline`] to use the super fast [`FlaxDPMSolverMultistepScheduler`].
171

Steven Liu's avatar
Steven Liu committed
172
173
174
175
> [!WARNING]
> The [`FlaxLMSDiscreteScheduler`] and [`FlaxDDPMScheduler`] are not compatible with the [`FlaxStableDiffusionPipeline`] yet.

```py
176
177
178
179
180
181
182
import jax
import numpy as np
from flax.jax_utils import replicate
from flax.training.common_utils import shard
from diffusers import FlaxStableDiffusionPipeline, FlaxDPMSolverMultistepScheduler

scheduler, scheduler_state = FlaxDPMSolverMultistepScheduler.from_pretrained(
Steven Liu's avatar
Steven Liu committed
183
    "runwayml/stable-diffusion-v1-5",
184
185
186
    subfolder="scheduler"
)
pipeline, params = FlaxStableDiffusionPipeline.from_pretrained(
Steven Liu's avatar
Steven Liu committed
187
    "runwayml/stable-diffusion-v1-5",
188
189
190
191
192
    scheduler=scheduler,
    revision="bf16",
    dtype=jax.numpy.bfloat16,
)
params["scheduler"] = scheduler_state
Steven Liu's avatar
Steven Liu committed
193
194
195
```

Then you can take advantage of Flax's compatibility with TPUs to generate a number of images in parallel. You'll need to make a copy of the model parameters for each available device and then split the inputs across them to generate your desired number of images.
196

Steven Liu's avatar
Steven Liu committed
197
```py
198
# Generate 1 image per parallel device (8 on TPUv2-8 or TPUv3-8)
Steven Liu's avatar
Steven Liu committed
199
prompt = "A photograph of an astronaut riding a horse on Mars, high resolution, high definition."
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
num_samples = jax.device_count()
prompt_ids = pipeline.prepare_inputs([prompt] * num_samples)

prng_seed = jax.random.PRNGKey(0)
num_inference_steps = 25

# shard inputs and rng
params = replicate(params)
prng_seed = jax.random.split(prng_seed, jax.device_count())
prompt_ids = shard(prompt_ids)

images = pipeline(prompt_ids, params, prng_seed, num_inference_steps, jit=True).images
images = pipeline.numpy_to_pil(np.asarray(images.reshape((num_samples,) + images.shape[-3:])))
```

Steven Liu's avatar
Steven Liu committed
215
216
217
## Models

Models are loaded from the [`ModelMixin.from_pretrained`] method, which downloads and caches the latest version of the model weights and configurations. If the latest files are available in the local cache, [`~ModelMixin.from_pretrained`] reuses files in the cache instead of re-downloading them.
218

Steven Liu's avatar
Steven Liu committed
219
Models can be loaded from a subfolder with the `subfolder` argument. For example, the model weights for [runwayml/stable-diffusion-v1-5](https://hf.co/runwayml/stable-diffusion-v1-5) are stored in the [unet](https://hf.co/runwayml/stable-diffusion-v1-5/tree/main/unet) subfolder.
220

Steven Liu's avatar
Steven Liu committed
221
222
```python
from diffusers import UNet2DConditionModel
223

Steven Liu's avatar
Steven Liu committed
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
unet = UNet2DConditionModel.from_pretrained("runwayml/stable-diffusion-v1-5", subfolder="unet", use_safetensors=True)
```

They can also be directly loaded from a [repository](https://huggingface.co/google/ddpm-cifar10-32/tree/main).

```python
from diffusers import UNet2DModel

unet = UNet2DModel.from_pretrained("google/ddpm-cifar10-32", use_safetensors=True)
```

To load and save model variants, specify the `variant` argument in [`ModelMixin.from_pretrained`] and [`ModelMixin.save_pretrained`].

```python
from diffusers import UNet2DConditionModel

unet = UNet2DConditionModel.from_pretrained(
    "runwayml/stable-diffusion-v1-5", subfolder="unet", variant="non_ema", use_safetensors=True
)
unet.save_pretrained("./local-unet", variant="non_ema")
```