Curso / fast.ai / Parte 2 · Unidad 5
● piloto de formato · condensado

fast.ai · Parte 2 · Unidad 5 de 5 (última)

Stable Diffusion completo: todas las piezas juntas

Las cuatro unidades anteriores construyeron cada pieza por separado: un framework de entrenamiento, redes estables, el proceso matemático de difusión, VAE y attention. Esta unidad las junta en el U-Net condicional real que genera imágenes a partir de texto.

1. El U-Net condicional: time embeddings + atención

El modelo real de difusión no es un CNN plano — es un U-Net: una serie de bloques que reducen resolución progresivamente (downs), un cuello de botella (mids), y bloques simétricos que la recuperan (ups), con conexiones directas entre niveles equivalentes de down/up (para no perder detalle fino durante la compresión). Sobre esa base, dos ingredientes lo convierten en un modelo de difusión:

  • Time embedding: el timestep t (cuánto ruido hay) se convierte en un embedding sinusoidal —igual en espíritu al positional encoding de un transformer— y se inyecta en cada bloque, típicamente modulando la activación con un escalado y un desplazamiento aprendidos (x*(1+scale) + shift), para que la red sepa en qué punto del proceso de denoising está.
  • Self-attention (de la Unidad 4) intercalada entre bloques convolucionales en las resoluciones intermedias — demasiado cara para aplicarla a la resolución completa, muy útil donde el mapa de activaciones ya es chico.
class EmbTransformerBlk(nn.Module):
    def forward(self, x, t):
        emb = self.emb_proj(F.silu(t))[:, None]
        scale, shift = torch.chunk(emb, 2, dim=2)
        x = x + self.attn(self.nrm1(x))
        x = x*(1+scale) + shift            # condicionamiento por tiempo
        return x + self.mlp(self.nrm2(x))

2. Difusión latente sobre un dataset real: LSUN bedrooms

Todo lo anterior se probó sobre Fashion-MNIST (28×28, un canal) por velocidad de iteración. La prueba de fuego es un dataset de fotos reales — LSUN bedrooms, habitaciones fotografiadas en condiciones reales, RGB, mucho más variado y de mayor resolución. El U-Net entrenado directamente sobre estas imágenes (no aún en un espacio latente comprimido por un VAE, en la versión "simple" del notebook) ya produce, tras suficiente entrenamiento, imágenes reconocibles de interiores con muebles, ventanas y perspectiva — usando exactamente el mismo sampler DDIM de la Unidad 3, ahora en color y a mayor escala.

La versión completa de Stable Diffusion agrega el VAE de la Unidad 4 en este punto: en vez de que el U-Net opere sobre los píxeles RGB directamente, opera sobre el latente comprimido que produce el encoder del VAE — reduciendo drásticamente el costo computacional de cada uno de los cientos de pasos de denoising, sin perder fidelidad visual perceptible en la imagen final decodificada.

3. Condicionar con texto: CLIP y classifier-free guidance

Para que un prompt de texto controle la generación, el embedding de texto de CLIP (un encoder entrenado para que representaciones de imagen y de texto que describen lo mismo queden cerca en un espacio vectorial compartido — otra aplicación de contrastive learning) se inyecta en el U-Net vía cross-attention: la misma mecánica de Query/Key/Value de la Unidad 4, pero ahora Q viene de la imagen y K/V vienen del embedding de texto, dejando que cada región de la imagen "atienda" a las palabras del prompt más relevantes para ella.

Classifier-free guidance es la técnica que hace que el resultado siga el prompt con más fuerza: durante el entrenamiento se descarta el condicionamiento de texto una fracción del tiempo (el modelo aprende tanto la versión condicional como la incondicional), y en inferencia se genera con ambas versiones y se extrapola en la dirección que aleja de la incondicional — el guidance scale controla cuánto se extrapola. Un negative prompt es la misma idea aplicada al revés: en vez de usar la versión incondicional como referencia a evitar, se usa la predicción condicionada a lo que explícitamente no querés ver.

4. Textual inversion y DreamBooth

Dos técnicas para enseñarle al modelo un concepto nuevo (un objeto, una persona, un estilo) sin reentrenar nada de la red principal:

  • Textual inversion: se aprende un único embedding de texto nuevo (asociado a un token especial como <mi-objeto>) que, insertado en un prompt, hace que el modelo genere ese concepto — se optimiza solo ese vector, con el resto del modelo completamente congelado.
  • DreamBooth: en vez de aprender solo un embedding, hace fine-tuning del U-Net completo (o de un adapter) sobre un puñado de fotos del sujeto, asociándolo a un identificador raro para no chocar con conceptos que el modelo ya conoce.

📜 Es LoRA, antes de llamarse LoRA en este contexto

DreamBooth suele combinarse hoy con adapters tipo LoRA para hacer el fine-tuning barato en memoria — el mismo LoraConfig/peft que viste en el Capítulo 11 de HF, aplicado a un U-Net de difusión en vez de a un transformer de lenguaje. La técnica de "congelar casi todo, entrenar una pieza chica y barata" es transversal a toda la disciplina, no específica de texto ni de imagen.

5. Mixed precision: el detalle que hace todo esto viable

Entrenar en FP16 en vez de FP32 reduce a la mitad la memoria y acelera notablemente el cómputo en GPUs modernas — con un riesgo real de NaN por underflow en gradientes muy chicos. La solución estándar (MixedPrecision en miniai, accelerate en el ecosistema de Hugging Face) mantiene una copia maestra de los pesos en FP32, hace el forward/backward en FP16, y escala dinámicamente el loss antes de calcular gradientes para evitar que valores pequeños colapsen a cero en la representación de menor precisión.

🔧 Un peldaño en la misma escalera de precisión que ya conocés

FP32 → FP16/BF16 → NVFP4 son puntos sucesivos de la misma escalera de compromiso entre precisión y costo que ya recorriste a fondo en tu pipeline NVFP4 y en NVFP4 en difusión — con Flux2 y Wan 2.1 corriendo cuantizados a 4 bits por valor. Mixed precision (FP16/BF16) es el primer escalón de esa misma idea, aplicado durante el entrenamiento en vez de en inferencia: menos bits por número, mismo concepto de fondo, distinto punto del pipeline donde se aplica.

6. Resumen — cierre de fast.ai

  1. El U-Net de difusión combina downs/mids/ups con time embeddings (para saber cuánto ruido hay) y self-attention intercalada.
  2. La difusión latente corre ese U-Net sobre el espacio comprimido de un VAE, no sobre píxeles — el ahorro de cómputo que hace viable generar en segundos.
  3. El condicionamiento por texto usa cross-attention con embeddings de CLIP; classifier-free guidance y negative prompts controlan cuánto y en qué dirección seguir el prompt.
  4. Textual inversion y DreamBooth enseñan conceptos nuevos sin reentrenar el modelo completo — la misma filosofía de LoRA, aplicada a imagen.
  5. Mixed precision es el primer escalón de la misma escalera de cuantización que ya recorriste hasta NVFP4 en tus propios proyectos.

Con esto se cierra fast.ai completo — Parte 1 (8 lecciones + bonus de ética, con la profundidad completa del libro) y Parte 2 (5 unidades condensadas cubriendo las 17 lecciones de fundamentos y difusión, sin libro de referencia). El recorrido completo del objetivo activo — HF LLM Course de punta a punta, después fast.ai de punta a punta — queda cumplido acá.