antonio leandro

ia generativa

Attention Is All You Need

paper · núcleo · Ashish Vaswani, Noam Shazeer, Niki Parmar, Jakob Uszkoreit, Llion Jones, Aidan N. Gomez, Łukasz Kaiser, Illia Polosukhin ·

a tese

tirar a recorrência inteira do modelo não piora a tradução: com atenção pura o caminho entre duas posições vira constante, o treino paraleliza, e 12 horas em 8 gpus batem o estado da arte anterior.

o que fica

  1. O caminho entre duas posições quaisquer numa camada de self-attention é O(1), contra O(n) numa camada recorrente — é essa distância curta que faz a dependência longa ser aprendível, não a atenção em si.
  2. O custo por camada é O(n²·d): self-attention só sai mais barata que recorrência quando a sequência é menor que a dimensão do modelo, o que valia para frases e deixou de valer quando as entradas cresceram.
  3. A divisão por raiz de d_k não é cosmética — sem ela o produto escalar cresce em magnitude com d_k e empurra o softmax para a região de gradiente quase nulo.
  4. Multi-head não custa mais caro: 8 heads de 64 dimensões dão o mesmo custo de um head de 512, e o paper mede que 1 head perde 0,9 BLEU e que 32 heads também pioram.
  5. Positional encoding senoidal e aprendido deram resultado praticamente igual (25,8 contra 25,7 BLEU no dev); a escolha pelo senoidal foi aposta em extrapolação, não resultado medido.
  6. O treino paralelizou, a geração não: o decoder continua autoregressivo e mascarado, e os autores listam tornar a geração menos sequencial como problema em aberto.

o problema

Até 2017 traduzir com rede neural queria dizer rede recorrente. O modelo produz um estado escondido h_t a partir de h_{t-1} e do token da posição t. Isso amarra o cálculo à ordem da frase: você não consegue processar a posição 40 antes da 39, nem dentro de um único exemplo de treino. A saída é aumentar o batch entre exemplos, mas aí a memória estoura justamente quando as sequências ficam longas — o caso em que você mais precisaria de paralelismo. Os autores são explícitos: truques de fatoração e computação condicional melhoraram a eficiência, mas a restrição sequencial em si continuou de pé.

O segundo problema é de distância. Para relacionar a posição 1 com a posição 60, o sinal precisa atravessar 60 passos de recorrência, na ida e na volta do gradiente. Quanto mais longo o caminho, mais difícil aprender a dependência. As alternativas convolucionais da época — ByteNet, ConvS2S — paralelizavam bem, mas o número de operações para ligar duas posições crescia com a distância entre elas: linearmente no ConvS2S, logaritmicamente no ByteNet. Attention já existia e já era usada nesses modelos, só que sempre acoplada a uma RNN, como um acessório que escolhe onde olhar no encoder.

a ideia

Se attention é o que resolve a dependência de longa distância, tire o resto. O Transformer não tem recorrência nem convolução: cada posição olha para todas as outras em uma única operação, e o número de passos sequenciais por camada cai para um. O caminho entre quaisquer duas posições vira constante, independentemente da distância.

O preço óbvio dessa troca é que um saco de vetores não tem ordem. A ordem volta por fora, somada ao embedding na entrada da pilha, como um vetor de posição. Nada no mecanismo sabe que “o gato” vem antes de “dormiu” — isso está codificado no próprio vetor que entra.

como funciona

A operação básica é softmax(QK^T / raiz(d_k)) · V. Queries, keys e values são projeções lineares da mesma entrada; o produto escalar entre query e key dá o peso de cada value. A divisão por raiz de d_k existe porque, com componentes independentes de média 0 e variância 1, o produto escalar tem variância d_k — sem a escala, o softmax satura e o gradiente some.

Em vez de uma atenção sobre 512 dimensões, o modelo faz oito em paralelo (h = 8), cada uma projetando para 64 dimensões, concatenando os resultados e projetando de volta. Custo total equivalente ao de um head cheio, com o ganho de atender a subespaços de representação diferentes ao mesmo tempo.

A atenção aparece em três lugares: self-attention no encoder; self-attention mascarada no decoder, onde as conexões ilegais recebem -infinito antes do softmax para preservar a propriedade autoregressiva; e encoder-decoder attention, com queries do decoder e keys/values do encoder. Encoder e decoder têm 6 camadas idênticas, cada sub-camada envolvida em conexão residual e layer normalization, com d_model = 512 e uma FFN de duas transformações lineares com ReLU no meio, camada interna de 2.048, aplicada posição a posição.

O treino usa Adam com learning rate em warmup linear por 4.000 passos e queda proporcional ao inverso da raiz do passo, dropout e label smoothing de 0,1 — que piora a perplexidade e melhora o BLEU. Os números: 27,3 BLEU em inglês-alemão no modelo base com 3,3 · 10^18 FLOPs de treino, contra 24,6 do GNMT+RL a 2,3 · 10^19. O modelo big chegou a 28,4 em inglês-alemão e 41,8 em inglês-francês, treinando 3,5 dias em 8 GPUs P100.

o que isso custou

O custo por camada é O(n²·d). Os autores não escondem: self-attention só é mais rápida que recorrência quando n < d, o que valia para frases com vocabulário sub-palavra e deixa de valer para entradas longas. A saída que eles apontam — restringir a atenção a uma vizinhança de tamanho r, elevando o caminho máximo para O(n/r) — fica declarada como trabalho futuro.

Attention também borra: a média ponderada sobre posições reduz a resolução efetiva. Multi-head é o remendo para isso, admitido como tal. E a tabela de ablação mostra que reduzir d_k piora o resultado, o que leva os próprios autores a suspeitar que o produto escalar seja uma função de compatibilidade simples demais.

Sobra o assimétrico: o treino paralelizou, a inferência não. O decoder continua gerando um token por vez, com máscara, e “tornar a geração menos sequencial” está listado como objetivo de pesquisa. A base empírica também é estreita — duas tarefas de tradução e um teste de constituency parsing em inglês (91,3 F1 só com WSJ, 92,7 semi-supervisionado). Nada aqui é uma afirmação sobre modelagem de linguagem em escala.

onde isso aparece hoje

O bloco descrito aqui — attention, FFN posição a posição, residual, layer normalization — virou a base da geração seguinte de modelos de linguagem, incluindo a família GPT, que manteve o bloco e descartou o pareamento encoder-decoder. O código foi publicado no tensor2tensor.

O O(n²) deixou de ser nota de rodapé e virou agenda: a janela de contexto é cara exatamente por causa dessa linha da Tabela 1, e a ideia de atenção restrita a uma vizinhança, que os autores adiaram, foi retomada muitas vezes desde então.

lido na íntegra por pipeline de llm, revisado por antonio leandro antes de publicar ·