Query, Key e Value — de onde vêm, o que significam, e por que essa única operação substituiu vinte anos de redes recorrentes.
Leia esta frase e responda rápido: "O troféu não coube na mala porque ele era muito grande."
"Ele" é o troféu. Você sabe disso instantaneamente. Agora troque uma palavra: "…porque ele era muito pequeno." Agora "ele" é a mala. A referência do pronome mudou por causa de um adjetivo que está sete palavras depois.
Para processar isso, o modelo precisa que a representação de "ele" seja capaz de buscar informação em qualquer outra posição da frase, escolhendo dinamicamente onde olhar. Não numa posição fixa, não na palavra anterior — em qualquer lugar, dependendo do conteúdo.
Até 2017, isso era feito com redes recorrentes: leia palavra por palavra, carregando um "estado de memória" que se atualiza a cada passo. Duas fraquezas fatais:
A atenção resolve os dois de uma vez: cada posição olha diretamente para todas as outras, e todas as posições são calculadas ao mesmo tempo.
A atenção transforma o problema de "lembrar do passado" (difícil, sequencial, com perdas) no problema de "buscar no passado" (fácil, paralelo, sem perdas). Foi essa troca que destravou a escala, e foi a escala que produziu tudo o que veio depois.
Esqueça matriz por um minuto. Pense num sistema de busca. Ele tem três papéis:
| Papel | Símbolo | No banco de dados | Na frase |
|---|---|---|---|
| Query (consulta) | o que você digitou na busca | "eu sou o pronome ele, estou procurando um substantivo masculino singular que possa ser meu antecedente" | |
| Key (chave) | a etiqueta indexada de cada item | "eu sou troféu, substantivo, masculino, singular, objeto físico" | |
| Value (valor) | o conteúdo devolvido quando o item casa | o significado completo de troféu, que será entregue a quem perguntou |
Um banco de dados comum faz busca dura: a query casa com exatamente uma key, e devolve aquele value. A atenção faz busca suave: a query é comparada com todas as keys, cada uma recebe uma nota de compatibilidade, as notas viram porcentagens que somam 100%, e o resultado é uma média ponderada de todos os values.
"ele" pergunta. "troféu" responde com 71% de relevância, "mala" com 22%, "grande" com 5%, o resto divide 2%. O novo vetor de "ele" passa a ser 0,71×troféu + 0,22×mala + 0,05×grande + … Ele deixou de ser um pronome vazio e virou um pronome que já carrega quem ele é. Essa é, literalmente, a operação que acontece.
Este é o ponto que mais gera confusão, então vamos com calma. Q, K e V não são coisas separadas que existem no texto. Eles são três projeções diferentes do mesmo vetor de entrada.
Cada token chega com seu vetor
Por que três? Porque os papéis são assimétricos. O que um token quer procurar não é a mesma coisa que ele quer anunciar sobre si, e nenhuma das duas é a informação que ele quer entregar quando for escolhido.
Se usássemos o mesmo vetor para query e key, a atenção seria forçadamente simétrica — se A olha muito para B, B teria que olhar muito para A. Mas linguagem não é assim: um pronome procura seu antecedente com urgência, e o substantivo não tem nenhum interesse recíproco no pronome.
No código real do GPT-2 as três matrizes estão fundidas numa só, de 768×2304 (= 3×768), chamada c_attn. Faz-se uma única multiplicação e depois se corta o resultado em três pedaços. É puramente eficiência — uma matmul grande é mais rápida que três pequenas. Conceitualmente são três matrizes.
Esta é a equação do Transformer. Vou escrevê-la e depois desmontar peça por peça.
Multiplicar
É aqui que nasce o custo quadrático. Essa matriz tem
Por que dividir pela raiz da dimensão? Não é estética — é uma necessidade estatística.
Suponha que
E por que isso importa tanto? Porque a próxima etapa é o softmax, que envolve
Softmax saturado tem gradiente praticamente nulo. O modelo para de aprender. A divisão por √
O √temperature que você vai usar na geração (apostila 07). A mesma matemática, em dois lugares do modelo.
A matriz
Uma cabeca de atencao do GPT-2 small, frase de 5 tokens: h (5, 768) entrada (apostila 02) | |-- x W_Q (768,64) --> Q (5, 64) |-- x W_K (768,64) --> K (5, 64) |-- x W_V (768,64) --> V (5, 64) Q @ K.T -> (5, 5) scores brutos / sqrt(64) -> (5, 5) escalados softmax(dim=-1) -> (5, 5) <-- O MAPA DE ATENCAO (linhas somam 1) @ V -> (5, 64) saida da cabeca Note: d_k = 64 = 768 / 12 cabecas. Cada cabeca trabalha num subespaco estreito. Na apostila 04 as 12 se juntam de volta em 768.
import torch, math import torch.nn.functional as F def atencao(Q, K, V): """Q,K,V: (n, d_k). Devolve (n, d_k) e o mapa (n, n).""" d_k = Q.shape[-1] # 1) toda query contra toda key -> (n, n) scores = Q @ K.transpose(-2, -1) # 2) estabiliza a escala para o softmax não saturar scores = scores / math.sqrt(d_k) # 3) cada linha vira uma distribuição que soma 1 A = F.softmax(scores, dim=-1) # 4) média ponderada dos values return A @ V, A
São essas quatro linhas. Tudo que o GPT-2, o RoBERTa, o GPT-4 e o Claude fazem de mais impressionante é essa operação, repetida com muitas cabeças, muitas camadas e muitos dados. A ideia central cabe em quatro linhas.
.venv\Scripts\python.exe lab\03_attention.py
output_attentions=True) para a frase do troféu, e desenha o mapa em ASCII com intensidade.O resultado rigoroso. A atenção do token "it" é bit a bit idêntica nas duas frases — diferença máxima exatamente 0,00. Isso não é bug: "it" está na posição 9 e "big"/"small" na 12. Num modelo causal, o passado não pode ser afetado pelo futuro. Você acabou de provar experimentalmente a causalidade da apostila 04, e um RoBERTa daria resultado diferente aqui. Isso é prova, não interpretação.
O resultado desconfortável. Quando olhamos o adjetivo (que vê a frase toda), a esperança era que "big" se ligasse ao troféu e "small" à mala. Não acontece. Os dois olham mais para a mala, e a diferença é ruído. O motivo: ~66% de toda a atenção está despejada no primeiro token — a chamada attention sink — e sobra pouquíssimo orçamento para o resto.
Seria possível escolher outro exemplo que "desse certo". Este ficou porque ensina a lição que importa: mapas de atenção são sugestivos, não explicativos. Jain & Wallace publicaram exatamente sobre isso em 2019 ("Attention is not Explanation"), mostrando que dá para alterar bastante os pesos de atenção sem mudar a saída do modelo. A atenção mostra por onde a informação pode ter fluído — não por onde ela decidiu. Ler esses mapas como se fossem a explicação do modelo é um erro, e ele custa caro.
As fontes primárias dos conceitos deste capítulo. Os números do texto foram medidos no laboratório; as ideias vêm daqui.
Os termos técnicos têm aqui o sentido de aprendizado de máquina. O glossário do curso mostra esse sentido ao lado dos outros que as mesmas palavras têm na TI.
Uma cabeça de atenção só sabe procurar um tipo de relação por vez. E, do jeito que está, ela deixa cada token ver o futuro.
A apostila 04 resolve os dois problemas: multi-head e a máscara causal.