Autodécodateurs et Autodécodateurs variatifs (VAE)
z = μ + σ·εC'est pourquoi chaque modèle d'image de diffusion latente et de correspondance de flux que vous utilisez en 2026 a un VAE à l'entrée.Type: Build
Languages: Python
Prerequisites: Phase 3 · 02 (Backprop), Phase 3 · 07 (CNNs), Phase 8 · 01 (Taxonomy)
Time: ~75 minutes
Le problème
Comprimez un chiffre MNIST de 784 pixels à un code à 16 chiffres, puis reconstruisez. Un autoencodeur simple fera une reconstruction MSE mais l'espace code est un gâchis. Choisissez un point aléatoire dans l'espace code, décodez-le, et vous obtenez du bruit. Il n'a pas de échantillonneur. C'est un modèle de compression habillé.
Ce que vous voulez vraiment, c'est: (a) l'espace de code est une distribution propre et lisse que vous pouvez échantillonner à partir d'un Gaussian isotropeN(0, I)Le codeur et le décodeur comprennent toujours bien. Trois objectifs, une architecture, une perte.
Le VAE 2013 de Kingma résout cette question en formant le codeur à produire une distribution q(z|x) = N(μ(x), σ(x)²), tirant cette distribution vers le priorN(0, I)par une pénalité KL, puis le prélèvement zde q(z|x)Avant de décoder, au moment de l'inférence, laissez tomber le codeur, échantillon z ~ N(0, I)La pénalité KL est ce qui oblige l'espace de code à être structuré.
En 2026, les VAE sont rarement livrés indépendamment ils ont été dépassés par la diffusion pour la qualité d'image brute mais ils sont le codeur de choix pour chaque modèle de diffusion latente (SD 1/2/XL/3, Flux, AudioCraft).
Le concept
!Autoencoder vs VAE: the reparameterization trick
Autoencoder. z = encoder(x)- Je suis là .x̂ = decoder(z), perte = ||x - x̂||²- L'espace de code est non structuré.
VAE encoder.Les sorties sont de deux vecteurs: μ(x)et log σ²(x)- Ils définissent ...q(z|x) = N(μ, diag(σ²))- Je suis désolé .
Reparameterization trick.Prise d' échantillons à partir de q(z|x)L'échantillon est réécrit comme z = μ + σ·εoù ε ~ N(0, I)- Maintenant .zest une fonction déterministe de (μ, σ)+ un bruit non paramétrique des gradients circulent μet σ- Je suis désolé .
Loss.Les preuves de la base de la base (ELBO), deux termes:
loss = reconstruction + β · KL[q(z|x) || N(0, I)]
= ||x - x̂||² + β · Σ_i ( σ_i² + μ_i² - log σ_i² - 1 ) / 2La reconstruction est en train de pousser x̂vers lex- KL pousse .q(z|x)Les données de base de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l'échantillon de l
Sampling.À l' inférence: tirage au sort z ~ N(0, I)Un passage en avant, pas d'échantillonnage itératif comme la diffusion.
Faites-le
code/main.pyIl est utilisé pour la mise en œuvre d'un petit VAE sans numpy ou torche. L'entrée est des données synthétiques 8 dimensions tirées d'un mélange gaussien à 2 composants en 8D. L'encodeur et le décodeur sont des MLP à couche cachée unique.
Étape 1: encodeur vers l'avant
pythondef encode(x, enc):
h = tanh(add(matmul(enc["W1"], x), enc["b1"]))
mu = add(matmul(enc["W_mu"], h), enc["b_mu"])
log_sigma2 = add(matmul(enc["W_sig"], h), enc["b_sig"])
return mu, log_sigma2log σ²Au lieu de σAinsi, la sortie du réseau est libre (softplus de σ est un piège gradients meurent à σ ≈ 0).
Étape 2: réparamétrifier et décoder
pythondef reparameterize(mu, log_sigma2, rng):
eps = [rng.gauss(0, 1) for _ in mu]
sigma = [math.exp(0.5 * lv) for lv in log_sigma2]
return [m + s * e for m, s, e in zip(mu, sigma, eps)]
def decode(z, dec):
h = tanh(add(matmul(dec["W1"], z), dec["b1"]))
return add(matmul(dec["W_out"], h), dec["b_out"])Étape 3: l'ELBO
pythondef elbo(x, x_hat, mu, log_sigma2, beta=1.0):
recon = sum((a - b) ** 2 for a, b in zip(x, x_hat))
kl = 0.5 * sum(math.exp(lv) + m * m - lv - 1 for m, lv in zip(mu, log_sigma2))
return recon + beta * kl, recon, klIl est vrai que les deux distributions sont gaussiennes, mais ne sont pas intégrées numériquement.
Étape 4: générer
pythondef sample(dec, z_dim, rng):
z = [rng.gauss(0, 1) for _ in range(z_dim)]
return decode(z, dec)C'est le modèle génératif.
Les pièges
- Posterior collapse.Les lecteurs à terme KL
q(z|x) → N(0, I)si agressivement quezne contient aucune information surx. Réparation: β-annulation (début β=0, rampe à 1), bits libres, ou sauter le KL sur les dimensions inactives. - Blurry samples.La probabilité du décodeur gaussien implique la reconstruction de l'ESM, qui est Bayes-optimale pour L2 (la moyenne) la moyenne d'un ensemble de chiffres plausibles est un chiffre flou. Fix: décodeur discrète (VQ-VAE, NVAE), ou utiliser le VAE uniquement comme un encodeur et diffusion en pile sur les latents (c'est ce que fait Stable Diffusion).
- β too large, too early.Voir l'effondrement postérieur.
- Latent dim too small.Le 16D fonctionne pour le MNIST, le 256-D pour l'ImageNet 2562, le 2048-D pour l'ImageNet 10242.
Utilisez-le
Le groupe VAE 2026:
| Situation | Pick |
|---|---|
| Image-latent encoder for diffusion | Stable Diffusion VAE (sd-vae-ft-ema) or Flux VAE |
| Audio-latent encoder | Encodec (Meta), SoundStream, or DAC (Descript) |
| Video latents | Sora's spatiotemporal patches, Latte VAE, WAN VAE |
| Disentangled representation learning | β-VAE, FactorVAE, TCVAE |
| Discrete latents (for transformer modelling) | VQ-VAE, RVQ (ResidualVQ) |
| Continuous latents for generation | Plain VAE, then condition a flow/diffusion model in that latent space |
Un modèle de diffusion latente est un modèle de diffusion VAE avec un modèle de diffusion vivant entre un encodeur et un décodeur. Le modèle de diffusion fait la compression grossière, le modèle de diffusion fait le travail lourd.
La faire partir
- Ça va .
outputs/skill-vae-trainer.md- Je suis désolé .
Les compétences requises: profil de l'ensemble de données + cible latente-dim + utilisation en aval (reconstruction, échantillonnage ou entrée de diffusion latente) et les résultats: choix d'architecture (plain/β/VQ/RVQ), horaire β, latente dim, probabilité de décoder (Gaussian vs catégorique), et plan d'évaluation (recon MSE, KL par dim, distance Fréchet entre q(z|x)et N(0, I))
Exercices
- Easy.Le changement
βdanscode/main.pyà0.01- Je suis là .0.1- Je suis là .1.0- Je suis là .5.0Enregistrer la reconstruction finale de MSE et KL. Quel β est le meilleur pareto pour vos données synthétiques ? - Medium.Remplacez la probabilité du décodeur gaussien par une probabilité de Bernoulli (perte de croisée entropie).
- Hard.Extension
code/main.pyen mini VQ-VAE: remplacez le continuzComparer la reconstruction MSE et indiquer le nombre d'entrées utilisées (l'effondrement du codebook est réel).
Les termes clés
| Term | What people say | What it actually means |
|---|---|---|
| Autoencoder | Encode-decode network | x → z → x̂, learn MSE. Not generative. |
| VAE | AE with a sampler | Encoder outputs a distribution, KL penalty shapes code space. |
| ELBO | Evidence lower bound | log p(x) ≥ recon - KL[q(z|x) || p(z)]; tight when q = p(z|x). |
| Reparameterization | z = μ + σ·ε | Rewrites stochastic node as deterministic + pure noise. Enables backprop through sampling. |
| Prior | p(z) | Target distribution for the latent, typically N(0, I). |
| Posterior collapse | "KL term wins" | Encoder ignores x, outputs the prior; decoder must hallucinate. |
| β-VAE | Tunable KL weight | loss = recon + β·KL. Higher β = more disentangled but blurrier. |
| VQ-VAE | Discrete latent | Replace continuous z with nearest codebook vector; enables transformer modelling. |
Note de production: le VAE est le chemin le plus chaud dans un serveur de diffusion
Dans un pipeline Stable Diffusion / Flux / SD3, le VAE est appelé deux fois par demande une fois pour encoder (si vous faites img2img / inpainting) et une fois pour décoder.128×128×16Les latents sont de retour à 1024×1024×3- Deux conséquences pratiques:
- Slice or tile the decode.
diffusersexposéspipe.vae.enable_slicing()etpipe.vae.enable_tiling()- Le Tiling négocie un petit artefact de couture pourO(tile²)mémoire au lieu deO(H·W)- Essentiel pour 10242+ sur les GPU de consommation. - bf16 decoder, fp32 numerics for the final resize.Le SD 1.x VAE a été libéré en fp32 et produit silencieusement des NaNs lorsqu'il est jeté à fp16 à 10242+.
madebyollin/sdxl-vae-fp16-fixpréférer toujours la variante fp16-fix ou utiliser bf16.
Pour en savoir plus
- Kingma & Welling (2013). Auto-Encoding Variational Bayes le papier de l'AEV.
- Higgins et al. (2017). β-VAE: Learning Basic Visual Concepts with a Constrained Variational Framework β-VAE démêlé.
- van den Oord et al. (2017). Neural Discrete Representation Learning VQ-VAE.
- Vahdat & Kautz (2021). NVAE: A Deep Hierarchical Variational Autoencoder l'image de pointe de l'AEV.
- Rombach et al. (2022). High-Resolution Image Synthesis with Latent Diffusion Models Diffusion stable; VAE en tant qu'encodeur.
- Défossez et al. (2022). High Fidelity Neural Audio Compression Encodec, la norme audio VAE.
This free lesson is part of the AI Engineering from Scratch curriculum. Read the full explanation, run the lesson code, and verify the result in the interactive reader or from the repository source.
Browse the complete course catalog or open this lesson on GitHub.