27  Fine-tuning para clasificación y representación

Dónde estamos. Ya tenemos un modelo base potente (Cap. 25). Pocas veces lo usamos “tal cual”: lo adaptamos a una tarea —clasificar correos, medir si dos frases significan lo mismo, generar embeddings para buscar—. Este capítulo cubre las dos adaptaciones más clásicas: clasificar (poner una cabeza y afinar) y representar (producir buenos vectores de texto con aprendizaje contrastivo). El fine-tuning de instrucciones y RLHF van en el Cap. 27; LoRA/PEFT en el 28 — aquí no.

27.1 La idea en una frase

Un modelo pre-entrenado es un generalista que ya entiende el lenguaje; adaptarlo es darle un curso corto —añadir una pequeña pieza y reajustar— para una tarea concreta, o reorganizar su espacio de representaciones para que lo parecido quede cerca.

🧩 Analogía — el generalista que hace un curso. El modelo base es alguien con cultura amplísima (sabe lenguaje en general). El fine-tuning es un curso breve y enfocado en un oficio (detectar spam, sentimiento). No reaprende a leer desde cero: adapta lo que ya sabe, rápido y con pocos datos nuevos. Si le aprietas demasiado con el curso estrecho, olvida habilidades generales (lo veremos: olvido catastrófico).

27.2 Conceptos clave y su papel en el transformer

Antes de entrar en detalle, definimos los términos de este capítulo y para qué sirve cada uno dentro de un transformer:

  • Transferencia (pre-entrenar → adaptar). Definición: reutilizar un modelo de lenguaje general y reajustarlo a una tarea. En el transformer: el conocimiento del pre-entrenamiento se reaprovecha, así que bastan pocos ejemplos etiquetados.
  • Cabeza de clasificación. Definición: una capa lineal (\(W\in\mathbb{R}^{K\times H}\)) más softmax sobre el vector resumen. En el transformer: traduce las representaciones internas a una respuesta de clase; es lo único que nace de cero al afinar.
  • Pooling ([CLS] vs mean-pooling). Definición: cómo se condensa la secuencia en un único vector de frase. En el transformer: el [CLS] crudo es mal embedding; promediar los tokens va mejor.
  • Congelar vs afinar. Definición: dejar la base fija (solo entrenar la cabeza) o actualizar todos los pesos. En el transformer: barato y sin olvido frente a más preciso pero más caro.
  • Olvido catastrófico. Definición: que las actualizaciones de la tarea nueva sobrescriban lo aprendido antes. En el transformer: el riesgo de afinar todos los pesos; se mitiga descongelando poco a poco.
  • Anisotropía / similitud coseno. Definición: que los vectores se amontonen en un cono estrecho, midiendo “parecido” por el coseno del ángulo. En el transformer: explica por qué el [CLS] sin afinar discrimina mal —“todo se parece a todo”—.
  • Bi-encoder vs cross-encoder (Sentence-BERT). Definición: codificar cada frase por separado (vectores reutilizables) frente a juzgar el par junto. En el transformer: el bi-encoder hace escalable la búsqueda semántica (65 h → 5 s).
  • Aprendizaje contrastivo. Definición: acercar los pares positivos y alejar los negativos (pérdida NT-Xent, con temperatura \(\tau\) y negativos en lote). En el transformer: reorganiza el espacio de representaciones para que lo parecido quede cerca (alineamiento + uniformidad).

Con esos términos en la mano, vamos a los detalles.

27.3 El paradigma: pre-entrenar y luego adaptar

La receta dominante en PLN es pre-entrenar → adaptar. Una de sus primeras articulaciones claras fue ULMFiT (Howard y Ruder 2018): entrenar un modelo de lenguaje general y luego afinarlo a una tarea de clasificación, con trucos para no romper lo aprendido (learning rates por capa, descongelado gradual). El resultado que abrió los ojos: con 100 ejemplos etiquetados, ULMFiT igualaba a un modelo entrenado desde cero con 100× más datos. Esa es la magia de la transferencia: el conocimiento del pre-entrenamiento se reutiliza.

