DATASCI 447 Lecture 27: Escaping the Prior Hole — The Diffusion Paradigm

Kevin McAlister

April 21, 2026

Administrative Stuff

THE STORY SO FAR

We’ve built a complete text-to-image pipeline:

  • VQ-VAE: compress images into discrete codebook tokens (L19-20)
  • GPT: autoregressive generation of token sequences (L24)
  • CLIP: text embeddings as conditioning signal (L26)

This is DALL-E 1. It works. But it has fundamental limitations that prevented it from scaling to the quality we expect from modern image generators.

Today: the alternative paradigm that replaced it. Diffusion models.

By the end of today, you’ll understand why diffusion won — and it comes down to fixing a problem we’ve been fighting all semester.

THE VQ-VAE CEILING AND THE CONTINUOUS ALTERNATIVE

Discrete codebooks bottleneck generation in two ways:

1. Finite vocabulary for an infinite visual world. A codebook with 512 entries divides the continuous visual manifold into 512 bins. Fine details between bins are lost.

2. No interpolation between concepts. In a discrete space, there’s no “halfway between code 237 and code 238.” The space between codebook entries is empty.

Continuous VAEs solve this — they map images to a dense, low-dimensional manifold. No discretization, no codebook limits. With perceptual and adversarial losses (L19), reconstructions can be sharp and detailed.

  • An infinite conceptual canvas. Smooth interpolation works naturally.

So why didn’t we just use a continuous VAE all along?

THE VQ-VAE CEILING AND THE CONTINUOUS ALTERNATIVE

THE KL TUG-OF-WAR

The fatal flaw of continuous VAEs: the KL penalty.

The VAE loss has two terms fighting each other:

\[\mathcal{L}_{\text{VAE}} = \underbrace{\text{Reconstruction}}_{\text{wants complex, detailed latents}} + \beta \cdot \underbrace{D_{KL}(q(\mathbf{z}|\mathbf{x}) \| \mathcal{N}(\mathbf{0}, \mathbf{I}))}_{\text{wants simple Gaussian latents}}\]

  • Reconstruction wants the encoder to preserve every detail — spread the latents out, use all dimensions, be expressive.

  • The KL term wants the encoder to collapse everything onto a unit Gaussian — simple, smooth, undifferentiated.

These goals are fundamentally in conflict.

  • The encoder can’t simultaneously be expressive AND match a simple Gaussian. It compromises — and the compromise is ugly.

THE PRIOR HOLE

The true posterior \(q(\mathbf{z}|\mathbf{x})\) looks like Swiss cheese — dense regions where training data maps to, surrounded by empty gaps where nothing lives.

  • During training, the encoder produces latents that cluster in specific regions. The KL penalty pushes them toward a Gaussian, but not hard enough to fill the entire space.

The problem appears at generation time. When we sample from \(\mathcal{N}(\mathbf{0}, \mathbf{I})\), we frequently land in the holes — regions of the latent space that the decoder has never seen during training.

The result: blurry, incoherent, artifacted generations. The decoder doesn’t know what to do with latent codes from the holes. It guesses, and it guesses badly.

  • The prior doesn’t match the true posterior, and sampling from the prior hits the gaps.

THE PRIOR HOLE

THE QUESTION

We want:

  • Continuous latent spaces (no discretization bottleneck)
  • Sharp, detailed reconstructions (perceptual + adversarial losses)
  • A prior we can actually sample from (no holes)

The KL penalty was our tool for making the prior matchable. But it fights reconstruction quality.

What if we dropped the strict KL penalty entirely and let the latent space be as complex as it needs to be?

New problem: how do we sample from an unknown, highly complex continuous distribution?

This is the question diffusion answers.

THE PARADIGM SHIFT

Diffusion doesn’t assume a shape for the prior. It learns it.

