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.
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 the model predicts the noise inside the noisy sample . DDIM first guesses the clean image from that prediction, then steps partway toward it. With noise schedule values and and knob :
In plain words: is the guessed clean image, is the predicted noise direction, is fresh random noise, and scales with . Setting kills the random term and the path turns fully deterministic: same starting noise always yields the same image. Setting recovers noisier DDPM-like behaviour. Because the model only ever predicts , no retraining is needed to change or skip steps.
Worked example
Take , predicted , , , . Square roots: , , , . Guessed clean: . Step down: . One strided update nudges to 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.
- gives a deterministic map from noise to image; adds back random noise.
- No retraining is needed to change steps or .
- Worked numbers: , next sample .
- Few steps trade texture for speed, and step count must stay fixed for fair comparisons.