27.4 Clasificar: poner una cabeza y afinar

El patrón canónico lo fijó BERT (Devlin et al. 2019). La idea es sencilla:

  1. Pasas el texto por el modelo y tomas una representación resumen de la secuencia. En BERT, ese resumen es el estado final del token especial [CLS] (un vector \(C \in \mathbb{R}^{H}\), con \(H\) = dimensión oculta).
  2. Le enchufas encima una cabeza de clasificación: una capa lineal con pesos \(W \in \mathbb{R}^{K \times H}\) (con \(K\) = número de clases) que convierte ese vector resumen en logits de clase, y un softmax encima.
  3. Afinas todos los pesos (modelo + cabeza) de extremo a extremo con los datos etiquetados.

Vamos a la cabeza término a término, porque es la pieza nueva:

  • \(C \in \mathbb{R}^{H}\) = el vector resumen de la frase (lo que el modelo “entendió” de toda la secuencia, condensado en \(H\) números).
  • \(W \in \mathbb{R}^{K \times H}\) = la cabeza. Cada una de sus \(K\) filas es un “detector” de una clase; al multiplicar \(W\,C\) obtienes \(K\) puntuaciones, una por clase. Es lo único que nace de cero en el fine-tuning; todo lo demás ya venía entrenado.
  • El softmax convierte esas \(K\) puntuaciones en probabilidades que suman 1.

Su función en el sistema: la cabeza es el traductor entre el lenguaje interno del modelo (vectores de \(H\) dimensiones) y la pregunta concreta de tu tarea (“¿spam o no?”, “¿positivo, neutro o negativo?”). Sin ella, el modelo te da una representación rica pero no una respuesta; sin afinar, esa representación no está orientada a tu tarea.

27.4.1 Congelar o afinar: dos modos

Tienes dos formas de usar el modelo base:

  • Extracción de características (backbone congelado): dejas los pesos del modelo fijos y entrenas solo la cabeza sobre las representaciones que produce. Barato (puedes precalcular y cachear las representaciones), resiste mejor el sobreajuste con pocos datos, y no olvida nada.
  • Fine-tuning completo: actualizas todos los pesos. Más preciso —sobre todo con más datos etiquetados o cambio de dominio—, pero más caro y con más riesgo de sobreajuste y olvido.

¿Cuánto se gana afinando todo? En el propio BERT, sobre reconocimiento de entidades, el mejor método con backbone congelado quedó a solo ~0,3 puntos de F1 del fine-tuning completo. Es decir: BERT funciona bien de las dos formas; afinar todo gana un poco, a cambio de más coste.

Advertencia⚠ El olvido catastrófico

Cuando afinas un modelo en una tarea nueva, sus actualizaciones pueden sobrescribir lo aprendido antes —pierde de golpe capacidades previas—. Es el olvido catastrófico (McCloskey y Cohen, 1989; revisión de French, 1999). Por eso ULMFiT descongela las capas poco a poco y se usan learning rates pequeños: para adaptar sin borrar. Es el riesgo de “apretar demasiado el curso estrecho” de la analogía.

27.5 Representar: por qué el [CLS] crudo es un mal embedding

Aquí viene un giro importante. Si quieres un vector de frase para comparar significados (buscar, agrupar), te tienta usar el [CLS] de un BERT sin afinar… y es mala idea. La razón es geométrica:

  • Degeneración de representaciones (Gao et al. 2019): al entrenar por máxima verosimilitud, los embeddings tienden a apretujarse en un cono estrecho del espacio, lo que limita su poder de representación.
  • Anisotropía (Ethayarajh 2019): las representaciones contextuales de BERT, ELMo y GPT-2 no se reparten por el espacio; viven en un cono angosto, sobre todo en las capas altas, donde hasta palabras al azar tienen alta similitud coseno.

