Phase 12 - Lesson 01

Vision Transformers y la Primitiva de Patch-Token

This lesson includes a graded coding exercise that runs in your browser, unlocked with lifetime access.

Antes de cualquier procesamiento multimodal, una imagen debe convertirse en una secuencia de tokens que un transformer pueda consumir. El artículo de ViT de 2020 resolvió esto con parches de 16x16 píxeles, una proyección lineal y un embedding de posición. Cinco años después, todos los modelos de frontera de 2026 (Claude Opus 4.7 en 2576px nativo, Gemini 3.1 Pro, Qwen3.5-Omni) siguen comenzando de esta manera: el codificador cambió de ViT a DINOv2 y luego a SigLIP 2, se agregaron tokens de registro y el esquema posicional pasó a ser 2D-RoPE, pero la primitiva se mantuvo. Esta lección analiza el pipeline de patch-token de extremo a extremo y lo construye en Python estándar para que el resto de la Fase 12 tenga un modelo mental concreto para los "tokens visuales".

Tipo: Conhecimento Idiomas: Python (librería estándar, tokenizador de parches + calculadora de geometría) Prerrequisitos: Fase 7 (Transformers), Fase 4 (Visión Computacional) Tiempo: ~120 minutos

Objetivos de Aprendizaje

  • Convertir una imagen HxWx3 en una secuencia de tokens de parches con la codificación posicional correcta.
  • Calcular la longitud de la secuencia, la cantidad de parámetros y los FLOPs para un ViT con base en (tamaño del parche, resolución, dimensión oculta, profundidad).
  • Nombrar las tres mejoras que llevaron a ViT de la investigación en 2020 a la producción en 2026: preentrenamiento autosupervisado (DINO / MAE), tokens de registro y empaquetado de resolución nativa.
  • Elegir entre CLS pooling, mean pooling y tokens de registro para una tarea downstream.

El Problema

Los transformers operan en secuencias de vectores. El texto ya es una secuencia (bytes o tokens). Una imagen es una cuadrícula 2D de píxeles con tres canales de color, no una secuencia. Si se aplana cada píxel, una imagen RGB de 224x224 se convierte en 150,528 tokens, y la autoatención (self-attention) con esa longitud es inviable (cuadrática en la longitud de la secuencia).

Los enfoques anteriores a 2020 acoplaban un extractor de características CNN en la entrada: ResNet produce un mapa de características de 7x7 de vectores de dimensión 2048, alimentando esos 49 tokens a un transformer. Esto funciona pero hereda los sesgos de la CNN (equivarianza de traslación, campos receptivos locales) y pierde el apetito por la escala del transformer.

Dosovitskiy et al. (2020) plantearon la pregunta directa: ¿qué pasa si nos saltamos la CNN? Dividir la imagen en parches de tamaño fijo (por ejemplo, 16x16 píxeles), proyectar linealmente cada parche en un vector, agregar un embedding posicional y alimentar la secuencia a un transformer convencional. En ese momento esto era una herejía: visión sin convoluciones. Con suficientes datos (JFT-300M, luego LAION), superó a ResNet en ImageNet y siguió mejorando.

Para 2026, la primitiva ViT es la base incuestionable. La torre de visión de cada VLM open-weights es algún descendiente (DINOv2, SigLIP 2, CLIP, EVA, InternViT). La pregunta ya no es "¿deberíamos usar parches?", sino "¿qué tamaño de parche, qué esquema de resolución, qué objetivo de preentrenamiento, qué codificación posicional?".

El Concepto

Los parches como tokens

Dada una imagen x de forma (H, W, 3) y un tamaño de parche P, se divide la imagen en una cuadrícula de (H/P) x (W/P) parches que no se solapan. Cada parche es un cubo de píxeles de P x P x 3. Se aplana cada cubo a un vector de 3 P^2. Se aplica una proyección lineal compartida W_E de forma (3 P^2, D) para mapear cada parche a la dimensión oculta D del modelo.

Para la configuración canónica de ViT-B/16:

  • Resolución 224, tamaño del parche 16 → cuadrícula 14x14 → 196 tokens de parche.
  • Cada parche consiste en 16 x 16 x 3 = 768 valores de píxeles, proyectados a D = 768.
  • Se agrega un token [CLS] aprendible → longitud de secuencia de 197.

La proyección de parches es matemáticamente idéntica a una convolución 2D con tamaño de kernel P, stride P y D canales de salida. Así es como el código de producción lo implementa en realidad: nn.Conv2d(3, D, kernel_size=P, stride=P). El marco de "proyección lineal" es conceptual; el marco del kernel es eficiente.

Embeddings posicionales

Los parches no tienen un orden intrínseco; el transformer los ve como un conjunto desordenado. Los primeros ViT agregaban un embedding posicional 1D aprendible (un vector de dimensión 768 por posición, 197 en total). Esto funciona, pero vincula el modelo a la resolución de entrenamiento: en la inferencia, se debe interpolar la tabla de posiciones si se cambia la cuadrícula.

