Ir para o conteúdo

20. Stable Diffusion

Os capítulos 16 a 19 montaram as peças. Neste capítulo elas viram um sistema que dá para rodar.

O Stable Diffusion4 não é uma ideia; são quatro, empilhadas. A pilha é o que fez a geração de imagens sair de uma demonstração de pesquisa que exigia um cluster para algo que roda num laptop:

  1. Um processo de difusão que transforma geração numa longa sequência de problemas fáceis de remoção de ruído.
  2. Um espaço latente, vindo de um VAE, para que essa sequência rode num espaço 48× menor que os pixels.
  3. Um encoder de texto, vindo do CLIP, para que se possa dizer ao processo o que fazer.
  4. Classifier-free guidance, para que ele de fato obedeça.

Os três primeiros aparecem na maioria das explicações. O quarto costuma ser pulado e é ele que transforma um modelo que tecnicamente se condiciona em texto num que obedece a um prompt.

Slides

Clique nos slides e use as setas ← → para navegar; F abre em tela cheia e P abre a visão do apresentador, com as notas. Os três simuladores desta página, além de três dos seus diagramas, rodam dentro dos slides. Abrir os slides numa aba nova


Modelos de Difusão

Modelos de difusão são treinados para prever um jeito de tirar um pouco de ruído de uma amostra a cada passo; depois de iterações suficientes, um resultado aparece. A ideia vem de 20151; desde então a mesma maquinaria já foi aplicada a imagens, fala, formas 3D, moléculas e grafos.

  • Difusão direta


    Leva dados a ruído perturbando-os aos poucos — um processo estocástico fixo, sem nada aprendido, que transforma uma amostra de dados em versões progressivamente mais ruidosas com um núcleo gaussiano.

    Este processo é usado apenas no treino, nunca na inferência.

  • Difusão reversa


    Desfaz aquilo, um pequeno passo por vez. Esta é a parte que se aprende e é o que transforma ruído aleatório em dados na inferência.

As duas cadeias percorrem os mesmos quadros. Avance passo a passo ou passe o mouse sobre um quadro para ver as suas setas; as equações das próximas seções são as que as legendas usam.

As duas cadeias de um modelo de difusão sobre os mesmos quatro quadros: x0, x t−1, x t e x T. Na direta (em cima), um processo fixo acrescenta ruído passo a passo e um único salto leva de x0 a x t. Entre as linhas, o passo reverso verdadeiro q(x t−1 | x t) está riscado: é intratável. Na reversa (embaixo), uma U-Net prevê o ruído e leva x t de volta a x t−1; a amostragem repete esse passo T vezes a partir de ruído novo. DIRETA · FIXA · ACRESCENTA RUÍDO REVERSA · APRENDIDA · REMOVE RUÍDO ⋯ q(xt​ | xt−1​) ⋯ um salto: xt​ = √ᾱt​ x0​ + √(1 − ᾱt) ε q(xt−1​ | xt) é desconhecido: exige todas as imagens ⋯ ⋯ amostragem: comece de ruído novo e aplique o passo aprendido T vezes x0​ xt−1​ xt​ xT​ x0​ xt−1​ xt​ xT​ pθ(xt−1​ | xt)U-Netεθ(xt​, t)

Difusão direta

Uma amostra \(x_0\) é corrompida com ruído gaussiano ao longo dos passos \(t = 1 \ldots T\):

\[ q(x_t \mid x_{t-1}) = \mathcal{N}\big(x_t;\, \sqrt{1 - \beta_t}\,x_{t-1},\; \beta_t I\big) \]

onde \(\mathcal{N}(x;\, m,\, \Sigma)\) é a densidade gaussiana de \(x\) com média \(m\) e covariância \(\Sigma\), \(I\) é a identidade (ruído independente em cada pixel) e \(\beta_t\), um número pequeno que cresce com \(t\), é o cronograma de ruído. \(T = 1000\) no DDPM e no Stable Diffusion. Escrito assim parece um laço e seria inútil se fosse um. O passo que torna a difusão treinável é que a composição de todas aquelas gaussianas é ela própria gaussiana, de modo que qualquer nível de ruído é alcançado em forma fechada:

\[ x_t = \sqrt{\bar\alpha_t}\, x_0 + \sqrt{1 - \bar\alpha_t}\, \epsilon, \qquad \bar\alpha_t = \prod_{s=1}^{t}(1 - \beta_s), \quad \epsilon \sim \mathcal{N}(0, I) \]

Sorteie um \(t\) aleatório, salte direto para lá e treine. Sem simular a cadeia, sem dependência sequencial entre exemplos de treino.

O objetivo de treino cabe numa linha

Dado isso, o que a rede deve prever? A resposta elegante e a que o DDPM2 adotou: preveja o ruído que foi acrescentado.

\[ \mathcal{L} = \mathbb{E}_{x_0,\,\epsilon,\,t} \Big[\big\| \epsilon - \epsilon_\theta(x_t, t, c) \big\|^2\Big] \]

É só isso. Um erro quadrático médio entre dois vetores, em que o alvo é uma amostra de ruído gaussiano que você mesmo sorteou. \(\epsilon_\theta\) é a rede (a U-Net), \(\theta\) são os seus pesos e \(c\) é o condicionamento (o texto, no Stable Diffusion); a média percorre imagens de treino \(x_0\), ruídos \(\epsilon\) e passos \(t\) sorteados uniformemente de 1 a \(T\). É regressão supervisionada comum, que é precisamente o que uma GAN (capítulo 18) não tem. É também a principal razão de a difusão tê-la deslocado: não há adversário, então o treino é estável e a perda é um sinal de progresso que significa alguma coisa.

Prever ruído, prever a imagem e prever velocidade