(Dos términos puente: similitud coseno = el coseno del ángulo entre dos vectores, 1 = misma dirección, 0 = perpendiculares; es como medimos “parecido”. Anisotropía = que los vectores apunten casi todos hacia el mismo lado, en vez de repartirse — entonces “todo se parece a todo” y el coseno deja de discriminar.)

La consecuencia es medible: en la tabla de Sentence-BERT, promediar vectores GloVe (viejos, no contextuales) da más correlación con el juicio humano de similitud (~61) que el vector [CLS] de BERT (~29). El [CLS] crudo es, de lejos, el peor. Por eso, si no vas a afinar, promediar los tokens (mean-pooling) ya va mejor que el [CLS].

27.6 Sentence-BERT: vectores de frase que sí sirven

La solución supervisada es Sentence-BERT (Reimers y Gurevych 2019): afinar BERT con una arquitectura siamesa (un bi-encoder) para que produzca vectores de frase comparables directamente por coseno. La clave es entender por qué no basta el BERT normal aplicado a pares:

  • Un cross-encoder mete las dos frases juntas y juzga su relación. Es preciso, pero para encontrar el par más parecido en una colección de 10 000 frases hace falta comparar todos los pares: ~50 millones de pasadas, ~65 horas. No escala a búsqueda.
  • Un bi-encoder codifica cada frase por separado en un vector reutilizable. Comparar es entonces calcular cosenos entre vectores ya precalculados: las mismas 65 horas se vuelven ~5 segundos.

La función de cada uno: el cross-encoder es para reordenar unos pocos candidatos con máxima precisión; el bi-encoder es para buscar/agrupar a gran escala, porque sus vectores se calculan una vez y se reusan. (Esto prepara el Cap. 31, RAG.)

27.7 Aprendizaje contrastivo: acercar lo parecido, alejar lo distinto

¿Cómo se entrena un buen espacio de embeddings? Con aprendizaje contrastivo: la idea es tirar de los pares positivos para juntarlos y empujar los negativos para separarlos.

🧩 Analogía — ordenar una biblioteca. Colocas los libros de modo que los parecidos (mismo tema, mismo autor) queden juntos y los distintos, lejos. Una vez ordenada, “encuéntrame libros como este” es solo coger los vecinos del estante, sin releer todos. (Y conviene que llenen toda la biblioteca, no que se amontonen en una esquina — justo el arreglo de la anisotropía.)

La función de pérdida moderna (la NT-Xent de SimCLR (Chen et al. 2020)) es:

\[ \mathcal{L}_i = -\log \frac{\exp\!\big(\operatorname{sim}(h_i, h_i^{+})/\tau\big)}{\sum_{j} \exp\!\big(\operatorname{sim}(h_i, h_j)/\tau\big)} \]

Término a término:

  • \(h_i\) = el ancla: el vector de la frase que estamos mirando.
  • \(h_i^{+}\) = su positivo: una frase emparejada (relacionada, o una “vista” alterada de la misma).
  • \(h_j\) = todos los candidatos del lote (incluye el positivo y el resto, que hacen de negativos).
  • \(\operatorname{sim}\) = la similitud coseno entre vectores normalizados.
  • \(\tau\) (temperatura) = un control de “cuánto castigar a los negativos difíciles”: \(\tau\) baja → la pérdida se obsesiona con los negativos más cercanos y los empuja con fuerza; \(\tau\) alta → los trata a todos por igual.
  • El numerador mide cuán cerca está el ancla de su positivo; el denominador, cuán cerca está de todo el mundo. La pérdida es baja solo si el positivo es, de lejos, lo más parecido al ancla. Eso es “acercar lo parecido y alejar lo demás”, escrito en matemáticas.

(Honestidad de linaje: esta forma con coseno + temperatura es la NT-Xent de SimCLR (2020). La “InfoNCE” original (Oord et al. 2018) usaba un producto escalar sin temperatura; conviene no confundirlas, aunque hoy “contrastivo” suele referirse a esta versión.)

Un truco que la hace barata: los negativos dentro del lote (in-batch negatives). Para cada ancla, las otras frases del mismo lote ya están codificadas → salen gratis como negativos.