Los backbones de visión modernos utilizan 2D-RoPE (M-RoPE de Qwen2-VL, el predeterminado de SigLIP 2) o posiciones 2D factorizadas. 2D-RoPE rota los vectores de consulta (query) y clave (key) según el índice (fila, columna) del parche, por lo que el modelo infiere la posición 2D relativa a partir del ángulo de rotación. Sin tabla de posiciones. El modelo maneja tamaños de cuadrícula arbitrarios durante la inferencia.

Token CLS, salida agregada (pooled output) y tokens de registro

¿Cuál es la representación a nivel de imagen? Coexisten tres opciones:

  1. Token [CLS]. Antepone un vector aprendible a la secuencia de parches. Después de todos los bloques del transformer, el estado oculto del token CLS es la representación de la imagen. Heredado de BERT. Utilizado por el ViT original y CLIP.
  2. Promedio simple (Mean pool). Promedia los estados ocultos de salida de los tokens de parches. Utilizado por SigLIP, DINOv2 y la mayoría de los VLM modernos.
  3. Tokens de registro (Register tokens). Darcet et al. (2023) observaron que los ViT entrenados sin un token de sumidero (sink token) explícito desarrollan parches "artefacto" de norma alta que secuestran la autoatención. Agregar de 4 a 16 tokens de registro aprendibles absorbe esta carga y mejora la calidad de la predicción densa (segmentación, profundidad). Tanto DINOv2 como SigLIP 2 se distribuyen con registros.

La elección es importante para las tareas downstream. CLS es adecuado para la clasificación. Para los VLM que alimentan tokens de parches a un LLM, se omite el pooling por completo: cada parche se convierte en un token de entrada del LLM. Los registros se descartan antes de la entrega (son andamiaje, no contenido).

Preentrenamiento: supervisado, contrastivo, mascarado, autodestilado

El ViT de 2020 se preentrenó con clasificación supervisada en JFT-300M. Rápidamente suplantado por:

  • CLIP (2021): contraste imagen-texto en 400 millones de parejas. Lección 12.02.
  • MAE (2021, He et al.): mascara el 75% de los parches y reconstruye los píxeles. Autosupervisado, funciona en imágenes puras.
  • DINO (2021) / DINOv2 (2023): autodistilación con estudiante-profesor, sin etiquetas, sin subtítulos. El DINOv2 ViT-g/14 de 2023 es el backbone puramente visual más fuerte y el predeterminado para casos de uso de "características densas".
  • SigLIP / SigLIP 2 (2023, 2025): CLIP con pérdida sigmoide y NaFlex para relación de aspecto nativa. La torre de visión dominante en los VLM abiertos de 2026 (Qwen, Idefics2, LLaVA-OneVision).

La elección del preentrenamiento determina para que sirve el backbone: CLIP/SigLIP para emparejamiento semántico con texto, DINOv2 para características visuales densas y MAE como punto de partida para el ajuste fino (finetuning) downstream.

Leyes de escala

La escala de ViT (Zhai et al. 2022) estableció que la calidad de un ViT obedece a leyes predecibles en tamaño de modelo, tamaño de datos y cómputo. Con cómputo fijo:

  • Modelo más grande + más datos → mejor calidad.
  • El tamaño del parche es una palanca entre la longitud de la secuencia y la fidelidad. El parche 14 (típico de DINOv2/SigLIP SO400m) genera más tokens por imagen que el parche 16; mejor para OCR y tareas densas, peor para la velocidad.
  • La resolución es la otra gran palanca. Pasar de 224 a 384 y luego a 512 casi siempre ayuda, con un costo cuadrático en FLOPs.

ViT-g/14 (1B de parámetros, parche 14, resolución 224 → 256 tokens) y SigLIP SO400m/14 (400M de parámetros, parche 14) son los dos codificadores más comunes para los VLM abiertos de 2026.

Recuento de parámetros para un ViT

El cálculo completo está en code/main.py. Para ViT-B/16 en 224:

patch_embed = 3 * 16 * 16 * 768 + 768  =  591k
cls + pos    = 768 + 197 * 768          =  152k
block        = 4 * 768^2 (QKVO) + 2 * 4 * 768^2 (MLP) + 2 * 2*768 (LN)
             = 12 * 768^2 + 3k          =  7.1M
12 blocks    = 85M
final LN    = 1.5k
total       ≈ 86M

Estime cada ViT de esta manera antes de cargar el checkpoint. El tamaño del backbone establece su límite mínimo de VRAM en cualquier VLM downstream.

Configuración de producción de 2026

