Course contents 29 / 33

29 / 33 · Diffusion Models

Latent diffusion and Stable Diffusion

Run diffusion in the latent space of an autoencoder instead of on pixels: perceptual versus semantic compression, the autoencoder, text conditioning through cross-attention, classifier-free guidance, faster samplers, and the editing tools built on the same model (image-to-image, inpainting, LoRA, textual inversion).

On this page 12

The DDPM and score matching notes describe one model that denoises images step by step. Every step runs a network over every pixel, and a sample needs tens to hundreds of steps. Most of that work is spent on details nobody sees: the exact texture of grass or the noise of a camera sensor. Latent diffusion (Rombach et al., 2022) splits the problem in two. An autoencoder removes the imperceptible detail once; the diffusion model works only on the small latent that remains and spends its capacity on what an image shows. Stable Diffusion is this design with a text encoder attached.

Which Stable Diffusion. The constants below belong to named checkpoints, not to latent diffusion in general. The 512×512512 \times 512 numbers, the latent scale 0.18215 and the 77-token text encoders are those of Stable Diffusion 1.x and 2.x, and the guidance scale 7.5 is the default of their Diffusers pipeline. SDXL, a later model, has a larger U-Net and two text encoders (Podell et al., 2023); its released autoencoder uses a latent scale of 0.13025 and its Diffusers pipeline a default guidance of 5.0.

Notation. An image x∈RH×W×3x \in \mathbb R^{H \times W \times 3}, an encoder E\mathcal E and a decoder D\mathcal D with z=E(x)∈Rh×w×cz = \mathcal E(x) \in \mathbb R^{h \times w \times c}, a downsampling factor f=H/h=W/wf = H/h = W/w. A condition yy (a prompt) and its encoder τ(y)\tau(y). The diffusion quantities ztz_t, αˉt\bar\alpha_t, εθ\varepsilon_\theta are those of the DDPM notes, applied to zz instead of xx.

Two kinds of compression#

A trained image model compresses in two senses. Perceptual compression throws away high-frequency detail that changes many bits of the image and almost nothing of what a person perceives. Semantic compression captures the layout and content of the image: which objects, where, in what style. A likelihood-based model in pixel space is charged for every bit, and the paper shows that most of those bits belong to the perceptual part. Latent diffusion assigns each part to a model suited to it: an autoencoder trained with perceptual and adversarial losses for the first, a diffusion model for the second.

The savings are large. Stable Diffusion at 512×512512 \times 512 uses f=8f = 8 and c=4c = 4: the image has 512⋅512⋅3=786,432512 \cdot 512 \cdot 3 = 786{,}432 numbers and the latent 64⋅64⋅4=16,38464 \cdot 64 \cdot 4 = 16{,}384, 48 times fewer. Attention grows faster still. Self-attention over a 64×6464 \times 64 grid compares 40962≈1.7⋅1074096^2 \approx 1.7 \cdot 10^7 pairs; over the 512×512512 \times 512 pixels it would compare 262,1442≈6.9⋅1010262{,}144^2 \approx 6.9 \cdot 10^{10}, 4096 times more, which is why pixel-space models attend only at coarse resolutions. Memory matters as much as time: one 4096×40964096 \times 4096 attention map already has 1.7⋅1071.7 \cdot 10^7 entries, 67 MB in 32-bit floats, for every head and every image of a batch. Libraries can compute attention in slices, a few heads or images at a time, which gives the same result with a lower peak memory at some cost in speed.

The autoencoder#

The first stage is trained once and then frozen. Its loss combines a reconstruction term, a perceptual loss that compares deep features of the reconstruction and the image, as LPIPS does, and a patch-based adversarial loss whose discriminator judges small patches, so that reconstructions stay sharp instead of averaging to blur. The latent is kept close to a simple distribution in one of two ways: a slight KL penalty toward N(0,I)\mathcal N(0, I), as in a VAE with a very small weight on the KL term, or a vector-quantization layer, as in VQ-VAE. Unlike a VAE that is used as a generator, this autoencoder is not asked to make prior samples look good: the diffusion model provides the prior.

