Skip to content

Commit 61af54c

Browse files
schedulers add glide noising schedule (huggingface#2347)
1 parent d9c7715 commit 61af54c

13 files changed

+225
-2
lines changed

schedulers/scheduling_ddim.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ class DDIMSchedulerOutput(BaseOutput):
4646
pred_original_sample: Optional[torch.FloatTensor] = None
4747

4848

49+
# Copied from diffusers.schedulers.scheduling_ddpm.betas_for_alpha_bar
4950
def betas_for_alpha_bar(num_diffusion_timesteps, max_beta=0.999) -> torch.Tensor:
5051
"""
5152
Create a beta schedule that discretizes the given alpha_t_bar function, which defines the cumulative product of
@@ -72,7 +73,7 @@ def alpha_bar(time_step):
7273
t1 = i / num_diffusion_timesteps
7374
t2 = (i + 1) / num_diffusion_timesteps
7475
betas.append(min(1 - alpha_bar(t2) / alpha_bar(t1), max_beta))
75-
return torch.tensor(betas)
76+
return torch.tensor(betas, dtype=torch.float32)
7677

7778

7879
class DDIMScheduler(SchedulerMixin, ConfigMixin):

schedulers/scheduling_deis_multistep.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
from .scheduling_utils import KarrasDiffusionSchedulers, SchedulerMixin, SchedulerOutput
2626

2727

28+
# Copied from diffusers.schedulers.scheduling_ddpm.betas_for_alpha_bar
2829
def betas_for_alpha_bar(num_diffusion_timesteps, max_beta=0.999):
2930
"""
3031
Create a beta schedule that discretizes the given alpha_t_bar function, which defines the cumulative product of

schedulers/scheduling_dpmsolver_multistep.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
from .scheduling_utils import KarrasDiffusionSchedulers, SchedulerMixin, SchedulerOutput
2525

2626

27+
# Copied from diffusers.schedulers.scheduling_ddpm.betas_for_alpha_bar
2728
def betas_for_alpha_bar(num_diffusion_timesteps, max_beta=0.999):
2829
"""
2930
Create a beta schedule that discretizes the given alpha_t_bar function, which defines the cumulative product of

schedulers/scheduling_dpmsolver_singlestep.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
from .scheduling_utils import KarrasDiffusionSchedulers, SchedulerMixin, SchedulerOutput
2525

2626

27+
# Copied from diffusers.schedulers.scheduling_ddpm.betas_for_alpha_bar
2728
def betas_for_alpha_bar(num_diffusion_timesteps, max_beta=0.999):
2829
"""
2930
Create a beta schedule that discretizes the given alpha_t_bar function, which defines the cumulative product of

schedulers/scheduling_euler_ancestral_discrete.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
import math
1516
from dataclasses import dataclass
1617
from typing import List, Optional, Tuple, Union
1718

@@ -45,6 +46,36 @@ class EulerAncestralDiscreteSchedulerOutput(BaseOutput):
4546
pred_original_sample: Optional[torch.FloatTensor] = None
4647

4748

49+
# Copied from diffusers.schedulers.scheduling_ddpm.betas_for_alpha_bar
50+
def betas_for_alpha_bar(num_diffusion_timesteps, max_beta=0.999) -> torch.Tensor:
51+
"""
52+
Create a beta schedule that discretizes the given alpha_t_bar function, which defines the cumulative product of
53+
(1-beta) over time from t = [0,1].
54+
55+
Contains a function alpha_bar that takes an argument t and transforms it to the cumulative product of (1-beta) up
56+
to that part of the diffusion process.
57+
58+
59+
Args:
60+
num_diffusion_timesteps (`int`): the number of betas to produce.
61+
max_beta (`float`): the maximum beta to use; use values lower than 1 to
62+
prevent singularities.
63+
64+
Returns:
65+
betas (`np.ndarray`): the betas used by the scheduler to step the model outputs
66+
"""
67+
68+
def alpha_bar(time_step):
69+
return math.cos((time_step + 0.008) / 1.008 * math.pi / 2) ** 2
70+
71+
betas = []
72+
for i in range(num_diffusion_timesteps):
73+
t1 = i / num_diffusion_timesteps
74+
t2 = (i + 1) / num_diffusion_timesteps
75+
betas.append(min(1 - alpha_bar(t2) / alpha_bar(t1), max_beta))
76+
return torch.tensor(betas, dtype=torch.float32)
77+
78+
4879
class EulerAncestralDiscreteScheduler(SchedulerMixin, ConfigMixin):
4980
"""
5081
Ancestral sampling with Euler method steps. Based on the original k-diffusion implementation by Katherine Crowson:
@@ -93,6 +124,9 @@ def __init__(
93124
self.betas = (
94125
torch.linspace(beta_start**0.5, beta_end**0.5, num_train_timesteps, dtype=torch.float32) ** 2
95126
)
127+
elif beta_schedule == "squaredcos_cap_v2":
128+
# Glide cosine schedule
129+
self.betas = betas_for_alpha_bar(num_train_timesteps)
96130
else:
97131
raise NotImplementedError(f"{beta_schedule} does is not implemented for {self.__class__}")
98132

@@ -214,6 +248,8 @@ def step(
214248
elif self.config.prediction_type == "v_prediction":
215249
# * c_out + input * c_skip
216250
pred_original_sample = model_output * (-sigma / (sigma**2 + 1) ** 0.5) + (sample / (sigma**2 + 1))
251+
elif self.config.prediction_type == "sample":
252+
raise NotImplementedError("prediction_type not implemented yet: sample")
217253
else:
218254
raise ValueError(
219255
f"prediction_type given as {self.config.prediction_type} must be one of `epsilon`, or `v_prediction`"

schedulers/scheduling_euler_discrete.py

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
import math
1516
from dataclasses import dataclass
1617
from typing import List, Optional, Tuple, Union
1718

@@ -45,6 +46,36 @@ class EulerDiscreteSchedulerOutput(BaseOutput):
4546
pred_original_sample: Optional[torch.FloatTensor] = None
4647

4748

49+
# Copied from diffusers.schedulers.scheduling_ddpm.betas_for_alpha_bar
50+
def betas_for_alpha_bar(num_diffusion_timesteps, max_beta=0.999):
51+
"""
52+
Create a beta schedule that discretizes the given alpha_t_bar function, which defines the cumulative product of
53+
(1-beta) over time from t = [0,1].
54+
55+
Contains a function alpha_bar that takes an argument t and transforms it to the cumulative product of (1-beta) up
56+
to that part of the diffusion process.
57+
58+
59+
Args:
60+
num_diffusion_timesteps (`int`): the number of betas to produce.
61+
max_beta (`float`): the maximum beta to use; use values lower than 1 to
62+
prevent singularities.
63+
64+
Returns:
65+
betas (`np.ndarray`): the betas used by the scheduler to step the model outputs
66+
"""
67+
68+
def alpha_bar(time_step):
69+
return math.cos((time_step + 0.008) / 1.008 * math.pi / 2) ** 2
70+
71+
betas = []
72+
for i in range(num_diffusion_timesteps):
73+
t1 = i / num_diffusion_timesteps
74+
t2 = (i + 1) / num_diffusion_timesteps
75+
betas.append(min(1 - alpha_bar(t2) / alpha_bar(t1), max_beta))
76+
return torch.tensor(betas, dtype=torch.float32)
77+
78+
4879
class EulerDiscreteScheduler(SchedulerMixin, ConfigMixin):
4980
"""
5081
Euler scheduler (Algorithm 2) from Karras et al. (2022) https://arxiv.org/abs/2206.00364. . Based on the original
@@ -97,6 +128,9 @@ def __init__(
97128
self.betas = (
98129
torch.linspace(beta_start**0.5, beta_end**0.5, num_train_timesteps, dtype=torch.float32) ** 2
99130
)
131+
elif beta_schedule == "squaredcos_cap_v2":
132+
# Glide cosine schedule
133+
self.betas = betas_for_alpha_bar(num_train_timesteps)
100134
else:
101135
raise NotImplementedError(f"{beta_schedule} does is not implemented for {self.__class__}")
102136

@@ -245,7 +279,9 @@ def step(
245279
sample = sample + eps * (sigma_hat**2 - sigma**2) ** 0.5
246280

247281
# 1. compute predicted original sample (x_0) from sigma-scaled predicted noise
248-
if self.config.prediction_type == "original_sample":
282+
# NOTE: "original_sample" should not be an expected prediction_type but is left in for
283+
# backwards compatibility
284+
if self.config.prediction_type == "original_sample" or self.config.prediction_type == "sample":
249285
pred_original_sample = model_output
250286
elif self.config.prediction_type == "epsilon":
251287
pred_original_sample = sample - sigma_hat * model_output

schedulers/scheduling_heun_discrete.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
import math
1516
from typing import List, Optional, Tuple, Union
1617

1718
import numpy as np
@@ -21,6 +22,36 @@
2122
from .scheduling_utils import KarrasDiffusionSchedulers, SchedulerMixin, SchedulerOutput
2223

2324

25+
# Copied from diffusers.schedulers.scheduling_ddpm.betas_for_alpha_bar
26+
def betas_for_alpha_bar(num_diffusion_timesteps, max_beta=0.999) -> torch.Tensor:
27+
"""
28+
Create a beta schedule that discretizes the given alpha_t_bar function, which defines the cumulative product of
29+
(1-beta) over time from t = [0,1].
30+
31+
Contains a function alpha_bar that takes an argument t and transforms it to the cumulative product of (1-beta) up
32+
to that part of the diffusion process.
33+
34+
35+
Args:
36+
num_diffusion_timesteps (`int`): the number of betas to produce.
37+
max_beta (`float`): the maximum beta to use; use values lower than 1 to
38+
prevent singularities.
39+
40+
Returns:
41+
betas (`np.ndarray`): the betas used by the scheduler to step the model outputs
42+
"""
43+
44+
def alpha_bar(time_step):
45+
return math.cos((time_step + 0.008) / 1.008 * math.pi / 2) ** 2
46+
47+
betas = []
48+
for i in range(num_diffusion_timesteps):
49+
t1 = i / num_diffusion_timesteps
50+
t2 = (i + 1) / num_diffusion_timesteps
51+
betas.append(min(1 - alpha_bar(t2) / alpha_bar(t1), max_beta))
52+
return torch.tensor(betas, dtype=torch.float32)
53+
54+
2455
class HeunDiscreteScheduler(SchedulerMixin, ConfigMixin):
2556
"""
2657
Implements Algorithm 2 (Heun steps) from Karras et al. (2022). for discrete beta schedules. Based on the original
@@ -69,6 +100,9 @@ def __init__(
69100
self.betas = (
70101
torch.linspace(beta_start**0.5, beta_end**0.5, num_train_timesteps, dtype=torch.float32) ** 2
71102
)
103+
elif beta_schedule == "squaredcos_cap_v2":
104+
# Glide cosine schedule
105+
self.betas = betas_for_alpha_bar(num_train_timesteps)
72106
else:
73107
raise NotImplementedError(f"{beta_schedule} does is not implemented for {self.__class__}")
74108

@@ -197,6 +231,8 @@ def step(
197231
pred_original_sample = model_output * (-sigma_input / (sigma_input**2 + 1) ** 0.5) + (
198232
sample / (sigma_input**2 + 1)
199233
)
234+
elif self.config.prediction_type == "sample":
235+
raise NotImplementedError("prediction_type not implemented yet: sample")
200236
else:
201237
raise ValueError(
202238
f"prediction_type given as {self.config.prediction_type} must be one of `epsilon`, or `v_prediction`"

schedulers/scheduling_k_dpm_2_ancestral_discrete.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
import math
1516
from typing import List, Optional, Tuple, Union
1617

1718
import numpy as np
@@ -22,6 +23,36 @@
2223
from .scheduling_utils import KarrasDiffusionSchedulers, SchedulerMixin, SchedulerOutput
2324

2425

26+
# Copied from diffusers.schedulers.scheduling_ddpm.betas_for_alpha_bar
27+
def betas_for_alpha_bar(num_diffusion_timesteps, max_beta=0.999) -> torch.Tensor:
28+
"""
29+
Create a beta schedule that discretizes the given alpha_t_bar function, which defines the cumulative product of
30+
(1-beta) over time from t = [0,1].
31+
32+
Contains a function alpha_bar that takes an argument t and transforms it to the cumulative product of (1-beta) up
33+
to that part of the diffusion process.
34+
35+
36+
Args:
37+
num_diffusion_timesteps (`int`): the number of betas to produce.
38+
max_beta (`float`): the maximum beta to use; use values lower than 1 to
39+
prevent singularities.
40+
41+
Returns:
42+
betas (`np.ndarray`): the betas used by the scheduler to step the model outputs
43+
"""
44+
45+
def alpha_bar(time_step):
46+
return math.cos((time_step + 0.008) / 1.008 * math.pi / 2) ** 2
47+
48+
betas = []
49+
for i in range(num_diffusion_timesteps):
50+
t1 = i / num_diffusion_timesteps
51+
t2 = (i + 1) / num_diffusion_timesteps
52+
betas.append(min(1 - alpha_bar(t2) / alpha_bar(t1), max_beta))
53+
return torch.tensor(betas, dtype=torch.float32)
54+
55+
2556
class KDPM2AncestralDiscreteScheduler(SchedulerMixin, ConfigMixin):
2657
"""
2758
Scheduler created by @crowsonkb in [k_diffusion](https://github.com/crowsonkb/k-diffusion), see:
@@ -71,6 +102,9 @@ def __init__(
71102
self.betas = (
72103
torch.linspace(beta_start**0.5, beta_end**0.5, num_train_timesteps, dtype=torch.float32) ** 2
73104
)
105+
elif beta_schedule == "squaredcos_cap_v2":
106+
# Glide cosine schedule
107+
self.betas = betas_for_alpha_bar(num_train_timesteps)
74108
else:
75109
raise NotImplementedError(f"{beta_schedule} does is not implemented for {self.__class__}")
76110

@@ -254,6 +288,8 @@ def step(
254288
pred_original_sample = model_output * (-sigma_input / (sigma_input**2 + 1) ** 0.5) + (
255289
sample / (sigma_input**2 + 1)
256290
)
291+
elif self.config.prediction_type == "sample":
292+
raise NotImplementedError("prediction_type not implemented yet: sample")
257293
else:
258294
raise ValueError(
259295
f"prediction_type given as {self.config.prediction_type} must be one of `epsilon`, or `v_prediction`"

schedulers/scheduling_k_dpm_2_discrete.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
import math
1516
from typing import List, Optional, Tuple, Union
1617

1718
import numpy as np
@@ -21,6 +22,36 @@
2122
from .scheduling_utils import KarrasDiffusionSchedulers, SchedulerMixin, SchedulerOutput
2223

2324

25+
# Copied from diffusers.schedulers.scheduling_ddpm.betas_for_alpha_bar
26+
def betas_for_alpha_bar(num_diffusion_timesteps, max_beta=0.999) -> torch.Tensor:
27+
"""
28+
Create a beta schedule that discretizes the given alpha_t_bar function, which defines the cumulative product of
29+
(1-beta) over time from t = [0,1].
30+
31+
Contains a function alpha_bar that takes an argument t and transforms it to the cumulative product of (1-beta) up
32+
to that part of the diffusion process.
33+
34+
35+
Args:
36+
num_diffusion_timesteps (`int`): the number of betas to produce.
37+
max_beta (`float`): the maximum beta to use; use values lower than 1 to
38+
prevent singularities.
39+
40+
Returns:
41+
betas (`np.ndarray`): the betas used by the scheduler to step the model outputs
42+
"""
43+
44+
def alpha_bar(time_step):
45+
return math.cos((time_step + 0.008) / 1.008 * math.pi / 2) ** 2
46+
47+
betas = []
48+
for i in range(num_diffusion_timesteps):
49+
t1 = i / num_diffusion_timesteps
50+
t2 = (i + 1) / num_diffusion_timesteps
51+
betas.append(min(1 - alpha_bar(t2) / alpha_bar(t1), max_beta))
52+
return torch.tensor(betas, dtype=torch.float32)
53+
54+
2455
class KDPM2DiscreteScheduler(SchedulerMixin, ConfigMixin):
2556
"""
2657
Scheduler created by @crowsonkb in [k_diffusion](https://github.com/crowsonkb/k-diffusion), see:
@@ -70,6 +101,9 @@ def __init__(
70101
self.betas = (
71102
torch.linspace(beta_start**0.5, beta_end**0.5, num_train_timesteps, dtype=torch.float32) ** 2
72103
)
104+
elif beta_schedule == "squaredcos_cap_v2":
105+
# Glide cosine schedule
106+
self.betas = betas_for_alpha_bar(num_train_timesteps)
73107
else:
74108
raise NotImplementedError(f"{beta_schedule} does is not implemented for {self.__class__}")
75109

@@ -237,6 +271,8 @@ def step(
237271
pred_original_sample = model_output * (-sigma_input / (sigma_input**2 + 1) ** 0.5) + (
238272
sample / (sigma_input**2 + 1)
239273
)
274+
elif self.config.prediction_type == "sample":
275+
raise NotImplementedError("prediction_type not implemented yet: sample")
240276
else:
241277
raise ValueError(
242278
f"prediction_type given as {self.config.prediction_type} must be one of `epsilon`, or `v_prediction`"

0 commit comments

Comments
 (0)