Move through the deck with (i) the arrow keys, (ii) a presentation clicker, or (iii) the buttons at the bottom left. The gear at the bottom right opens the slide settings.
a red kite above blue water
Question: What does each different seed change inside the sampler? It produces a different random starting tensor.
Diffusion reuses (i) image tensors from Part 8, (ii) squared error from Part 5, (iii) prompt embeddings from Part 3, and (iv) attention from Part 9.
Take one photograph and add noise to it, a little, then more, until nothing of the picture survives. The noise looks like the static of an untuned television, and a computer adds any of these noise levels in microseconds.
Question: Which direction along this strip is hard? Left to right is arithmetic anyone can run. Right to left is the hard direction, and a trained model walks it in many small steps.
Training needs photographs paired with sentences that describe them, and the public web already carries both, because many pictures on web pages carry written alt text. The Flickr30k collection gathered 31,783 captioned photographs from the photo site Flickr, while the builders of LAION-5B parsed 5.85 billion image and text pairs out of the alt text of crawled pages.
Because the training program adds the corruption itself, every photograph becomes endless training material: any picture, any noise level, and any random draw of noise give one exercise, the noisy picture beside the noise that produced it, whose answer the program already holds.
No person labels the noise: the captions arrive with the pictures, and the targets come from the program's own draws. One collection of captioned photographs supplies as many exercises as a training run can use.
Noise has a size, which statisticians call the standard deviation. Independent noise combines by squares, exactly as the sides of a right triangle do: noise of standard deviation 3 followed by noise of standard deviation 4 is distributed exactly as one draw of standard deviation 5, because 3^2+4^2=5^2.
Because standard deviations combine by squares, the training program can produce any noise level with one draw of the right standard deviation, without stepping there.
The network receives three inputs: the noisy picture, the step number, which records how much noise the picture carries, and the caption. It returns one output: its estimate of the noise inside the picture.
Run the loop from pure noise and a photograph condenses out of it, a little at each step.
Generation starts from a fresh random tensor, so a second run with different starting noise produces a different kite over different water, which is why one prompt with three seeds gave three different pictures.
The animation replays the recorded noise of the earlier frames in reverse order (illustrative); a trained sampler estimates the noise at every step in place of reading a record.
A video is a stack of photographs, so it is stored as one tensor with dimensions for frame, height, width, and channel. Nothing in the method changes when the tensor gains a dimension: noise is added over the whole tensor at once, standard deviations combine by the same squares, and the denoiser removes noise from the whole tensor over the same small steps.
Because the network reads every frame of the tensor together, the kite it uncovers in frame 12 matches the kite of frame 11, which is why generated motion holds together. Ho and colleagues built video diffusion this way in 2022, and OpenAI announced the video generator Sora in February 2024.
| Date | System | What it brought |
|---|---|---|
| April 2022 | DALL-E 2 (OpenAI) | Diffusion image generation reached a broad public audience |
| July 12, 2022 | Midjourney | Opened its beta as a service reached through Discord |
| August 22, 2022 | Stable Diffusion (Stability AI) | Stability AI released the weights publicly; the model builds on the latent diffusion of Rombach and colleagues |
| February 2024 | Sora (OpenAI) | OpenAI announced diffusion video generation of clips up to one minute long |
| August 1, 2024 | FLUX.1 (Black Forest Labs) | An image generation model from Black Forest Labs, which the latent diffusion authors Rombach, Blattmann, Esser, and Lorenz founded |
The research line behind these products runs from the 2015 forward and reverse processes to the 2023 diffusion transformers.
Each of the five is computed with real numbers a student could recompute.
| 1 | 0 |
| -1 | 0.5 |
An image tensor stores channel values in a table. This illustrative grayscale image contains four normalized values.
Every pixel value in this worked image is illustrative. Training tensors retain real values, even when a display clips values to its visible range.
Keep 0.8 of each current value, then mix in 0.6 times a random noise value.
For the classroom: ask four students to calculate one coordinate each before revealing the result.
Variance is the average of the squared distances from the mean. Start with two values whose mean is zero.
When the image component and noise component each have variance one, their independent variance contributions add. Independent means that the program draws noise without using the image value. The variance statement concerns one tensor coordinate across many examples and noise draws.
At the next forward diffusion step, the program uses x_1 and draws a fresh noise sample.
The two noise arrays are illustrative draws selected for simple arithmetic.
Question: after two steps, what coefficient multiplies the original image x_0?
At each teaching step, multiplying the current tensor by 0.8 shrinks the original image contribution, while adding the scaled fresh noise introduces random variation.
Pause: allow four seconds after the question. Students who multiplied the two retained coefficients found the clean contribution.
| step | coefficient on the clean image |
|---|---|
| 0 | 1 |
| 1 | 0.8 |
| 2 | 0.64 |
| 3 | 0.512 |
| 4 | 0.4096 |
The illustrative teaching schedule uses a large variance at each step so that the shrinking clean coefficient is easy to see.
Production schedules can spread corruption across many smaller steps.
When the cumulative clean coefficient approaches zero, the final state has a distribution close to standard Gaussian noise.
Illustrative schedule. The 2020 denoising diffusion probabilistic model, or DDPM, experiments used 1,000 steps with scheduled variances from 10^{-4} to 0.02.
| symbol | spoken name | meaning |
|---|---|---|
| t | time index | the selected noise level |
| \beta_t | beta at time t | the scheduled variance added at this step |
| \alpha_t=1-\beta_t | alpha at time t | the retained variance factor |
| \eta_t | eta at time t | a fresh array of standard Gaussian noise values |
Uppercase T marks the final scheduled time. Standard Gaussian values cluster around zero, include positive and negative values, and have variance one in each coordinate.
The standard symbols summarize the two calculations with four pixels.
In the first teaching step, \alpha_1=0.64 and \beta_1=0.36, so the two square roots are 0.8 and 0.6.
The cumulative product \bar{\alpha}_t multiplies the retained variance factors from step 1 through step t.
The bar marks the cumulative product through time t.
\epsilon, pronounced epsilon, is one standard Gaussian array that represents the combined noise from all earlier steps.
Because sums of independent Gaussian values remain Gaussian, training code can draw one effective \epsilon and construct x_t directly.
Consider the image with two values, x_0=(1,-1).
For this example, the program retains (i) x_0, (ii) t, (iii) \epsilon, and (iv) the constructed x_t while it calculates the loss.
Illustrative image, noise level, and noise sample.
The neural network receives the noisy values and the time. Suppose its illustrative prediction is \hat{\epsilon}=(-0.5,\,0.5).
Mean squared error averages the squared errors. The symbol L names this loss.
The denoiser calculates \hat{\epsilon} from (i) the noisy tensor x_t, (ii) the time t, and (iii) an optional condition c.
Across many batches, random sampling approximates an average over the training data, times, and Gaussian noise tensors.
Solving the direct corruption equation for x_0 defines \hat{x}_0 from the predicted noise.
If the model predicts the exact noise (-1,1), the same calculation recovers (1,-1).
This equation calculates a clean estimate from the current state and the predicted noise.
Illustrative predictor with one weight, initialized at 0.10
Before training, software initializes the denoiser weights once from a distribution chosen by the implementation.
\Delta, pronounced delta, means change in a quantity.
Read \partial L/\partial w as the partial derivative of L with respect to w.
The exact local slope, -0.80, is close to the finite difference slope, -0.79. Both negative values indicate that a small increase in w lowers the loss near w=0.10.
The optimizer uses the loss gradient to update w. The illustrative learning rate r=0.05 scales the gradient and determines the update magnitude.
During real training, the optimizer updates many weights across the denoiser's connected layers.
| PyTorch pseudocode | calculation |
|---|---|
| x0 = image_batch | read a batch of clean tensors |
| t = torch.randint(1, T + 1, (B,), device=x0.device) | choose one noise level per image |
| eps = torch.randn_like(x0) | draw the target Gaussian noise |
| a = alpha_bar[t][:, None, None, None] | look up each cumulative retained variance |
| xt = torch.sqrt(a) * x0 + torch.sqrt(1 - a) * eps | construct each noisy input directly |
| eps_hat = model(xt, t, text_features) | run the neural network forward pass |
| loss = ((eps_hat - eps) ** 2).mean() | average the squared prediction error |
| optimizer.zero_grad() | clear gradients from the preceding batch |
| loss.backward() | run the backward pass through the denoiser |
| optimizer.step() | update the learned parameters |
The code assumes that alpha_bar has an unused entry at index zero.
| operation | when it runs | what it does | learned weights |
|---|---|---|---|
| forward diffusion | training input creation | mixes a clean tensor with scheduled noise | none |
| network forward pass | training and sampling | predicts noise from the current tensor, time, and condition | reads the learned weights |
| backward pass | training | computes gradients of the loss through the network | calculates gradients for the learned weights |
| reverse diffusion | sampling | uses repeated denoiser predictions to calculate earlier states | reads the learned weights without updating them |
Teaching cue: require the full operation name whenever a student uses the word forward or backward.
The system stores the noise added to one training photograph, then subtracts the same values during generation.
Question: where would that stored photograph appear when a user supplies only a prompt?
Sampling starts from a newly drawn random tensor. Using parameters learned across many images and noise levels, the denoiser maps each current tensor, time index, and condition to a noise prediction.
Generation draws each entry of x_T from a standard Gaussian distribution.
When the forward schedule is chosen appropriately, the distribution of corrupted training images at time T is close to the standard Gaussian starting distribution.
The trained parameters stay fixed while the tensor changes through the reverse steps.
The matrix is an illustrative random draw.
At one illustrative time, the schedule lists \alpha_t=0.64, \beta_t=0.36, and \bar{\alpha}_t=0.36.
\mu, pronounced mu, names the predicted mean; \theta names the learned parameters. This scalar is one coordinate of that mean.
At intermediate steps, an ancestral DDPM sampler adds a fresh standard Gaussian draw z.
At the final step, the sampler uses z=0.
Illustrative values rounded to four decimal places, using the DDPM fixed small variance \sigma_t^2=\tilde{\beta}_t.
The network uses (x_t,t,c) to calculate the predicted noise \hat{\epsilon}_t. The scalar calculation below applies to every coordinate of the current tensor.
| PyTorch pseudocode | calculation |
|---|---|
| x = torch.randn(sample_shape) | draw the starting tensor |
| for t in range(T, 0, -1): | visit the noise levels in reverse order |
| eps_hat = model(x, t, text_features) | predict noise with fixed parameters |
| scale = beta[t] / torch.sqrt(1 - alpha_bar[t]) | calculate the correction scale |
| mean = (x - scale * eps_hat) / torch.sqrt(alpha[t]) | calculate the reverse mean |
| z = torch.randn_like(x) if t > 1 else 0 | draw fresh noise for intermediate steps |
| x = mean + sigma[t] * z | calculate the next tensor |
Real implementations batch model calls, manage devices and precision, and may use a sampler with a different update.
The 2020 DDPM denoiser used a backbone based on U-Net, with residual blocks, attention, and a sinusoidal time embedding.
Question: should the same visible value receive the same correction at every time?
| current value | noise level | likely context |
|---|---|---|
| 0.2 | small t | much of the clean signal remains |
| 0.2 | large t | random noise contributes much of the observed value |
The model needs the noise level.
A time embedding maps t to a vector. Network blocks receive that vector so that one shared denoiser can behave differently across the schedule.
Latent diffusion uses cross attention between image features and prompt embeddings.
Learned projections of image features form queries, while learned projections of prompt embeddings form keys and values. The weighted sum of value vectors updates the image feature inside the denoiser.
Illustrative vectors and weights. Real prompt embeddings contain many coordinates and depend on tokenization.
During training for classifier-free guidance, the program sometimes replaces a prompt condition with an empty condition, so one denoiser learns conditional and unconditional predictions.
Question: with the illustrative guidance scale s=2, what value does the sampler use?
At s=1, this convention returns \hat{\epsilon}_{\mathrm{prompt}}. When s is larger, the difference \hat{\epsilon}_{\mathrm{prompt}}-\hat{\epsilon}_{\mathrm{empty}} receives more weight, which can reduce output variation or create artifacts.
Rombach and colleagues, in 2022, applied the repeated diffusion calculations to an autoencoder's latent representation and used cross attention for conditioning inputs such as text.
In their 2022 Video Diffusion Models architecture, Ho and colleagues used spatial convolutions within each frame and temporal attention across frames.
A seed initializes a random number generator, which produces (i) the starting tensor and (ii) any later random draws.
| run settings | expected path within one implementation |
|---|---|
| same model, prompt, sampler, settings, and seed | the random number sequence repeats |
| same settings with a different seed | a different random number sequence begins |
| same seed with a changed model or sampler | the tensor sequence can differ because the model or sampler calculation changed |
Question: does the seed contain a hidden picture? The seed initializes a random number sequence. The trained denoiser maps each current tensor, time index, and prompt condition to a noise prediction.
Each sampling step calls the denoiser, so fewer calls usually reduce generation time.
Song, Meng, and Ermon introduced denoising diffusion implicit models, or DDIMs, in 2021. Their update reuses a DDPM training objective and permits deterministic trajectories with selected time levels.
The resulting speed and image quality depend on (i) the trained model, (ii) the sampler, and (iii) the selected time sequence.
A deterministic DDIM trajectory still changes when its initial random tensor changes.
Illustrative generation record
| model | classroom denoiser A |
|---|---|
| prompt | a red kite above blue water |
| seed | 17 |
| sampler | DDIM, 30 steps |
| guidance scale | 2 |
1. Compute 0.8(0.5)+0.6(-0.5).
0.4-0.3=0.1.
2. With x_0=1, \bar{\alpha}_t=0.36, and \epsilon=-1, compute x_t.
x_t=0.6(1)+0.8(-1)=-0.2.
3. For \epsilon=(-1,1) and \hat{\epsilon}=(-0.5,0.5), compute mean squared error.
The two squared errors are 0.25 and 0.25, so their mean is 0.25.
4. Which training action changes the learned parameters?
The optimizer step updates the parameters using gradients calculated during the backward pass.
5. What clean image enters the sampler at time T?
Sampling begins with a fresh Gaussian tensor, so no clean image enters at time T.