Nota🧠 Curiosidad — el mismo texto, dos veces, como par positivo (SimCSE)

¿De dónde sacas “pares parecidos” sin etiquetas? SimCSE (Gao et al. 2021) tuvo una idea casi de chiste: pasar la misma frase dos veces por el modelo, con dos máscaras de dropout distintas (el ruido aleatorio que el modelo ya aplica al entrenar). Las dos salidas, ligeramente distintas, son un par positivo; las demás frases del lote, los negativos. Funciona sorprendentemente bien — y si quitas el dropout, las representaciones colapsan. Su versión supervisada usa pares de implicación (NLI) como positivos y contradicciones como negativos difíciles, llegando a ~81,6 de correlación (unos +2,2 puntos sobre el mejor resultado previo).

27.7.1 Qué hace bien un buen espacio: alineamiento y uniformidad

Dos propiedades miden la calidad de un espacio contrastivo (Wang y Isola 2020):

  • Alineamiento: los pares positivos quedan cerca (libros parecidos, vecinos).
  • Uniformidad: los vectores se reparten por toda la esfera, conservando el máximo de información (libros llenando toda la biblioteca, no amontonados).

La pérdida contrastiva optimiza ambas a la vez, y SimCSE mostró que precisamente rehace el espacio anisótropo de BERT para que sea más uniforme — cerrando el círculo con el problema del cono estrecho.

27.8 Modelos de embedding modernos (puente al RAG)

Esta maquinaria es la base de los buscadores semánticos de hoy:

  • DPR (Karpukhin et al. 2020): un bi-encoder para preguntas-respuestas, entrenado con negativos en lote + un negativo difícil minado por BM25. Superó a un buscador clásico (BM25) por 9-19% absoluto en recuperación top-20.
  • E5 (Wang et al. 2022): pre-entrenamiento contrastivo débilmente supervisado sobre pares de texto; primer modelo que batió a BM25 en el benchmark BEIR sin datos etiquetados.
  • MTEB (Muennighoff et al. 2022): el leaderboard estándar de embeddings8 tipos de tarea, 58 datasets, 112 idiomas — la forma en que hoy se comparan estos modelos.

La receta común: lotes grandes (muchos negativos en lote) + negativos difíciles. Lo retomaremos en el Cap. 31 (RAG).

27.9 Cuándo afinar y cuándo usar embeddings de estantería

  • Afina cuando tienes una tarea fija con datos etiquetados suficientes y quieres la máxima precisión o adaptarte a un dominio concreto.
  • Usa embeddings congelados (de estantería) para búsqueda/agrupamiento, cuando muchos usos comparten un mismo espacio de vectores, cuando hay pocas etiquetas, o cuando el coste de cómputo/servicio importa (calcula el vector una vez, reúsalo).
Nota🧪 Pruébalo — tafagent

tafagent perfila el modelo base que vas a adaptar: su γ (alcance), régimen y presupuesto de KV. Útil antes de afinar para saber con qué comportamiento de atención partes —si vas a usarlo como encoder de embeddings para textos largos, su perfil de decaimiento (Cap. 15-20) te dice hasta dónde “ve” de verdad—.

27.10 Resumen

  • Paradigma: pre-entrenar → adaptar (ULMFiT); el conocimiento base se reutiliza (100 ejemplos ≈ 100× más datos desde cero).
  • Clasificar: añadir una cabeza lineal (\(W \in \mathbb{R}^{K\times H}\)) sobre el resumen [CLS] y afinar. Congelado (solo cabeza, barato, sin olvido) vs completo (más preciso, ~0,3 F1 más en BERT) — ojo al olvido catastrófico.
  • Representar: el [CLS] crudo es mal embedding (anisotropía/cono estrecho); mean-pooling va mejor; Sentence-BERT (bi-encoder) da vectores reutilizables por coseno (65 h → 5 s frente al cross-encoder).
  • Contrastivo: acercar positivos, alejar negativos (pérdida NT-Xent, con coseno + temperatura \(\tau\)); negativos en lote gratis; alineamiento + uniformidad.
  • SimCSE: mismo texto con dos dropouts = par positivo (no supervisado); NLI con negativos difíciles (supervisado).
  • Modernos: DPR, E5, evaluados en MTEB — base del buscador semántico (→ RAG, Cap. 31).

