Laboratório GPT-2 · RoBERTa · Parte I — A fundação
03

Atenção:
o coração do Transformer

Query, Key e Value — de onde vêm, o que significam, e por que essa única operação substituiu vinte anos de redes recorrentes.

Apostila 03 de 15 Pré-requisito: apostilas 01 e 02

1 O problema que a atenção resolve

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.

Por que a solução antiga (RNN) não bastava

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 frase que resume o Transformer

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.

2 A analogia central: consulta a um banco de dados

Esqueça matriz por um minuto. Pense num sistema de busca. Ele tem três papéis:

PapelSímboloNo banco de dadosNa frase
Query
(consulta)
Qo que você digitou na busca"eu sou o pronome ele, estou procurando um substantivo masculino singular que possa ser meu antecedente"
Key
(chave)
Ka etiqueta indexada de cada item"eu sou troféu, substantivo, masculino, singular, objeto físico"
Value
(valor)
Vo conteúdo devolvido quando o item casao 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.

Concretamente

"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.

3 De onde vêm Q, K e V

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 h de 768 dimensões (o que construímos na apostila 02). Aí o modelo o multiplica por três matrizes aprendidas, distintas:

Q = h WQ     K = h WK     V = h WV Três matrizes de 768×768, todas aprendidas no treino. Mesmo h de entrada, três "óculos" diferentes para enxergá-lo.

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.

Detalhe de implementação do GPT-2

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.

4 A fórmula, símbolo por símbolo

Esta é a equação do Transformer. Vou escrevê-la e depois desmontar peça por peça.

Atenção(Q,K,V) = softmax(QK⊤√dk) V

Peça 1 — QK⊤: as notas de compatibilidade

Multiplicar Q (n×64) por K⊤ (64×n) produz uma matriz n×n. A posição (i,j) dessa matriz é o produto interno entre a query do token i e a key do token j:

sij = qi · kj = Σc=1dk qi,c kj,c Produto interno mede alinhamento: alto quando os dois vetores apontam na mesma direção, negativo quando apontam em direções opostas. É a "nota de relevância bruta" de j para i.

É aqui que nasce o custo quadrático. Essa matriz tem n² entradas. Dobrar o comprimento do texto quadruplica o trabalho. Com n=1024 são mais de um milhão de produtos internos — por cabeça, por camada.

Peça 2 — dividir por √dk: a razão por trás do divisor

Por que dividir pela raiz da dimensão? Não é estética — é uma necessidade estatística.

Suponha que q e k tenham componentes aproximadamente independentes, com média 0 e variância 1. O produto interno soma dk desses produtos. Pela soma de variâncias de variáveis independentes:

Var(q·k) = Σ Var(qckc) = dk   ⟹   desvio ≈ √dk Com dk=64, os scores brutos flutuam numa escala de ±8. Dividindo por √64 = 8, voltam para escala ±1.

E por que isso importa tanto? Porque a próxima etapa é o softmax, que envolve es. Com scores na escala de ±8, um score de 8 contra um de 0 dá uma razão de e8 ≈ 2981 para 1. O softmax satura: vira quase um one-hot, todo o peso num token só.

Softmax saturado tem gradiente praticamente nulo. O modelo para de aprender. A divisão por √dk existe para manter o softmax na sua faixa útil, onde o gradiente flui. Sem ela, o Transformer simplesmente não treina.

Guarde esta ideia

O √dk é um controle de temperatura embutido. Dividir por um número maior = distribuição mais suave, atenção mais espalhada. Dividir por menos = atenção mais concentrada. É exatamente o mesmo mecanismo do parâmetro temperature que você vai usar na geração (apostila 07). A mesma matemática, em dois lugares do modelo.

Peça 3 — softmax: notas viram porcentagens

aij = exp(sij)Σj′ exp(sij′) Torna tudo positivo (pela exponencial) e faz cada linha somar exatamente 1. Agora aij é lido como "a fração da atenção de i que vai para j".

A matriz A resultante, n×n, é o mapa de atenção — o objeto que você vai visualizar no laboratório. Cada linha é uma distribuição de probabilidade: onde aquele token está olhando.

Peça 4 — multiplicar por V: a mistura

zi = Σj aij vj O novo vetor do token i é a média dos values de todos os tokens, ponderada pela atenção. Se ai,troféu=0,71, então 71% do novo "ele" é troféu.

5 As dimensões, passo a passo

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.

6 Implementação do zero — 8 linhas

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.

7 No laboratório

.venv\Scripts\python.exe lab\03_attention.py
  1. Roda a implementação acima com vetores pequenos e mostra a matriz A em números, para você confirmar que cada linha soma 1,000.
  2. Demonstra a saturação: calcula a mesma atenção com e sem a divisão por √dk, e imprime a entropia das distribuições. Você vai ver o softmax colapsar.
  3. Extrai a atenção real do GPT-2 (com output_attentions=True) para a frase do troféu, e desenha o mapa em ASCII com intensidade.
  4. Compara as duas versões da frase — e aqui você vai receber dois resultados, um deles desconfortável. Leia a caixa abaixo antes de rodar.
Dois resultados que você precisa saber ler

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.

Exercício 3 — preveja antes de rodar

  1. Se todos os scores de uma linha forem iguais, o que o softmax devolve? E o que isso significa sobre o que aquele token está fazendo?
  2. Um texto de 512 tokens custa quanto, em produtos internos, comparado a um de 256? Justifique com a fórmula, não com intuição.
  3. Multiplique todos os scores por 10 antes do softmax. Descreva o mapa resultante. Agora divida por 10. Descreva de novo. Que parâmetro de geração isso imita?
  4. Difícil: por que o produto interno, e não a distância euclidiana, para medir compatibilidade? Pense em (a) custo computacional em GPU e (b) o que acontece com vetores de magnitudes diferentes.
Referências

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.

  1. Bahdanau, D., Cho, K. e Bengio, Y. (2015). Neural Machine Translation by Jointly Learning to Align and Translate. ICLR 2015. arXiv:1409.0473
  2. Vaswani, A. et al. (2017). Attention Is All You Need. NeurIPS 2017. arXiv:1706.03762
  3. Jain, S. e Wallace, B. C. (2019). Attention is not Explanation. NAACL 2019. arXiv:1902.10186

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.