Previsão de \(\epsilon\), de \(x_0\) e de \(\mathbf{v}\), com \(\mathbf{v} = \sqrt{\bar\alpha_t}\,\epsilon - \sqrt{1-\bar\alpha_t}\,x_0\), são algebricamente intercambiáveis — dado \(x_t\) e o cronograma, qualquer uma dá as outras. Elas diferem apenas em como a perda é ponderada entre níveis de ruído e essa ponderação importa: recuperar \(x_0\) a partir de um \(\epsilon\) previsto divide por \(\sqrt{\bar\alpha_t}\), que é quase zero perto de \(t = T\): a previsão de \(\epsilon\) é menos confiável justamente onde a imagem é decidida. É por isso que o modelo de 768 px do SD 2 passou para a previsão de \(\mathbf{v}\) e que o SD3 e o FLUX preveem uma velocidade. Veja também o capítulo 21, onde o mesmo objeto reaparece como campo de velocidade.

Difusão reversa

Amostrar roda o processo de trás para frente:

\[ p_\theta(x_{t-1} \mid x_t) = \mathcal{N}\big(x_{t-1};\, \mu_\theta(x_t, t),\, \Sigma_\theta(x_t, t)\big) \]

\(\mu_\theta\) e \(\Sigma_\theta\) são a média e a covariância de cada passo para trás; o DDPM fixa a covariância em \(\beta_t I\) e só aprende a média. (O texto \(c\) fica fora de \(\mu_\theta\) e de \(\Sigma_\theta\) para encurtar a notação.) Não podemos usar o verdadeiro \(q(x_{t-1} \mid x_t)\) — ele depende da distribuição dos dados e é intratável. A rede o aproxima e a U-Net13 é a arquitetura usual porque remover ruído exige tanto detalhe fino quanto estrutura global, que é exatamente o que um encoder–decoder com conexões de atalho oferece.

A previsão do ruído é tudo de que um passo precisa. Inverter a forma fechada dá o palpite atual da rede para a amostra limpa e a média do DDPM dá um pequeno passo de \(x_t\) na direção dele:

\[ \begin{aligned} \hat x_0 &= \frac{x_t - \sqrt{1-\bar\alpha_t}\,\epsilon_\theta(x_t, t, c)}{\sqrt{\bar\alpha_t}} \\ \mu_\theta(x_t, t) &= \frac{1}{\sqrt{1-\beta_t}}\Big(x_t - \frac{\beta_t}{\sqrt{1-\bar\alpha_t}}\,\epsilon_\theta(x_t, t, c)\Big) \end{aligned} \]

Vale olhar para \(\hat x_0\): no começo da amostragem ele é uma média borrada de tudo o que o prompt permite e fica mais nítido passo a passo. O laboratório o decodifica a cada passo e o Diffusion Explainer mais abaixo mostra a mesma progressão.

Treino e amostragem, lado a lado

A mesma rede roda em dois laços de formatos bem diferentes. No treino, a cada passo: escolha um \(t\) aleatório para cada imagem, salte para aquele nível de ruído com a forma fechada acima, gere o embedding de \(t\) e regrida o ruído. Na amostragem: comece do ruído e chame a rede \(T\) vezes seguidas, cada chamada recebendo a saída da anterior.

Treino e amostragem compartilham uma U-Net. À esquerda, o treino: um lote em que cada imagem sorteia o seu t, um salto até x t em forma fechada e uma perda entre o ruído sorteado e o previsto, que atualiza os pesos. À direita, a amostragem: comece do ruído x T, dê um passo para trás com o ruído previsto e repita T vezes até x0. TREINO · UMA PASSAGEM POR IMAGEM AMOSTRAGEM · T PASSAGENS, EM ORDEM ε εθ​ atualiza θ εθ​ × T t = 1: fim Um lote: cada imagem sorteia o seu t t = 14 t = 350 t = 721 Salto para aquele nível de ruído=√ᾱt​+√(1−ᾱt)xt​x0​ε Perda: ‖ε − εθ(xt​, t)‖²um passo de gradiente; depois, o próximo lote U-Net εθ(xt​, t)θ Início: xT​ ~ 𝒩(0, I), t = Truído sorteado pela semente Um passo para trásxt−1​ = μθ(xt​, t) + σt​ zμθ​ remove uma parte, em escala, de εθ​σt​ z: ruído novo no DDPM; 0 no DDIM Depois do último passo: x0​uma imagem nova

O cronograma de ruído não é um detalhe

O \(\beta_t\) decide quanto sinal sobrevive em cada \(t\) e portanto no que o modelo gasta seu orçamento de treino. Dois bugs bem conhecidos moram nessa única função.

SNR terminal. O Stable Diffusion 1.x usa um cronograma linear escalado cujo \(\bar\alpha_T \approx 0{,}0047\) — não zero. O treino, portanto, sempre deixa um traço tênue da imagem real no último passo (\(\sqrt{\bar\alpha_T} \approx 0{,}068\) dela), enquanto a amostragem começa de ruído de verdade. O descompasso tem consequência famosa: o SD 1.x não consegue produzir uma imagem realmente preta ou realmente branca, porque o brilho médio do conjunto de treino vaza para o primeiro passo23. Reescalar o cronograma para SNR terminal zero resolve.

Resolução. Um nível de ruído não significa a mesma coisa em 512 px e em 1024 px: mais pixels significa mais redundância, então o mesmo \(\bar\alpha\) destrói proporcionalmente menos informação. Reaproveitar um cronograma de 512 px em resolução maior ruidifica de menos, nunca se pede ao modelo que resolva a parte formadora de estrutura e a saída parece uma repetição ladrilhada de uma imagem menor. O SD3 torna a correção explícita como um deslocamento de timestep dependente da resolução24.

Difusão latente: a ideia que a tornou acessível

