Phase 08: Generative AI

Modelos de difusão DDPM a partir do zero

Ho, Jain, Abbeel (2020) deu ao campo uma receita que não podia parar. Destruir os dados com ruído em mil pequenos passos. Treinar uma rede neural para prever o ruído. Reverte o processo à inferência. Hoje todo modelo de imagem, vídeo, 3D e música da corrente dominante funciona neste loop, possivelmente com a combinação de fluxo ou truques de consistência no topo.

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 · z

ondeσ_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:

  1. 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.
  1. 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.
  1. 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, eps

Passo 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 x

Para 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 crutcomo 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

RoleTypical stack in 2026
Image pixel-space diffusion (small, toy)DDPM + U-Net
Image latent diffusionVAE encoder + U-Net or DiT (Lesson 07)
Video latent diffusionSpatiotemporal DiT (Sora, Veo, WAN)
Audio latent diffusionEncodec + 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

  1. Easy.Mudança de T de 40 para 10 em code/main.pyComo a qualidade da amostra (histograma visual das saídas) se degrada?
  2. Medium.Passe da previsão ε para a previsão v. Retrai a passagem inversa. Comparar a qualidade final da amostra.
  3. 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 em w = 0, 1, 3, 7- Não .

Termos-chave

TermWhat people sayWhat 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":

  1. 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.
  2. 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.
  3. 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

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.