Atención y self-attention en Python
La atención permite que cada token mire a los demás y decida cuáles importan. Cada token tiene una consulta (lo que busca), una clave (lo que ofrece) y un valor (la información que transmite).
El concepto en palabras sencillas
La atención permite que cada token mire a los demás y decida cuáles importan. Cada token tiene una consulta (lo que busca), una clave (lo que ofrece) y un valor (la información que transmite).
Calcula a mano la scaled dot-product attention con consultas, claves y valores, y añade una máscara causal como GPT.
Ideas clave
- Los pesos de atención salen de un softmax, por lo que cada fila suma 1.
- Dividir entre √d evita que las puntuaciones crezcan demasiado en vectores largos.
- Una máscara causal impide que un token mire los tokens futuros durante la generación.
- La multi-head attention ejecuta varias atenciones en paralelo, y la codificación posicional añade el orden de las palabras.
¿Cuándo se utiliza?
- Entender qué pasa dentro de las redes neuronales y las bibliotecas de IA.
- Aprender la idea antes de implementarla en los retos correspondientes.
- Prepararte para cursos de aprendizaje automático, entrevistas y proyectos.
Pruébalo en acción
Haz clic en una fila del mapa de calor para ver adónde mira ese token. Activa la máscara causal para ocultar los tokens futuros y cambia la nitidez para concentrar la atención.
Código de ejemplo
import math
def softmax(row):
exps = [math.exp(v - max(row)) for v in row]
return [e / sum(exps) for e in exps]
# Three tokens, each with a query, key and value vector of size 2.
Q = [[1, 0], [0, 1], [1, 1]]
K = [[1, 0], [0, 1], [1, 1]]
V = [[10, 0], [0, 10], [5, 5]]
d = len(K[0])
def attention(causal=False):
out = []
for i, q in enumerate(Q):
# Score: how well this query matches every key, scaled by sqrt(d).
scores = [sum(a * b for a, b in zip(q, k)) / math.sqrt(d) for k in K]
if causal: # a token may only look at itself and earlier tokens
scores = [s if j <= i else -1e9 for j, s in enumerate(scores)]
weights = softmax(scores)
out.append([round(sum(w * v[c] for w, v in zip(weights, V)), 2) for c in range(2)])
return out
print("attention:", attention())
print("causal attention:", attention(causal=True))
Resultado esperado
attention: [[6.02, 3.98], [3.98, 6.02], [5.0, 5.0]]
causal attention: [[10.0, 0.0], [3.3, 6.7], [5.0, 5.0]]
Cómo funciona
Para cada consulta, las puntuaciones son sus productos escalares con todas las claves, divididos entre √d. Softmax convierte las puntuaciones en pesos, y la salida es la media ponderada de los valores. Con la máscara causal, el primer token solo se ve a sí mismo, así que su salida es exactamente su propio valor [10, 0].
Cambia los valores y ejecuta el programa en el compilador Python online de CodeUtility sin instalar Python.
Ejercicios prácticos
Modifica las entradas y prueba casos límite antes de usar conjuntos de datos mayores.
- Cambia las entradas o los pesos y predice la salida antes de ejecutar.
- Imprime los valores intermedios para seguir cada paso del cálculo.
- Resuelve los retos enlazados abajo para implementar la idea por tu cuenta.
Practica con un reto
Usa lo que cubre esta lección para resolver un problema real. Cada reto se ejecuta en el navegador, con pruebas al instante y una revisión de IA.
- Codificación posicional sinusoidal Calcula los vectores de posición seno y coseno que los Transformers suman a los embeddings de los tokens. Intermedio
- Atención por producto escalar escalado Implementa la operación de atención, el corazón de los Transformers y los grandes modelos de lenguaje. Difícil
- Autoatención causal (enmascarada) Implementa la atención enmascarada de los modelos GPT, donde cada token solo puede ver a sí mismo y a los tokens anteriores. Intermedio
- Autoatención multicabeza Proyecta la entrada en consultas, claves y valores, ejecuta la atención en varias cabezas en paralelo y combínalas. Difícil