Rodar difusão sobre \(512 \times 512 \times 3 = 786{.}432\) números significa uma passagem inteira da U-Net nessa resolução em cada um dos cinquenta passos — caro o bastante para que sistemas no espaço de pixels como o Imagen e o DALL·E 2 gerem em 64 × 64 e depois ampliem numa cascata. A difusão latente4 move o processo inteiro para o espaço latente de um VAE (o autoencoder do capítulo 17):

Pixels Latente do SD 1.5
Formato \(512\times512\times3\) \(64\times64\times4\)
Números 786.432 16.384
— 48× menos, em cada um dos 50 passos

O fator 48 é \(8 \times 8\) (cada lado encolhe 8×) vezes \(3/4\) (três canais de cor viram quatro canais latentes). A divisão é o ponto: o autoencoder cuida do detalhe perceptual — textura, nitidez, altas frequências — e o modelo de difusão cuida de semântica e composição. Cada um faz a parte em que é bom e a parte cara roda no espaço pequeno.

O diagrama abaixo segue a figura do artigo de difusão latente4. Escolha um caminho para ver que partes o treino usa e que partes a geração usa.

Difusão latente em três espaços. Pixels: a imagem x, o encoder E e o decoder D do VAE e a imagem gerada x̃. Latente, 64 × 64 × 4: no treino, z0 vindo do encoder, ruído acrescentado num t sorteado, z t na U-Net e a perda; na geração, z T vindo do ruído, a U-Net e o agendador repetidos T vezes e depois z0 para o decoder. Texto: o prompt, o encoder de texto do CLIP e os embeddings c, que chegam à U-Net pela atenção cruzada. PIXELS · 512 × 512 × 3 LATENTE · 64 × 64 × 4 TEXTO · 77 TOKENS zt​, t εθ​ × T K, V xuma foto ℰencoder(congelado) 𝒟decoder(congelado) x̃a imagem z0​ some ruídot sorteado, um salto zt​ perda‖ε − εθ‖² U-Net εθ(zt​, t, c)atenção cruzada:Q de zt​; K e V de c zT​𝒩(0, I) agendadorzt​ → zt−1​ z0​ “um gato no espaço”prompt encoder de textoCLIP · congelado c · 77 × 768

Daqui em diante a difusão roda no latente, então a sua variável passa a se chamar \(z_t\) em vez de \(x_t\): \(z_0\) é a imagem codificada e \(z_T\) o ruído inicial. Tudo o que veio acima vale sem mudança.

Os três componentes:

  • Encoder de texto — o CLIP (capítulo 19) transforma o prompt numa sequência de embeddings. Congelado.
  • U-Net — remove ruído do latente, com camadas de atenção cruzada em que a query vem do latente e chave/valor dos embeddings de texto (capítulo 11). É o único lugar por onde o prompt entra e é exatamente a atenção cruzada de um decoder Transformer.
  • VAE — codifica para latentes no treino, decodifica para pixels no fim da amostragem. Congelado.

Marcos

Onze anos em três faixas: os métodos, os modelos construídos com eles e as ferramentas que cresceram em volta dos modelos. Clique num nome para abrir o artigo ou o lançamento.

Marcos da geração de imagens por difusão, de 2015 a 2026, num eixo de anos com três faixas: os métodos (difusão em 2015, DDPM e DDIM em 2020, difusão latente e classifier-free guidance em 2021, flow matching e DiT em 2022, destilação de poucos passos a partir de 2023), os modelos (Stable Diffusion v1 e 2.0 em 2022, SDXL em 2023, SD 3, FLUX.1 e SD 3.5 em 2024) e o ecossistema em volta deles (LoRA, texto-para-3D, ControlNet, IP-Adapter, vídeo). MÉTODO MODELO ECOSSISTEMA 2015 2020 2021 2022 2023 2024 2025 2026 2016–19 Difusão Sohl-Dickstein et al. DDPM prever o ruído DDIM determinístico, menos passos Classifier-free guidance duas passagens, extrapolar Difusão latente (LDM) difundir no latente de um VAE Flow matching caminhos retos, velocidade DiT a U-Net vira um Transformer Destilação, poucos passos LCM · Turbo · Lightning Stable Diffusion v1 LDM + texto do CLIP, 512² SD 2.0 encoder de texto OpenCLIP SDXL U-Net de 2,6B, 1024² SD 3 MMDiT + fluxo retificado FLUX.1 DiT de 12B, fluxo retificado SD 3.5 o MMDiT aberto, revisto LoRA adaptadores de posto baixo DreamFusion → Magic3D texto-para-3D com modelo 2D ControlNet bordas, profundidade, pose IP-Adapter uma imagem como prompt SVD → vídeo classe Sora difusão latente de vídeo

O pipeline, de ponta a ponta

Uma imagem do SD 1.5 em 512 × 512 com 25 passos, etapa por etapa. O último passo mostra o caminho que o treino segue no lugar dela. A cor de cada caixa diz em que espaço ela trabalha; laranja marca o treino.

ESPAÇO DO TEXTO ESPAÇO LATENTE · 4 × 64 × 64 ESPAÇO DOS PIXELS · 3 × 512 × 512 “um gato no espaço” prompt tokenizador ids · 1 × 77 encoder de texto CLIP 123,1 M · congelado c · 1 × 77 × 768 e ∅, o prompt vazio zT​ ~ N(0, I) semente → ruído × 25 passos zt​ 1 × 4 × 64 × 64 ×2 U-Net 859,5 M 2 × 4 × 64 × 64 atenção cruzada: K, V de ∅ e de c ε(zt​, ∅) ε(zt​, c) ε̃ = ε∅​ + w · (εc​ − ε∅​) guidance, w = 7,5 agendador zt​ → zt−1​ z0​, depois do último passo decoder do VAE 49,5 M · uma vez imagem 1 × 3 × 512 × 512 encoder do VAE imagem real → z0​ somar ruído t aleatório: q(zt​ | z0​) perda MSE com o ε real

