Atenção e self-attention em Python
A atenção permite que cada token olhe os outros tokens e decida quais importam. Cada token tem uma consulta (o que procura), uma chave (o que oferece) e um valor (a informação que repassa).
O conceito em palavras simples
A atenção permite que cada token olhe os outros tokens e decida quais importam. Cada token tem uma consulta (o que procura), uma chave (o que oferece) e um valor (a informação que repassa).
Calcule à mão a scaled dot-product attention com consultas, chaves e valores, e acrescente uma máscara causal como no GPT.
Ideias principais
- Os pesos de atenção vêm de um softmax, então cada linha soma 1.
- Dividir por √d evita que as pontuações fiquem grandes demais em vetores longos.
- Uma máscara causal impede que um token olhe tokens futuros durante a geração.
- A multi-head attention roda várias atenções em paralelo, e a codificação posicional acrescenta a ordem das palavras.
Quando usar?
- Entender o que acontece dentro das redes neurais e das bibliotecas de IA.
- Aprender a ideia antes de implementá-la nos desafios correspondentes.
- Se preparar para cursos de aprendizado de máquina, entrevistas e projetos.
Veja na prática
Clique numa linha do mapa de calor para ver para onde aquele token olha. Ative a máscara causal para esconder os tokens futuros e mude a nitidez para concentrar a atenção.
Código de exemplo
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))
Saída esperada
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]]
Como funciona
Para cada consulta, as pontuações são seus produtos escalares com todas as chaves, divididos por √d. O softmax transforma as pontuações em pesos, e a saída é a média ponderada dos valores. Com a máscara causal, o primeiro token só vê a si mesmo, então sua saída é exatamente seu próprio valor [10, 0].
Altere os valores e execute o programa no compilador Python online CodeUtility sem instalar Python.
Exercícios práticos
Altere as entradas e teste casos de borda antes de usar conjuntos de dados maiores.
- Mude as entradas ou os pesos e preveja a saída antes de executar.
- Imprima os valores intermediários para acompanhar cada passo do cálculo.
- Resolva os desafios indicados abaixo para implementar a ideia você mesmo.
Pratique com um desafio
Use o conteúdo desta lição para resolver um problema real. Cada desafio roda no navegador, com testes instantâneos e uma revisão por IA.
- Codificação posicional senoidal Calcule os vetores de posição seno e cosseno que os Transformers somam aos embeddings dos tokens. Médio
- Atenção por produto escalar escalonado Implemente a operação de atenção, o coração dos Transformers e dos grandes modelos de linguagem. Difícil
- Autoatenção causal (mascarada) Implemente a atenção mascarada dos modelos GPT, em que cada token só pode ver a si mesmo e os tokens anteriores. Médio
- Autoatenção multi-cabeça Projete a entrada em consultas, chaves e valores, execute a atenção em várias cabeças em paralelo e combine-as. Difícil