Three quantities are on offer as the thing a network should output: the noise , the clean image , or the velocity . They are usually introduced as three ideas that happen to be related, which makes the choice between them look empirical.
It is not. Given and , any one of the three determines the other two exactly, with no approximation and no information lost. They are one quantity written in three coordinate systems, and the coordinate change is a rotation.
The rotation
-
The variance-preserving identity from the first concept, given names. Two non-negative numbers whose squares sum to one are a cosine and a sine, so there is an angle here whether or not anyone mentions it.
-
The forward process, and the definition of velocity. The second line is not derived from anything — it is a definition, chosen so that the pair below comes out orthogonal.
-
Stack the two lines. Because c² + s² = 1 this matrix is a rotation — orthogonal, determinant one — which means it preserves lengths and is invertible everywhere on the chain.
-
A rotation inverts by transposing. So x₀ = c·x_t − s·v and ε = s·x_t + c·v: two multiply-adds, no division, and no timestep at which either is ill-conditioned.
-
The same recovery from an ε estimate instead, and the contrast is the whole practical argument. Going through ε divides by √ᾱ, which on the textbook curve is 0.068 at the end of the chain, so whatever error the network made comes out fifteen times larger. On the rescaled curve the model actually ships, √ᾱ at t = 999 is exactly zero and the division does not exist at all — which the pitfall below is about.
Why v is never approximately anything
-
The definition again, to be read as a sum of two terms rather than as an approximation of either. Both terms are always present; only their coefficients move.
-
At the clean end the sine vanishes and v is the noise exactly. This is the regime where predicting the image is nearly hopeless, because there is almost none of it missing to predict.
-
At the noisy end the verdict flips exactly: v is the negated image. This is the regime where predicting the noise is hopeless, because the input has become the noise, and copying the input scores perfectly.
-
And the crossover, where the two are weighted equally, is exactly ᾱ = ½ — which is SNR = 1, which is t = 354 on the textbook curve and t = 337 on the rescaled one the model trains on. The one number in this topic a reader will not believe until they compute it turns out to be the hinge of the target choice as well, on whichever curve they compute it.
This is the concrete difference between SD1.5 and SD2.1. Both are latent diffusion models with nearly the same UNet; SD1.5 was trained against and SD2.1 against , and the joint model here inherits the latter — prediction_type: "v_prediction" is the class default and what the shipped config asks for.
The practical consequence is unpleasant, and it is why the field treats this as a convention rather than a detail: a checkpoint's prediction type is not recoverable from its weights. Load -trained weights into a pipeline configured for and nothing raises. The sampler computes on an output that is really , and what it gets is
falling to at and to itself by . The error is largest at the start of sampling and vanishes at the end, so the output is not noise — it is a structured, over-saturated, clipped image that looks like a model with a bad prompt rather than a model with a misconfigured target. That is the failure mode worth recognising by sight.
On the shipped curve that first line is not finite at all: is exactly zero at , so the division does not exist, and trailing spacing makes that the first timestep the sampler visits. The rescale turns a silent misconfiguration into a loud one, which is the rare case of a numerical degeneracy being the friendlier behaviour.
If ε, x₀ and v carry exactly the same information, why does swapping the target change what the trained model is good at?
Show answer
Because the loss is not invariant under the coordinate change even though the information is. Squared error in -space is squared error in -space multiplied by , which on the textbook curve runs from to across the chain, and on the shipped one runs from to unbounded. The optimiser sees a different trade between timesteps and allocates capacity accordingly.
Two things follow. First, the target is a weighting scheme in disguise, so arguing about it in terms of accuracy is arguing about the wrong axis. Second, if you wanted an model to behave like a model, you would not have to change the architecture — you would have to change the per-timestep loss weight to , which is a one-line change that most codebases do not expose.