Lección 3

Bigram: aprender sin neuronas

Antes de construir una red neuronal, vamos a resolver el problema de la manera más ingenua posible: contando. Esto es train0.py de Karpathy.

1. El camarero con buena memoria

Imagina un camarero que trabaja en el mismo bar hace 10 años. Nunca tomó cursos de psicología ni leyó libros de patrones de consumo. Pero ha atendido miles de pedidos. Cuando escucha "quiero un café con...", automáticamente dice "¿leche?" porque el 80% de las veces que alguien dijo "café con" en su bar, la siguiente palabra fue "leche".

No aprendió una regla. Solo acumuló conteos. Eso es exactamente el modelo bigram.

☕ La tabla bigram es como la memoria del camarero: guarda, para cada par (carácter_actual, carácter_siguiente), cuántas veces apareció esa combinación en el dataset. Cuando necesita predecir, solo consulta la fila del carácter actual y elige el más frecuente.

2. La tabla de conteo

Una tabla bigram es una matriz de 27×27. Cada posición tabla[i][j] contiene un número: cuántas veces el token j apareció inmediatamente después del token i en el dataset.

✍️ Construyendo la tabla con el nombre "emma"
El nombre "emma" con tokens BOS:
  [BOS] → e → m → m → a → [BOS]
  [26]  → [4]→[12]→[12]→[0]→[26]

Cada par (actual → siguiente) actualiza la tabla:
  tabla[26][4]  += 1   ← [BOS]→e: empezar con 'e'
  tabla[4][12]   += 1   ← e→m
  tabla[12][12]  += 1   ← m→m
  tabla[12][0]   += 1   ← m→a
  tabla[0][26]   += 1   ← a→[BOS]: terminar con 'a'

Hacemos esto para los 32.000 nombres del dataset.
Al final, tabla[i][j] contiene el número de veces que
el carácter j siguió al carácter i en todo el dataset.
      
Heatmap · Tabla bigram (subconjunto: 6 caracteres)
Heatmap de tabla bigram para los caracteres a, e, i, n, r y [BOS] Matriz 6x6 donde el color de cada celda indica la frecuencia del par (fila→columna). Más cyan = más frecuente.

Más brillante = más frecuente ese par en el dataset de nombres. La fila [BOS] muestra qué letras inician los nombres más frecuentemente.

3. De conteos a probabilidades

Una vez que tienes la tabla de conteos, convertirla en probabilidades es dividir cada fila por la suma de esa fila. Si después de "a" apareció "n" 500 veces, "l" 300 veces y otras letras 200 veces (total 1000), entonces:

✍️ De conteos a probabilidades para la fila "a"
Conteos después de 'a' (simplificado):
  a→n: 500  a→l: 300  a→r: 120  a→[BOS]: 80

Total: 500 + 300 + 120 + 80 = 1000

Probabilidades:
  P(n|a) = 500/1000 = 0.50  (50%)
  P(l|a) = 300/1000 = 0.30  (30%)
  P(r|a) = 120/1000 = 0.12  (12%)
  P([BOS]|a) = 80/1000 = 0.08  (8%) ← termina aquí

Suma: 0.50 + 0.30 + 0.12 + 0.08 = 1.00 ✅

Para generar el siguiente carácter desde 'a':
→ Lanzamos un dado ponderado con estas probabilidades.
  La mayoría de las veces saldrá 'n', pero a veces 'l', etc.
      

4. Generando nombres con la tabla

Con la tabla lista, generar un nombre es un proceso simple de 4 pasos que se repite:

Proceso · Generación con bigram
Proceso de generación con tabla bigram INICIO [BOS] token actual CONSULTAR fila [BOS] de la tabla MUESTREAR a próximo token ¿ES [BOS]? SÍ → nombre listo NO → volver al paso 2

El proceso se repite hasta generar el token [BOS], que marca el fin del nombre.

🎮 Generador bigram en vivo

Esta demo usa una tabla bigram simplificada basada en frecuencias reales de nombres. Mueve el slider de temperatura y presiona "Generar" para ver nombres nuevos.

0.8

Temperatura 0.5 = conservador (nombres más comunes). Temperatura 2.0 = creativo (nombres raros).

Presiona "Generar 10 nombres" →

5. Las limitaciones del bigram

El modelo bigram es simple y funciona hasta cierto punto. Pero tiene una limitación fundamental:

⚠️ El bigram solo recuerda el último carácter. Para decidir qué sigue después de "karpathy", solo mira la "y" — no sabe que empezó con "k". Una red neuronal puede considerar todo el contexto anterior, no solo el carácter inmediato.
CaracterísticaBigram (train0)GPT completo (train5)
Contexto que consideraSolo el carácter anteriorTodos los anteriores (hasta 16)
Parámetros que aprende0 (solo cuenta)3.808 parámetros
Puede generalizarNo — solo lo que vioSí — interpola patrones
ComplejidadUna tablaTokenizador + atención + MLP + Adam
🔑 El bigram es el punto de partida de Karpathy (train0.py) porque demuestra el problema en su forma más simple. Cada lección siguiente agrega una pieza que resuelve una limitación del anterior.

6. Lo que aprendiste

En esta lección:
  • Un modelo bigram es una tabla 27×27 que cuenta cuántas veces cada par (actual → siguiente) apareció en el dataset.
  • Para predecir, divide los conteos por la suma de la fila → probabilidades que suman 1.
  • Para generar, empieza en [BOS] y muestrea repetidamente hasta volver a [BOS].
  • La limitación es que solo mira el carácter inmediato anterior — sin memoria de contexto más largo.