A noise schedule sets how noise changes across diffusion time steps. In forward diffusion, it determines how clean images become noisy training examples. During sampling, a scheduler also manages the sequence of denoising steps that turns random noise into an image. The schedule is not the denoising U-Net: the U-Net predicts what to remove, while the scheduler controls when and how the image is updated. section 5.0 section 5.4 section 5.4.2
Two forward schedules illustrate why the choice matters:
- Linear: increase the variance of added noise linearly with time. It is straightforward to implement. section 5.5
- Cosine: change noise according to a cosine-based progression. Compared with the illustrated linear schedule, its noise weight rises more gradually across time; the cited comparison reports better generated-image quality. section 5.1.3 section 5.5
To inspect a schedule before training, plot its weights on the clean image and random noise against relative time t/T. Then apply both schedules to the same image at selected steps: the resulting rows make their different rates of corruption visible. section 5.1.3
noise_scheduler = diffusers.DDPMScheduler(
num_train_timesteps=1000,
beta_schedule="squaredcos_cap_v2")
The DDPM configuration fixes 1,000 training steps and selects diffusers’ capped, cosine-based beta schedule with beta_schedule="squaredcos_cap_v2". section 5.4.1
The number of steps is a practical choice: too few can make denoising abrupt, while too many increase computation for limited quality gains. For sampling with the trained clothing-image U-Net, set the scheduler’s timesteps, start from random noise, and repeatedly pass the model’s output to scheduler.step to obtain the previous sample. section 5.4.1 section 5.4.2
Listing 5.6 Generating images using the trained model
@torch.no_grad()
def sample(n_sample, model, noise_scheduler, seed=None):
if seed is not None:
torch.manual_seed(seed)
noise_scheduler.set_timesteps(1000)
image=torch.randn((n_sample,1,32,32)).to(device) #1
for t in noise_scheduler.timesteps: #2
model_output=model(image,t)['sample'] #3
image=noise_scheduler.step(model_output,int(t), #4
image,generator=None)['prev_sample']
return image
The sampling loop shows the division of labor directly: the U-Net produces model_output, and the scheduler uses it with the current timestep and image to compute prev_sample. section 5.4.2
Inference schedulers can differ from the forward noise schedule. A latent-diffusion example sets 50 inference steps with a DDPM sampler. For Stable Diffusion, DDIM and LMS are presented as alternative reverse-process solvers: DDIM can be quicker with fewer steps, while LMS may favor visual fidelity at greater computational cost. section 9.3.2 section 10.4