Uma imagem, em formatos

O mesmo caminho, com o tensor que sai de cada etapa, para o SD 1.5 em 512 × 512 e 25 passos de amostragem. As contagens de parâmetros são as que o laboratório imprime.

Etapa Saída Formato Parâmetros
Tokenizador ids dos tokens, completados ou truncados para 77 \(1 \times 77\) —
Encoder de texto do CLIP um embedding por token: \(c\) \(1 \times 77 \times 768\) 123,1 M
Ruído inicial (a semente o decide) \(z_T\) \(1 \times 4 \times 64 \times 64\) —
U-Net, duas vezes por passo (com e sem o prompt) \(\epsilon_\theta(z_t, \varnothing)\), \(\epsilon_\theta(z_t, c)\) \(2 \times 4 \times 64 \times 64\) 859,5 M
Guidance + agendador \(z_{t-1}\) \(1 \times 4 \times 64 \times 64\) —
Decoder do VAE, uma vez no fim a imagem \(1 \times 3 \times 512 \times 512\) 49,5 M

Quase toda a computação está numa linha: 25 passos × 2 passagens = 50 avaliações da U-Net por imagem, contra uma passagem do encoder de texto e uma do decoder. É por isso que as alavancas que tornam a geração rápida — menos passos, destilação, um modelo sem guidance — agem todas sobre a linha da U-Net.

Uma imagem, em números

O mesmo laço, linha a linha, com todos os números na tela. O latente tem 4 números em vez de 16.384 e a U-Net é de brinquedo, com uma previsão de ruído exata (os latentes de cada legenda são uma gaussiana), então cada valor pode ser conferido à mão; o cronograma, os timesteps e o passo do DDIM são os do SD 1.5. A linha do guidance é o assunto da próxima seção.

iteração
 

Classifier-free guidance: a parte que o faz obedecer

Um modelo treinado com pares (imagem, legenda) se condiciona em texto e se você amostrar dele honestamente a aderência ao prompt é decepcionante. Todo sistema texto-para-imagem que você já usou, portanto, faz algo que não é amostrar da própria distribuição.

Treine o modelo com a legenda descartada 10% das vezes, de modo que uma única rede aprenda tanto a previsão de ruído condicional \(\epsilon_\theta(x_t, c)\) quanto a incondicional \(\epsilon_\theta(x_t, \varnothing)\) (o passo \(t\) fica implícito nesta seção). Depois, a cada passo de amostragem, avalie os dois e extrapole além do condicional25:

\[ \tilde\epsilon = \epsilon_\theta(x_t, \varnothing) \;+\; w \cdot \big(\epsilon_\theta(x_t, c) - \epsilon_\theta(x_t, \varnothing)\big) \]

Com \(w = 0\) você tem o modelo incondicional. Com \(w = 1\), amostragem condicional pura. Além disso você está amplificando a direção para a qual o prompt aponta — o que não é amostrar de nenhuma distribuição que o modelo aprendeu e funciona mesmo assim. No Stable Diffusion, o "sem prompt" \(\varnothing\) é o embedding da string vazia, não um vetor de zeros. O guidance_scale dos pipelines usuais (7,5 por padrão) é este \(w\).

O painel amostra uma distribuição de brinquedo (oito aglomerados num anel, três dos quais o "prompt" pede) com scores exatos (o score é o gradiente do log da densidade, a previsão de ruído a menos de uma escala: veja a SDE mais abaixo), escritos na forma de velocidade do capítulo 21; o guidance combina as duas previsões com a mesma linha. Ele varre o \(w\) e mede as três coisas que se contrapõem. Com 32 passos, a aderência ao prompt já é de 99% em \(w = 1\), porque o condicional deste brinquedo é exato; um condicional aprendido não é e essa diferença é o que os pipelines reais pagam \(w > 1\) para fechar. A diversidade cai monotonicamente já a partir do primeiro passo além de 1: a dispersão dentro do modo (a distância média de uma amostra ao centro do seu aglomerado, em unidades de σ, o desvio padrão de um aglomerado) vai de 1,03σ em \(w = 1\) para 0,76σ em \(w = 3\) e 0,63σ em \(w = 7{,}5\). A fração fora da variedade, de 1% em \(w = 3\), sobe para 17% em \(w = 10\) e 63% em \(w = 15\) — o que, numa imagem real, é aquele visual saturado, queimado e de alto contraste que todo mundo reconhece numa escala de guidance de 20.

O guidance dobra seu custo de inferência

Duas passagens diretas por passo, uma das quais você calcula para depois subtrair: metade da computação de U-Net de uma imagem guiada vai para o ramo incondicional. Destilar o guidance para dentro do modelo — de modo que uma única passagem produza a previsão guiada — é um dos truques padrão para tornar modelos de poucos passos rápidos.

Vá e experimente: Diffusion Explainer

O Diffusion Explainer15 é uma visualização interativa deste pipeline, feita para o ensino pelo Polo Club da Georgia Tech. Ele não gera nada enquanto você olha: as imagens foram calculadas de antemão para um conjunto de prompts prontos, cada um com uma variante, em algumas sementes e escalas de guidance. É isso que o torna instantâneo e também o seu limite — você não pode digitar o seu próprio prompt; o laboratório existe para isso. Reserve quinze minutos.

Simulador: Diffusion Explainer

O pipeline do Stable Diffusion aberto etapa por etapa, feito pelo Polo Club da Georgia Tech. As imagens são pré-calculadas, então ele responde na hora e não precisa de GPU. Foi desenhado para uma tela de pelo menos 1200 × 768 px: abra numa aba própria e deixe esta página ao lado. A interface é em inglês.