The downsampling factor sets the split. With f=1f = 1 the diffusion model still does all the perceptual work and trains slowly; with f=32f = 32 the autoencoder loses information the decoder cannot restore, and quality stops improving. The paper finds ff between 4 and 16 a good balance and f=4f = 4 and f=8f = 8 best. Because the KL penalty is weak, the latents of Stable Diffusion have a variance different from 1; the code multiplies them by a fixed scale, 0.18215 for versions 1.x and 2.x, so that the diffusion starts from data of roughly unit variance.

Diffusion in the latent#

Training is the DDPM objective with zz in place of xx:

L=Ez0=E(x), ε, t[∥ε−εθ(αˉt z0+1−αˉt ε, t, τ(y))∥2].\mathcal L = \mathbb E_{z_0 = \mathcal E(x),\ \varepsilon,\ t}\Big[\big\lVert \varepsilon - \varepsilon_\theta\big(\sqrt{\bar\alpha_t}\, z_0 + \sqrt{1 - \bar\alpha_t}\,\varepsilon,\ t,\ \tau(y)\big)\big\rVert^2\Big] .

Generation draws zT∼N(0,I)z_T \sim \mathcal N(0, I), runs the reverse chain in the latent space and decodes once at the end, x^=D(z0)\hat x = \mathcal D(z_0). The network is a U-Net, convolutional with attention layers at the lower resolutions.

Figure

Latent diffusion: Stable Diffusion at 512×512

Training and generation in the latent spaceTraining: a 512×512 image is encoded into a 64×64×4 latent, noise is added, and a U-Net learns to predict that noise, receiving the text through cross-attention. Generation: a latent drawn from normal noise goes through 20–50 U-Net steps with a scheduler and classifier-free guidance, and the decoder turns the result into an image.image512×512×3encoder E÷8 per sidelatent z₀64×64×4add noiseup to step tU-Netpredicts the noise εprompttexttext encoder77 vectorspure noiseN(0, I), step TU-Net + scheduler20–50 steps, CFGz₀64×64×4decoder D×8 per sideimage512×512×3cross-attentiontraininggenerationTraining and generation in the latent spaceTraining: a 512×512 image is encoded into a 64×64×4 latent, noise is added, and a U-Net learns to predict that noise, receiving the text through cross-attention. Generation: a latent drawn from normal noise goes through 20–50 U-Net steps with a scheduler and classifier-free guidance, and the decoder turns the result into an image.image512×512×3encoder E÷8 per sidelatent z₀64×64×4add noiseup to step tU-Netpredicts the noise εprompttexttext encoder77 vectorspure noiseN(0, I), step TU-Net + scheduler20–50 steps, CFGz₀64×64×4decoder D×8 per sideimage512×512×3cross-attentiontraininggeneration
Top: training. The encoder of a frozen autoencoder shrinks the image eightfold per side into a latent with 4 channels, noise of step t is added, and a U-Net learns to predict that noise; the text enters the U-Net through cross-attention. Bottom: generation. A latent drawn from normal noise goes through 20–50 steps, at each of which the scheduler updates it from the U-Net prediction with classifier-free guidance, and only at the end does the decoder turn it into pixels. The diffusion sees 16,384 numbers instead of 786,432.

Conditioning through cross-attention#

The condition enters through cross-attention (attention note): the queries come from the U-Net features of ztz_t, the keys and values from the encoded condition,

Attention(Q,K,V)=softmax(QK⊤d)V,Q=WQ φ(zt),K=WK τ(y),V=WV τ(y),\mathrm{Attention}(Q, K, V) = \mathrm{softmax}\Big(\frac{Q K^\top}{\sqrt d}\Big) V, \qquad Q = W_Q\, \varphi(z_t), \quad K = W_K\, \tau(y), \quad V = W_V\, \tau(y),

