PASO 9 / 10

Output / Softmax

Después de pasar por todos los bloques, tenemos vectores procesados. Ahora hay que convertirlos en una predicción concreta: ¿cuál es la siguiente palabra? Acá se cierra el ciclo de generación.

🎯 De un vistazo

Este es el paso final del "forward pass": tomar el vector procesado y convertirlo en una palabra concreta.

PROPÓSITO

¿Para qué sirve?

Convertir el vector final en una probabilidad sobre todo el vocabulario, y a partir de ahí elegir la siguiente palabra que el modelo va a generar.

APORTE

¿Qué aporta al modelo?

La salida concreta: traduce los vectores abstractos a algo usable (una palabra). También permite controlar la "creatividad" del modelo (temperatura, sampling).

NECESIDAD

¿Por qué es indispensable?

Sin este paso, el modelo solo produce vectores de números que nadie entiende. Es lo que cierra la brecha entre "cómputo interno" y "texto que leés en pantalla".

↓ A continuación, el detalle con ejemplos y visualizaciones ↓

1. ¿Dónde estamos?

Recapitulemos. Le dimos al modelo la frase "el perro come" y queremos que prediga la siguiente palabra. Hasta ahora:

Para predecir la siguiente palabra usamos el vector del ÚLTIMO token. En "el perro come", usamos el vector de "come". ¿Por qué el último? Porque ese vector, gracias a la atención, ya "absorbió" información de toda la frase anterior, y es el que está en posición de predecir qué viene después.

El vector que vamos a usar

Vector final de "come" (después de los N bloques):
  vec_final = [+0.85, -0.42, +0.33, +1.20]   (dim 4)

Este vector ya "entiende" que viene después de "el perro come".
Nuestra tarea: convertirlo en una predicción de palabra.

2. Del vector final a los "logits"

Primer paso: convertir el vector (dim 4) en un puntaje por cada palabra del vocabulario. Si el vocabulario tiene 8 palabras, necesitamos 8 puntajes. Esos puntajes se llaman logits.

¿Cómo? Multiplicando el vector final por una matriz especial llamada matriz de "des-embedding" (o "unembedding"), de forma [d_model × vocab_size]. Es básicamente lo opuesto al paso 2: en lugar de "palabra → vector", hace "vector → puntaje por palabra".
logits = vec_final · Wunembed

[dim 4] · [4 × 8] = [dim 8] — un puntaje por cada una de las 8 palabras del vocabulario

💡 Dato: weight tying

En muchos modelos, la matriz de unembedding es literalmente la matriz de embeddings del paso 2, pero traspuesta (filas ↔ columnas). Esto se llama "weight tying" y ahorra millones de parámetros. Tiene sentido: la misma "tabla" que traduce palabra→vector se reutiliza para vector→palabra.

Nuestro vocabulario de ejemplo (8 palabras)

Para visualizar, usamos un vocabulario chiquito de 8 palabras candidatas para seguir "el perro come ___":

Los logits calculados

Multiplicando el vector de "come" por la matriz de unembedding, obtenemos un logit por palabra:

Los logits son puntajes "crudos" — pueden ser positivos o negativos, no suman nada en particular. Todavía NO son probabilidades. Para eso falta el softmax.

3. Softmax → probabilidades

Ya conocés softmax del paso 4. Lo aplicamos a los logits para convertirlos en probabilidades (todas entre 0 y 1, suman 1):

probabilidad(palabra) = elogit / Σ elogits

Distribución de probabilidad sobre el vocabulario

Ahora SÍ son probabilidades. La palabra con la barra más larga es la que el modelo considera más probable como continuación de "el perro come".

El modelo no "decide" una palabra — produce una distribución de probabilidad sobre TODAS las palabras del vocabulario. En un modelo real, esa distribución es sobre ~50,000 palabras. Acá la simplificamos a 8 para poder verla.

4. Sampling: ¿cómo se elige LA palabra?

Tenemos una distribución de probabilidad. Pero al final hay que elegir UNA palabra concreta. Hay varias estrategias, y la elección afecta mucho el "estilo" del texto generado.

🎮 Probá las distintas estrategias

Estrategia:

Resumen de estrategias

Estrategia Qué hace Resultado
Greedy Siempre elige la palabra más probable. Determinista. Texto coherente pero repetitivo y "aburrido".
Temperature Divide los logits por T antes del softmax. T<1 = más confiado; T>1 = más aleatorio. Controla la "creatividad". T alto = más variado pero más errores.
Top-k Solo considera las k palabras más probables, descarta el resto. Evita elegir palabras absurdas (cola larga de baja probabilidad).
Top-p (nucleus) Considera las palabras más probables hasta que su suma llegue a p (ej. 0.9). Adaptativo: pocas opciones cuando el modelo está seguro, más cuando duda.

5. El bucle autoregresivo: generar palabra por palabra

Algo que sorprende a mucha gente: el modelo NO genera la frase completa de una vez. Genera UNA palabra, la agrega al texto, y vuelve a correr TODO el modelo desde el principio para predecir la siguiente. Repite hasta terminar.

1 Input: "el perro come" → modelo → predice "carne"
2 Input: "el perro come carne" → modelo → predice "porque"
3 Input: "el perro come carne porque" → modelo → predice "tiene"
4 Input: "el perro come carne porque tiene" → modelo → predice "hambre"
5 ... continúa hasta predecir un token especial de "fin de texto" <|endoftext|>

🎮 Simulá la generación

Apretá "Generar siguiente palabra" y mirá cómo se va construyendo el texto, palabra por palabra:

el perro come
0.8
Esto explica varias cosas que ves al usar ChatGPT/Claude:
  • Por qué el texto aparece palabra por palabra (cada una requiere un forward pass completo).
  • Por qué a veces "se contradice" — solo ve lo que generó hasta ahora, no planea la frase entera.
  • Por qué textos más largos cuestan más (más palabras = más pasadas por el modelo).

✅ Resumen: el modelo ya genera texto

  1. Tomamos el vector del último token (el más "informado").
  2. Lo multiplicamos por la matriz de unembedding → logits (un puntaje por palabra).
  3. Aplicamos softmax → probabilidades sobre el vocabulario.
  4. Elegimos una palabra con una estrategia de sampling (greedy, temperature, top-k, top-p).
  5. Agregamos esa palabra al texto y repetimos todo (bucle autoregresivo) hasta terminar.

¡Con esto, el modelo ya genera texto! Falta entender una sola cosa: ¿cómo aprendió todos esos pesos? Las matrices de embeddings, de atención, de FFN, etc. no aparecieron de la nada.

En el Paso 10: Entrenamiento (el último) vamos a ver cómo, a partir de billones de ejemplos de texto, el modelo ajusta todos sus parámetros para predecir cada vez mejor la siguiente palabra.