¿Te resulta más fácil leer con fondo crema, un tono de color, más contraste o un texto más grande? Elige tus colores y tu texto una sola vez, para todas las páginas.

Lección gratuita

Dentro de un bloque transformer

Después de esta lección: Puedo seguir un token a través de los pasos de un bloque transformer.

Lección de 65 min2 comandosLaboratorio JupyterLab de ciencia de datos: pandas, Matplotlib y scikit-learn en el navegador

La pieza que repite un modelo de lenguaje

Un bloque transformer es la unidad con la que se construye un modelo de lenguaje, y un modelo apila ese mismo bloque muchas veces. Contiene una atención enmascarada con varias cabezas y luego una pequeña red para cada token. Unos atajos y un reajuste de escala rodean las dos partes.

Quien entiende un bloque entiende la forma del modelo entero.

Al final de esta lección

Nota

Puedo seguir un token a través de los pasos de un bloque transformer.

Palabras clave

PalabraQué significa
Máscara causalimpide que un token mire a los tokens siguientes
Cabezaun paso de atención con sus propias tablas de consulta, clave y valor
Etapa densauna pequeña red aplicada a cada token por separado
Conexión residualsuma la entrada de un paso a su salida
Normalizaciónreajusta un vector para que sus números tengan un tamaño estable
Bloqueatención y etapa densa con sus residuos, repetidos para formar un modelo

Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.

Una máscara causal oculta el futuro

Un modelo de lenguaje aprende a adivinar el token siguiente. Si un token pudiera mirar a los tokens de después, vería la respuesta.

Por eso una máscara causal deja que cada token mire solo a sí mismo y a los tokens anteriores. Un token posterior recibe un peso de 0. En la práctica, su puntuación pasa a menos infinito antes del softmax, porque e elevado a menos infinito vale 0.

Ejemplo resuelto: los pesos con el futuro enmascarado

TokenPuntuacionesPuede mirarPesos
Primero1, 2, 0solo el primero1, 0, 0
Segundo2, 1, 1el primero y el segundo0,731, 0,269, 0
Tercero0, 1, 3los tres0,042, 0,114, 0,844

Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.

Enmascarar el futuro en Python

Código: python
import math

# scores[i][j]: cuánto encaja la consulta del token i con la clave del token j.
scores = [[1, 2, 0], [2, 1, 1], [0, 1, 3]]

for i in range(3):
    powers = []
    for j in range(3):
        if j <= i:
            powers.append(math.exp(scores[i][j]))
        else:
            # Un token posterior: enmascarado, no recibe ningún peso.
            powers.append(0)
    total = sum(powers)
    weights = []
    for p in powers:
        weights.append(round(p / total, 3))
    print("token", i, "pesos", weights)
# Cambia j <= i por True, para no enmascarar nada, y pulsa Ejecutar.
# ¿Cómo cambia la fila del primer token, y por qué es hacer trampa?

La misma máscara con NumPy

Comando
docker exec jupyter python3 -c "import numpy as np; S = np.array([[1, 2, 0], [2, 1, 1], [0, 1, 3]], dtype=float); S[np.triu(np.ones((3, 3), dtype=bool), 1)] = -np.inf; W = np.exp(S) / np.exp(S).sum(axis=1, keepdims=True); print(W.round(3).tolist())"

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Varias cabezas buscan cosas distintas

Un paso de atención solo mezcla de una manera. Por eso un bloque ejecuta varias cabezas en paralelo, cada una con sus propias tablas de consulta, clave y valor.

Una cabeza puede unir una palabra con la palabra anterior. Otra puede unir un adjetivo con el nombre que describe. Sus salidas se ponen una detrás de otra, y una última tabla aprendida las devuelve a la longitud habitual.

Ejemplo resuelto: juntar dos cabezas

PasoPara el token lleno
Salida de la cabeza 17,88, 2,12
Salida de la cabeza 21, 3
Una detrás de otra7,88, 2,12, 1, 3
Tras la tabla de mezclavuelta a la longitud habitual

Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.

Etapa densa, residuos y normalización

Después de la atención, cada token pasa solo por una pequeña etapa densa. Son dos capas con ReLU entre ellas, como en una red neuronal sencilla.

Una conexión residual suma la entrada de cada paso a su salida, así que no se pierde nada de lo ya sabido. La normalización reajusta cada vector: sus números quedan con media 0 y una dispersión estable. Las dos cosas mantienen entrenable una pila profunda.

Ejemplo resuelto: un residuo y luego la normalización

PasoNúmeros
Entrada de lleno1, 2
Salida de la atención7,88, 2,12
Residuo: sumarlas8,88, 4,12
Normalizado: media 01, -1

Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.

Normalizar un vector con NumPy

Comando
docker exec jupyter python3 -c "import numpy as np; x = np.array([2.0, 4.0, 6.0]); print(x.mean(), ((x - x.mean()) / x.std()).round(2).tolist())"

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Un error frecuente

Advertencia

Mucha gente piensa que la etapa densa hace que los tokens hablen entre sí. Trabaja con cada token por separado. Los tokens solo comparten información en la atención, así que un dato que viene de otro token tiene que pasar antes por ahí.

Sobre este laboratorio y su código: Laboratorio JupyterLab de ciencia de datos: pandas, Matplotlib y scikit-learn en el navegador

¿Enseñas a una clase? Asigna este módulo a tus alumnos con guía del profesor, tareas con corrección automática y un laboratorio para cada alumno.