El codificador con el que se distribuyen la mayoría de los VLM abiertos en 2026 es SigLIP 2 SO400m/14 en resolución nativa (NaFlex). Tiene:

  • 400 millones de parámetros.
  • Tamaño de parche 14, resolución predeterminada 384 → 729 tokens de parche por imagen.
  • Promedio simple (Mean pool) para tareas a nivel de imagen; los 729 parches fluyen hacia el LLM para VQA.
  • 4 tokens de registro, descartados antes de la entrega al LLM.
  • 2D-RoPE con escalado a nivel de imagen para relación de aspecto nativa.

Cada decisión en esa configuración proviene de un artículo que puede leer.

Uso

El archivo code/main.py es un tokenizador de parches y una calculadora de geometría. Recibe (H de imagen, W, parche P, D oculto, profundidad L) y reporta:

  • La forma de la cuadrícula y la longitud de la secuencia después de aplicar los parches.
  • Secuencia de tokens para una imagen sintética de juguete de 8x8 píxeles (siguiendo la ruta de aplanar + proyectar).
  • El recuento de parámetros desglosado por embedding de parche, embedding de posición, bloques de transformer y cabezal.
  • FLOPs por forward pass en la resolución objetivo.
  • Una tabla de comparación entre ViT-B/16 @ 224, ViT-L/14 @ 336, DINOv2 ViT-g/14 @ 224, SigLIP SO400m/14 @ 384.

Ejecútelo. Compare el recuento de parámetros con los números publicados. Juegue con el tamaño del parche y la resolución para sentir el costo del recuento de tokens.

Envío

Esta lección produce outputs/skill-patch-geometry-reader.md. Dada una configuración de ViT (tamaño de parche, resolución, dimensión oculta, profundidad), produce una estimación de recuento de tokens, recuento de parámetros y VRAM con justificaciones. Use esta habilidad cada vez que elija un backbone de visión para un VLM; esto evita sorpresas del tipo "los tokens explotaron y mi contexto de LLM se llenó".

Ejercicios

  1. Calcule la longitud de la secuencia de tokens de parche para Qwen2.5-VL en una entrada nativa de 1280x720 con un tamaño de parche de 14. ¿Cómo se compara eso con una representación de solo CLS?

  2. ¿Cuántos tokens produce un fotograma de 1080p (1920x1080) con un parche de 14? A 30 FPS en un video de 5 minutos, ¿cuántos tokens visuales se obtienen en total? ¿Qué optimización de costos le ahorra más: pooling, muestreo de fotogramas (frame sampling) o fusión de tokens (token merging)?

  3. Implemente mean pooling sobre tokens de parches en Python puro. Verifique que el mean-pool sobre 196 tokens de una salida de DINOv2 coincida con lo que devuelve el forward del modelo cuando solicita un embedding agrupado (pooled embedding).

  4. Lea la Sección 3 de "Vision Transformers Need Registers" (arXiv:2309.16588). Describa en dos oraciones qué artefacto absorben los registros y por qué es importante para la predicción densa downstream.

  5. Modifique code/main.py para admitir patch-n'-pack: dada una lista de imágenes de diferentes resoluciones, produzca una única secuencia empaquetada y la máscara de atención diagonal por bloques. Verifique con respecto a la Lección 12.06 cuando llegue a ella.

Términos Clave

Término Lo que dice la gente Lo que realmente significa
Patch "Cuadrado de 16x16 píxeles" Una región de tamaño fijo que no se superpone de la imagen de entrada; se convierte en un token
Embedding de parche (Patch embedding) "Proyección lineal" Una matriz de aprendizaje compartida (o Conv2d con stride=P) que mapea los píxeles aplanados del parche a vectores de dimensión D
Token CLS "Token de clase" Vector de aprendizaje prepuesto cuyo estado oculto final representa toda la imagen; opcional en 2026
Token de registro (Register token) "Token de sumidero" Tokens de aprendizaje adicionales que absorben los artefactos de atención de alta norma que desarrollan los ViT durante el preentrenamiento
Embedding de posición (Position embedding) "Información posicional" Vector o rotación por posición que hace que la secuencia reconozca el orden; 2D-RoPE es el valor predeterminado moderno
Cuadrícula (Grid) "Cuadrícula de parches" La matriz 2D (H/P) x (W/P) de parches para una resolución y tamaño de parche determinados
NaFlex "Resolución flexible nativa" Característica de SigLIP 2: un solo modelo sirve para múltiples relaciones de aspecto y resoluciones sin volver a entrenar
Backbone "Torre de visión" El codificador de imágenes preentrenado cuyas salidas de tokens de parche alimentan al LLM en un VLM
Pooling "Resumen a nivel de imagen" Estrategia para convertir tokens de parche en un solo vector: CLS, promedio (mean), pooling de atención o basado en registros
Parche 14 vs 16 "Cuadrícula más fina vs más gruesa" El parche 14 produce más tokens por imagen, mejor fidelidad para OCR, más lento; el parche 16 es el valor predeterminado clásico

Lecturas Adicionales

0 lifetime access. Curriculum based on AI Engineering from Scratch by Rohit Ghumare (MIT, used under attribution).