where φ(zt)\varphi(z_t) are flattened intermediate features. Every spatial position of the latent attends over the tokens of the prompt, so different regions can follow different words. In Stable Diffusion τ\tau is a frozen text encoder that turns a prompt into 77 token vectors: CLIP ViT-L/14 with 768 dimensions in versions 1.x, OpenCLIP ViT-H/14 with 1024 in versions 2.x. The same mechanism accepts other conditions, such as class labels, segmentation maps or low-resolution images.

Prompt weighting. Every token reaches the U-Net as its own vector τ(y)i\tau(y)_i, so a concept can be emphasised or toned down after encoding, without retraining. A common rule moves the token’s vector away from, or toward, the vector at the same position for an empty prompt,

τ(y)i  ←  τ(∅)i+wi (τ(y)i−τ(∅)i),\tau(y)_i \;\leftarrow\; \tau(\varnothing)_i + w_i\,\big(\tau(y)_i - \tau(\varnothing)_i\big),

with wi>1w_i > 1 to boost the concept and wi<1w_i < 1 to suppress it. The change acts through cross-attention: the token’s key changes how much the latent attends to it, and its value what the latent reads from it. The Compel library writes weights as suffixes, each + a factor 1.11.1 and each - a factor 0.90.9: ball++ has weight 1.12=1.211.1^2 = 1.21, ball-- 0.92=0.810.9^2 = 0.81, and forest--- 0.93=0.7290.9^3 = 0.729. For weights below 11 it also blends the result with the encoding of the prompt in which those tokens are masked out.

Classifier-free guidance#

A conditional model sampled as it is follows the prompt only loosely. Classifier-free guidance (Ho and Salimans, 2022) strengthens it without a separate classifier. During training the condition is replaced by an empty one in a fraction of the steps, 10 or 20 % in the paper, so one network learns both εθ(zt,t,y)\varepsilon_\theta(z_t, t, y) and εθ(zt,t,∅)\varepsilon_\theta(z_t, t, \varnothing). At sampling time the two predictions are extrapolated:

ε~=εθ(zt,t,∅)+s (εθ(zt,t,y)−εθ(zt,t,∅)).\tilde\varepsilon = \varepsilon_\theta(z_t, t, \varnothing) + s\,\big(\varepsilon_\theta(z_t, t, y) - \varepsilon_\theta(z_t, t, \varnothing)\big) .

s=0s = 0 is unconditional, s=1s = 1 the plain conditional model, and s>1s > 1 moves beyond it; the Diffusers pipeline for Stable Diffusion 1.x and 2.x uses s=7.5s = 7.5 by default. Since the noise prediction is a scaled score, sθ=−εθ/1−αˉts_\theta = -\varepsilon_\theta / \sqrt{1 - \bar\alpha_t} (score matching note), the guided prediction is the score

(1−s) ∇log⁡p(z)+s ∇log⁡p(z∣y)=∇log⁡[p(z)1−s p(z∣y)s],(1 - s)\, \nabla \log p(z) + s\, \nabla \log p(z \mid y) = \nabla \log\big[p(z)^{1 - s}\, p(z \mid y)^{s}\big],

and by Bayes’ rule p(z∣y)∝p(y∣z) p(z)p(z \mid y) \propto p(y \mid z)\, p(z) this is ∇log⁡p(z)+s ∇log⁡p(y∣z)\nabla \log p(z) + s\, \nabla \log p(y \mid z): the unconditional score plus ss times the gradient of an implicit classifier.

