O treino precisa de num aleatório entre 1 e 1000. É preciso rodar a cadeia vezes?
Não: uma composição de gaussianas é gaussiana.
Sorteie , sorteie , salte. Cada exemplo de um lote pode estar num nível de ruído diferente.
O processo direto é fixo: nada nele é aprendido e a inferência nunca o usa.
: a imagem limpa · : ela depois de passos de ruído, de · : quanto ruído o passo acrescenta (o cronograma) · : gaussiana em com média e covariância · : a identidade, ruído independente por pixel · : ruído gaussiano padrão.
A perda cabe numa linha
O alvo é um ruído que você mesmo sorteou; é o texto.
Regressão supervisionada comum: sem adversário, treino estável, uma perda que significa algo.
Isso, mais que a qualidade das imagens, é o que fez a difusão deslocar a GAN.
As previsões de , de e de são intercambiáveis dados e o cronograma. Elas diferem em como a perda pesa os níveis de ruído.
: a rede (a U-Net, com pesos ) · : média sobre imagens, ruídos e sorteados · : uma mistura dos dois alvos.
A volta: da previsão de ruído a um passo
A rede devolve . Como obter o palpite atual dela para a imagem limpa?
Inverta a forma fechada:
Perto de , : qualquer erro em é amplificado. Daí os objetivos de e de velocidade.
O agendador (scheduler: a regra que transforma a previsão num passo) anda um pouco de na direção de . Repita.
Uma rede, dois laços
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 IMAGEMAMOSTRAGEM · T PASSAGENS, EM ORDEMεεθatualiza θεθ× Tt = 1: fimUm lote: cada imagem sorteia o seu tt = 14t = 350t = 721Salto para aquele nível de ruído=√ᾱt+√(1−ᾱt)xtx0εPerda: ‖ε − εθ(xt, t)‖²um passo de gradiente; depois, o próximo loteU-Net εθ(xt, t)θInício: xT ~ 𝒩(0, I), t = Truído sorteado pela sementeUm passo para trásxt−1 = μθ(xt, t) + σt zμθ remove uma parte, em escala, de εθσt z: ruído novo no DDPM; 0 no DDIMDepois do último passo: x0uma imagem nova
O cronograma de ruído não é um detalhe
SD 1.x: "linear escalado" ( em linha reta) de 0,00085 a 0,012, em passos.
Quanto da imagem sobrevive no último passo de treino, ?
, então da imagem ainda está lá — não zero.
A amostragem começa de ruído puro: um descompasso treino/teste.
Consequência: o SD 1.x não consegue fazer uma imagem realmente preta ou realmente branca. O brilho médio vaza.
A correção: reescalar o cronograma para SNR terminal zero (Lin et al., 2024).
SNR (razão sinal-ruído) , a variância do sinal sobre a do ruído em . Terminal: em . No SD 1.x, . O laboratório lê no agendador, que conta de 0 a 999: .
Cada lado encolhe 8×: uma célula do latente resume 8 × 8 pixels × 3 cores = 192 números em 4. .
Pago em cada passo de amostragem. O VAE custa uma codificação ou uma decodificação.
A ida e volta pelo VAE, medida
Laboratório, seção 2: uma foto 512 × 512, codificada e decodificada.
latente
1 × 4 × 64 × 64
desvio, latente cru
4,12
desvio × 0,18215
0,75
PSNR da reconstrução
27,7 dB
latente → RGB linear, R²
0,92
O fator de escala 0,18215 leva o latente à variância unitária no conjunto de treino, a escala do ruído. Nesta foto: 4,12 × 0,18215 = 0,75.
O decoder devolve o detalhe fino; o latente guarda layout e cor.
Um mapa linear de 4 canais para RGB já dá uma prévia reconhecível — o truque por trás das prévias de cada passo do Diffusion Explainer.
Formato: (imagens, canais, altura, largura). PSNR = 10 log₁₀(pico² / erro quadrático médio), em dB: mais alto é mais fiel. R²: fração da variância das cores da foto, reduzida a 64 × 64, que o mapa linear explica.
Difusão latente, de ponta a ponta
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 × 3LATENTE · 64 × 64 × 4TEXTO · 77 TOKENSzt, tεθ× TK, Vxuma fotoℰencoder(congelado)𝒟decoder(congelado)x̃a imagemz0some ruídot sorteado, um saltoztperda‖ε − εθ‖²U-Net εθ(zt, t, c)atenção cruzada:Q de zt; K e V de czT𝒩(0, I)agendadorzt → zt−1z0“um gato no espaço”promptencoder de textoCLIP · congeladoc · 77 × 768
Três componentes; um deles faz o trabalho
componente
papel
parâmetros
chamadas por imagem
encoder de texto do CLIP
prompt → (tokens × números)
123,1 M
2 (prompt e prompt vazio)
U-Net
prevê no latente
859,5 M
50 (25 passos × 2)
decoder do VAE
latente → pixels
49,5 M
1
O encoder de texto e o VAE estão congelados; só a U-Net foi treinada para a difusão.
Todo ganho de velocidade que você vai ver age na linha da U-Net: menos passos, destilação, sem guidance.
M = milhões de parâmetros, contados na seção 1 do laboratório. O VAE inteiro tem 83,7 M, mas na geração só o decoder (49,5 M) roda. A U-Net é 81% do total: 859,5 / (123,1 + 859,5 + 83,7).
O prompt, do jeito que a U-Net o vê
O tokenizador completa ou trunca todo prompt para 77 tokens: <start>, as palavras, <end> e preenchimento.
O encoder de texto devolve um vetor por token: (768 é a largura do encoder do CLIP ViT-L/14).
"Sem prompt" é a codificação da string vazia — não zeros.
cosseno entre as matrizes inteiras, achatadas (laboratório, seção 3)
"a lighthouse on a cliff at sunset" vs "…, watercolor painting"
0,78
"a lighthouse on a cliff at sunset" vs "a bowl of ramen on a wooden table"
0,24
"a lighthouse on a cliff at sunset" vs ""
0,20
A única porta: atenção cruzada
vem das features do latente, em cada resolução da U-Net: 64², 32², 16² e 8² (o lado cai à metade por nível).
vêm dos 77 vetores do texto. : a dimensão de cada query e chave.
A imagem pergunta, o texto responde: a atenção cruzada de um decoder Transformer.
Dois prompts que diferem por uma palavra, mesma semente. O que é idêntico nas duas execuções e o que muda?
Idênticos: , os pesos da U-Net, o agendador.
Muda: só e .
O laço de amostragem, por extenso
latentes = randn(1, 4, 64, 64, generator=semente) # z_T: a semente o decide
emb = cat([codificar(""), codificar(prompt)]) # ∅ e cfor t in agendador.timesteps: # 25 passos
eps_u, eps_c = unet(cat([latentes] * 2), t, emb).chunk(2)
eps = eps_u + w * (eps_c - eps_u) # guidance: uma linha
latentes = agendador.step(eps, t, latentes).prev_sample
imagem = vae.decode(latentes / 0.18215)
O laboratório escreve este laço e o confere contra o pipeline da biblioteca: maior diferença de pixel 1 (em 255).
50 chamadas da U-Net (25 passos × 2); 1,41 s por passo num Apple M2 (uma T4 é mais rápida).
chunk(2): separa o lote de 2 nas duas previsões (∅ e c) · prev_sample: o latente do passo seguinte · / 0.18215: desfaz o fator de escala do VAE.
Simulador · uma imagem, em números
iteração
Classifier-free guidance
Treine com a legenda descartada 10% das vezes: uma rede aprende e .
O que dão e ? E o padrão dos pipelines, ?
é o guidance_scale dos pipelines. : o modelo incondicional, que ignora o prompt. : amostragem condicional pura.
extrapola além do condicional: nenhuma distribuição que o modelo aprendeu. Funciona mesmo assim.
Custo: duas passagens da U-Net por passo, para qualquer diferente de 0 e de 1.
: a previsão de ruído da U-Net com o prompt (o passo fica implícito) · : o prompt vazio.
Simulador · guidance numa distribuição de brinquedo
Guidance no modelo de verdade, medido
Laboratório, seção 6: "a red fox sitting in a snowy forest, photograph", sementes 0, 1, 2, 20 passos de DDIM.
nota CLIP (prompt)
saturação
diversidade entre sementes
0
13,2
0,20
0,259
1
33,0
0,20
0,184
3
34,7
0,22
0,064
7,5
33,4
0,31
0,057
15
33,9
0,40
0,041
A aderência sobe rápido e depois achata; a saturação continua subindo.
A diversidade entre sementes cai a cada passo, 0,259 → 0,041: com grande as três sementes desenham a mesma raposa centralizada.
Nota CLIP: 100 × o cosseno entre os embeddings CLIP ViT-B/32 da imagem e do prompt. Diversidade: distância de cosseno média entre os embeddings CLIP das três sementes. Saturação: saturação HSV média.
Semente e prompt: quem decide o quê
Laboratório, seção 6: "a lighthouse on a cliff at sunset" ± ", watercolor painting", DDIM, .
par
correlação entre as duas imagens, em cinza e reduzidas a 64 × 64 (o layout)
mesmo prompt, sementes 0 e 1
0,15
mesma semente 0, com e sem o modificador
0,85
A semente fixa e, com ele, a maior parte do layout, decidido nos primeiros passos.
O modificador muda estilo e cor pela atenção cruzada.
Os das duas trajetórias já diferem no passo 1 (), mas os layouts terminam com correlação 0,85.
Vá e experimente: Diffusion Explainer
Associe as três caixas dele ao capítulo: encoder de texto → refinador (U-Net + agendador) → decoder.
Controle de timestep (50 passos): quando dá para dizer o que é o objeto? Quando só o detalhe muda?
Guidance 0, 1, 7, 20: preveja cada um pela fórmula antes.
Semente: quais caixas mudam e quais não?
Compare dois prompts que diferem por um modificador, com a mesma semente e o mesmo guidance: quando eles divergem?
As imagens são pré-calculadas: nada de prompt próprio — para isso existe o laboratório. Lee et al., IEEE VIS 2024. Interface em inglês.
Samplers: o mesmo modelo, de cinco a cinquenta passos
sampler
o que é
passos típicos
DDPM
ancestral, estocástico
1000
DDIM
ODE determinística; invertível, então serve para editar
50
Euler / Heun
solvers de ODE comuns
20–30
DPM-Solver++
integrador exponencial; o padrão prático
15–25
UniPC, DEIS
multipasso de ordem mais alta
10–20
O treino dá ; transformá-lo em imagem é um problema numérico separado.
Abaixo de ~10 passos nenhum solver salva: esse regime exige destilação.
Ancestral: sorteia ruído novo a cada passo · ODE: equação diferencial sem sorteio, então a semente fixa a imagem · ordem mais alta: usa várias avaliações (ou as dos passos anteriores) para dar um passo mais preciso.
Destilação: de cinquenta passos para um
método
ideia
passos
destilação progressiva
um aluno dá dois passos do professor de uma vez; repita
8192 → 4 (metade por rodada, 11 rodadas)
LCM-LoRA
salta de qualquer ponto da trajetória para o fim; vem como um LoRA
2–8
ADD (SDXL-Turbo)
acrescenta um discriminador: a perda de GAN volta
1–4
Laboratório, seção 7, mesmo prompt e mesma semente:
chamadas da U-Net
nota CLIP
tempo (M2)
DDIM, 1 passo,
2 (1 × 2)
13,1
2,4 s
DDIM, 4 passos,
8 (4 × 2)
32,5
6,1 s
DDIM, 25 passos,
50 (25 × 2)
34,1
34,1 s
LCM-LoRA, 4 passos,
4 (4 × 1: sem guidance)
33,9
4,5 s
Controle: o que se faz de fato com ele
mecanismo
o que faz
como
img2img
começa de uma imagem
codifica, ruidifica até um , remove o ruído; força = qual
inpainting
refaz uma região mascarada
mantém o original ruidificado fora da máscara a cada passo
ControlNet
pose, profundidade, bordas
cópia treinável da metade encoder, ligada por convoluções zeradas
IP-Adapter
uma imagem de referência
atenção cruzada extra que lê embeddings de imagem do CLIP
LoRA
um estilo, um personagem
atualização de posto baixo das camadas de atenção (aula de transfer learning)
Todos congelam a base e acrescentam um pequeno caminho ao lado. O ControlNet e o LoRA o iniciam em zero, então o treino começa exatamente no modelo base. É por isso que eles compõem.
O que mudou depois do SD 1.5
SD 1.5 (2022)
SDXL (2023)
SD3 / FLUX (2024)
backbone
U-Net, 860M
U-Net, 2,6B + refinador
MMDiT (Transformer de difusão multimodal)
encoder de texto
CLIP ViT-L
dois CLIP
T5-XXL + CLIP
latente
4 canais
4 canais
16 canais
objetivo
, DDPM
fluxo retificado
tamanho nativo
512²
1024²
1024²+, cronograma deslocado
Quatro mudanças de fundo (Transformer, T5, 16 canais, fluxo); nenhuma delas é "mais parâmetros".
O fluxo retificado é a próxima aula; o backbone Transformer, a seguinte.
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. Ninguém cujo trabalho está ali foi consultado.
Litígio sobre dados de treino, ainda em aberto.
O estilo de um artista vivo, com nome e sobrenome, reproduzido sob demanda.
Memorização documentada de imagens individuais de treino.
Material ilegal encontrado numa auditoria, que tirou o conjunto do ar.
Proveniência é uma propriedade de engenharia do seu sistema, não uma nota de rodapé.
Laboratório · o Stable Diffusion, aberto
Notebook no Colab, ~2 h, GPU T4 (nível gratuito), Stable Diffusion 1.5 com diffusers. Cada seção termina num checkpoint.
Difusão = muitos problemas fáceis de remover ruído; a forma fechada torna o treino paralelo.
A perda é um erro quadrático contra um ruído que você sorteou: estável e a razão de a difusão bater as GANs.
O cronograma decide o que se aprende: é por que o SD 1.x não renderiza preto.
Difusão latente: 48× menos números por passo; o VAE cuida do detalhe.
Guidance: uma linha, duas passagens da U-Net, aderência comprada com diversidade.
O sampler é uma escolha separada; abaixo de ~10 passos, destilação (e a GAN volta).
ControlNet, IP-Adapter, LoRA: base congelada + pequeno caminho. Desde o SD 1.5: Transformer, T5, 16 canais, fluxo.
Roteiro: (1) difusão: processo direto, perda, volta; (2) o cronograma de ruído; (3) difusão latente e
os três componentes; (4) classifier-free guidance; (5) Diffusion Explainer; (6) samplers, destilação,
controle; (7) o que mudou depois do SD 1.5. Fecha com o laboratório no Colab.
Resposta nos slides de guidance: a aderência ao prompt decepciona; w = 7,5 não é amostragem "honesta".
Avance pelas seis etapas: as duas direções, um passo direto, o salto em forma fechada (o próximo slide), o passo reverso verdadeiro, que é intratável, o palpite da U-Net e a amostragem. Passe o mouse sobre um quadro para ver as suas setas. A linha reversa termina numa figura diferente: a amostragem faz uma imagem nova.
O laboratório decodifica x̂0 a cada passo; o Diffusion Explainer mostra a mesma progressão.
Treino (à esquerda): um lote em que cada imagem tem o seu t, o salto, a perda; uma passagem por imagem, todas em paralelo. Amostragem (à direita): comece do ruído, dê um passo para trás, repita T vezes seguidas. A mesma U-Net, os mesmos pesos.
Comece no cronograma linear escalado: ponto vermelho em t = 1. Marque "forçar SNR terminal zero".
Depois suba a resolução para 1024: a curva sobe, a imagem fica ruidificada de menos. Aumente o
deslocamento para ver a correção do SD3 (o tracejado é a curva sem deslocamento na mesma resolução).
Clique em Treino, depois em Geração. O treino usa o encoder e nunca o decoder; a geração usa o decoder e nunca o encoder. Os dois usam a U-Net e o encoder de texto. O próximo slide conta os parâmetros.
Números impressos pela seção 1 do laboratório.
O laço do slide anterior num latente de 4 números, com uma U-Net de brinquedo exata (os latentes de cada
legenda são uma gaussiana) e o cronograma real do SD 1.5. Padrão: "uma maçã vermelha", semente 3, w = 7,5,
25 passos. Avance: 5 tokens reais + 5 de enchimento; ‖c‖ = 1,18 e ‖∅‖ = 1,11 (não é zero); t = 961 … 1,
ᾱ_961 = 0,00728. Iteração 1: ε_∅ e ε_c quase iguais (π ≈ 0,25 cada); ε̃₁ = 1,2481; x̂₀₁ = −5,36 (÷ 0,0853:
erros × 11,7). Trajetória: x̂₀ converge, 10,5 → 0,23 → 0,008. Depois mude um controle por vez: w = 1
(amostra honesta, a 0,41 de μ_c), w = 0 (a semente 3 desenha um campo de neve), w = 15 (0,98 além de μ_c,
64 de 192 valores cortados), N = 1 (t = 1: o próprio ruído), N = 4 (começa em t = 751 e termina a 0,18 do
resultado de 25 passos).
Scores exatos, então w = 1 já dá 99% no prompt aqui; um condicional aprendido não dá. Com 32 passos:
dispersão de 1,03σ em w = 1, 0,76σ em w = 3, 0,63σ em w = 7,5; fora da variedade 1% em w = 3, 17% em
w = 10, 63% em w = 15.