Type at least 2 letters. Enter opens the first result, Esc closes.

    Generative Models · Lesson 8 · Diffusion and flow matching

    Diffusion parameterizations: ε\varepsilon, x0x_0, vv and the score; SNR weighting; EDM preconditioning

    Advanced 100 min 5 interactive figures 3 videos Colab notebook

    Before this lesson: lesson 06 (the score, denoising score matching, Tweedie's formula at one noise level) and lesson 07 (the forward process q(xt∣x0)q(x_t \mid x_0), the ELBO and the ε\varepsilon-loss, noise schedules). You also need conditional expectation and the Gaussian density (probability and statistics) and the change of variables in an integral. Time: about 100 minutes, plus the notebook.


    Why this matters #

    Lesson 07 trained a network to predict the noise ε\varepsilon (DDPM, Stable Diffusion 1). Other models predict other things. EDM (Karras et al. 2022) predicts the clean sample through a preconditioned network. Progressive distillation, Imagen Video and the 768-pixel Stable Diffusion 2 model predict the velocity vv. Score-based SDE models predict the score. Flow matching and rectified flow (lesson 10, Stable Diffusion 3) predict a flow velocity. These look like different methods. They are not: at the optimum they are one function, seen through different linear maps.

    What really differs is (1) how the loss weights the noise levels, (2) the scale of the target the network must output, and (3) how much a network error grows when it is converted to a clean-sample estimate. These three points explain most training choices: cosine vs linear schedules, min-SNR weighting, vv-prediction, EDM preconditioning, zero terminal SNR, and schedule shifts for large images. When you choose a target and a weighting for a new model (for example a latent diffusion model of weather fields or seismic waveforms), you choose a point in this design space.

    1. Predict first #

    2. The picture #

    One equation, two unknowns #

    Fix one noise level tt. The noisy sample is

    xt=at x0+σt ε,ε∼N(0,I),x_t = a_t\, x_0 + \sigma_t\, \varepsilon, \qquad \varepsilon \sim \mathcal N(0, I),

    with signal scale ata_t and noise scale σt\sigma_t. In DDPM, at=αˉta_t = \sqrt{\bar\alpha_t} and σt=1−αˉt\sigma_t = \sqrt{1 - \bar\alpha_t} (lesson 07). The network sees xtx_t. It does not see x0x_0 or ε\varepsilon. But the equation links them: a guess of x0x_0 fixes the guess of ε\varepsilon, and the other way round:

    ε=xt−atx0σt,x0=xt−σtεat.\varepsilon = \frac{x_t - a_t x_0}{\sigma_t}, \qquad x_0 = \frac{x_t - \sigma_t \varepsilon}{a_t}.

    So "predict the noise" and "predict the clean sample" are two ways to write the same answer.

    The noise level as a rotation #

    Look at one coordinate. Then (x0,ε)(x_0, \varepsilon) is a point in a plane. In the variance-preserving (VP) case at2+σt2=1a_t^2 + \sigma_t^2 = 1, so we can write at=cos⁡ϕa_t = \cos\phi and σt=sin⁡ϕ\sigma_t = \sin\phi for an angle ϕ\phi between 0°0° (clean) and 90°90° (pure noise). Then xt=cos⁡ϕ x0+sin⁡ϕ εx_t = \cos\phi\, x_0 + \sin\phi\, \varepsilon is the coordinate of the point along the unit direction (cos⁡ϕ,sin⁡ϕ)(\cos\phi, \sin\phi).

    Define the velocity as the coordinate along the perpendicular direction (−sin⁡ϕ,cos⁡ϕ)(-\sin\phi, \cos\phi):

    v=at ε−σt x0=−sin⁡ϕ x0+cos⁡ϕ ε=dxtdϕ.v = a_t\, \varepsilon - \sigma_t\, x_0 = -\sin\phi\, x_0 + \cos\phi\, \varepsilon = \frac{d x_t}{d\phi}.

    It is called the velocity because it is the rate at which xtx_t moves as the angle ϕ\phi grows. The pair (xt,v)(x_t, v) is the pair (x0,ε)(x_0, \varepsilon) in a frame rotated by ϕ\phi. A rotation is easy to undo, so

    x0=at xt−σt v,ε=σt xt+at v.x_0 = a_t\, x_t - \sigma_t\, v, \qquad \varepsilon = \sigma_t\, x_t + a_t\, v .

    Check the first one: atxt−σtv=at2x0+atσtε−atσtε+σt2x0=x0a_t x_t - \sigma_t v = a_t^2 x_0 + a_t\sigma_t\varepsilon - a_t\sigma_t\varepsilon + \sigma_t^2 x_0 = x_0, because at2+σt2=1a_t^2 + \sigma_t^2 = 1.

    Given xtx_t, the unknown point (x0,ε)(x_0, \varepsilon) lies on one line: the line atx0+σtε=xta_t x_0 + \sigma_t\varepsilon = x_t, perpendicular to the direction of xtx_t. Any prediction picks one point on this line. An ε\varepsilon-network reports its vertical coordinate, an x0x_0-network its horizontal coordinate, a vv-network its position along the line.

    Interactive figure: loading…

    Drag the orange prediction along the dashed line. All points on that line have the same xtx_t. The blue point is the true pair (x0,ε)(x_0, \varepsilon); the violet arrow is vv. The distance between the two points along the line is the error Δv\Delta v. Its horizontal part is the x0x_0-error and its vertical part the ε\varepsilon-error. Move the angle ϕ\phi to high noise: the line becomes almost horizontal, so a small ε\varepsilon-error is a large x0x_0-error (the orange bar σt/at\sigma_t/a_t grows). The two vv bars never exceed 1.

    How errors grow when you convert #

    A real network makes errors. The figure shows what happens to them:

    • From ε\varepsilon to x0x_0: an error δ\delta in ε^\hat\varepsilon becomes an error (σt/at) δ(\sigma_t/a_t)\,\delta in x^0\hat x_0. At high noise at→0a_t \to 0, so this blows up.
    • From x0x_0 to ε\varepsilon: an error δ\delta in x^0\hat x_0 becomes (at/σt) δ(a_t/\sigma_t)\,\delta in ε^\hat\varepsilon. At low noise σt→0\sigma_t \to 0, so this blows up.
    • From vv: x^0=atxt−σtv^\hat x_0 = a_t x_t - \sigma_t \hat v and ε^=σtxt+atv^\hat\varepsilon = \sigma_t x_t + a_t \hat v, so a vv-error is multiplied by σt≤1\sigma_t \le 1 or by at≤1a_t \le 1. It never grows.

    This is the main practical reason to prefer vv (or the EDM preconditioning of section 3) over ε\varepsilon when the model must work at very high noise.

    Quick check

    At a VP noise level with at=0.6a_t = 0.6 and σt=0.8\sigma_t = 0.8, an ε\varepsilon-network makes an error of 0.30.3. What is the error of the x^0\hat x_0 computed from it?

    The best prediction is a conditional mean #

    Many pairs (x0,ε)(x_0, \varepsilon) give the same xtx_t. A network that only sees xtx_t cannot know which pair was used. So what is the best it can do? For a squared-error loss the answer is always the same: the minimizer of E∥target−f(xt)∥2\mathbb E\|\text{target} - f(x_t)\|^2 over all functions ff is the conditional mean E[target∣xt]\mathbb E[\text{target} \mid x_t] (proof in section 3). The best x0x_0-prediction is the average of all clean samples that could have produced xtx_t, weighted by how likely they are.

    This optimal x0x_0-prediction is called the denoiser D(xt)=E[x0∣xt]D(x_t) = \mathbb E[x_0 \mid x_t]. Every other target is a linear function of (x0,ε)(x_0, \varepsilon) for a fixed xtx_t, and the conditional mean is linear. So the optimal ε\varepsilon, vv and score predictions are the same linear maps applied to DD. One function determines all of them, and Tweedie's formula says which one: the score of the noisy density. In the simplest variance-exploding (VE) form x=x0+σεx = x_0 + \sigma\varepsilon (no scaling, a=1a = 1), it reads

    D(x)=E[x0∣x]=x+σ2 ∇xlog⁡pσ(x).D(x) = \mathbb E[x_0 \mid x] = x + \sigma^2\, \nabla_x \log p_\sigma(x).

    The denoiser is one step from xx along the score, with step size σ2\sigma^2. You met this form in lesson 06.

    Interactive figure: loading…

    Drag the yellow observation xx and change the noise level σ\sigma. The magenta curve is the posterior p(x0∣x)p(x_0 \mid x) over the clean value, computed on a grid with Bayes' rule. Its mean is the orange line. The violet arrow is the Tweedie step σ2∇log⁡pσ(x)\sigma^2 \nabla \log p_\sigma(x), computed from the exact score. It ends exactly at the posterior mean (compare the two bold numbers). At high noise the posterior covers both modes, and D(x)D(x) lies between them: the best guess in squared error is an average, not a plausible sample. The lower plot shows the whole denoiser for this σ\sigma. Data: 0.3 N(−1,0.22)+0.7 N(1.5,0.52)0.3\,\mathcal N(-1, 0.2^2) + 0.7\,\mathcal N(1.5, 0.5^2); the score is exact, not learned.

    Quick check

    Data x0∼N(0,σdata2)x_0 \sim \mathcal N(0, \sigma_{\text{data}}^2) with σdata=0.5\sigma_{\text{data}} = 0.5. You observe x=x0+σε=1.0x = x_0 + \sigma\varepsilon = 1.0 with σ=0.5\sigma = 0.5 (VE form). What is the optimal denoiser output D(x)D(x)?

    3. Definitions and main results #

    Conversions #

    From xtx_t and one prediction you get all the others (VP case):

    given x^0\hat x_0 ε^\hat\varepsilon v^\hat v score s^\hat s
    ε^\hat\varepsilon (xt−σtε^)/at(x_t - \sigma_t\hat\varepsilon)/a_t — (ε^−σtxt)/at(\hat\varepsilon - \sigma_t x_t)/a_t −ε^/σt-\hat\varepsilon/\sigma_t
    x^0\hat x_0 — (xt−atx^0)/σt(x_t - a_t\hat x_0)/\sigma_t (atxt−x^0)/σt(a_t x_t - \hat x_0)/\sigma_t −(xt−atx^0)/σt2-(x_t - a_t\hat x_0)/\sigma_t^2
    v^\hat v atxt−σtv^a_t x_t - \sigma_t\hat v σtxt+atv^\sigma_t x_t + a_t\hat v — −(σtxt+atv^)/σt-(\sigma_t x_t + a_t\hat v)/\sigma_t

    The first two columns use only xt=atx0+σtεx_t = a_t x_0 + \sigma_t\varepsilon. The vv entries also use at2+σt2=1a_t^2 + \sigma_t^2 = 1; for example, v=atε−σt(xt−σtε)/at=(ε−σtxt)/atv = a_t\varepsilon - \sigma_t(x_t - \sigma_t\varepsilon)/a_t = (\varepsilon - \sigma_t x_t)/a_t. The score column is exact for the optimal predictions (Theorem 1 below); for a trained network it defines the score model.

    The squared loss is minimized by the conditional mean #

    Lemma. Let YY be a target and XX an input with E∥Y∥2<∞\mathbb E\|Y\|^2 < \infty. Over all functions ff, E∥Y−f(X)∥2\mathbb E\|Y - f(X)\|^2 is smallest for f∗(x)=E[Y∣X=x]f^*(x) = \mathbb E[Y \mid X = x], and the minimum is E tr⁡Cov⁡(Y∣X)\mathbb E\,\operatorname{tr}\operatorname{Cov}(Y \mid X).

    Proof.

    1. Write Y−f(X)=(Y−f∗(X))+(f∗(X)−f(X))Y - f(X) = (Y - f^*(X)) + (f^*(X) - f(X)).
    2. Expand the square. The cross term is 2 E[(f∗(X)−f(X))⊤(Y−f∗(X))]2\,\mathbb E\big[(f^*(X) - f(X))^\top (Y - f^*(X))\big].
    3. Condition on XX: the first factor is fixed, and E[Y−f∗(X)∣X]=0\mathbb E[Y - f^*(X) \mid X] = 0. So the cross term is 0.
    4. Hence E∥Y−f(X)∥2=E∥Y−f∗(X)∥2+E∥f∗(X)−f(X)∥2\mathbb E\|Y - f(X)\|^2 = \mathbb E\|Y - f^*(X)\|^2 + \mathbb E\|f^*(X) - f(X)\|^2. The second term is ≥0\ge 0 and is 0 only for f=f∗f = f^*. The first term is E tr⁡Cov⁡(Y∣X)\mathbb E\,\operatorname{tr}\operatorname{Cov}(Y \mid X). ■\blacksquare

    So with unlimited capacity, the ε\varepsilon-network learns E[ε∣xt]\mathbb E[\varepsilon \mid x_t], the x0x_0-network learns E[x0∣xt]\mathbb E[x_0 \mid x_t], and so on, at every noise level.

    Theorem 1 (Tweedie's formula) #

    For any data distribution with a finite mean, and xt=atx0+σtεx_t = a_t x_0 + \sigma_t\varepsilon with at>0a_t > 0, σt>0\sigma_t > 0,

    E[x0∣xt]=xt+σt2 ∇log⁡pt(xt)at,E[ε∣xt]=−σt ∇log⁡pt(xt).\mathbb E[x_0 \mid x_t] = \frac{x_t + \sigma_t^2\,\nabla \log p_t(x_t)}{a_t}, \qquad \mathbb E[\varepsilon \mid x_t] = -\sigma_t\,\nabla \log p_t(x_t).

    Why this is true (intuition). The noisy density ptp_t is the data density blurred by a Gaussian. Its score at xtx_t points toward where the clean data that could explain xtx_t is concentrated. Moving along the score by σt2\sigma_t^2 (the noise variance) moves you to the center of that mass.

    Proof.

    1. xtx_t given x0x_0 is N(atx0,σt2I)\mathcal N(a_t x_0, \sigma_t^2 I), so pt(x)=∫N(x;atx0,σt2I) pdata(x0) dx0p_t(x) = \int \mathcal N(x; a_t x_0, \sigma_t^2 I)\, p_{\text{data}}(x_0)\, dx_0.
    2. The gradient of a Gaussian density in xx is ∇xN(x;atx0,σt2I)=−x−atx0σt2 N(x;atx0,σt2I)\nabla_x \mathcal N(x; a_t x_0, \sigma_t^2 I) = -\frac{x - a_t x_0}{\sigma_t^2}\,\mathcal N(x; a_t x_0, \sigma_t^2 I).
    3. Differentiate step 1 under the integral (allowed for a Gaussian kernel): ∇pt(x)=−1σt2∫(x−atx0) N(x;atx0,σt2I) pdata(x0) dx0\nabla p_t(x) = -\frac{1}{\sigma_t^2}\int (x - a_t x_0)\,\mathcal N(x; a_t x_0, \sigma_t^2 I)\,p_{\text{data}}(x_0)\,dx_0.
    4. Bayes' rule: p(x0∣xt=x)=N(x;atx0,σt2I) pdata(x0)/pt(x)p(x_0 \mid x_t = x) = \mathcal N(x; a_t x_0, \sigma_t^2 I)\,p_{\text{data}}(x_0)/p_t(x). Divide step 3 by pt(x)p_t(x); the integral becomes an expectation over this posterior: ∇log⁡pt(x)=∇pt(x)pt(x)=−x−at E[x0∣xt=x]σt2\nabla \log p_t(x) = \frac{\nabla p_t(x)}{p_t(x)} = -\frac{x - a_t\,\mathbb E[x_0 \mid x_t = x]}{\sigma_t^2}.
    5. Solve step 4 for E[x0∣xt]\mathbb E[x_0 \mid x_t]: this is the first formula.
    6. ε=(xt−atx0)/σt\varepsilon = (x_t - a_t x_0)/\sigma_t is linear in x0x_0 for fixed xtx_t, so E[ε∣xt]=(xt−at E[x0∣xt])/σt=−σt ∇log⁡pt(xt)\mathbb E[\varepsilon \mid x_t] = (x_t - a_t\,\mathbb E[x_0 \mid x_t])/\sigma_t = -\sigma_t\,\nabla \log p_t(x_t) by step 4. ■\blacksquare

    With at=1a_t = 1, σt=σ\sigma_t = \sigma this is the VE form of section 2.

    Consequences.

    • All optima are one function. ε∗=−σt∇log⁡pt\varepsilon^* = -\sigma_t\nabla\log p_t, x0∗=(xt+σt2∇log⁡pt)/atx_0^* = (x_t + \sigma_t^2\nabla\log p_t)/a_t, v∗=atε∗−σtx0∗v^* = a_t\varepsilon^* - \sigma_t x_0^*. With unlimited capacity, the choice of target does not change the learned model at any single noise level. It changes how the levels are weighted and how training behaves (Theorem 2).
    • Denoising score matching is the same thing. Regressing s^\hat s on −ε/σt-\varepsilon/\sigma_t is the ε\varepsilon-loss divided by σt2\sigma_t^2; its optimum is −E[ε∣xt]/σt=∇log⁡pt-\mathbb E[\varepsilon \mid x_t]/\sigma_t = \nabla\log p_t.
    • The loss has a floor. By the lemma, the minimum of E∥ε−ε^∥2\mathbb E\|\varepsilon - \hat\varepsilon\|^2 is E tr⁡Cov⁡(ε∣xt)>0\mathbb E\,\operatorname{tr}\operatorname{Cov}(\varepsilon \mid x_t) > 0. A loss value alone does not say how good a model is.
    Second-order Tweedie: the posterior covariance

    Write m(x)=E[x0∣xt=x]m(x) = \mathbb E[x_0 \mid x_t = x]. Two facts give the covariance of the posterior.

    1. The posterior is p(x0∣x)∝pdata(x0)exp⁡ ⁣(atx0⊤x/σt2−at2∥x0∥2/(2σt2))p(x_0 \mid x) \propto p_{\text{data}}(x_0)\exp\!\big(a_t x_0^\top x/\sigma_t^2 - a_t^2\|x_0\|^2/(2\sigma_t^2)\big). As a function of xx, xx enters only through η=atx/σt2\eta = a_t x/\sigma_t^2, like the natural parameter of an exponential family. For such a family the derivative of the mean with respect to η\eta is the covariance. So ∂m/∂x=(at/σt2)Cov⁡(x0∣x)\partial m/\partial x = (a_t/\sigma_t^2)\operatorname{Cov}(x_0 \mid x).
    2. Differentiate Tweedie's formula: ∂m/∂x=(I+σt2 ∇2log⁡pt(x))/at\partial m/\partial x = (I + \sigma_t^2\,\nabla^2 \log p_t(x))/a_t.

    Together:

    Cov⁡(x0∣xt)=σt2at2(I+σt2 ∇2log⁡pt(xt)).\operatorname{Cov}(x_0 \mid x_t) = \frac{\sigma_t^2}{a_t^2}\big(I + \sigma_t^2\,\nabla^2 \log p_t(x_t)\big).

    Posterior sampling for inverse problems uses it (lesson 15).

    Theorem 2 (the losses differ only by an SNR weight) #

    Let x^0\hat x_0, ε^\hat\varepsilon be one network output written in two forms, so that xt=atx^0+σtε^x_t = a_t\hat x_0 + \sigma_t\hat\varepsilon. Then for every example

    ∥x0−x^0∥2=∥ε−ε^∥2SNR(t).\|x_0 - \hat x_0\|^2 = \frac{\|\varepsilon - \hat\varepsilon\|^2}{\mathrm{SNR}(t)} .

    In the VP case, with v^=atε^−σtx^0\hat v = a_t\hat\varepsilon - \sigma_t\hat x_0,

    ∥v−v^∥2=(1+1SNR(t))∥ε−ε^∥2=(1+SNR(t)) ∥x0−x^0∥2.\|v - \hat v\|^2 = \Big(1 + \frac{1}{\mathrm{SNR}(t)}\Big)\|\varepsilon - \hat\varepsilon\|^2 = \big(1 + \mathrm{SNR}(t)\big)\,\|x_0 - \hat x_0\|^2 .

    Proof.

    1. The true pair and the predicted pair give the same xtx_t: atx0+σtε=atx^0+σtε^a_t x_0 + \sigma_t\varepsilon = a_t\hat x_0 + \sigma_t\hat\varepsilon. So at(x0−x^0)=−σt(ε−ε^)a_t(x_0 - \hat x_0) = -\sigma_t(\varepsilon - \hat\varepsilon).
    2. Take squared norms: at2∥x0−x^0∥2=σt2∥ε−ε^∥2a_t^2\|x_0 - \hat x_0\|^2 = \sigma_t^2\|\varepsilon - \hat\varepsilon\|^2. Divide by at2a_t^2: this is the first identity, since σt2/at2=1/SNR\sigma_t^2/a_t^2 = 1/\mathrm{SNR}. (No VP assumption so far.)
    3. For vv: v−v^=at(ε−ε^)−σt(x0−x^0)v - \hat v = a_t(\varepsilon - \hat\varepsilon) - \sigma_t(x_0 - \hat x_0). Insert step 1, x0−x^0=−(σt/at)(ε−ε^)x_0 - \hat x_0 = -(\sigma_t/a_t)(\varepsilon - \hat\varepsilon): v−v^=(at+σt2/at)(ε−ε^)=at2+σt2at(ε−ε^)=1at(ε−ε^)v - \hat v = \big(a_t + \sigma_t^2/a_t\big)(\varepsilon - \hat\varepsilon) = \frac{a_t^2 + \sigma_t^2}{a_t}(\varepsilon - \hat\varepsilon) = \frac{1}{a_t}(\varepsilon - \hat\varepsilon), using VP.
    4. Square: ∥v−v^∥2=∥ε−ε^∥2/at2\|v - \hat v\|^2 = \|\varepsilon - \hat\varepsilon\|^2/a_t^2, and 1/at2=(at2+σt2)/at2=1+1/SNR1/a_t^2 = (a_t^2 + \sigma_t^2)/a_t^2 = 1 + 1/\mathrm{SNR}. The last form follows from step 2. ■\blacksquare

    Read it in "x0x_0 units" (the factor in front of ∥x0−x^0∥2\|x_0 - \hat x_0\|^2): the x0x_0-loss has weight 11, the ε\varepsilon-loss has weight SNR\mathrm{SNR}, the vv-loss has weight 1+SNR1 + \mathrm{SNR}, and the plain score loss ∥s^+ε/σt∥2\|\hat s + \varepsilon/\sigma_t\|^2 has weight SNR/σt2\mathrm{SNR}/\sigma_t^2. So, compared with the x0x_0-loss, the ε\varepsilon-loss puts much more weight on low noise (high SNR), and much less on high noise.

    Quick check

    A model must give good x^0\hat x_0 estimates at very high noise (at≈0.01a_t \approx 0.01). Which output is the safest choice for the network?

    All losses as one weighted integral over λ\lambda (Kingma and Gao 2023) #

    Theorem 2 lets us write every loss in ε\varepsilon units. Write xλx_\lambda for the noisy sample at log-SNR λ\lambda. Every common objective is a special case of

    Lw(x0)=12∫λmin⁡λmax⁡w(λ)  Eε ∥ε−ε^(xλ;λ)∥2 dλ\mathcal L_w(x_0) = \frac12 \int_{\lambda_{\min}}^{\lambda_{\max}} w(\lambda)\; \mathbb E_\varepsilon\,\|\varepsilon - \hat\varepsilon(x_\lambda; \lambda)\|^2\, d\lambda

    for some weight function w(λ)≥0w(\lambda) \ge 0.

    How a schedule turns into a weight, step by step. Training draws t∼U(0,1)t \sim \mathcal U(0, 1) and computes λ=λt\lambda = \lambda_t. Because λt\lambda_t decreases in tt, this gives λ\lambda a density p(λ)=−dt/dλp(\lambda) = -dt/d\lambda (change of variables for densities). Then

    Et∼U(0,1)[g(λt)]=∫g(λ) p(λ) dλ⟹Lw=12 Eλ∼p(λ), ε[w(λ)p(λ) ∥ε−ε^∥2].\mathbb E_{t \sim \mathcal U(0,1)}\big[g(\lambda_t)\big] = \int g(\lambda)\, p(\lambda)\, d\lambda \quad\Longrightarrow\quad \mathcal L_w = \frac12\,\mathbb E_{\lambda \sim p(\lambda),\,\varepsilon}\Big[\frac{w(\lambda)}{p(\lambda)}\,\|\varepsilon - \hat\varepsilon\|^2\Big].

    So a loss with weight ww can be trained with any schedule, if each sample is multiplied by w(λ)/p(λ)w(\lambda)/p(\lambda). In the other direction, the plain loss Lsimple=Et∥ε−ε^∥2L_{\text{simple}} = \mathbb E_t\|\varepsilon - \hat\varepsilon\|^2 has w(λ)=p(λ)w(\lambda) = p(\lambda): for LsimpleL_{\text{simple}} the schedule is the weight.

    Example: the cosine schedule. Without the small offset, at=cos⁡(πt/2)a_t = \cos(\pi t/2) and σt=sin⁡(πt/2)\sigma_t = \sin(\pi t/2).

    1. SNR=cot⁡2(πt/2)\mathrm{SNR} = \cot^2(\pi t/2), so λ=−2log⁡tan⁡(πt/2)\lambda = -2\log\tan(\pi t/2).
    2. Solve for tt: t=2πarctan⁡(e−λ/2)t = \frac{2}{\pi}\arctan(e^{-\lambda/2}).
    3. Differentiate: dtdλ=2π⋅11+e−λ⋅(−12e−λ/2)=−1π⋅1eλ/2+e−λ/2\frac{dt}{d\lambda} = \frac{2}{\pi}\cdot\frac{1}{1 + e^{-\lambda}}\cdot\big(-\tfrac12 e^{-\lambda/2}\big) = -\frac{1}{\pi}\cdot\frac{1}{e^{\lambda/2} + e^{-\lambda/2}}.
    4. So p(λ)=12πsech⁡(λ/2)p(\lambda) = \frac{1}{2\pi}\operatorname{sech}(\lambda/2), a bell shape centered at λ=0\lambda = 0.

    Implied weights (up to a constant factor), using Theorem 2 to move each loss to ε\varepsilon units:

    objective w(λ)w(\lambda) decreasing in λ\lambda?
    continuous-time ELBO 11 yes (constant)
    ε\varepsilon-loss, cosine schedule (LsimpleL_{\text{simple}}) p(λ)∝sech⁡(λ/2)p(\lambda) \propto \operatorname{sech}(\lambda/2) no
    x0x_0-loss, cosine schedule p(λ) e−λp(\lambda)\,e^{-\lambda} yes
    vv-loss, cosine schedule p(λ)(1+e−λ)=e−λ/2/πp(\lambda)(1 + e^{-\lambda}) = e^{-\lambda/2}/\pi yes
    flow matching, t∼U(0,1)t \sim \mathcal U(0, 1) 12e−λ/2\tfrac12 e^{-\lambda/2} yes
    EDM N(λ; 2.4, 2.42) (e−λ+σdata2)/σdata2\mathcal N(\lambda;\, 2.4,\, 2.4^2)\,(e^{-\lambda} + \sigma_{\text{data}}^2)/\sigma_{\text{data}}^2 no
    min-SNR-γ\gamma, ε\varepsilon-loss, cosine p(λ) min⁡(1,γe−λ)p(\lambda)\,\min(1, \gamma e^{-\lambda}) no

    Min-SNR-γ\gamma (Hang et al. 2023, usually γ=5\gamma = 5) caps the weight in x0x_0 units at min⁡(SNR,γ)\min(\mathrm{SNR}, \gamma). In ε\varepsilon units that is min⁡(SNR,γ)/SNR=min⁡(1,γ/SNR)\min(\mathrm{SNR}, \gamma)/\mathrm{SNR} = \min(1, \gamma/\mathrm{SNR}). It lowers the weight of the easy, low-noise levels.

    Monotone weights are ELBOs (Kingma and Gao 2023, Theorem 1). If w(λ)w(\lambda) decreases as λ\lambda grows (it increases with tt), then Lw\mathcal L_w equals, up to a constant, an average over noise levels of the negative ELBO of noise-perturbed data. That is maximum likelihood with Gaussian noise as data augmentation. The vv-loss with the cosine schedule and flow matching have monotone weights; LsimpleL_{\text{simple}} with the cosine schedule and EDM do not.

    Interactive figure: loading…

    Pick a target and the way λ\lambda is sampled. The orange curve is the weight w(λ)w(\lambda) of the resulting loss. It is the product of the aqua density p(λ)p(\lambda) (how often training sees each noise level) and the violet target factor (Theorem 2: 11 for ε\varepsilon, e−λe^{-\lambda} for x0x_0, 1+e−λ1 + e^{-\lambda} for vv). The grey line is the ELBO, w=1w = 1. Notice that x0x_0 and vv tilt the weight toward high noise (left), and that min-SNR-5 cuts the weight at low noise (right). The badge says whether the weight decreases in λ\lambda. The linear schedule is drawn in its continuous form, β(t)\beta(t) from 0.10.1 to 2020.

    Theorem 3 (the continuous-time ELBO depends on the schedule only through its end points) #

    The ELBO of a diffusion model with TT steps contains a sum of terms Lt−1L_{t-1}, one per step (lesson 07). As T→∞T \to \infty with a fixed function SNR(t)\mathrm{SNR}(t) on t∈[0,1]t \in [0, 1], this sum becomes (Kingma et al. 2021, VDM, eq. 15)

    L∞=−12 Ex0,ε∫01SNR′(t) ∥x0−x^0(xt;t)∥2 dt.L_\infty = -\frac12\,\mathbb E_{x_0, \varepsilon} \int_0^1 \mathrm{SNR}'(t)\,\|x_0 - \hat x_0(x_t; t)\|^2\, dt .

    SNR′(t)<0\mathrm{SNR}'(t) < 0, so L∞≥0L_\infty \ge 0. Claim. Suppose the network uses its input only through the rescaled sample xt/atx_t/a_t and the value SNR(t)\mathrm{SNR}(t). Then

    L∞=12∫SNRmin⁡SNRmax⁡E ∥x0−x~(x0+ε/u, u)∥2 du,L_\infty = \frac12 \int_{\mathrm{SNR}_{\min}}^{\mathrm{SNR}_{\max}} \mathbb E\,\big\|x_0 - \tilde x\big(x_0 + \varepsilon/\sqrt{u},\ u\big)\big\|^2\, du ,

    where SNRmax⁡=SNR(0)\mathrm{SNR}_{\max} = \mathrm{SNR}(0), SNRmin⁡=SNR(1)\mathrm{SNR}_{\min} = \mathrm{SNR}(1) and x~(z,u)\tilde x(z, u) is the network written as a function of z=xt/atz = x_t/a_t and u=SNRu = \mathrm{SNR}. Only the two end points of the schedule enter. The other two ELBO terms (the prior term at t=1t = 1 and the reconstruction term at t=0t = 0) also depend only on the end points.

    Why this is true (intuition). The integrand is "the denoising error at signal-to-noise ratio uu". The schedule only says when (at which tt) each uu is visited and how fast. Integrating over uu instead of tt removes the "when".

    Proof (from the discrete ELBO to the end points)
    1. One step of the discrete ELBO. Ho et al. (2020, eq. 12) give Lt−1=βt22β~t αt(1−αˉt) E∥ε−ε^∥2+CtL_{t-1} = \frac{\beta_t^2}{2\tilde\beta_t\,\alpha_t(1 - \bar\alpha_t)}\,\mathbb E\|\varepsilon - \hat\varepsilon\|^2 + C_t for the reverse variance β~t=1−αˉt−11−αˉtβt\tilde\beta_t = \frac{1 - \bar\alpha_{t-1}}{1 - \bar\alpha_t}\beta_t. Insert β~t\tilde\beta_t: the weight is βt2αt(1−αˉt−1)\frac{\beta_t}{2\alpha_t(1 - \bar\alpha_{t-1})}.
    2. In SNR form. With SNR(t)=αˉt/(1−αˉt)\mathrm{SNR}(t) = \bar\alpha_t/(1 - \bar\alpha_t) and αˉt=αtαˉt−1\bar\alpha_t = \alpha_t\bar\alpha_{t-1}: SNR(t−1)SNR(t)=1−αˉtαt(1−αˉt−1)\frac{\mathrm{SNR}(t-1)}{\mathrm{SNR}(t)} = \frac{1 - \bar\alpha_t}{\alpha_t(1 - \bar\alpha_{t-1})}, so SNR(t−1)SNR(t)−1=1−αˉt−αt+αˉtαt(1−αˉt−1)=βtαt(1−αˉt−1)\frac{\mathrm{SNR}(t-1)}{\mathrm{SNR}(t)} - 1 = \frac{1 - \bar\alpha_t - \alpha_t + \bar\alpha_t}{\alpha_t(1 - \bar\alpha_{t-1})} = \frac{\beta_t}{\alpha_t(1 - \bar\alpha_{t-1})}. So the weight is 12(SNR(t−1)/SNR(t)−1)\tfrac12\big(\mathrm{SNR}(t-1)/\mathrm{SNR}(t) - 1\big).
    3. In x0x_0 units. Theorem 2, step 2 (no VP needed) gives ∥ε−ε^∥2=SNR(t) ∥x0−x^0∥2\|\varepsilon - \hat\varepsilon\|^2 = \mathrm{SNR}(t)\,\|x_0 - \hat x_0\|^2. Hence Lt−1=12(SNR(t−1)−SNR(t)) E∥x0−x^0∥2+CtL_{t-1} = \tfrac12\big(\mathrm{SNR}(t-1) - \mathrm{SNR}(t)\big)\,\mathbb E\|x_0 - \hat x_0\|^2 + C_t.
    4. The limit. Put the steps on a grid ti=i/Tt_i = i/T. Then SNR(ti−1)−SNR(ti)≈−SNR′(ti)/T\mathrm{SNR}(t_{i-1}) - \mathrm{SNR}(t_i) \approx -\mathrm{SNR}'(t_i)/T, and the sum over ii is a Riemann sum of the integral L∞L_\infty.
    5. Change of variables. SNR(t)\mathrm{SNR}(t) is strictly decreasing, so it is invertible. Set u=SNR(t)u = \mathrm{SNR}(t), du=SNR′(t) dtdu = \mathrm{SNR}'(t)\,dt; t=0↦SNRmax⁡t = 0 \mapsto \mathrm{SNR}_{\max} and t=1↦SNRmin⁡t = 1 \mapsto \mathrm{SNR}_{\min}: L∞=−12∫SNRmax⁡SNRmin⁡E∥x0−x^0∥2 du=12∫SNRmin⁡SNRmax⁡E∥x0−x^0∥2 duL_\infty = -\frac12 \int_{\mathrm{SNR}_{\max}}^{\mathrm{SNR}_{\min}} \mathbb E\|x_0 - \hat x_0\|^2\,du = \frac12 \int_{\mathrm{SNR}_{\min}}^{\mathrm{SNR}_{\max}} \mathbb E\|x_0 - \hat x_0\|^2\,du.
    6. The integrand depends only on uu. xt/at=x0+(σt/at) ε=x0+ε/ux_t/a_t = x_0 + (\sigma_t/a_t)\,\varepsilon = x_0 + \varepsilon/\sqrt{u}. The law of this rescaled input depends only on uu. By assumption the network output is x~(xt/at,u)\tilde x(x_t/a_t, u). So the integrand is a function of uu alone, and the schedule enters only through the limits. ■\blacksquare

    The same in λ\lambda. With du=eλdλdu = e^\lambda d\lambda and eλ∥x0−x^0∥2=∥ε−ε^∥2e^\lambda\|x_0 - \hat x_0\|^2 = \|\varepsilon - \hat\varepsilon\|^2 (Theorem 2), L∞=12∫E∥ε−ε^∥2 dλL_\infty = \frac12 \int \mathbb E\|\varepsilon - \hat\varepsilon\|^2\, d\lambda: the weight w(λ)=1w(\lambda) = 1 of the table. The same change of variables shows that every Lw\mathcal L_w with a fixed w(λ)w(\lambda) does not depend on the schedule between the end points (Kingma and Gao 2023, section 3.2).

    What the schedule still changes.

    • The variance of training. The schedule is the importance-sampling distribution p(λ)p(\lambda) of the Monte Carlo estimate. It sets the variance of the loss and gradient estimates, and with it the training speed.
    • The weight, for losses defined in tt. For LsimpleL_{\text{simple}}, w(λ)=p(λ)w(\lambda) = p(\lambda), so a new schedule is a new objective.
    • The end points. SNRmin⁡\mathrm{SNR}_{\min} must be close to 0 so that x1x_1 matches the Gaussian prior (see zero terminal SNR below), and SNRmax⁡\mathrm{SNR}_{\max} sets how clean the last step is.
    • The time grid of the sampler (lesson 09).
    • Resolution. More pixels average the noise, so the coarse structure survives longer at the same SNR. The shifted cosine schedule (Hoogeboom et al. 2023) uses λ(t)+2log⁡(64/d)\lambda(t) + 2\log(64/d) for resolution dd; for d=256d = 256 the shift is 2log⁡(1/4)=−2.772\log(1/4) = -2.77.
    Quick check

    You replace the noise schedule of a continuous-time diffusion model by another one with the same SNRmin⁡\mathrm{SNR}_{\min} and SNRmax⁡\mathrm{SNR}_{\max}, and keep the continuous-time ELBO as the loss. What changes?

    EDM preconditioning (Karras et al. 2022, section 5) #

    EDM works in the VE form x=y+σnx = y + \sigma n: clean data yy with standard deviation σdata\sigma_{\text{data}}, noise n∼N(0,I)n \sim \mathcal N(0, I), noise level σ\sigma. (The link to VP: y=x0y = x_0, σ=σt/at\sigma = \sigma_t/a_t, x=xt/atx = x_t/a_t.) The network FθF_\theta is wrapped in a denoiser

    Dθ(x;σ)=cskip(σ) x+cout(σ) Fθ(cin(σ) x; cnoise(σ)).D_\theta(x; \sigma) = c_{\text{skip}}(\sigma)\,x + c_{\text{out}}(\sigma)\,F_\theta\big(c_{\text{in}}(\sigma)\,x;\ c_{\text{noise}}(\sigma)\big).

    The four coefficients are chosen so that the network always sees inputs and targets of unit size. The loss is Eσ,y,n ω(σ) ∥Dθ(y+σn;σ)−y∥2\mathbb E_{\sigma, y, n}\,\omega(\sigma)\,\|D_\theta(y + \sigma n; \sigma) - y\|^2. (Karras et al. call the loss weight λ(σ)\lambda(\sigma); we write ω\omega to avoid a clash with the log-SNR.) Since Dθ−y=cout(Fθ−Ftarget)D_\theta - y = c_{\text{out}}\big(F_\theta - F_{\text{target}}\big) with the effective target

    Ftarget=y−cskip xcout,F_{\text{target}} = \frac{y - c_{\text{skip}}\,x}{c_{\text{out}}},

    the loss is E ω cout2 ∥Fθ−Ftarget∥2\mathbb E\,\omega\,c_{\text{out}}^2\,\|F_\theta - F_{\text{target}}\|^2. The coefficients follow in four steps.

    1. Unit input variance. Var⁡(cinx)=cin2(σdata2+σ2)=1\operatorname{Var}(c_{\text{in}} x) = c_{\text{in}}^2(\sigma_{\text{data}}^2 + \sigma^2) = 1, so cin=1/σ2+σdata2c_{\text{in}} = 1/\sqrt{\sigma^2 + \sigma_{\text{data}}^2}.
    2. Unit target variance. y−cskipx=(1−cskip) y−cskipσny - c_{\text{skip}}x = (1 - c_{\text{skip}})\,y - c_{\text{skip}}\sigma n has variance (1−cskip)2σdata2+cskip2σ2(1 - c_{\text{skip}})^2\sigma_{\text{data}}^2 + c_{\text{skip}}^2\sigma^2 (per coordinate; yy and nn are independent). For Var⁡(Ftarget)=1\operatorname{Var}(F_{\text{target}}) = 1, cout2c_{\text{out}}^2 must equal this variance.
    3. Smallest error amplification. An error of FθF_\theta reaches DθD_\theta multiplied by coutc_{\text{out}}. So choose cskipc_{\text{skip}} to make the variance of step 2 as small as possible. Set its derivative to zero: −2(1−cskip)σdata2+2cskipσ2=0-2(1 - c_{\text{skip}})\sigma_{\text{data}}^2 + 2c_{\text{skip}}\sigma^2 = 0, so cskip=σdata2σ2+σdata2c_{\text{skip}} = \frac{\sigma_{\text{data}}^2}{\sigma^2 + \sigma_{\text{data}}^2}. Insert it into step 2: cout=σ σdataσ2+σdata2c_{\text{out}} = \frac{\sigma\,\sigma_{\text{data}}}{\sqrt{\sigma^2 + \sigma_{\text{data}}^2}}.
    4. Equal effective weight. Choose ω(σ)=1/cout2=σ2+σdata2(σ σdata)2\omega(\sigma) = 1/c_{\text{out}}^2 = \frac{\sigma^2 + \sigma_{\text{data}}^2}{(\sigma\,\sigma_{\text{data}})^2}, so every noise level has weight 1 on the loss of FθF_\theta.
    5. Empirical choices (not derived): cnoise=14ln⁡σc_{\text{noise}} = \tfrac14\ln\sigma; training levels ln⁡σ∼N(−1.2,1.22)\ln\sigma \sim \mathcal N(-1.2, 1.2^2); σdata=0.5\sigma_{\text{data}} = 0.5 for images; sampling from σmax⁡=80\sigma_{\max} = 80 down to σmin⁡=0.002\sigma_{\min} = 0.002.

    What FθF_\theta learns. Insert x=y+σnx = y + \sigma n and the coefficients:

    Ftarget=σ y−σdata2 nσdataσ2+σdata2.F_{\text{target}} = \frac{\sigma\,y - \sigma_{\text{data}}^2\, n}{\sigma_{\text{data}}\sqrt{\sigma^2 + \sigma_{\text{data}}^2}} .

    For σ→0\sigma \to 0 this tends to −n-n: the network predicts the noise, like ε\varepsilon-prediction. For σ→∞\sigma \to \infty it tends to y/σdatay/\sigma_{\text{data}}: the network predicts the signal, like x0x_0-prediction. In between it mixes the two, and its variance is always σ2σ2+σdata2+σdata2σ2+σdata2=1\frac{\sigma^2}{\sigma^2 + \sigma_{\text{data}}^2} + \frac{\sigma_{\text{data}}^2}{\sigma^2 + \sigma_{\text{data}}^2} = 1.

    Interactive figure: loading…

    Move the noise level σ\sigma from left to right. Top: cskipc_{\text{skip}} falls from 1 to 0 around σ=σdata\sigma = \sigma_{\text{data}}, coutc_{\text{out}} rises like σ\sigma and then stops at σdata\sigma_{\text{data}}, while ε\varepsilon-prediction (grey dashed, cout=σc_{\text{out}} = \sigma) keeps growing to 80. Bottom: the effective target has a noise part and a signal part; their shares always add up to 1. The Monte Carlo readout checks Var⁡(Ftarget)≈1\operatorname{Var}(F_{\text{target}}) \approx 1 with 2000 samples. Switch the data to two points: the variance is still 1, because only Var⁡(y)=σdata2\operatorname{Var}(y) = \sigma_{\text{data}}^2 matters.

    The skip path is the best linear denoiser. For Gaussian data y∼N(0,σdata2)y \sim \mathcal N(0, \sigma_{\text{data}}^2), E[y∣x]=σdata2σdata2+σ2 x=cskip x\mathbb E[y \mid x] = \frac{\sigma_{\text{data}}^2}{\sigma_{\text{data}}^2 + \sigma^2}\,x = c_{\text{skip}}\,x (the Wiener filter) and Var⁡(y∣x)=cout2\operatorname{Var}(y \mid x) = c_{\text{out}}^2. So cskipxc_{\text{skip}}x is already the optimal denoiser for Gaussian data, and FθF_\theta learns only the correction for the non-Gaussian structure.

    Older choices as special cases of the EDM form

    (Karras et al., Table 1; Kingma and Gao, Appendix E.2.)

    • ε\varepsilon-prediction: cskip=1c_{\text{skip}} = 1, cout=−σc_{\text{out}} = -\sigma. Network errors are multiplied by σ\sigma, by 80 at EDM's σmax⁡\sigma_{\max}.
    • x0x_0-prediction: cskip=0c_{\text{skip}} = 0, cout=1c_{\text{out}} = 1.
    • vv-prediction is EDM with σdata=1\sigma_{\text{data}} = 1. With at=1/1+σ2a_t = 1/\sqrt{1 + \sigma^2}, σt=σ/1+σ2\sigma_t = \sigma/\sqrt{1+\sigma^2} and xt=atxx_t = a_t x: x^0=atxt−σtv^=11+σ2 x−σ1+σ2 v^\hat x_0 = a_t x_t - \sigma_t\hat v = \frac{1}{1 + \sigma^2}\,x - \frac{\sigma}{\sqrt{1 + \sigma^2}}\,\hat v. So cskip=1/(1+σ2)c_{\text{skip}} = 1/(1 + \sigma^2) and cout=−σ/1+σ2c_{\text{out}} = -\sigma/\sqrt{1 + \sigma^2} (the minus sign only flips the sign of FF), and the network input xt=atxx_t = a_t x is exactly cinxc_{\text{in}}x.
    • In λ\lambda form, EDM's weight in ε\varepsilon units is ω(σ) σ2=(e−λ+σdata2)/σdata2\omega(\sigma)\,\sigma^2 = (e^{-\lambda} + \sigma_{\text{data}}^2)/\sigma_{\text{data}}^2, and its training density is λ=−2ln⁡σ∼N(2.4,2.42)\lambda = -2\ln\sigma \sim \mathcal N(2.4, 2.4^2): the EDM row of the table.

    Zero terminal SNR (Lin et al. 2024) #

    Common schedules end with SNR(T)>0\mathrm{SNR}(T) > 0:

    schedule (T=1000T = 1000) αˉT\sqrt{\bar\alpha_T} SNR(T)\mathrm{SNR}(T)
    linear, βt\beta_t from 10−410^{-4} to 0.020.02 0.00640.0064 4.0×10−54.0 \times 10^{-5}
    cosine (offset 0.0080.008, βt≤0.999\beta_t \le 0.999) 4.9×10−54.9 \times 10^{-5} 2.4×10−92.4 \times 10^{-9}
    Stable Diffusion "scaled linear" 0.0680.068 0.00470.0047
    • So in training, xT=αˉT x0+1−αˉT εx_T = \sqrt{\bar\alpha_T}\,x_0 + \sqrt{1 - \bar\alpha_T}\,\varepsilon still contains some signal. At inference, sampling starts from xT∼N(0,I)x_T \sim \mathcal N(0, I), which contains none. This is a train–test mismatch.
    • The leaked signal is mostly the lowest frequency, such as the mean of each channel. Averaging DD values divides the noise by D\sqrt D but keeps the signal. The model learns to read the mean brightness from xTx_T. At inference it reads a mean near 0, so Stable Diffusion made only images of medium brightness: it could not make a very dark or very bright image.
    • The fix (Lin et al.): (1) shift and rescale αˉt\sqrt{\bar\alpha_t} so that αˉT=0\sqrt{\bar\alpha_T} = 0 while αˉ1\sqrt{\bar\alpha_1} stays the same; (2) train with vv-prediction; (3) start sampling at t=Tt = T; (4) rescale classifier-free guidance (lesson 11) to avoid over-exposure.
    • Why not ε\varepsilon at t=Tt = T. With aT=0a_T = 0, xT=εx_T = \varepsilon exactly. The ε\varepsilon-target equals the input, so it is trivial, and x^0=(xT−σTε^)/aT\hat x_0 = (x_T - \sigma_T\hat\varepsilon)/a_T is 0/00/0: the network gives no information about x0x_0. The vv-target there is v=−x0v = -x_0, so a vv-network predicts minus the conditional data mean, which is well defined.
    • EDM avoids the problem differently: it starts from N(0,σmax⁡2I)\mathcal N(0, \sigma_{\max}^2 I) with σmax⁡=80≫σdata\sigma_{\max} = 80 \gg \sigma_{\text{data}}, so the remaining mismatch is tiny.
    Interactive figure: loading…

    Compare the schedules and change the latent size. Blue and magenta: the channel mean of xTx_T in training, for a bright image (clean mean +0.5+0.5) and a dark one (−0.5-0.5). Aqua dashed: the channel mean of pure noise, which is where sampling starts. With the Stable Diffusion schedule at 64×6464 \times 64 the two training curves are clearly apart, so the network learns to read the brightness from xTx_T. At inference the start is always near 0. Increase nn: the leak gets worse, because the noise average shrinks like 1/n1/n but the signal does not. Zero terminal SNR makes all three curves equal.

    Quick check

    A text-to-image model with the "scaled linear" schedule cannot generate a fully black image. What does zero terminal SNR (with vv-prediction) fix?

    Answers to section 1. (1) Yes, at every noise level. Both optima are conditional means, linked by the conversions (Theorem 1). But the two averaged losses weight the levels differently, by a factor SNR\mathrm{SNR} (Theorem 2). So with finite capacity and finite training they spend their effort differently. (2) The factor is σt/at≈0.995/0.1≈10\sigma_t/a_t \approx 0.995/0.1 \approx 10, so the x^0\hat x_0-error is about 0.50.5: ten times larger. (3) It must output xTx_T itself, because xT=εx_T = \varepsilon when aT=0a_T = 0. The implied x^0=(xT−σTε^)/0\hat x_0 = (x_T - \sigma_T\hat\varepsilon)/0 is undefined, so an ε\varepsilon-network carries no information about x0x_0 at that step; use vv (or x0x_0).

    4. Worked example #

    One VP noise level with αˉ=0.64\bar\alpha = 0.64:

    at=0.8,σt=0.6,SNR=0.640.36=169≈1.778,λ=ln⁡169≈0.575.a_t = 0.8, \quad \sigma_t = 0.6, \quad \mathrm{SNR} = \frac{0.64}{0.36} = \frac{16}{9} \approx 1.778, \quad \lambda = \ln\tfrac{16}{9} \approx 0.575 .

    Data: x0∼N(0,σdata2)x_0 \sim \mathcal N(0, \sigma_{\text{data}}^2) in one dimension with σdata=0.5\sigma_{\text{data}} = 0.5.

    (a) Tweedie.

    1. The noisy density: xt=0.8 x0+0.6 εx_t = 0.8\,x_0 + 0.6\,\varepsilon is a sum of independent Gaussians, so pt=N(0, 0.82⋅0.25+0.62)=N(0, 0.16+0.36)=N(0,0.52)p_t = \mathcal N(0,\ 0.8^2 \cdot 0.25 + 0.6^2) = \mathcal N(0,\ 0.16 + 0.36) = \mathcal N(0, 0.52).
    2. Observe xt=1.3x_t = 1.3. The score of N(0,0.52)\mathcal N(0, 0.52) is −x/0.52-x/0.52, so it is −1.3/0.52=−2.5-1.3/0.52 = -2.5.
    3. Tweedie: E[x0∣xt]=(1.3+0.36⋅(−2.5))/0.8=(1.3−0.9)/0.8=0.5\mathbb E[x_0 \mid x_t] = (1.3 + 0.36 \cdot (-2.5))/0.8 = (1.3 - 0.9)/0.8 = 0.5.
    4. Check with Gaussian conditioning: E[x0∣xt]=Cov⁡(x0,xt)Var⁡(xt) xt=0.8⋅0.250.52⋅1.3=0.5\mathbb E[x_0 \mid x_t] = \frac{\operatorname{Cov}(x_0, x_t)}{\operatorname{Var}(x_t)}\,x_t = \frac{0.8 \cdot 0.25}{0.52} \cdot 1.3 = 0.5 ✓.
    5. E[ε∣xt]=−σt⋅score=−0.6⋅(−2.5)=1.5\mathbb E[\varepsilon \mid x_t] = -\sigma_t \cdot \text{score} = -0.6 \cdot (-2.5) = 1.5. Check: (1.3−0.8⋅0.5)/0.6=0.9/0.6=1.5(1.3 - 0.8 \cdot 0.5)/0.6 = 0.9/0.6 = 1.5 ✓.
    6. E[v∣xt]=at⋅1.5−σt⋅0.5=1.2−0.3=0.9\mathbb E[v \mid x_t] = a_t \cdot 1.5 - \sigma_t \cdot 0.5 = 1.2 - 0.3 = 0.9. Check with the table: (ε^−σtxt)/at=(1.5−0.78)/0.8=0.9(\hat\varepsilon - \sigma_t x_t)/a_t = (1.5 - 0.78)/0.8 = 0.9 ✓, and back: atxt−σtv^=1.04−0.54=0.5a_t x_t - \sigma_t \hat v = 1.04 - 0.54 = 0.5 ✓.

    (b) Loss floors. The best possible losses are the posterior variances (the lemma).

    • Var⁡(ε∣xt)=1−Cov⁡(ε,xt)2Var⁡(xt)=1−0.620.52=1−0.6923=0.3077\operatorname{Var}(\varepsilon \mid x_t) = 1 - \frac{\operatorname{Cov}(\varepsilon, x_t)^2}{\operatorname{Var}(x_t)} = 1 - \frac{0.6^2}{0.52} = 1 - 0.6923 = 0.3077.
    • Var⁡(x0∣xt)=0.25−(0.8⋅0.25)20.52=0.25−0.040.52=0.1731\operatorname{Var}(x_0 \mid x_t) = 0.25 - \frac{(0.8 \cdot 0.25)^2}{0.52} = 0.25 - \frac{0.04}{0.52} = 0.1731.
    • Theorem 2 says the second is the first divided by SNR\mathrm{SNR}: 0.3077⋅9/16=0.17310.3077 \cdot 9/16 = 0.1731 ✓.
    • Second-order Tweedie gives the same: 0.360.64(1+0.36⋅(−10.52))=0.5625⋅0.3077=0.1731\frac{0.36}{0.64}\big(1 + 0.36 \cdot (-\tfrac{1}{0.52})\big) = 0.5625 \cdot 0.3077 = 0.1731 ✓.

    (c) Error conversion. Suppose the network outputs ε^=1.6\hat\varepsilon = 1.6: an error of 0.10.1 against the optimum 1.51.5. (Theorem 2 holds for any two pairs on the line atx0+σtε=xta_t x_0 + \sigma_t\varepsilon = x_t.)

    • x^0=(1.3−0.6⋅1.6)/0.8=0.34/0.8=0.425\hat x_0 = (1.3 - 0.6 \cdot 1.6)/0.8 = 0.34/0.8 = 0.425: error −0.075-0.075, squared 0.005625=0.01/SNR0.005625 = 0.01/\mathrm{SNR} ✓.
    • v^=(1.6−0.6⋅1.3)/0.8=0.82/0.8=1.025\hat v = (1.6 - 0.6 \cdot 1.3)/0.8 = 0.82/0.8 = 1.025: error 0.125=0.1/at0.125 = 0.1/a_t, squared 0.015625=0.01⋅(1+9/16)0.015625 = 0.01 \cdot (1 + 9/16) ✓.

    (d) The same point in EDM form. σ=σt/at=0.75\sigma = \sigma_t/a_t = 0.75 and x=xt/at=1.625x = x_t/a_t = 1.625. With σdata=0.5\sigma_{\text{data}} = 0.5, σ2+σdata2=0.5625+0.25=0.8125\sigma^2 + \sigma_{\text{data}}^2 = 0.5625 + 0.25 = 0.8125:

    • cin=1/0.8125=1.109c_{\text{in}} = 1/\sqrt{0.8125} = 1.109, cskip=0.25/0.8125=0.3077c_{\text{skip}} = 0.25/0.8125 = 0.3077, cout=0.75⋅0.5/0.8125=0.375/0.9014=0.4160c_{\text{out}} = 0.75 \cdot 0.5/\sqrt{0.8125} = 0.375/0.9014 = 0.4160, cnoise=14ln⁡0.75=−0.0719c_{\text{noise}} = \tfrac14\ln 0.75 = -0.0719.
    • ω(σ)=0.8125/(0.75⋅0.5)2=0.8125/0.140625=5.778=1/cout2\omega(\sigma) = 0.8125/(0.75 \cdot 0.5)^2 = 0.8125/0.140625 = 5.778 = 1/c_{\text{out}}^2.
    • cskip x=0.3077⋅1.625=0.5=E[x0∣xt]c_{\text{skip}}\,x = 0.3077 \cdot 1.625 = 0.5 = \mathbb E[x_0 \mid x_t], and cout2=0.1731=Var⁡(x0∣xt)c_{\text{out}}^2 = 0.1731 = \operatorname{Var}(x_0 \mid x_t). For Gaussian data the skip path is already optimal: the best FθF_\theta is 00.
    • At σ=80\sigma = 80: cout=40/6400.25=0.49999c_{\text{out}} = 40/\sqrt{6400.25} = 0.49999 for EDM, but 8080 for ε\varepsilon-prediction. An FF-error of 0.010.01 moves x^0\hat x_0 by 0.0050.005 with EDM and by 0.80.8 with ε\varepsilon-prediction.

    5. In code #

    NumPy and SciPy check the worked example, Tweedie's formula for non-Gaussian data, Theorem 2, the EDM target and Theorem 3. The notebook has these cells and the exercises.

    import numpy as np
    from scipy.integrate import quad
    from scipy.stats import norm
    
    a, s, sd = 0.8, 0.6, 0.5          # VP level (alpha_bar = 0.64) and sigma_data
    xt = 1.3
    
    # (a) Tweedie for Gaussian data: p_t = N(0, a^2 sd^2 + s^2)
    score = -xt / (a**2 * sd**2 + s**2)
    x0_hat = (xt + s**2 * score) / a
    eps_hat = -s * score
    v_hat = a * eps_hat - s * x0_hat
    print(round(score, 4), round(x0_hat, 4), round(eps_hat, 4), round(v_hat, 4))  # -2.5 0.5 1.5 0.9
    
    # (b) Tweedie for a two-component mixture, against Bayes' rule by quadrature
    w, mu, sk = np.array([0.3, 0.7]), np.array([-1.0, 1.5]), np.array([0.2, 0.5])
    xm = 0.7
    var = a**2 * sk**2 + s**2                         # each component of p_t
    r = w * norm.pdf(xm, a * mu, np.sqrt(var)); r /= r.sum()
    score_m = -np.sum(r * (xm - a * mu) / var)        # exact score of p_t
    p0 = lambda x0: np.sum(w * norm.pdf(x0, mu, sk))
    joint = lambda x0: p0(x0) * norm.pdf(xm, a * x0, s)
    post_mean = quad(lambda x0: x0 * joint(x0), -10, 10)[0] / quad(joint, -10, 10)[0]
    print(round(post_mean, 6), round((xm + s**2 * score_m) / a, 6))  # 1.235454 1.235454
    
    # (c) Theorem 2 on random outputs: x0- and v-errors implied by an eps-error
    rng = np.random.default_rng(0)
    x0, eps, eps_n = rng.normal(size=(3, 100_000))
    x_t = a * x0 + s * eps
    x0_n = (x_t - s * eps_n) / a                       # the same output, in x0 form
    v, v_n = a * eps - s * x0, (eps_n - s * x_t) / a   # ... and in v form
    L_eps, L_x0, L_v = [np.mean((p - q)**2) for p, q in [(eps, eps_n), (x0, x0_n), (v, v_n)]]
    snr = a**2 / s**2
    print(np.isclose(L_x0, L_eps / snr), np.isclose(L_v, L_eps * (1 + 1 / snr)))  # True True
    
    # (d) EDM at the same point: sigma = s/a, x = x_t/a
    sig = s / a
    c_skip, c_out = sd**2 / (sig**2 + sd**2), sig * sd / np.sqrt(sig**2 + sd**2)
    print(round(c_skip, 4), round(c_out, 4), round(c_skip * xt / a, 4))  # 0.3077 0.416 0.5
    y, n = sd * rng.normal(size=100_000), rng.normal(size=100_000)
    F = (y - c_skip * (y + sig * n)) / c_out           # effective target
    print(round(F.var(), 2))                           # 1.0
    
    # (e) Theorem 3: two schedules with the same end points (lambda from 10 to -10)
    mmse = lambda u: sd**2 / (1 + u * sd**2)          # error of E[x0 | x_t] at SNR u
    for lam, dlam in [(lambda t: 10 - 20 * t, lambda t: -20.0),
                      (lambda t: 10 - 20 * t**3, lambda t: -60 * t**2)]:
        f = lambda t: -0.5 * np.exp(lam(t)) * dlam(t) * mmse(np.exp(lam(t)))
        print(round(quad(f, 0, 1, limit=200)[0], 6))   # 4.306938 (both)
    print(round(0.5 * np.log((1 + np.exp(10) * sd**2) / (1 + np.exp(-10) * sd**2)), 6))  # 4.306938
    

    In (e), for Gaussian data the best x0x_0-error at SNR uu is mmse(u)=σdata2/(1+u σdata2)\mathrm{mmse}(u) = \sigma_{\text{data}}^2/(1 + u\,\sigma_{\text{data}}^2), so L∞=12ln⁡1+SNRmax⁡σdata21+SNRmin⁡σdata2L_\infty = \tfrac12\ln\frac{1 + \mathrm{SNR}_{\max}\sigma_{\text{data}}^2}{1 + \mathrm{SNR}_{\min}\sigma_{\text{data}}^2} in closed form. The linear and the cubic schedule give the same value. Zero terminal SNR for the Stable Diffusion schedule and the rescaling of Lin et al.:

    import numpy as np
    
    betas = np.linspace(0.00085**0.5, 0.012**0.5, 1000)**2   # Stable Diffusion "scaled linear"
    sab = np.sqrt(np.cumprod(1 - betas))                      # sqrt(alpha_bar_t), t = 1..T
    print(round(sab[-1], 4), round(sab[-1]**2 / (1 - sab[-1]**2), 4))   # 0.0683 0.0047
    
    # The leak: channel mean of x_T for a 64 x 64 latent channel with clean mean 0.5
    signal = sab[-1] * 0.5
    noise_std = np.sqrt(1 - sab[-1]**2) / 64                  # mean of 4096 noise values
    print(round(signal, 4), round(noise_std, 4), round(signal / noise_std, 1))  # 0.0341 0.0156 2.2
    
    # Lin et al., Algorithm 1: shift so the last value is 0, scale so the first is kept
    new = (sab - sab[-1]) * sab[0] / (sab[0] - sab[-1])
    print(np.isclose(new[0], sab[0]), new[-1])                # True 0.0
    

    A clean channel mean of 0.50.5 is 2.22.2 noise standard deviations away from 0 at t=Tt = T: easy for a network to detect.

    6. Where it shows up #

    • Image and video models. Stable Diffusion 1.x uses ε\varepsilon-prediction. The 768-pixel Stable Diffusion 2 model and Imagen Video use vv-prediction. Progressive distillation (Salimans and Ho 2022) needs vv or x0x_0, because ε\varepsilon-prediction breaks down at high noise when only a few sampling steps are left (lesson 12).
    • Flow matching and rectified flow (lesson 10). With xt=(1−t) x0+t εx_t = (1 - t)\,x_0 + t\,\varepsilon and the velocity target u=ε−x0u = \varepsilon - x_0, the conversions are x^0=xt−t u^\hat x_0 = x_t - t\,\hat u and ε^=xt+(1−t) u^\hat\varepsilon = x_t + (1 - t)\,\hat u: one more linear target. With t∼U(0,1)t \sim \mathcal U(0, 1) its weight is w(λ)=12e−λ/2w(\lambda) = \tfrac12 e^{-\lambda/2}, the same shape as vv with the cosine schedule (Kingma and Gao 2023, Appendix D). Stable Diffusion 3 trains rectified flow with a logit-normal distribution of tt and shifts it for higher resolutions (Esser et al. 2024).
    • Weather and climate. GenCast and NVIDIA's CorrDiff build on the EDM formulation: a denoiser Dθ(x;σ)D_\theta(x; \sigma) trained over noise levels σ\sigma, and samplers on a σ\sigma grid.
    • Inverse problems and data assimilation. Diffusion posterior sampling uses the Tweedie estimate x^0(xt)\hat x_0(x_t) to approximate the likelihood of observations; second-order Tweedie gives the posterior covariance (lesson 15).
    • Scientific data in practice. Standardize the data and set σdata\sigma_{\text{data}} from it; do not copy 0.50.5 from image models. For long records or large grids, think about the resolution shift: more values per sample need lower SNR to destroy the coarse structure.

    7. Common mistakes #

    • Mixing VP and VE variables. σ=σt/at\sigma = \sigma_t/a_t and x=xt/atx = x_t/a_t. A VP-trained network inside an EDM-style sampler needs this rescaling of its input.
    • Sign conventions. Here v=atε−σtx0v = a_t\varepsilon - \sigma_t x_0 (Salimans and Ho). The rectified-flow velocity ε−x0\varepsilon - x_0 is a different target with a different time variable.
    • Converting ε\varepsilon to x0x_0 at high noise. x^0=(xt−σtε^)/at\hat x_0 = (x_t - \sigma_t\hat\varepsilon)/a_t divides by a small ata_t. Clip x^0\hat x_0 to the data range, or use vv or x0x_0.
    • Comparing loss values across parameterizations. They are in different units. Compare in one unit, for example the x0x_0-error at each noise level.
    • "The schedule does not matter." True only for the continuous-time loss with a fixed w(λ)w(\lambda). It always matters for the variance of training and for sampling, and for LsimpleL_{\text{simple}} it is the weight.
    • ε\varepsilon-prediction with a zero-terminal-SNR schedule. The last step is undefined.
    • Wrong noise conditioning. Feeding a network a tt or cnoisec_{\text{noise}} from a different schedule than in training gives wrong denoisers at every level.
    • Reading D(x)D(x) as a sample. The optimal denoiser is a posterior mean. At high noise it is a blurry average between modes, not a realistic clean sample.

    8. Check yourself #

    1. VP level with αˉ=0.36\bar\alpha = 0.36 (at=0.6a_t = 0.6, σt=0.8\sigma_t = 0.8). Given xt=(0.5,−1.0)x_t = (0.5, -1.0) and v^=(0.2,0.4)\hat v = (0.2, 0.4), find x^0\hat x_0 and ε^\hat\varepsilon.
      Answerx^0=atxt−σtv^=(0.3−0.16, −0.6−0.32)=(0.14,−0.92)\hat x_0 = a_t x_t - \sigma_t\hat v = (0.3 - 0.16,\ -0.6 - 0.32) = (0.14, -0.92). ε^=σtxt+atv^=(0.4+0.12, −0.8+0.24)=(0.52,−0.56)\hat\varepsilon = \sigma_t x_t + a_t\hat v = (0.4 + 0.12,\ -0.8 + 0.24) = (0.52, -0.56). Check: 0.6 x^0+0.8 ε^=(0.084+0.416, −0.552−0.448)=(0.5,−1.0)0.6\,\hat x_0 + 0.8\,\hat\varepsilon = (0.084 + 0.416,\ -0.552 - 0.448) = (0.5, -1.0) ✓.
    2. At SNR=0.25\mathrm{SNR} = 0.25, an ε\varepsilon-prediction has squared error 0.040.04. What are the squared errors of the implied x^0\hat x_0 and v^\hat v (VP)?
      Answerx^0\hat x_0: 0.04/SNR=0.04/0.25=0.160.04/\mathrm{SNR} = 0.04/0.25 = 0.16. v^\hat v: 0.04 (1+1/0.25)=0.04⋅5=0.20.04\,(1 + 1/0.25) = 0.04 \cdot 5 = 0.2.
    3. Which w(λ)w(\lambda) does the continuous-time ELBO use, and which does the ε\varepsilon-loss with t∼U(0,1)t \sim \mathcal U(0, 1) use?
      AnswerThe ELBO: w(λ)=1w(\lambda) = 1. The ε\varepsilon-loss: w(λ)=p(λ)=−dt/dλw(\lambda) = p(\lambda) = -dt/d\lambda, the density of log-SNR values that the schedule produces (sech⁡(λ/2)/(2π)\operatorname{sech}(\lambda/2)/(2\pi) for the cosine schedule).
    4. Why does min-SNR-γ\gamma use the weight min⁡(1,γ/SNR)\min(1, \gamma/\mathrm{SNR}) on the ε\varepsilon-loss?
      AnswerIt caps the weight in x0x_0 units at min⁡(SNR,γ)\min(\mathrm{SNR}, \gamma). The ε\varepsilon-loss equals SNR\mathrm{SNR} times the x0x_0-loss (Theorem 2), so the ε\varepsilon-weight is min⁡(SNR,γ)/SNR=min⁡(1,γ/SNR)\min(\mathrm{SNR}, \gamma)/\mathrm{SNR} = \min(1, \gamma/\mathrm{SNR}). It lowers the weight of the low-noise levels.
    5. In step 3 of the EDM derivation, why minimize the target variance over cskipc_{\text{skip}}?
      Answercoutc_{\text{out}} scales the target to unit variance, so cout2c_{\text{out}}^2 equals that variance. An error of FθF_\theta reaches DθD_\theta multiplied by coutc_{\text{out}}. The smallest variance gives the smallest coutc_{\text{out}}, so network errors are amplified as little as possible.
    6. Explain why the channel mean leaks through xTx_T when SNR(T)>0\mathrm{SNR}(T) > 0, and why it leaks more at higher resolution.
      AnswerThe channel mean of xTx_T is αˉT xˉ0\sqrt{\bar\alpha_T}\,\bar x_0 plus the mean of DD noise values, whose standard deviation is 1−αˉT/D\sqrt{1 - \bar\alpha_T}/\sqrt D. The signal part does not shrink with DD, but the noise part does. So with more values per channel the mean is easier to read. For Stable Diffusion's schedule and 64×6464 \times 64 latents, a clean mean of 0.50.5 is 2.22.2 noise standard deviations from 0.
    Recall cardsAnswer in your head first, then reveal. Add the cards to your review deck to see them again just before you would forget.
    1. Write x^0\hat x_0 in terms of xtx_t and ε^\hat\varepsilon.

    2. Define the vv-target and recover x0x_0 from it (VP).

    3. How is the optimal ε\varepsilon-prediction related to the score?

    4. State Tweedie's formula for xt=atx0+σtεx_t = a_t x_0 + \sigma_t\varepsilon.

    5. Why do the ε\varepsilon-, x0x_0- and vv-networks have the same optimum?

    6. An ε^\hat\varepsilon has error δ\delta. What is the error of the implied x^0\hat x_0?

    7. For one output, how is ∥x0−x^0∥2\|x_0 - \hat x_0\|^2 related to ∥ε−ε^∥2\|\varepsilon - \hat\varepsilon\|^2?

    8. Which weight w(λ)w(\lambda) does the continuous-time ELBO put on the ε\varepsilon-loss, and which does LsimpleL_{\text{simple}} use?

    9. Give EDM's cskipc_{\text{skip}} and coutc_{\text{out}}.

    10. What goes wrong when SNR(T)>0\mathrm{SNR}(T) > 0, and what is the fix?

    Open the review →

    9. Interview angle #

    • "ε\varepsilon, x0x_0 or vv: which and why?" — The same optimum (Tweedie). Different weights over SNR (SNR\mathrm{SNR}, 11, 1+SNR1 + \mathrm{SNR} in x0x_0 units) and different error amplification. ε\varepsilon is bad at high noise, x0x_0 at low noise; vv (or EDM preconditioning) is safe at both ends.
    • "State and prove Tweedie's formula." — E[x0∣xt]=(xt+σt2∇log⁡pt)/at\mathbb E[x_0 \mid x_t] = (x_t + \sigma_t^2\nabla\log p_t)/a_t. Differentiate the Gaussian convolution under the integral and use Bayes' rule.
    • "Does the noise schedule matter?" — Not for the continuous-time ELBO, except its end points. Yes for the variance of training (importance sampling), for losses weighted in tt, and for sampling.
    • "Why could Stable Diffusion not make very dark images?" — SNR(T)>0\mathrm{SNR}(T) > 0 leaks the image mean in training; at inference the start has mean 0. Fix: zero terminal SNR, vv-prediction, start at t=Tt = T.
    • "What do cskipc_{\text{skip}} and coutc_{\text{out}} do in EDM?" — They give a unit-variance target with the smallest error amplification. The skip path is the Wiener filter, and the network predicts noise at low σ\sigma and signal at high σ\sigma.

    10. Practice #

    The notebook for this lesson has five exercises, each with a check cell and a folded solution:

    1. Write the six conversions (ε↔x0\varepsilon \leftrightarrow x_0, vv from and to both, score from ε\varepsilon) and pass round-trip tests.
    2. Tweedie for a mixture: compute D(x)=x+σ2∇log⁡pσ(x)D(x) = x + \sigma^2\nabla\log p_\sigma(x) from the exact score and compare it with a Monte Carlo estimate of E[x0∣x]\mathbb E[x_0 \mid x] by binning noisy samples.
    3. Check the loss-weight identities of Theorem 2 on random predictions at several noise levels.
    4. Write the EDM coefficients and check by Monte Carlo that the effective target has unit variance for two different data distributions.
    5. Compute the continuous-time ELBO of the Gaussian toy for two schedules with the same end points (equal) and for one with a different end point (not equal).

    11. Watch and read #

    The chapters "How diffusion models work" and "Training and score matching" cover prediction targets and noise levels; "Frequency perspective" explains why resolution changes the schedule.
    Open on YouTube · the player loads from youtube-nocookie.com when you press play
    Start at the chapter "Sampling and training"; the chapter "Image spectrum and tuning" connects noise schedules to image frequencies.
    Open on YouTube · the player loads from youtube-nocookie.com when you press play
    The chapters "Diffusion modeling" and "Training techniques" show how these choices are made in large latent diffusion models.
    Open on YouTube · the player loads from youtube-nocookie.com when you press play