Instead of forcing the encoder to produce \(\mathcal{N}(\mathbf{0}, \mathbf{I})\) directly — which creates the prior hole — diffusion takes a completely different approach:

  • Gradually transform ANY distribution into \(\mathcal{N}(\mathbf{0}, \mathbf{I})\) through a fixed noising process. Then learn to reverse it.

  • The prior is still Gaussian at \(t = T\) — we haven’t abandoned that. We just don’t force the encoder to get there in one impossible step. Instead, we spread that work across \(T\) tiny, manageable steps.

The VAE asks the encoder to teleport the data to a Gaussian in one jump.

Diffusion says: walk there slowly, one small step at a time, and learn to retrace your steps.

THE CORE IDEA

Two processes:

Forward process (fixed, no learning): gradually add noise to data until it becomes pure Gaussian noise. This is the “walk to the Gaussian.”

Reverse process (learned): gradually remove noise from Gaussian noise until it becomes data. This is “retracing your steps.”

If we can learn the reverse process, we can:

  1. Sample from \(\mathcal{N}(\mathbf{0}, \mathbf{I})\) — easy, we know how to do that
  2. Apply the learned reverse process step by step
  3. Arrive at a clean sample from the data distribution

No prior holes. The Gaussian at \(t = T\) is reached by actually walking there, so the reverse path exists and is learnable.

THE FORWARD PROCESS: SMEARING THE MANIFOLD

Visualize what the forward process does to the data distribution:

  • Start: data lives on a concentrated, low-dimensional manifold
  • Each step adds a tiny bit of Gaussian noise, inflating the manifold slightly
  • After many steps, the structure is completely destroyed
  • End: an isotropic Gaussian cloud — no trace of the original data

The manifold gets smeared from a concentrated surface into a diffuse cloud that fills the entire space. Every point in the space is now reachable.

THE FORWARD PROCESS: SMEARING THE MANIFOLD

WHY WOULD THIS EVEN WORK?

Diffusion seems to come out of left field. Why would “add noise then learn to remove it” be a good generative model?

The idea comes from three independent intellectual threads that converged around 2020:

1. Physics — non-equilibrium thermodynamics.

A drop of ink in water spreads until it’s uniformly dissolved. This is thermodynamic diffusion — a structured state dissolving into maximum entropy equilibrium. The process is gradual, Markovian, and well-understood mathematically.

  • Sohl-Dickstein et al. (2015) asked: if the forward process (structure \(\to\) noise) follows known physics, can we learn the reverse (noise \(\to\) structure)?

  • This is why it’s called “diffusion.” It’s not a metaphor — the forward process is literally thermodynamic diffusion applied to data.

THREE THREADS CONVERGING

2. Statistics — score matching and Langevin dynamics.

The score function \(\nabla_\mathbf{x} \log p(\mathbf{x})\) is the gradient of the log-density at any point. Think of it as a vector field that points “uphill” toward higher-density regions of the data.

  • If you know the score everywhere, you can generate samples by following the gradient uphill — this is Langevin dynamics, a random walk biased toward high-density regions.

  • Song & Ermon (2019) showed: train a neural network to estimate the score at multiple noise levels.

The deep connection we’ll see later: the noise prediction \(\boldsymbol{\epsilon}_\theta(\mathbf{x}_t, t)\) that diffusion learns IS the score function, up to a scaling factor. Predicting noise and estimating the gradient of the log-density are mathematically equivalent.

THREE THREADS CONVERGING

3. Representation learning — denoising autoencoders.

Vincent et al. (2008) showed that training a network to denoise corrupted inputs implicitly learns the data distribution. The optimal denoising function points toward the data manifold. You saw this in your own autoencoders early in the semester!

Diffusion extends this from one noise level to a continuum of noise levels — it’s a denoising autoencoder trained at every scale simultaneously.

Ho et al. (2020) — the DDPM paper — unified all three threads into one clean framework. That’s the formulation we’re learning today.

THE FORWARD PROCESS: THE MATH

Define the forward process as a Markov chain — each step only depends on the previous step:

\[q(\mathbf{x}_t | \mathbf{x}_{t-1}) = \mathcal{N}(\mathbf{x}_t; \sqrt{1 - \beta_t}\,\mathbf{x}_{t-1},\; \beta_t \mathbf{I})\]

  • In plain English: take the image from the previous step, shrink it slightly (multiply by \(\sqrt{1 - \beta_t}\), which is just under 1), and add a small amount of random noise (scaled by \(\beta_t\), which is small).

Why shrink?

  • Without it, the image would get brighter and brighter as we add noise.

  • The shrinking keeps the overall magnitude constant while the noise gradually overwhelms the signal.

THE FORWARD PROCESS: THE MATH

\[q(\mathbf{x}_t | \mathbf{x}_{t-1}) = \mathcal{N}(\mathbf{x}_t; \sqrt{1 - \beta_t}\,\mathbf{x}_{t-1},\; \beta_t \mathbf{I})\]

\(\beta_t\) is the noise schedule — it controls how much noise we add at each step.

  • Small early (gentle noising), larger later after a bunch of noise addition (more aggressive).

Typical values: \(\beta_1 = 0.0001\), \(\beta_T = 0.02\), linearly spaced. Tiny amounts of noise, applied 1000 times.

THE CLOSED FORM: WHY TRAINING IS PRACTICAL

The key trick: we don’t need to iterate \(T\) steps to get to timestep \(t\).

  • Define: \(\alpha_t = 1 - \beta_t\) (the “signal retention” at step \(t\))

  • Define: \(\bar{\alpha}_t = \prod_{s=1}^{t} \alpha_s\) (the cumulative signal survival rate — how much of the original image survives after \(t\) steps)

Then we can jump directly to any timestep in one shot:

\[q(\mathbf{x}_t | \mathbf{x}_0) = \mathcal{N}(\mathbf{x}_t;\; \sqrt{\bar{\alpha}_t}\,\mathbf{x}_0,\; (1 - \bar{\alpha}_t)\mathbf{I})\]

Or equivalently, using the reparameterization trick from VAEs:

\[\mathbf{x}_t = \sqrt{\bar{\alpha}_t}\,\mathbf{x}_0 + \sqrt{1 - \bar{\alpha}_t}\,\boldsymbol{\epsilon}, \quad \boldsymbol{\epsilon} \sim \mathcal{N}(\mathbf{0}, \mathbf{I})\]

THE CLOSED FORM: WHY TRAINING IS PRACTICAL

In plain English: the noisy image at step \(t\) is a weighted mix of the clean image and pure noise.

  • \(\sqrt{\bar{\alpha}_t}\) controls how much signal survives; \(\sqrt{1 - \bar{\alpha}_t}\) controls how much noise is added.

  • The weights are designed so the total variance stays constant — we’re not making the image “louder,” we’re replacing signal with noise.

Why this matters for training: to create a noisy image at step 500, we don’t have to add noise 500 times sequentially. We just plug in \(\bar{\alpha}_{500}\), generate one noise sample, and mix. One multiplication, one addition, done.

VISUALIZING THE NOISE SCHEDULE

THE REVERSE PROCESS: LEARNING TO DENOISE

The forward process is fixed and known. The reverse process is what we need to learn.

  • Start at \(\mathbf{x}_T \sim \mathcal{N}(\mathbf{0}, \mathbf{I})\) (pure noise). Learn a model \(p_\theta(\mathbf{x}_{t-1} | \mathbf{x}_t)\) that removes one step of noise. Apply it \(T\) times to walk from pure noise back to clean data.

In plain English: given a noisy image, make it slightly less noisy. Do this 1000 times in a row, and you go from static to a photograph.

The true reverse step \(q(\mathbf{x}_{t-1} | \mathbf{x}_t)\) is intractable — computing it requires knowing the entire data distribution \(p(\mathbf{x}_0)\), which is the thing we’re trying to learn. So we approximate it with a neural network.

The question: what should the neural network predict?

THE REVERSE PROCESS: LEARNING TO DENOISE