Skip to content
AI360Xpert
Beta

DDIM Sampling

DDIM keeps the trained diffusion model but walks a shorter, non-random path from noise to image, so fifty steps do the work of a thousand.

DDIM jumps the noisy sample from 0.5 to 0.507 in one strided deterministic update with eta set to zero
DDIM jumps the noisy sample from 0.5 to 0.507 in one strided deterministic update with eta set to zero

Why Does This Exist?

Diffusion models train on a thousand tiny noise steps, and the obvious sampler replays all thousand at generation time. That works but crawls: every image pays for every intermediate, and interactive use becomes impossible. Users want the quality without the wait.

DDIM keeps the same trained noise predictor and changes only the sampling path. It proves the forward process need not be Markovian, so generation can skip steps and even run deterministically. Stable diffusion is where most readers meet this sampler, diffusion transformers use it on patch tokens, and image generation is the map it belongs on.

Think of It Like This

Stairs versus a ramp with landings

DDPM walks down a thousand stairs one at a time, checking balance on each. DDIM notices the staircase follows a smooth ramp underneath, so it strides down landings fifty steps apart and lands in nearly the same spot.

Setting eta to zero removes the random wobble from each stride, like walking the ramp with a handrail. The analogy stops at the model: stairs and ramps do not need a neural network to predict the slope, while DDIM leans on one every landing.

How It Actually Works

At step tt the model predicts the noise ϵ\epsilon inside the noisy sample xtx_t. DDIM first guesses the clean image x0x_0 from that prediction, then steps partway toward it. With noise schedule values αt\alpha_t and αt−1\alpha_{t-1} and knob η\eta:

xt−1=αt−1⋅x0+1−αt−1−σ2⋅ϵ+σ⋅zx_{t-1} = \sqrt{\alpha_{t-1}} \cdot x_0 + \sqrt{1 - \alpha_{t-1} - \sigma^2} \cdot \epsilon + \sigma \cdot z

In plain words: x0x_0 is the guessed clean image, ϵ\epsilon is the predicted noise direction, zz is fresh random noise, and σ\sigma scales with η\eta. Setting η=0\eta = 0 kills the random term and the path turns fully deterministic: same starting noise always yields the same image. Setting η=1\eta = 1 recovers noisier DDPM-like behaviour. Because the model only ever predicts ϵ\epsilon, no retraining is needed to change η\eta or skip steps.

Worked example

Take xt=0.5x_t = 0.5, predicted ϵ=0.3\epsilon = 0.3, αt=0.49\alpha_t = 0.49, αt−1=0.64\alpha_{t-1} = 0.64, η=0\eta = 0. Square roots: 0.49=0.7\sqrt{0.49} = 0.7, 1−0.49≈0.714\sqrt{1 - 0.49} \approx 0.714, 0.64=0.8\sqrt{0.64} = 0.8, 1−0.64=0.6\sqrt{1 - 0.64} = 0.6. Guessed clean: x0=(0.5−0.714×0.3)/0.7=(0.5−0.214)/0.7≈0.408x_0 = (0.5 - 0.714 \times 0.3) / 0.7 = (0.5 - 0.214) / 0.7 \approx 0.408. Step down: xt−1=0.8×0.408+0.6×0.3≈0.327+0.18=0.507x_{t-1} = 0.8 \times 0.408 + 0.6 \times 0.3 \approx 0.327 + 0.18 = 0.507. One strided update nudges 0.50.5 to 0.5070.507 along the deterministic ramp.

Code

One deterministic DDIM update, the exact arithmetic behind skipping.

import math

def ddim_step(x_t: float, eps: float, alpha_t: float, alpha_prev: float) -> tuple[float, float]:    """Deterministic DDIM step with eta 0; returns guessed x0 and x_prev."""    x0 = (x_t - math.sqrt(1.0 - alpha_t) * eps) / math.sqrt(alpha_t)  # clean guess    x_prev = math.sqrt(alpha_prev) * x0 + math.sqrt(1.0 - alpha_prev) * eps  # no fresh noise    return x0, x_prev

print(ddim_step(0.5, 0.3, 0.49, 0.64))  # -> (0.408..., 0.506...)

Watch Out For

Skipping so far that details wash out

Twenty steps often look fine, five steps look smooth but wrong: fine texture goes first, then small objects. The symptom is plastic skin and missing background detail while overall layout survives.

Treat step count as a quality knob per model. Verify faces and text at your chosen count instead of trusting a number from another checkpoint.

Expecting identical images across step counts

Deterministic means same noise plus same steps gives the same image. It does not mean 50 steps and 200 steps agree with each other. More steps refine the path, so outputs shift as you add them.

Fix the step count before comparing prompts or seeds. Otherwise you will blame the prompt for a sampler difference.

The Quick Version

  • DDIM reuses the trained noise predictor with a shorter, strided sampling path.
  • η=0\eta = 0 gives a deterministic map from noise to image; η=1\eta = 1 adds back random noise.
  • No retraining is needed to change steps or η\eta.
  • Worked numbers: x0≈0.408x_0 \approx 0.408, next sample ≈0.507\approx 0.507.
  • Few steps trade texture for speed, and step count must stay fixed for fair comparisons.