Abrir o Diffusion Explainer

  1. Associe as caixas dele a este capítulo. A ferramenta nomeia três etapas. Antes de abri-las, associe cada uma a um componente da difusão latente:

    Diffusion Explainer Este capítulo Saída (SD 1.x)
    Text Representation Generator tokenizador + encoder de texto do CLIP \(77 \times 768\)
    Image Representation Refiner U-Net + agendador, repetidos ao longo dos timesteps, no espaço latente \(4 \times 64 \times 64\)
    Image Upscaler decoder do VAE \(3 \times 512 \times 512\)

    Expanda a primeira e encontre o número 77: o que acontece com um prompt mais curto que isso e o que aconteceria com um mais longo? Expanda a segunda e encontre as duas previsões de ruído que ela combina — é a linha do guidance da seção anterior.

  2. Arraste o controle de timestep. Ele percorre os 50 passos da amostragem. Antes de apertar play, preveja: o que se define primeiro, o layout ou a textura? Depois encontre o primeiro passo em que você consegue dizer o que é o objeto e o passo a partir do qual só o detalhe muda. As imagens que ele mostra a cada passo são uma projeção linear barata do latente de 4 canais para cor, não uma passagem do decoder do VAE; o laboratório mede até onde um mapa linear chega.

  3. Mude a escala de guidance. Ele oferece 0, 1, 7 e 20. Preveja cada uma pela fórmula antes de clicar: 0 é o modelo incondicional — que parte do prompt sobrevive? —, 1 é amostragem condicional pura, 7 está perto do padrão usual e 20 está muito além dele. Onde você vê a aderência do painel de guidance acima e onde vê o visual fora da variedade?

  4. Mude a semente. A semente fixa o ruído inicial \(z_T\) e nada mais. Quais caixas do diagrama mudam e quais continuam iguais (olhe a representação do texto)? Uma semente nova muda o assunto ou a composição?

  5. Compare dois prompts que diferem por um modificador. Use o modo de comparação com um par pronto cujos prompts diferem por uma única expressão (um estilo ou um adjetivo, por exemplo) e mantenha fixas a semente e o guidance. Em que timestep as duas imagens começam a diferir e quanto da composição sobrevive até o fim? Explique com o pipeline: o ruído inicial é idêntico e o prompt só entra pela atenção cruzada.

O que ele deixa de fora também ensina: o número de passos, o agendador e a resolução são fixos e o treino não aparece — ele mostra só o caminho da inferência.

Samplers: o mesmo modelo, de cinco a cinquenta passos

O treino te dá \(\epsilon_\theta\). Transformá-lo numa imagem é um problema numérico separado: integrar uma ODE ou SDE reversa e o solver é escolha sua. É por isso que o mesmo checkpoint roda com 50 passos ou com 20 quase sem diferença visível.

Sampler O que é Passos típicos
DDPM2 O amostrador ancestral estocástico original 1000
DDIM3 Determinístico; reinterpreta o processo como ODE, então passos podem ser pulados. Também torna o mapa ruído→imagem invertível, que é o que a edição de imagens exige 50
Euler / Heun Solvers de ODE comuns sobre o mesmo campo 20–30
DPM-Solver++26 Um solver de integrador exponencial exato que explora a estrutura semilinear. O padrão prático 15–25
UniPC, DEIS Variantes multipasso de ordem mais alta 10–20

O número de passos é um botão e não é o único

Menos passos é mais barato e, em algum ponto, mais borrado ou estruturalmente errado. Samplers estocásticos corrigem erro acumulado e precisam de mais passos; determinísticos são reprodutíveis a partir da semente e mais baratos. Abaixo de ~10 passos nenhum solver salva — esse regime exige destilação, não um integrador melhor.

Destilação: de cinquenta passos para um

Uma linha de trabalho separada comprime a trajetória de amostragem para dentro dos pesos.

Método Ideia Passos
Destilação progressiva27 Treine um aluno a dar dois passos do professor de uma vez. Repita, dividindo ao meio a cada rodada 8192 → 4
LCM / LCM-LoRA28 Consistência: aprender um mapa de qualquer ponto da trajetória direto para o ponto final. Entregue como um LoRA que converte um modelo existente 2–8
SDXL-Turbo / ADD29 Acrescente um discriminador — a perda de GAN do capítulo 18 — para que saídas de um passo pareçam reais em vez de médias 1–4
Lightning, Hyper-SD Combinações dos anteriores 1–8

Repare no que a linha do ADD implica: a GAN, deslocada como geradora, voltou como aquilo que torna a difusão de tempo real possível (o StreamDiffusion31 monta um pipeline interativo sobre modelos assim). E repare no custo honesto — modelos de poucos passos trocam diversidade por velocidade, o que você percebe na hora se amostrar o mesmo prompt vinte vezes.

Controle: tudo que você de fato faz com isso

Texto é uma interface ruim para "coloque o sujeito aqui, nesta pose". Cinco mecanismos cobrem quase todo fluxo real:

Mecanismo O que faz Como
img2img Começar de uma imagem existente em vez de ruído puro Codifique-a, some ruído até um \(t\) intermediário e remova o ruído a partir dali. A força é apenas em qual \(t\) você começa
Inpainting Regerar uma região mascarada A cada passo, substitua o latente não mascarado pelo original (com o ruído correto) — ou use um checkpoint de inpainting cuja U-Net recebe a máscara e a imagem mascarada como canais extras de entrada
ControlNet21 Condicionar em estrutura — um esqueleto de pose, um mapa de profundidade, um mapa de bordas Uma cópia treinável da metade encoder, somada à U-Net congelada por convoluções inicializadas em zero, de modo que o treino começa como identidade
IP-Adapter22 Condicionar numa imagem de referência — estilo ou identidade Camadas extras de atenção cruzada que leem embeddings de imagem do CLIP, acrescentadas ao lado da atenção cruzada do texto
LoRA Um estilo, um personagem, um conceito Capítulo 14, aplicado às camadas de atenção da U-Net. É todo o ecossistema comunitário de fine-tuning

