|
|
import torch |
|
|
import math |
|
|
|
|
|
|
|
|
def get_named_beta_schedule( |
|
|
schedule_name, |
|
|
num_diffusion_timesteps, |
|
|
min_beta=1e-4, |
|
|
max_beta=0.02, |
|
|
s=0.008, |
|
|
): |
|
|
""" |
|
|
Get a pre-defined beta schedule for the given name. |
|
|
|
|
|
The beta schedule library consists of beta schedules which remain similar |
|
|
in the limit of num_diffusion_timesteps. |
|
|
Beta schedules may be added, but should not be removed or changed once |
|
|
they are committed to maintain backwards compatibility. |
|
|
""" |
|
|
if schedule_name == "linear": |
|
|
|
|
|
|
|
|
|
|
|
scale = 1.0 |
|
|
beta_start = scale * min_beta |
|
|
beta_end = scale * max_beta |
|
|
return torch.linspace( |
|
|
beta_start, beta_end, num_diffusion_timesteps, |
|
|
) |
|
|
|
|
|
elif schedule_name == "cosine": |
|
|
return betas_for_alpha_bar( |
|
|
num_diffusion_timesteps, |
|
|
lambda t: math.cos((t + s) / (1 + s) * math.pi / 2) ** 2, |
|
|
) |
|
|
else: |
|
|
raise NotImplementedError(f"unknown beta schedule: {schedule_name}") |
|
|
|
|
|
def betas_for_alpha_bar(num_diffusion_timesteps, alpha_bar, max_beta=0.999): |
|
|
""" |
|
|
Create a beta schedule that discretizes the given alpha_t_bar function, |
|
|
which defines the cumulative product of (1-beta) over time from t = [0,1]. |
|
|
|
|
|
:param num_diffusion_timesteps: the number of betas to produce. |
|
|
:param alpha_bar: a lambda that takes an argument t from 0 to 1 and |
|
|
produces the cumulative product of (1-beta) up to that |
|
|
part of the diffusion process. |
|
|
:param max_beta: the maximum beta to use; use values lower than 1 to |
|
|
prevent singularities. |
|
|
""" |
|
|
betas = [] |
|
|
for i in range(num_diffusion_timesteps): |
|
|
t1 = i / num_diffusion_timesteps |
|
|
t2 = (i + 1) / num_diffusion_timesteps |
|
|
betas.append(min(1 - alpha_bar(t2) / alpha_bar(t1), max_beta)) |
|
|
return torch.tensor(betas, dtype=torch.float32) |
|
|
|