A score at each noise level, not a target distribution. The identity holds separately at every step, with the noised marginals qtq_t in place of pp: the guided prediction is the score of rt(z)∝qt(z)1−s qt(z∣y)sr_t(z) \propto q_t(z)^{1-s}\, q_t(z \mid y)^{s}. For s=0s = 0 and s=1s = 1 the family rtr_t is the noising of one distribution. For other ss it is in general not: noising p1−s p(⋅∣y)sp^{1-s}\, p(\cdot \mid y)^{s} does not give rtr_t, and no other single distribution does either. In the worked example below, every rtr_t is a Gaussian, and the clean distribution it would have to come from has mean 2.402.40 at the last step but 2.582.58 at t=0.2t = 0.2, with time running from 00 (data) to 11 (noise). A sampler driven by the guided score therefore does not in general end at p1−s p(⋅∣y)sp^{1-s}\, p(\cdot \mid y)^{s}, and the stochastic DDPM sampler and the deterministic DDIM sampler of the next section end at different distributions with the same network (Bradley and Nakkiran, 2024). What the identity gives is the direction of each step: toward regions that the implicit classifier at that noise level favours.

Worked example. Take an unconditional p=N(0,4)p = \mathcal N(0, 4) and a conditional p(⋅∣y)=N(2,1)p(\cdot \mid y) = \mathcal N(2, 1). At the last step the guided score is the score of p1−s p(⋅∣y)sp^{1-s}\, p(\cdot \mid y)^{s}, a Gaussian with precision (1−s)/4+s(1 - s)/4 + s and mean 2s2s divided by that precision. At s=3s = 3 the precision is 2.52.5, so the standard deviation is 0.630.63 and the mean 2.42.4; at s=7.5s = 7.5 the precision is 5.8755.875, the standard deviation 0.410.41 and the mean 2.552.55. The samplers end elsewhere. With exact Gaussian scores, so that no network error enters, and the continuous-time version of DDPM’s linear schedule (β\beta from 0.10.1 to 2020), guided sampling at s=3s = 3 ends at mean 2.632.63 and standard deviation 0.520.52 with the stochastic sampler and at mean 3.003.00 and standard deviation 0.250.25 with the deterministic one; at s=7.5s = 7.5 at 2.672.67 and 0.310.31, and at 2.882.88 and 0.010.01. The direction agrees with the tilted density, more strongly: guidance narrows the distribution and pushes it away from the unconditional mean, past the conditional one. Samples become more typical of the prompt and less diverse, the precision side of the trade-off from the precision and recall note. Each step costs two network evaluations, one with the prompt and one without.

Figure

At the last step the guided score points to a narrower, shifted density

Densities at four guidance scaless = 0: unconditional: mean 0.00, sd 2.00; s = 1: conditional: mean 2.00, sd 1.00; s = 3: mean 2.40, sd 0.63; s = 7.5: mean 2.55, sd 0.41.-6-4-20246s = 0: unconditionals = 1: conditionals = 3s = 7.5Densities at four guidance scaless = 0: unconditional: mean 0.00, sd 2.00; s = 1: conditional: mean 2.00, sd 1.00; s = 3: mean 2.40, sd 0.63; s = 7.5: mean 2.55, sd 0.41.-6-4-20246s = 0: unconditionals = 1: conditionals = 3s = 7.5
A toy example: unconditional distribution N(0, 4), conditional N(2, 1). At the last step the guided score at scale s is the score of the density p(x)^(1−s) p(x | y)^s, which for Gaussians is again a Gaussian. s = 1 gives the conditional distribution; s = 3 gives a standard deviation of 0.63 and a mean of 2.40; s = 7.5, the default for Stable Diffusion 1.x and 2.x, gives 0.41 and 2.55. This density is narrower than the conditional one and pushed further from the unconditional mean: samples more typical of the prompt, at the cost of diversity. The curves show the direction of guidance, not the distribution of samples: guided samplers in this example end at narrower distributions still, different for DDPM and DDIM (see the text).

Fewer steps#

DDPM samples with as many steps as it was trained with, 1000, because each step undoes one small Gaussian step. Fast samplers start from a deterministic description of the same model. In continuous time the forward process is a stochastic differential equation, and Song et al. (2021) show that the probability flow ODE