O padrão comum a ControlNet, IP-Adapter e LoRA

Os três congelam o modelo base e acrescentam um pequeno caminho treinável ao lado dele. O ControlNet e o LoRA vão um passo além e inicializam esse caminho para não fazer nada (convoluções zeradas; o \(B = 0\) de um LoRA), de modo que o treino começa exatamente no modelo base. É por isso que eles compõem — dá para empilhar um LoRA, um ControlNet e um IP-Adapter num mesmo checkpoint — e por que a comunidade consegue produzir milhares de adaptadores para um modelo que ninguém retreina. É a mesma ideia do capítulo 14, transplantada para um modelo generativo.

O que mudou depois do SD 1.5

O gráfico de marcos acima diz quando; não diz o que mudou. Eis o que cada geração de fato mudou, o que é mais útil que os números de versão:

SD 1.5 (2022)5 SDXL (2023) SD 3 / FLUX (2024)30
Backbone U-Net, 860M U-Net, 2,6B + refinador MMDiT — um Transformer (capítulo 22)19
Encoder de texto CLIP ViT-L Dois encoders CLIP T5-XXL + CLIP (dois no SD3 e no SD 3.516, um no FLUX)
Latente 4 canais 4 canais 16 canais
Objetivo previsão de \(\epsilon\), DDPM previsão de \(\epsilon\) Fluxo retificado (capítulo 21)20
Tamanho nativo 512² 1024², múltiplas proporções 1024²+, cronograma deslocado por resolução

Quatro temas e nenhum deles é "mais parâmetros":

  1. A U-Net virou Transformer. Escala melhor e é uma arquitetura compartilhada com todo o resto do curso.
  2. Codificação de texto melhor. T5 ao lado do CLIP, porque a torre de texto do CLIP é pequena e se comporta como saco de palavras (capítulo 19) — uma das razões pelas quais o SD 1.5 não escrevia nem lidava com prompts longos e composicionais.
  3. Um latente mais rico. 4 → 16 canais: menos perdido na compressão. Junto com o T5, é daí que veio texto legível em imagens geradas.
  4. A difusão virou flow matching. Caminhos mais retos, menos passos, objetivo mais simples. É o próximo capítulo.

De onde vieram os dados de treino

O SD 1.x foi treinado em subconjuntos do LAION-5B: pares imagem-URL raspados do Common Crawl e filtrados por similaridade do CLIP (capítulo 19). Ninguém cujo trabalho está ali foi consultado. As consequências não são hipotéticas — litígio ativo sobre dados de treino, modelos que reproduzem sob demanda o estilo de um artista vivo com nome e sobrenome, memorização documentada de imagens individuais de treino e, em uma auditoria, material ilegal que forçou a retirada do conjunto do ar. Se você constrói sobre esses modelos, você herda tudo isso. Proveniência é uma propriedade de engenharia do seu sistema, não uma nota de rodapé.

Laboratório: o Stable Diffusion, aberto

O pipeline desta página é desmontado num notebook no Colab que roda o Stable Diffusion 1.5 com o diffusers da Hugging Face10, um componente por vez. Ele precisa de GPU: no Colab, Ambiente de execução → Alterar o tipo de ambiente de execução → GPU T4 (o nível gratuito basta; as primeiras células baixam uns 2 GB de pesos e a execução de referência de todas as células levou 11 minutos na GPU de um notebook Apple M2, mais lenta que uma T4). São oito seções, cada uma terminando num checkpoint com valor de verificação:

  1. os três componentes e as suas contagens de parâmetros;
  2. a ida e volta pelo VAE: a compressão de 48× (medida) e até onde chega um mapa linear do latente para cor;
  3. o encoder de texto: 77 tokens, uma matriz \(77 \times 768\) e a cara do prompt vazio;
  4. o processo direto num latente e o SNR terminal do SD 1.5, lido no agendador;
  5. o laço de remoção de ruído escrito por extenso — agendador, duas chamadas da U-Net e a linha do guidance — conferido contra o pipeline da biblioteca, com \(\hat x_0\) decodificado a cada passo;
  6. escala de guidance e semente, medidas: aderência ao prompt, saturação e diversidade;
  7. passos e destilação: o mesmo modelo de 1 a 25 passos e o mesmo modelo com um LCM-LoRA em 4;
  8. img2img escrito à mão, com uma tabela para preencher.

Abrir o laboratório no Colab — salve uma cópia no seu Drive (Arquivo → Salvar uma cópia no Drive) para rodar e editar.

Para além do laboratório: o Diffusion Course da Hugging Face11 vai mais longe com o diffusers; tutoriais mais curtos rodam o SD em Python9, chamam o SD3 pela API17 e passam pelas versões do SD18. Explicações ilustradas do DDPM128, da U-Net14 e do Stable Diffusion6 cobrem o mesmo terreno com outras figuras.

Pontos principais

  1. A difusão transforma geração em muitos problemas fáceis de remoção de ruído e a forma fechada \(x_t = \sqrt{\bar\alpha_t}x_0 + \sqrt{1-\bar\alpha_t}\epsilon\) é o que torna o treino paralelo.
  2. A perda é um erro quadrático comum contra um ruído que você mesmo sorteou. Sem adversário, com treino estável: a principal razão pela qual a difusão bateu as GANs.
  3. O cronograma de ruído decide o que o modelo aprende. SNR terminal não nulo é por que o SD 1.x não renderiza preto; a resolução muda o significado de um nível de ruído, daí o deslocamento de timestep.
  4. A difusão latente roda o processo num espaço 48× menor. O VAE cuida do detalhe, o modelo de difusão cuida da semântica.
  5. O classifier-free guidance é uma linha, dobra o custo de inferência e é o que faz o modelo obedecer ao prompt. Ele troca diversidade por aderência e em excesso empurra as amostras para fora da variedade.
  6. O sampler é uma escolha separada do modelo. DPM-Solver++ com 15–25 passos é o padrão prático; abaixo de ~10 passos você precisa de destilação, não de um solver melhor.
  7. A destilação chega a 1–4 passos e um dos métodos vencedores usa uma perda adversarial — a GAN voltando como componente.
  8. ControlNet, IP-Adapter e LoRA congelam a base e acrescentam um pequeno caminho ao lado dela. É por isso que eles compõem.
  9. Desde o SD 1.5: backbone Transformer, encoders de texto melhores, latentes de 16 canais, fluxo retificado. Não "maior".

