Modelos de difusão DDPM a partir do zero
Type: Build
Languages: Python
Prerequisites: Phase 3 · 02 (Backprop), Phase 8 · 02 (VAE)
Time: ~75 minutes
O problema
Queres uma amostra para ?p_data(x)O que realmente se quer é um objetivo de treinamento que seja (a) uma única perda estável (sem ponto de sela, sem minimax), (b) um limite inferior em log p(x)(de modo que tenha probabilidades), e (c) amostras que correspondam à qualidade do SOTA.
Sohl-Dickstein et al. (2015) teve uma resposta teórica: definir uma cadeia de Markov q(x_t | x_{t-1})que gradualmente adiciona ruído gaussiano, e treinar uma cadeia inversap_θ(x_{t-1} | x_t)Ho, Jain, Abbeel (2020) mostrou que a perda pode ser simplificada para uma linha prever o ruído e limpar a matemática. Em 2020 isso foi uma curiosidade. Em 2021 produziu amostras de última geração. Em 2022 tornou-se Diffusão estável. Em 2026 é o substrato.
O conceito
!DDPM: forward noise, reverse denoise
Forward process q.Adicionar ruído Gaussiano .TA forma fechada a razão pela qual a matemática é tratável é que o passo acumulativo é também gaussiano:
q(x_t | x_0) = N( sqrt(α̅_t) · x_0, (1 - α̅_t) · I )ondeα̅_t = ∏_{s=1..t} (1 - β_s)para um calendário de β_t- Escolha .β_tde 1e-4 a 0,02 linearmente sobre T=1000 passos e x_Té aproximadamente N(0, I)- Não .
Reverse process p_θ.Aprenda uma rede neural .ε_θ(x_t, t)que prevê o ruído que foi adicionado.x_t, denotado por:
x_{t-1} = (1 / sqrt(α_t)) · ( x_t - (β_t / sqrt(1 - α̅_t)) · ε_θ(x_t, t) ) + σ_t · zondeσ_tÉ um dos dois .sqrt(β_t)A expressão é feia, mas é apenas álgebra.x_{t-1}dada a posterior q(x_{t-1} | x_t, x_0)e substituindox_0com a sua estimativa prévia de ruído.
Training loss.
L_simple = E_{x_0, t, ε} [ || ε - ε_θ( sqrt(α̅_t) · x_0 + sqrt(1 - α̅_t) · ε, t ) ||² ]Amostra x_0De dados, escolha um aleatóriot, amostra ε ~ N(0, I), calcular o barulho .x_tUma perda, sem minimos, sem KL, sem truques de reparametrização.
Sampling.Começa .x_T ~ N(0, I)Repita o passo inverso det = T- Não .1- Já está.
Por que funciona
Três intuições:
- Denoising is easy; generating is hard.- Não .
t=TA rede tem de resolver um problema trivial.t=0A rede só tem de limpar alguns pixels.tO problema é difícil, mas a rede tem muitos gradientes fluindo através dos mesmos pesos de todos os níveis de ruído.
- Score matching in disguise.Vincent (2011) provou que prever o ruído é equivalente a estimar
∇_x log q(x_t | x_0)O SDE inverso usa esta pontuação para subir o gradiente de densidade um caminho aleatório guiado em direção a regiões de alta probabilidade.
- The ELBO reduces to simple MSE.O limite inferior variável completo tem um termo KL por etapa de tempo. Com a parâmetrizagem do DDPM, esses termos KL simplificam para MSE na previsão de ruído com coeficientes específicos; Ho caiu os coeficientes (chamando-o de perda "simples") e a qualidade melhorou.
Construí-lo
code/main.pyO "net" é um pequeno MLP que leva(x_t, t)O treinamento é a perda de uma linha.
Passo 1: calendário de execução (formulario fechado)
pythonbetas = [1e-4 + (0.02 - 1e-4) * t / (T - 1) for t in range(T)]
alphas = [1 - b for b in betas]
alpha_bars = []
cum = 1.0
for a in alphas:
cum *= a
alpha_bars.append(cum)Passo 2: amostra x_tem uma só vez
pythondef forward_sample(x0, t, alpha_bars, rng):
a_bar = alpha_bars[t]
eps = rng.gauss(0, 1)
x_t = math.sqrt(a_bar) * x0 + math.sqrt(1 - a_bar) * eps
return x_t, epsPasso 3: um passo de formação
pythondef train_step(x0, model, alpha_bars, rng):
t = rng.randrange(T)
x_t, eps = forward_sample(x0, t, alpha_bars, rng)
eps_hat = model_forward(model, x_t, t)
loss = (eps - eps_hat) ** 2
return loss, gradient_step(model, ...)Passo 4: amostragem inversa
pythondef sample(model, alpha_bars, T, rng):
x = rng.gauss(0, 1)
for t in range(T - 1, -1, -1):
eps_hat = model_forward(model, x, t)
beta_t = 1 - alphas[t]
x = (x - beta_t / math.sqrt(1 - alpha_bars[t]) * eps_hat) / math.sqrt(alphas[t])
if t > 0:
x += math.sqrt(beta_t) * rng.gauss(0, 1)
return xPara um problema 1-D com 40 passos de tempo e um MLP de 24 unidades, este aprende a mistura de dois modos em ~ 200 épocas.
Condicionamento de tempo
A rede precisa saber qual é o passo a seguir.
- Sinusoidal embedding.Como codificação posicional do Transformer.
embed(t) = [sin(t/ω_0), cos(t/ω_0), sin(t/ω_1), ...]Passa por um MLP, transmite-se à rede. - Film / group-norm conditioning.Projecto de inserção em escala/bias por canal (FiLM) em cada bloco.
Nosso código de brinquedo usa sinusoidal → concat.
Encurralagens
- Schedule matters a lot.Linear
βO programa de cálculo é o DDPM padrão, mas o cronograma cosínico (Nichol & Dhariwal, 2021) dá uma melhor FID para a mesma computação. - Timestep embedding is fragile.Passando cru
tcomo um float funciona para brinquedo 1-D mas falha para imagens; sempre use um incorporado adequado. - V-prediction vs ε-prediction.Para regimes estreitos (t muito pequenos ou muito grandes),
ε- a previsão de V (v = α·ε - σ·x) é mais estável; SDXL, SD3 e Flux utilizam-na. - Classifier-free guidance.Na inferência, calcular as condições e as incondições.
ε, entãoε_cfg = (1 + w) · ε_cond - w · ε_uncondcomw ≈ 3-7- Coberto na lição 8. - 1000 steps is a lot.A produção utiliza DDIM (20-50 passos), DPM-Solver (10-20 passos) ou destilação (1-4 passos).
Usá-lo
| Role | Typical stack in 2026 |
|---|---|
| Image pixel-space diffusion (small, toy) | DDPM + U-Net |
| Image latent diffusion | VAE encoder + U-Net or DiT (Lesson 07) |
| Video latent diffusion | Spatiotemporal DiT (Sora, Veo, WAN) |
| Audio latent diffusion | Encodec + diffusion transformer |
| Science (molecules, proteins, physics) | Equivariant diffusion (EDM, RFdiffusion, AlphaFold3) |
A difusão é a espinha dorsal generativa universal. A combinação de fluxos (Lessão 13) é o concorrente 2024-2026, que geralmente ganha na velocidade de inferência pela mesma qualidade.
Envia-o
Salvaroutputs/skill-diffusion-trainer.md. A competência assume um conjunto de dados + orçamento e resultados de cálculo: cronograma (linear/cosino/sigmoide), meta de previsão (ε/v/x), número de etapas, escala de orientação, família de amostragens e um protocolo de avaliação.
Exercícios
- Easy.Mudança de T de 40 para 10 em
code/main.pyComo a qualidade da amostra (histograma visual das saídas) se degrada? - Medium.Passe da previsão ε para a previsão v. Retrai a passagem inversa. Comparar a qualidade final da amostra.
- Hard.Adicionar orientação sem classificador. Condição em um rótulo de classe
c ∈ {0, 1}, diminuir 10% do tempo durante o treinamento e no tempo de amostragem de usoε = (1+w)·ε_cond - w·ε_uncond. Medir a taxa de acidentes no modo condicional emw = 0, 1, 3, 7- Não .
Termos-chave
| Term | What people say | What it actually means |
|---|---|---|
| Forward process | "Adding noise" | Fixed Markov chain q(x_t | x_{t-1}) that destroys the data. |
| Reverse process | "Denoising" | Learned chain p_θ(x_{t-1} | x_t) that reconstructs the data. |
| β schedule | "The noise ladder" | Per-step variance; linear, cosine, or sigmoid. |
| α̅ | "Alpha bar" | Cumulative product ∏(1 - β); gives closed-form x_t from x_0. |
| Simple loss | "MSE on noise" | ||ε - ε_θ(x_t, t)||²; all variational derivations collapse to this. |
| ε-prediction | "Predict noise" | Output is the noise added; standard DDPM. |
| V-prediction | "Predict velocity" | Output is α·ε - σ·x; better conditioning across t. |
| DDPM | "The paper" | Ho et al. 2020; linear β, 1000 steps, U-Net. |
| DDIM | "Deterministic sampler" | Non-Markov sampler, 20-50 steps, same training objective. |
| Classifier-free guidance | "CFG" | Mix conditional and unconditional noise predictions to amplify conditioning. |
Nota de produção: a inferência de difusão é um problema de contagem de etapas
O documento DDPM executar T=1000 passos reversa. Ninguém envia isso na produção. Cada pilha de inferência real escolhe uma das três estratégias e cada mapa limpo para enquadramento de produção de "de onde vem a latência":
- Faster sampler, same model.DDIM (20-50 passos), DPM-Solver++ (10-20), UniPC (8-16). Substituição de drop-in do loop inverso; o treinado
ε_θOs pesos são intocados, reduz a latência 20 a 50 vezes. - Distillation.Treinar um aluno para se adequar ao professor em menos passos: Distilação Progressiva (2 → 1), Modelos de Consistência (arbitrário → 1-4), LCM, SDXL-Turbo, SD3-Turbo. Cortar a latência mais 5-10x, requer reformulação.
- Caching and compilation.
torch.compile(unet, mode="reduce-overhead"), os retrospectivos de difusão do TensorRT-LLM,xformers/SDPA atenção, bf16 pesos. Cortes por etapa latência ~ 2×.
Para um servidor de difusão de produção, a conversação orçamental é a mesma que a literatura de produção descreve para os LLM: a latência é num_steps × step_cost + VAE_decode, o volume é batch_size × (num_steps × step_cost)^-1. O TTFT é pequeno (um passo); o TPOT é equivalente ao tempo de resposta total porque a geração de imagens é "todo ao mesmo tempo" da perspectiva do utilizador.
Mais leitura
- Sohl-Dickstein et al. (2015). Deep Unsupervised Learning using Nonequilibrium Thermodynamics o papel de difusão, antes do seu tempo.
- Ho, Jain, Abbeel (2020). Denoising Diffusion Probabilistic Models DDPM.
- Song, Meng, Ermon (2021). Denoising Diffusion Implicit Models- DDIM, menos passos.
- Nichol & Dhariwal (2021). Improved DDPM- Calendário cosínico, variação aprendida.
- Dhariwal & Nichol (2021). Diffusion Models Beat GANs on Image Synthesis Orientações para o classificador.
- Ho & Salimans (2022). Classifier-Free Diffusion Guidance- CFG.
- Karras et al. (2022). Elucidating the Design Space of Diffusion-Based Generative Models (EDM)- Notação unificada, receita mais limpa.
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.