dzdt=−12 β(t) [z+∇zlog⁡qt(z)]=−12 β(t) [z−εθ(z,t)1−αˉt]\begin{aligned} \frac{dz}{dt} &= -\tfrac12\,\beta(t)\,\big[z + \nabla_z \log q_t(z)\big] \\ &= -\tfrac12\,\beta(t)\,\Big[z - \frac{\varepsilon_\theta(z, t)}{\sqrt{1 - \bar\alpha_t}}\Big] \end{aligned}

has the same marginal qtq_t as the noising process at every time. Here β(t)\beta(t) is the noise rate in continuous time, with βt≈β(t) Δt\beta_t \approx \beta(t)\,\Delta t for one discrete step and dαˉt/dt=−β(t) αˉtd\bar\alpha_t/dt = -\beta(t)\,\bar\alpha_t, and the score is replaced by the scaled noise predictor (score matching note). Integrating the ODE from zT∼N(0,I)z_T \sim \mathcal N(0, I) down to t=0t = 0 maps every noise latent to one sample, and a solver that takes large steps needs few network evaluations.

DDIM is Euler’s method in the right coordinates. Divide the latent by its signal coefficient and measure time by the noise-to-signal ratio,

zˉ=zαˉt,σt=1−αˉtαˉt,\bar z = \frac{z}{\sqrt{\bar\alpha_t}}, \qquad \sigma_t = \sqrt{\frac{1 - \bar\alpha_t}{\bar\alpha_t}},

so that zˉ=z0+σt ε\bar z = z_0 + \sigma_t\,\varepsilon. Differentiating zˉ\bar z with dαˉt/dt=−β(t) αˉtd\bar\alpha_t/dt = -\beta(t)\,\bar\alpha_t, the terms in zz cancel, and dzˉ/dtd\bar z/dt and dσt/dtd\sigma_t/dt both carry the factor β(t)/(2αˉt(1−αˉt))\beta(t)/\big(2\sqrt{\bar\alpha_t(1 - \bar\alpha_t)}\big). The ODE becomes dzˉ/dσ=εθd\bar z/d\sigma = \varepsilon_\theta (Song, Meng and Ermon, 2021, §4.3, Eq. 14), with the exact solution from σt\sigma_t to an earlier, smaller σs\sigma_s

zˉs=zˉt+∫σtσsεθ dσ.\bar z_s = \bar z_t + \int_{\sigma_t}^{\sigma_s} \varepsilon_\theta\, d\sigma .

Euler’s method holds εθ\varepsilon_\theta at its value at σt\sigma_t for the whole step. Multiplying back by αˉs\sqrt{\bar\alpha_s} gives the DDIM update (their Eq. 12 with no added noise):

zs=αˉs  z^0+1−αˉs  εθ(zt,t),z^0=zt−1−αˉt  εθ(zt,t)αˉt.\begin{gathered} z_s = \sqrt{\bar\alpha_s}\;\hat z_0 + \sqrt{1 - \bar\alpha_s}\;\varepsilon_\theta(z_t, t), \\ \hat z_0 = \frac{z_t - \sqrt{1 - \bar\alpha_t}\;\varepsilon_\theta(z_t, t)}{\sqrt{\bar\alpha_t}} . \end{gathered}

Predict the clean latent, then noise it again to the level of step ss with the same predicted noise. The step ss can be any earlier step, so a 50-step schedule simply visits every twentieth tt. The Euler sampler of diffusion libraries, after Karras et al. (2022), makes this same update with its own choice of noise levels; its “ancestral” variant adds fresh noise after each step. DDIM is deterministic and maps each noise latent to one image. Running its update in the other direction, from the image toward noise, gives an approximate inversion: the ideal ODE can be integrated both ways, but every Euler step evaluates εθ\varepsilon_\theta at the start of the step, so the backward pass does not exactly undo the forward one. The error shrinks with more steps and grows with model error and with guidance.