Adicional

DDPM vs DDIM

Aspecto DDPM DDIM
Amostragem Estocástica: ruído novo a cada passo Determinística: a semente fixa a imagem
Velocidade Muitos passos (mais lento) Menos passos (mais rápido)
Mesma semente, duas vezes Imagens diferentes A mesma imagem

SDE

Song et al.7 levam o número de passos ao infinito. A cadeia direta vira uma equação diferencial estocástica (SDE) em tempo contínuo \(t \in [0, T]\): \(f(x, t)\) é uma deriva, \(g(t)\) dá a escala do ruído e \(dw\) é um incremento de movimento browniano, a versão contínua de acrescentar um pouco de ruído gaussiano. Chame de \(p_t\) a densidade dos dados ruidosos no instante \(t\). Toda SDE direta tem uma reversa, que vai do ruído de volta aos dados (\(\bar w\) é um movimento browniano que corre para trás no tempo). A única incógnita dela é o score \(\nabla_x \log p_t(x)\), a direção em que \(p_t\) cresce mais rápido. Uma rede treinada como no DDPM o fornece, porque a previsão de ruído é o score a menos de uma escala:

\[ \nabla_x \log p_t(x_t) \approx -\frac{\epsilon_\theta(x_t, t)}{\sqrt{1 - \bar\alpha_t}} \]

O amostrador do DDPM é uma discretização da SDE reversa. O DDIM é uma discretização da sua gêmea determinística, a ODE de fluxo de probabilidade \(dx = \big[f(x, t) - \tfrac12 g(t)^2 \nabla_x \log p_t(x)\big]\,dt\), que não tem termo de ruído e chega às mesmas distribuições \(p_t\).

A difusão baseada em score como duas equações diferenciais estocásticas. Em cima: a SDE direta dx = f(x, t) dt + g(t) dw leva x(0), os dados, a x(T), ruído. No meio: uma distribuição de dados em uma dimensão, com dois modos, se achata passo a passo numa única gaussiana padrão; no segundo painel, setas mostram o score, o gradiente de log p t, apontando para os modos. Embaixo: a SDE reversa, dx = [f(x, t) − g(t)² ∇x log p t(x)] dt + g(t) dw̄, leva o ruído de volta aos dados; o score é o único termo desconhecido. SDE DIRETA · DADOS → RUÍDO x(0) x(T) dx = f(x, t) dt + g(t) dw p0​ · dados pt​ pt​ pt​ pT​ ≈ 𝒩(0, 1) setas laranja: o score ∇x​ log pt(x), que aponta para os x mais prováveis x(0) x(T) dx = [ f(x, t) − g(t)² ∇x​ log pt(x) ] dt + g(t) dw̄ em laranja, o score: o único termo desconhecido, aprendido pela rede SDE REVERSA · RUÍDO → DADOS

Arquitetura U-Net

A U-Net é uma arquitetura de rede neural convolucional projetada originalmente para segmentar imagens biomédicas13. Desde então ela foi amplamente adotada em geração de imagens, inclusive em modelos de difusão como o Stable Diffusion. Seu formato é um U: um encoder (o caminho de contração) divide a resolução por dois e acrescenta canais a cada nível, um decoder (o caminho de expansão) o espelha e conexões de atalho levam cada nível do encoder até o nível do decoder de mesma resolução, de modo que o detalhe fino perdido na descida está disponível na subida. A versão do Stable Diffusion acrescenta o timestep e o texto.

Abaixo, a U-Net do Stable Diffusion 1.5, bloco a bloco. Cada "Transformer" é autoatenção, depois atenção cruzada ao texto, depois uma camada feed-forward. O embedding do timestep é somado dentro de todo ResBlock. Canais e resolução são os da configuração do diffusers que o laboratório carrega. Um bloco de subida tem três ResBlocks, um para cada tensor de atalho que chega na sua resolução.

A U-Net do Stable Diffusion 1.5 desenhada como um U. O latente ruidoso (B, 4, 64, 64) entra pelo conv_in com 320 canais. Quatro blocos de descida vão de 64×64 a 8×8 (320, 640, 1280, 1280 canais), o bloco do meio fica no fundo (em 8×8) e quatro blocos de subida voltam a 64×64; em cada resolução três conexões de atalho cruzam do lado da descida para o da subida. Down 1 a 3, o bloco do meio e Up 2 a 4 têm atenção cruzada aos embeddings do texto (77 × 768); Down 4 e Up 1 não têm. O embedding do timestep (1280) é somado dentro de todo ResBlock. O conv_out devolve o ruído previsto, (B, 4, 64, 64). latente ruidoso zt​ · B×4×64×64 conv_in: 4 → 320 εθ​(zt​, t, c) · B×4×64×64 conv_out: 320 → 4 64×64 Down 1 · 320 canais 2 × (Res + Transformer) t c Up 4 · 320 canais 3 × (Res + Transformer) t c 3 atalhos ÷2 ×2 32×32 Down 2 · 640 canais 2 × (Res + Transformer) t c Up 3 · 640 canais 3 × (Res + Transformer) t c 3 atalhos ÷2 ×2 16×16 Down 3 · 1280 canais 2 × (Res + Transformer) t c Up 2 · 1280 canais 3 × (Res + Transformer) t c 3 atalhos ÷2 ×2 8×8 Down 4 · 1280 canais 2 × Res t Up 1 · 1280 canais 3 × Res t 3 atalhos Mid · 1280 canais Res + Transformer + Res t c 8×8 t timestep t → senoidal → MLP: 1280-d, somado dentro de todo ResBlock c embeddings do texto c, 77 × 768: chaves e valores de toda atenção cruzada

