Module 6 — Modèles de diffusion : bruiter puis débruiter
Les modèles de diffusion ont détrôné les GAN sur la génération d'images entre 2020 et 2022. Leur idée fondatrice est étonnamment simple : au lieu d'apprendre à générer une image en un coup, on apprend à retirer un petit peu de bruit à chaque étape, et on répète. La difficulté n'est plus l'entraînement (stable) mais l'échantillonnage (coûteux), et toutes les avancées récentes visent à l'accélérer.
Deux processus, l'un connu, l'autre à apprendre
Le processus avant ajoute du bruit gaussien à une image en étapes ( typiquement) :
Les forment un planning croissant de à typiquement. Après pas, est indiscernable d'un bruit gaussien pur . Une propriété clé rend le processus utilisable : on peut tirer directement depuis sans passer par les pas intermédiaires, grâce à :
Le processus arrière est celui qu'on apprend. Il essaie d'estimer , qui n'a pas de forme close en général. La distribution vraie est intractable ; on la remplace par une gaussienne dont on apprend la moyenne, avec une variance fixée (ou apprise à part).
Ce que le réseau prédit vraiment
Voici le point qui simplifie tout et qui est à retenir. Plutôt que de prédire ou , on entraîne un réseau à prédire le bruit ajouté au pas . C'est la formulation DDPM (Ho, 2020).
La perte prend une forme remarquablement simple, sans terme KL et sans variance :
En pseudo-code, une itération d'entraînement tient en cinq lignes :
import torch
import torch.nn.functional as F
def perte_diffusion(modele, x0, alphas_barre, T):
t = torch.randint(0, T, (x0.size(0),), device=x0.device)
eps = torch.randn_like(x0)
a = alphas_barre[t].view(-1, 1, 1, 1)
x_t = a.sqrt() * x0 + (1 - a).sqrt() * eps
eps_pred = modele(x_t, t)
return F.mse_loss(eps_pred, eps)
Trois lignes de vérité importantes :
- Le réseau ne voit jamais l'image propre pendant l'entraînement : il ne voit que et le pas , et cherche à retrouver le bruit.
- La perte est une MSE, la plus stable qu'on connaisse en deep learning ; c'est pourquoi les modèles de diffusion s'entraînent beaucoup plus tranquillement que les GAN.
- L'ELBO théorique se simplifie à ce terme au prix d'une repondération implicite qui donne plus d'importance aux pas intermédiaires ; c'est un choix de Ho (2020) qui a mieux marché en pratique que la version pondérée par la vraie borne.
Le U-Net et le conditionnement par le pas de temps
L'architecture standard pour est un U-Net avec des connexions de saut entre l'encodeur et le décodeur, des blocs résiduels, et souvent des couches d'attention aux résolutions basses. Ce qu'il faut ajouter par rapport au U-Net de segmentation : injecter l'information du pas à chaque bloc.
La méthode standard suit trois étapes. On construit un plongement sinusoïdal de (comme le positional encoding des transformers), on le passe dans deux couches denses pour produire un vecteur, puis on l'ajoute (ou on module) les activations des blocs résiduels. Sans ce conditionnement, le réseau ne sait pas quel niveau de bruit il doit retirer, et il échoue à couvrir la trajectoire.
def plongement_sinusoidal(t, dim):
demi = dim // 2
freqs = torch.exp(-torch.arange(demi, device=t.device) * (10.0 / demi))
angles = t.float().unsqueeze(1) * freqs.unsqueeze(0)
return torch.cat([angles.sin(), angles.cos()], dim=-1)
Échantillonner : DDPM contre DDIM
Générer une image consiste à partir de et à appliquer pas de débruitage. La procédure DDPM est stochastique : chaque pas ré-injecte un peu de bruit.
Le problème est la lenteur : 1000 passes avant du réseau pour une seule image. C'est là que DDIM (Song, 2021) intervient. En remarquant que l'équation d'échantillonnage peut être déterministe (), on peut sauter des pas et n'en garder que 20 à 50 sans perte majeure de qualité.
| Échantillonneur | Nb de pas typique | Stochastique | Reproductible |
|---|---|---|---|
| DDPM | 1000 | oui | non pour un même |
| DDIM | 20-50 | non | oui pour un même |
| DPM-Solver, UniPC | 10-20 | non | oui |
Les échantillonneurs modernes (DPM-Solver 2024, UniPC) descendent jusqu'à une dizaine de pas avec des images encore convaincantes, en interprétant la diffusion comme une équation différentielle stochastique dont on cherche une meilleure intégration numérique.
Pour comparer deux modèles de diffusion ou deux échantillonneurs, fixez torch.manual_seed(...) et tirez le même pour les deux. Sans cela, la variance des images générées écrase les différences réelles. Sur DDIM avec la même graine, deux entraînements devraient produire des images visuellement proches, ce qui rend les régressions faciles à voir.
Diffusion latente : le passage à l'échelle
Faire tourner une diffusion pixel par pixel sur des images en est prohibitif. La diffusion latente (Rombach, 2022, à la base de Stable Diffusion) coupe le problème en deux :
- Un autoencodeur (module 2, cette fois convolutif) compresse l'image en une carte latente 8 fois plus petite, par exemple .
- La diffusion s'apprend et s'échantillonne dans cet espace latent, pas dans l'espace pixel.
- Le décodeur de l'autoencodeur reconstruit l'image finale à partir du latent débruité.
Le gain de calcul est spectaculaire — deux ordres de grandeur — et la qualité perceptuelle reste comparable parce que l'autoencodeur préserve la structure sémantique. Cette architecture est le socle sur lequel repose presque toute la génération d'images de production actuelle, et c'est elle que le module suivant va conditionner par du texte.
En résumé
- Un modèle de diffusion apprend à débruiter par petits pas ; le processus avant est fixé, seul le processus arrière est appris via un U-Net conditionné par le pas .
- L'objectif se réduit à une MSE sur le bruit prédit , ce qui explique la stabilité de l'entraînement comparée aux GAN.
- L'échantillonnage DDPM est stochastique et lent (1000 pas) ; DDIM le rend déterministe et supporte 20-50 pas sans perte majeure.
- La diffusion latente déplace le processus dans l'espace comprimé d'un autoencodeur, réduit le coût de deux ordres de grandeur et sert de socle à Stable Diffusion.
Module suivant : conditionner la génération par du texte pour passer de « générer une image » à « générer l'image décrite par une consigne ».