Worked example. One-dimensional data N(0,0.52)\mathcal N(0, 0.5^2), the exact noise predictor, DDPM’s linear schedule, zTz_T drawn from its exact distribution and DDIM steps evenly spaced in tt. The samples should have standard deviation 0.50.5. With 1 step they have 0.0020.002, with 10 steps 0.3700.370, with 50 steps 0.4710.471 and with 1000 steps 0.49850.4985. A single step from pure noise returns z^0\hat z_0, the posterior mean E[z0∣zT]\mathbb E[z_0 \mid z_T], which is close to the average of all data; too few first-order steps shrink the samples toward that average. The same setting shows that inversion is approximate even with an exact noise predictor: inverting the point 0.80.8 with DDIM steps and generating back returns 0.420.42 with 10 steps, 0.710.71 with 50 and 0.800.80 with 1000.

DPM-Solver: integrate the known part exactly. In the variable λ=log⁡(αˉ/1−αˉ)=−log⁡σ\lambda = \log\big(\sqrt{\bar\alpha}/\sqrt{1 - \bar\alpha}\big) = -\log\sigma, half the log signal-to-noise ratio, the same exact solution reads zˉs=zˉt−∫λtλse−λ ε^θ(λ) dλ\bar z_s = \bar z_t - \int_{\lambda_t}^{\lambda_s} e^{-\lambda}\,\hat\varepsilon_\theta(\lambda)\,d\lambda (Lu et al., 2022a, Eq. 3.4). DPM-Solver expands ε^θ\hat\varepsilon_\theta in a Taylor series in λ\lambda around the start of each step and integrates the exponential weight exactly. Its first-order version is DDIM (their §4.1); the second- and third-order versions spend two or three network evaluations per step but need far fewer steps. DPM-Solver++ (Lu et al., 2022b) applies the same idea to the predicted clean latent z^0\hat z_0 instead of the noise and uses a multistep second-order update that reuses the evaluation of the previous step. Earlier high-order solvers became unstable at the large guidance scales of text-to-image models, even slower than DDIM; the multistep form reduces the effective step size and keeps them stable.

How many steps. The numbers depend on guidance. Without it, DPM-Solver produces high-quality samples in 10 to 20 network evaluations, with FID 4.70 at 10 and 2.87 at 20 on CIFAR-10 (Lu et al., 2022a). With guidance, Lu et al. (2022b) find that DDIM generally needs 100 to 250 steps to converge, while DPM-Solver++ gives high-quality samples in 15 to 20 steps, for pixel-space and latent-space models alike. On Stable Diffusion with guidance scale 7.5, DPM-Solver++ reaches with 15 to 20 steps the latent error that the default 50-step sampler (PNDM) has; in the same test every solver already gave an FID of about 15 to 16 at 10 steps, because the decoder turns a latent that has not quite converged into a good image (their §7.2). The network does not change; only the update rule between its evaluations does, which is why diffusion libraries let the sampler (the scheduler) be swapped after training.