Vídeos

Deepia: Diffusion Models: DDPM | Generative AI Animated

Deepia: Score-based Diffusion Models | Generative AI Animated

But how do AI images and videos actually work? | Guest video by Welch Labs



  1. Sohl-Dickstein, J., Weiss, E. A., Maheswaranathan, N., & Ganguli, S. (2015). Deep Unsupervised Learning using Nonequilibrium Thermodynamics — ICML. ↩

  2. Ho, J., Jain, A., & Abbeel, P. (2020). Denoising Diffusion Probabilistic Models — NeurIPS. ↩↩

  3. Song, J., Meng, C., & Ermon, S. (2021). Denoising Diffusion Implicit Models — ICLR. ↩

  4. Rombach, R., Blattmann, A., Lorenz, D., Esser, P., & Ommer, B. (2022). High-Resolution Image Synthesis with Latent Diffusion Models — CVPR. Código: CompVis/latent-diffusion. ↩↩↩

  5. Hugging Face - Stable Diffusion v1 - Release ↩

  6. Dagshub - Stable Diffusion: Best Open Source Version of DALL-E 2 ↩

  7. Song, Y., Sohl-Dickstein, J., Kingma, D. P., Kumar, A., Ermon, S., & Poole, B. (2021). Score-Based Generative Modeling through Stochastic Differential Equations — ICLR. ↩

  8. Diffusion Models Clearly Explained ↩

  9. Generate Images from Text in Python - Stable Diffusion ↩

  10. Hugging Face - Diffusers ↩

  11. Hugging Face - Diffusion Course ↩

  12. How to Run Stable Diffusion: A Step-by-Step Guide ↩

  13. Ronneberger, O., Fischer, P., & Brox, T. (2015). U-Net: Convolutional Networks for Biomedical Image Segmentation — MICCAI. ↩↩

  14. GeeksForGeeks - U-Net Architecture Explained ↩

  15. Lee, S., Hoover, B., Strobelt, H., Wang, Z. J., Peng, S., Wright, A., Li, K., Park, H., Yang, H., & Chau, D. H. (2024). Diffusion Explainer: Visual Explanation for Text-to-image Stable Diffusion — IEEE VIS (artigo curto). A ferramenta: poloclub.github.io/diffusion-explainer; código: poloclub/diffusion-explainer. ↩

  16. Hugging Face - Stable Diffusion 3.5 Large ↩

  17. How to Use Stable Diffusion 3 API ↩

  18. Stable Diffusion Models, por Ankit Kumar. ↩

  19. Peebles, W., & Xie, S. (2023). Scalable Diffusion Models with Transformers — ICCV. DiT; código: facebookresearch/DiT. ↩

  20. Lipman, Y., Chen, R. T. Q., Ben-Hamu, H., Nickel, M., & Le, M. (2023). Flow Matching for Generative Modeling — ICLR. ↩

  21. Zhang, L., Rao, A., & Agrawala, M. (2023). Adding Conditional Control to Text-to-Image Diffusion Models — ICCV. O ControlNet e a convolução inicializada em zero que torna seguro acrescentá-lo. ↩

  22. Ye, H., Zhang, J., Liu, S., Han, X., & Yang, W. (2023). IP-Adapter: Text Compatible Image Prompt Adapter for Text-to-Image Diffusion Models. ↩

  23. Lin, S., Liu, B., Li, J., & Yang, X. (2024). Common Diffusion Noise Schedules and Sample Steps are Flawed — WACV. Onde o bug do SNR terminal não nulo é diagnosticado e corrigido. ↩

  24. Esser, P., et al. (2024). Scaling Rectified Flow Transformers for High-Resolution Image Synthesis — ICML. SD3: MMDiT, fluxo retificado e o deslocamento de timestep dependente da resolução. ↩

  25. Ho, J., & Salimans, T. (2022). Classifier-Free Diffusion Guidance — apresentado primeiro no workshop Deep Generative Models da NeurIPS 2021. Duas linhas de método e um dos artigos de maior impacto da área. ↩

  26. Lu, C., Zhou, Y., Bao, F., Chen, J., Li, C., & Zhu, J. (2022). DPM-Solver++: Fast Solver for Guided Sampling of Diffusion Probabilistic Models. ↩

  27. Salimans, T., & Ho, J. (2022). Progressive Distillation for Fast Sampling of Diffusion Models — ICLR. ↩

  28. Luo, S., Tan, Y., Huang, L., Li, J., & Zhao, H. (2023). Latent Consistency Models: Synthesizing High-Resolution Images with Few-Step Inference. A versão em LoRA: Luo, S., et al. (2023). LCM-LoRA: A Universal Stable-Diffusion Acceleration Module. ↩

  29. Sauer, A., Lorenz, D., Blattmann, A., & Rombach, R. (2023). Adversarial Diffusion Distillation. SDXL-Turbo. ↩

  30. Black Forest Labs (2024). FLUX.1, código oficial de inferência. ↩

  31. Kodaira, A., et al. (2023). StreamDiffusion: A Pipeline-level Solution for Real-time Interactive Generation; código: cumulo-autumn/StreamDiffusion, sugerido por Pedro Fracassi. ↩