Siguiente (Capítulo 27): afinar para clasificar es una cosa; lograr que un modelo siga instrucciones y se alinee con lo que queremos es otra. Entramos en SFT, RLHF y DPO.

27.11 Ejercicios

  1. La cabeza. En la cabeza \(W \in \mathbb{R}^{K\times H}\), ¿qué representan \(K\) y \(H\)? ¿Por qué es “lo único que nace de cero” al afinar?
  2. Congelar vs afinar. Tienes 200 ejemplos etiquetados y poco cómputo. ¿Qué modo elegirías y por qué? ¿Y si tuvieras 2 millones?
  3. El [CLS] crudo. Explica con la palabra “anisotropía” por qué el [CLS] de un BERT sin afinar es un mal vector de frase.
  4. Bi vs cross. ¿Por qué un cross-encoder no escala a buscar en 10 000 frases y un bi-encoder sí? ¿Qué precalcula el bi-encoder?
  5. Temperatura. En la pérdida contrastiva, ¿qué le pasa al tratamiento de los negativos difíciles si bajas mucho \(\tau\)?
  6. SimCSE. ¿Cómo construye SimCSE un par positivo sin etiquetas, y qué ocurre si quitas el dropout?

Referencias

Chen, Ting, Simon Kornblith, Mohammad Norouzi, y Geoffrey Hinton. 2020. «A Simple Framework for Contrastive Learning of Visual Representations». ICML. https://arxiv.org/abs/2002.05709.
Devlin, Jacob, Ming-Wei Chang, Kenton Lee, y Kristina Toutanova. 2019. «BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding». NAACL. https://arxiv.org/abs/1810.04805.
Ethayarajh, Kawin. 2019. «How Contextual Are Contextualized Word Representations? Comparing the Geometry of BERT, ELMo, and GPT-2 Embeddings». EMNLP. https://arxiv.org/abs/1909.00512.
Gao, Jun, Di He, Xu Tan, Tao Qin, Liwei Wang, y Tie-Yan Liu. 2019. Representation Degeneration Problem in Training Natural Language Generation Models. https://arxiv.org/abs/1907.12009.
Gao, Tianyu, Xingcheng Yao, y Danqi Chen. 2021. «SimCSE: Simple Contrastive Learning of Sentence Embeddings». EMNLP. https://arxiv.org/abs/2104.08821.
Howard, Jeremy, y Sebastian Ruder. 2018. «Universal Language Model Fine-tuning for Text Classification». ACL. https://arxiv.org/abs/1801.06146.
Karpukhin, Vladimir et al. 2020. «Dense Passage Retrieval for Open-Domain Question Answering». EMNLP. https://arxiv.org/abs/2004.04906.
Muennighoff, Niklas, Nouamane Tazi, Loïc Magne, y Nils Reimers. 2022. MTEB: Massive Text Embedding Benchmark. https://arxiv.org/abs/2210.07316.
Oord, Aaron van den, Yazhe Li, y Oriol Vinyals. 2018. Representation Learning with Contrastive Predictive Coding. https://arxiv.org/abs/1807.03748.
Reimers, Nils, y Iryna Gurevych. 2019. «Sentence-BERT: Sentence Embeddings Using Siamese BERT-Networks». EMNLP. https://arxiv.org/abs/1908.10084.
Wang, Liang, Nan Yang, Xiaolong Huang, et al. 2022. Text Embeddings by Weakly-Supervised Contrastive Pre-training (E5). https://arxiv.org/abs/2212.03533.
Wang, Tongzhou, y Phillip Isola. 2020. «Understanding Contrastive Representation Learning Through Alignment and Uniformity on the Hypersphere». ICML. https://arxiv.org/abs/2005.10242.