Editing with the same model#

  • Image-to-image (SDEdit, Meng et al., 2022). Encode an existing image, add noise to an intermediate step, zt=αˉt z0+1−αˉt εz_t = \sqrt{\bar\alpha_t}\, z_0 + \sqrt{1 - \bar\alpha_t}\,\varepsilon, and run the remaining denoising steps with a new prompt. The strength λ∈[0,1]\lambda \in [0, 1] chooses the step: with 40 sampling steps and λ=0.6\lambda = 0.6, the last 24 are run. Low strength keeps the composition; strength 1 ignores the input.
  • Inpainting. To change only a masked region, at every step the latent outside the mask is replaced by the original latent noised to the same step, and only the masked part follows the model: zt−1←(1−m)⊙zt−1orig+m⊙zt−1∗z_{t-1} \leftarrow (1 - m) \odot z^{\text{orig}}_{t-1} + m \odot z^*_{t-1}, where mm is the mask downsampled to the latent grid (1 where the image may change), zt−1orig=αˉt−1 z0+1−αˉt−1 εz^{\text{orig}}_{t-1} = \sqrt{\bar\alpha_{t-1}}\, z_0 + \sqrt{1 - \bar\alpha_{t-1}}\,\varepsilon and zt−1∗z^*_{t-1} is the sampler’s update. With f=8f = 8 the mask is applied on 8×88 \times 8 pixel blocks, so its edge is blended by the decoder rather than followed exactly. Dedicated inpainting models instead receive the mask and the masked image as extra input channels and are trained for the task.
  • LoRA. Fine-tune the attention layers with low-rank updates W+αrBAW + \frac{\alpha}{r} B A (PEFT note) to teach a style or a subject from a small dataset; the update can be fused into the weights for inference. For a d×kd \times k weight it trains r(d+k)r(d + k) numbers instead of dkdk: with d=k=1280d = k = 1280 that is 0.6%0.6\% of the layer for r=4r = 4 and 5%5\% for r=32r = 32.
  • Textual inversion (Gal et al., 2023). Freeze everything and learn only the embedding vv of a new token, such as <S*>, by minimizing the diffusion loss on three to five images of a concept, v∗=arg⁡min⁡vEz0,y,ε,t ∥ε−εθ(zt,t,τ(yv))∥2v^* = \arg\min_v \mathbb E_{z_0, y, \varepsilon, t}\, \lVert \varepsilon - \varepsilon_\theta(z_t, t, \tau(y_v))\rVert^2 (their Eq. 2), where yvy_v is a template prompt such as “a photo of <S*>” with vv in place of the token’s embedding. The token can then be used in any prompt.

What changed#

Pixel-space diffusionLatent diffusion
Space of the diffusionpixels, 512⋅512⋅3512 \cdot 512 \cdot 3latent, 64⋅64⋅464 \cdot 64 \cdot 4
Who removes imperceptible detailthe diffusion model, slowlythe autoencoder, once
Attentiononly at coarse resolutionsaffordable over the whole latent grid
Conditioningpossible, costlycross-attention to a text encoder
Number of steps (set by the sampler, not the space)same samplers: about 1000 for DDPM, about 50 with DDIM in common use (100 to 250 to converge with guidance), 15 to 20 with DPM-Solver++same
Cost of one stepa U-Net pass over 512⋅512⋅3512 \cdot 512 \cdot 3 numbers, twice with guidancea pass over 64⋅64⋅464 \cdot 64 \cdot 4 numbers, twice with guidance, plus one decoder pass per image
Ceiling on detailthe networkthe decoder of the autoencoder

Limitations#

  • The decoder bounds the detail. Fine text, faces at small scale and exact textures depend on what the autoencoder can reconstruct; the diffusion model cannot add what D\mathcal D cannot express.
  • Guidance is a trade-off. Large ss improves prompt adherence and typicality at the cost of diversity and, beyond some value, of image quality.
  • The text encoder limits understanding. A frozen CLIP-like encoder with 77 tokens struggles with counting, spatial relations and long prompts.
  • Still iterative. Tens of network evaluations per image remain, twice that with guidance, and too few steps of a first-order sampler shrink the samples toward their average.
  • Memory. Attention over the latent grid needs memory quadratic in the number of positions; slicing trades speed for memory.
  • Data. The models are trained on large scraped image–text collections, with the questions of consent, copyright and bias that come with them.

Summary#

  • An autoencoder removes perceptual detail once; diffusion runs in its latent, 48 times smaller than the image for Stable Diffusion at 512×512512 \times 512.
  • The autoencoder is trained with reconstruction, perceptual and patch-adversarial losses and a weak KL or VQ regularization; ff between 4 and 16 balances speed and fidelity.
  • Text enters the U-Net through cross-attention: queries from the latent, keys and values from the text encoder. Per-token weights move token vectors away from or toward those of an empty prompt.
  • Classifier-free guidance extrapolates from the unconditional to the conditional prediction. At each noise level this is the score of qt1−s qt(⋅∣y)sq_t^{1-s}\, q_t(\cdot \mid y)^s, but the samples do not in general follow p1−s p(⋅∣y)sp^{1-s}\, p(\cdot \mid y)^s, and DDPM and DDIM sampling end at different distributions; both narrow the distribution toward the prompt.
  • Samplers integrate the probability flow ODE of the same model: DDIM is Euler’s method in (zˉ,σ)(\bar z, \sigma) coordinates, DPM-Solver integrates the linear part exactly and expands the network in λ\lambda; with guidance DPM-Solver++ needs 15 to 20 steps. Image-to-image, inpainting, LoRA and textual inversion reuse the model for editing.

Notebook#

The advanced diffusion notebook of the HSE-LAMBDA Deep Generative Models repository uses the Hugging Face Diffusers library (cell numbers count every cell, markdown included, from 1). It has no saved outputs, so it documents the procedure rather than results.

  • Cells 5–9: a recap of DDPM and the Stable Diffusion pipeline, then text-to-image with stabilityai/stable-diffusion-2-1-base in float32, 25 steps and guidance scale 7.5. enable_attention_slicing() computes attention in slices to lower the peak memory, as described above. The markdown of cell 6 gives the text embedding as 77×76877 \times 768, the size for Stable Diffusion 1.x; the 2.1 model used here has an OpenCLIP encoder with 1024 dimensions.
  • Cells 10–12: schedulers. The ODE in the markdown keeps only the noise term: the probability flow ODE of the variance-preserving process also has a term proportional to ztz_t and a factor 12\frac12. The Euler update is written with added noise, while EulerDiscreteScheduler is deterministic by default (the stochastic variant is EulerAncestralDiscreteScheduler), and DDIM is said to allow parallel sampling, which it does not; it allows fewer steps and an approximate inversion. The markdown and the README give 10–15 steps for DPM-Solver++ and 20–30 for Euler. The DPM-Solver++ paper reports 15 to 20 steps for guided sampling, which is what Stable Diffusion does; about 10 steps is the figure for DPM-Solver without guidance; and the papers give no step count for the Euler sampler. The README lists the DPM-Solver paper, cited above. In cell 11 swap_scheduler replaces the scheduler of the same pipeline object and returns it, so pipe_euler and pipe_dpm are one pipeline: both images of the side-by-side are produced with DPM-Solver++.
  • Cells 13–16: batch generation of three prompts and prompt weighting with Compel: ball-- (weight 0.810.81), ball++ (1.211.21), and ball++ together with forest--- (0.7290.729). The markdown describes the (token:weight) syntax of another tool and a normalized weighted sum of token embeddings; Compel’s syntax is the one used in the code, and its weighting acts on the text-encoder output.
  • Cells 17–20: image-to-image on a 768×768768 \times 768 picture, with strength 0.6 (24 of 40 steps) and 1.0.
  • Cells 21–22: inpainting with the same base checkpoint, 50 steps. Its U-Net has 4 input channels, so the pipeline uses the latent replacement written above rather than the mask-conditioned inpainting models.
  • Cells 23–24: a pixel-art LoRA loaded into Stable Diffusion XL and fused with scale 0.8. The markdown says a LoRA trains about 0.2% of the parameters of SD-XL. The adapter loaded here has rank 32 and 85.1 million parameters, all in the U-Net (from the header of its weight file), about 3.3% of the 2.6 billion parameters of the SD-XL U-Net (Podell et al., 2023); 0.2% would correspond to rank 2. The share depends on the rank and on which layers are adapted.
  • Cells 25–26: textual inversion with a concept token from the sd-concepts-library, loaded into runwayml/stable-diffusion-v1-5. That repository is no longer published under this name; the same weights are at stable-diffusion-v1-5/stable-diffusion-v1-5, to which the Hub API redirects the old id. The markdown gives the textual-inversion objective written above.

Next#

Text, masks and the strength of image-to-image are coarse controls: they say what should appear and roughly where, but not exactly where a given point of the image should end up. The next note, Point-based image editing: DragGAN and DragDiffusion, asks for precise geometric edits of the form “move this point there”: first by optimizing the latent code of a GAN (DragGAN), then by optimizing the noisy latent of a diffusion model (DragDiffusion).

References#