Paper explained

Attention Is All You Need, explained from zero.

The paper that introduced the Transformer, in plain language: queries, keys and values, attention step by step with small numbers, multi-head attention, positional encoding, the full architecture, training, results and code.

O problema que o paper resolveThe problem the paper solves

Em 2017, os melhores modelos de tradução e de texto usavam redes recorrentes (RNN, LSTM, GRU). Elas leem a frase uma palavra por vez, da esquerda para a direita, carregando um “resumo” do que já leram. Isso tem dois custos: (1) não dá para paralelizar dentro de uma frase, porque a palavra 5 só pode ser processada depois da 4; (2) informação de palavras distantes precisa atravessar muitos passos e vai se perdendo.In 2017 the best translation and text models used recurrent networks (RNN, LSTM, GRU). They read a sentence one word at a time, left to right, carrying a “summary” of what they have read. That has two costs: (1) you cannot parallelise inside a sentence, because word 5 can only be processed after word 4; (2) information from distant words has to cross many steps and fades along the way.

RNNCada palavra espera a anteriorEach word waits for the previous oneThecatsatonmatAttentionToda palavra olha para todas, ao mesmo tempoEvery word looks at every other, at the same timeThecatsatonmat
Em cima, a RNN: uma fila. Embaixo, a atenção: ligações diretas entre quaisquer duas palavras.Top, the RNN: a queue. Bottom, attention: direct links between any two words.

A ideia do paper cabe no título: “Attention Is All You Need” (“atenção é tudo de que você precisa”). Os autores propõem o Transformer, uma arquitetura que abandona a recorrência e a convolução e usa só mecanismos de atenção para relacionar as palavras entre si. O resultado: treina bem mais rápido (a atenção é toda feita com multiplicações de matrizes, ótimas para GPU) e traduz melhor.The paper’s idea fits in its title: “Attention Is All You Need”. The authors propose the Transformer, an architecture that drops recurrence and convolution and uses only attention mechanisms to relate words to each other. The result: it trains much faster (attention is all matrix multiplication, ideal for GPUs) and translates better.

Como ler esta nota. As seções seguem a ordem do paper (seção 3, “Model Architecture”, é o coração). Os números e fórmulas vêm do próprio paper (Vaswani et al., 2017, arXiv:1706.03762); os exemplos numéricos pequenos são meus, calculados à mão para você acompanhar. Quando algo não está no paper, está marcado.How to read this note. The sections follow the paper’s order (section 3, “Model Architecture”, is the heart). Numbers and formulas come from the paper itself (Vaswani et al., 2017, arXiv:1706.03762); the small numeric examples are mine, worked by hand so you can follow along. Anything not in the paper is marked.

A intuição: atenção como uma busca em bibliotecaThe intuition: attention as a library lookup

Imagine uma biblioteca. Você chega com uma pergunta (Query). Cada livro tem um título na lombada (Key) e um conteúdo (Value). Você compara sua pergunta com todas as lombadas, decide “esse combina 70%, aquele 25%, aquele 5%” e leva uma mistura dos conteúdos, na proporção dessas notas. Isso é atenção.Imagine a library. You arrive with a question (Query). Each book has a spine title (Key) and contents (Value). You compare your question with every spine, decide “this one matches 70%, that one 25%, that one 5%” and take away a blend of the contents in those proportions. That is attention.

Query (Q)Query (Q)“o que eu procuro?”“what am I looking for?”Key (K): título 1Key (K): title 1Key (K): título 2Key (K): title 2Key (K): título 3Key (K): title 3Value (V): conteúdo 1Value (V): content 1Value (V): conteúdo 2Value (V): content 2Value (V): conteúdo 3Value (V): content 3compara a Query com cada Key → pesos (somam 1)compare the Query with every Key → weights (sum to 1)mistura os Values usando esses pesosblend the Values using those weightsResultado: um “resumo” dos Values, mais parecido com os que combinam com a Query.Result: a “summary” of the Values, closest to those that match the Query.
Query, Key e Value: a Query pontua cada Key; as pontuações viram pesos que misturam os Values.Query, Key and Value: the Query scores each Key; the scores become weights that blend the Values.

Um exemplo em linguagem naturalA natural-language example

Na frase “O animal não atravessou a rua porque ele estava cansado”, a palavra “ele” precisa descobrir a quem se refere. Na atenção, “ele” faz uma Query; todas as palavras oferecem Keys; “animal” recebe a nota mais alta e passa seu Value para “ele”. A representação de “ele” passa a carregar o significado de “animal”. (O paper mostra figuras assim no apêndice, com pesos de atenção reais.)In the sentence “The animal didn’t cross the street because it was too tired”, the word “it” has to find what it refers to. In attention, “it” makes a Query; every word offers Keys; “animal” gets the highest score and passes its Value to “it”. The representation of “it” now carries the meaning of “animal”. (The paper shows figures like this in its appendix, with real attention weights.)

Self-attention (auto-atenção) é quando Query, Key e Value vêm da mesma frase: cada palavra consulta todas as outras da própria frase (e a si mesma). É isso que substitui a recorrência.Self-attention is when Query, Key and Value all come from the same sentence: each word queries all the others in its own sentence (and itself). That is what replaces recurrence.

Scaled dot-product attention: a fórmula passo a passoScaled dot-product attention: the formula step by step

Esta é a equação central do paper (a número 1). Em matrizes: Attention(Q, K, V) = softmax(Q·Kᵀ / √dₖ) · V. Vamos desmontá-la.This is the paper’s central equation (number 1). In matrix form: Attention(Q, K, V) = softmax(Q·Kᵀ / √dₖ) · V. Let’s take it apart.

Q · Kᵀpontuaçõesscores÷ √dₖescalascalemáscara(só no decoder)(decoder only)softmaxpesos, soma 1weights, sum 1× VmisturablendAttention(Q, K, V) = softmax(Q·Kᵀ / √dₖ) · V — equação (1) do paperAttention(Q, K, V) = softmax(Q·Kᵀ / √dₖ) · V — equation (1) of the paper
O pipeline da atenção: cinco operações simples.The attention pipeline: five simple operations.
  1. Q·Kᵀ: o produto escalar entre a Query de uma palavra e a Key de cada palavra mede “o quanto combinam” (quanto maior, mais parecidas). Como Q e K são matrizes, uma multiplicação calcula todas as combinações de uma vez: uma tabela n × n.Q·Kᵀ: the dot product between one word’s Query and every word’s Key measures “how well they match” (larger = more alike). Because Q and K are matrices, one multiplication computes all pairs at once: an n × n table.
  2. ÷ √dₖ: divide pelo tamanho do vetor de Key. Explicado logo abaixo.÷ √dₖ: divide by the size of the Key vector. Explained right below.
  3. softmax: transforma cada linha de pontuações em pesos positivos que somam 1 (como porcentagens). Pontuações altas viram pesos grandes.softmax: turns each row of scores into positive weights that sum to 1 (like percentages). High scores become large weights.
  4. × V: cada palavra recebe a média dos Values de todas as palavras, ponderada por esses pesos.× V: each word receives the average of all the Values, weighted by those weights.

Exemplo numérico minúsculoA tiny numeric example

Frase de 3 palavras, vetores de 2 números (dₖ = 2), e para simplificar Q = K = V = o próprio vetor da palavra: the = [1, 0], cat = [0, 1], sleeps = [1, 1]. Para a query “sleeps”: produtos escalares com cada palavra = 1, 1 e 2; dividindo por √2 ≈ 1,41 dá 0,71, 0,71 e 1,41; o softmax dá pesos 0,25, 0,25 e 0,50. A saída é 0,25·[1,0] + 0,25·[0,1] + 0,50·[1,1] = [0,75 ; 0,75].A 3-word sentence, vectors of 2 numbers (dₖ = 2), and to keep it simple Q = K = V = the word’s own vector: the = [1, 0], cat = [0, 1], sleeps = [1, 1]. For the query “sleeps”: dot products with each word = 1, 1 and 2; dividing by √2 ≈ 1.41 gives 0.71, 0.71 and 1.41; softmax gives weights 0.25, 0.25 and 0.50. The output is 0.25·[1,0] + 0.25·[0,1] + 0.50·[1,1] = [0.75 ; 0.75].

Palavra (query)Word (query)Pontuações vs. the, cat, sleepsScores vs. the, cat, sleepsPesos (softmax)Weights (softmax)SaídaOutput
the0,71 · 0,00 · 0,710.71 · 0.00 · 0.710,40 · 0,20 · 0,400.40 · 0.20 · 0.40[0,80 ; 0,60][0.80 ; 0.60]
cat0,00 · 0,71 · 0,710.00 · 0.71 · 0.710,20 · 0,40 · 0,400.20 · 0.40 · 0.40[0,60 ; 0,80][0.60 ; 0.80]
sleeps0,71 · 0,71 · 1,410.71 · 0.71 · 1.410,25 · 0,25 · 0,500.25 · 0.25 · 0.50[0,75 ; 0,75][0.75 ; 0.75]

Repare: “sleeps” deu o maior peso a si mesma (0,50) porque seu vetor é o mais “forte”. Num modelo real, Q, K e V são projeções aprendidas do vetor da palavra, então o modelo aprende o que consultar, o que anunciar e o que entregar.Notice: “sleeps” gave the highest weight to itself (0.50) because its vector is the “strongest”. In a real model Q, K and V are learned projections of the word’s vector, so the model learns what to ask, what to advertise and what to deliver.

Por que dividir por √dₖ?Why divide by √dₖ?

O paper explica em uma nota de rodapé: se os componentes de q e k são variáveis independentes com média 0 e variância 1, o produto escalar q·k (soma de dₖ termos) tem média 0 e variância dₖ. Com dₖ = 64, os números ficam em torno de ±8 ou mais; o softmax de números tão grandes “satura” (um peso quase 1, o resto quase 0) e o gradiente fica minúsculo, o que dificulta o treino. Dividir por √dₖ devolve a variância para 1. É o “scaled” do nome.The paper explains this in a footnote: if the components of q and k are independent variables with mean 0 and variance 1, the dot product q·k (a sum of dₖ terms) has mean 0 and variance dₖ. With dₖ = 64 the numbers sit around ±8 or more; a softmax over such large numbers “saturates” (one weight near 1, the rest near 0) and the gradient becomes tiny, which makes training hard. Dividing by √dₖ brings the variance back to 1. That is the “scaled” in the name.

O paper compara com a atenção aditiva (uma pequena rede neural para pontuar). Teoricamente parecidas, mas a atenção por produto escalar é bem mais rápida e usa menos memória na prática, porque é só multiplicação de matrizes.The paper compares this with additive attention (a small neural network for scoring). Similar in theory, but dot-product attention is much faster and more memory-efficient in practice because it is just matrix multiplication.

Multi-head attention: várias atenções em paraleloMulti-head attention: several attentions in parallel

Uma única atenção tira uma média sobre as palavras, e isso mistura tudo num só “ponto de vista”. O paper propõe rodar h atenções em paralelo, cada uma com suas próprias projeções aprendidas, e juntar os resultados. Cada cabeça pode se especializar numa relação: uma olha o sujeito do verbo, outra o adjetivo vizinho, outra a referência de um pronome.A single attention takes an average over the words, mixing everything into one “point of view”. The paper proposes running h attentions in parallel, each with its own learned projections, and joining the results. Each head can specialise in one relation: one looks at the verb’s subject, another at the neighbouring adjective, another at a pronoun’s referent.

xcabeça 1head 1Wq,Wk,Wv própriosown Wq, Wk, Wvcabeça 2head 2Wq,Wk,Wv própriosown Wq, Wk, Wvcabeça 3head 3Wq,Wk,Wv própriosown Wq, Wk, Wv…h = 8 cabeçash = 8 headsconcatenaconcatWᴼout
Cada cabeça projeta x com matrizes próprias, faz a atenção, e os resultados são concatenados e projetados por Wᴼ.Each head projects x with its own matrices, runs attention, and the results are concatenated and projected by Wᴼ.
ItemItemValor no paper (modelo base)Paper value (base model)O que significaWhat it means
d_modeld_model512tamanho do vetor que representa cada palavra, em todo o modelosize of the vector representing each word, throughout the model
hh8número de cabeçasnumber of heads
d_k = d_v64 (= 512 / 8)cada cabeça trabalha com vetores menoreseach head works with smaller vectors

Detalhe esperto: como cada cabeça usa vetores de 64 (e não 512), o custo total é parecido com o de uma atenção única de 512. Você ganha vários pontos de vista quase de graça. Fórmula do paper: MultiHead(Q,K,V) = Concat(head₁,…,head_h)·Wᴼ, com head_i = Attention(Q·Wᵢᵠ, K·Wᵢᴷ, V·Wᵢⱽ).Clever detail: since each head uses vectors of 64 (not 512), the total cost is similar to a single 512-dimensional attention. You get several points of view almost for free. Paper formula: MultiHead(Q,K,V) = Concat(head₁,…,head_h)·Wᴼ, with head_i = Attention(Q·Wᵢᵠ, K·Wᵢᴷ, V·Wᵢⱽ).

O experimento do paper (Tabela 3, linha A) confirma: com 1 cabeça, o BLEU é 0,9 pior que o melhor ajuste; mas com cabeças demais (32) também piora. Há um ponto ótimo (8 ou 16).The paper’s experiment (Table 3, row A) confirms it: with 1 head, BLEU is 0.9 worse than the best setting; but too many heads (32) also hurts. There is a sweet spot (8 or 16).

Posição: como o modelo sabe a ordem das palavrasPosition: how the model knows word order

Há um problema: a atenção trata a frase como um conjunto. Se você embaralhar as palavras, as contas de Q·Kᵀ dão os mesmos números só que reordenados. “O cão mordeu o homem” e “O homem mordeu o cão” pareceriam iguais. Sem recorrência, o modelo não tem noção de ordem, então o paper soma ao vetor de cada palavra um vetor de posição.There is a problem: attention treats the sentence as a set. Shuffle the words and Q·Kᵀ yields the same numbers, just reordered. “Dog bites man” and “Man bites dog” would look alike. Without recurrence the model has no sense of order, so the paper adds a position vector to each word’s vector.

PE(pos, 2i)   = sin( pos / 10000^(2i / d_model) )
PE(pos, 2i+1) = cos( pos / 10000^(2i / d_model) )

pos é a posição da palavra (0, 1, 2…) e i indexa a dimensão do vetor. Cada dimensão é uma onda (seno ou cosseno) de comprimento diferente: as primeiras oscilam rápido, as últimas devagar, como os ponteiros de segundos, minutos e horas de um relógio. A combinação de todos os “ponteiros” identifica cada posição de forma única. Exemplo com d_model = 4:pos is the word’s position (0, 1, 2…) and i indexes the vector dimension. Each dimension is a wave (sine or cosine) of a different wavelength: the first ones oscillate fast, the last ones slowly, like the second, minute and hour hands of a clock. The combination of all “hands” identifies each position uniquely. Example with d_model = 4:

PosiçãoPositiondim 0 (sin)dim 1 (cos)dim 2 (sin)dim 3 (cos)
00,0000.0001,0001.0000,0000.0001,0001.000
10,8410.8410,5400.5400,0100.0101,0001.000
20,9090.909−0,416−0.4160,0200.0201,0001.000

Por que senos? O paper levanta a hipótese de que isso facilita o modelo a aprender a atender por posição relativa, pois, para qualquer deslocamento fixo k, PE(pos+k) é uma função linear de PE(pos). Os autores também testaram embeddings de posição aprendidos e obtiveram resultados quase idênticos (Tabela 3, linha E); escolheram os senoidais porque podem extrapolar para frases mais longas que as vistas no treino.Why sines? The paper hypothesises it makes it easy for the model to learn to attend by relative position, since for any fixed offset k, PE(pos+k) is a linear function of PE(pos). The authors also tried learned position embeddings and got nearly identical results (Table 3, row E); they chose sinusoids because they may extrapolate to sequences longer than those seen in training.

Os vetores de posição têm o mesmo tamanho (d_model) dos embeddings das palavras e são somados, não concatenados. Os embeddings das palavras ainda são multiplicados por √d_model antes da soma (seção 3.4).Position vectors have the same size (d_model) as the word embeddings and are added, not concatenated. Word embeddings are also multiplied by √d_model before the sum (section 3.4).

A arquitetura completa do TransformerThe full Transformer architecture

O Transformer segue o desenho clássico de encoder-decoder: o encoder lê a frase de entrada e a transforma em representações ricas; o decoder usa essas representações para gerar a saída uma palavra por vez. Cada um é uma pilha de N = 6 camadas idênticas.The Transformer follows the classic encoder-decoder design: the encoder reads the input sentence and turns it into rich representations; the decoder uses them to produce the output one word at a time. Each is a stack of N = 6 identical layers.

ENCODER ×6DECODER ×6Feed-forwardFeed-forward+ Add & Norm+ Add & NormSelf-attentionSelf-attentionmulti-cabeçamulti-head+ Add & Norm+ Add & NormFeed-forwardFeed-forward+ Add & Norm+ Add & NormAtenção encoder-decoderEncoder-decoder attentionQ: decoder · K,V: encoderQ: decoder · K,V: encoder+ Add & Norm+ Add & NormSelf-attention mascaradaMasked self-attentionnão vê o futurocannot see the future+ Add & Norm+ Add & Normmemória do encoderencoder memoryEmbedding + posiçãoEmbedding + positionEmbedding + posiçãoEmbedding + positionfrase de entradainput sentencepalavras já geradas (deslocadas)words generated so far (shifted)
Encoder à esquerda, decoder à direita. A seta do meio é a “memória” que o decoder consulta.Encoder on the left, decoder on the right. The middle arrow is the “memory” the decoder consults.

Cada camada do encoder tem 2 sub-blocosEach encoder layer has 2 sub-blocks

  1. Self-attention multi-cabeça: cada palavra olha todas as outras da frase de entrada.Multi-head self-attention: each word looks at all the others in the input sentence.
  2. Rede feed-forward por posição: FFN(x) = max(0, x·W₁ + b₁)·W₂ + b₂. Duas camadas lineares com ReLU no meio (512 → 2048 → 512), aplicadas igualmente a cada palavra, separadamente. É onde o modelo “pensa” sobre o que a atenção juntou.Position-wise feed-forward network: FFN(x) = max(0, x·W₁ + b₁)·W₂ + b₂. Two linear layers with a ReLU in between (512 → 2048 → 512), applied identically to each word, separately. It is where the model “thinks” about what attention gathered.

Em volta de cada sub-bloco há uma conexão residual (soma-se a entrada à saída: x + Sublayer(x)) seguida de normalização de camada (LayerNorm). Isso ajuda o treino de redes profundas: o sinal original sempre passa direto. É o “Add & Norm” do desenho.Around each sub-block there is a residual connection (the input is added to the output: x + Sublayer(x)) followed by layer normalization (LayerNorm). It helps train deep networks: the original signal always flows straight through. That is the “Add & Norm” in the drawing.

O decoder tem 3 sub-blocosThe decoder has 3 sub-blocks

  1. Self-attention mascarada: cada palavra gerada só pode olhar as anteriores (veja abaixo).Masked self-attention: each generated word may only look at the previous ones (see below).
  2. Atenção encoder-decoder: as Queries vêm do decoder; as Keys e Values vêm da saída do encoder. É assim que, ao gerar “gato”, o decoder consulta a frase original.Encoder-decoder attention: Queries come from the decoder; Keys and Values come from the encoder output. That is how, when generating “cat”, the decoder consults the source sentence.
  3. Feed-forward, igual ao do encoder.Feed-forward, same as the encoder’s.

Por fim, a saída do decoder passa por uma camada linear e um softmax, que dá a probabilidade de cada palavra do vocabulário ser a próxima. O paper reaproveita a mesma matriz de pesos para os embeddings de entrada, de saída e para essa camada final (seção 3.4).Finally, the decoder output goes through a linear layer and a softmax that gives the probability of each vocabulary word being the next one. The paper shares the same weight matrix between the input embeddings, the output embeddings and this final layer (section 3.4).

As três formas de uso da atenção (seção 3.2.3)The three ways attention is used (section 3.2.3)

OndeWhereQ vem de…Q comes from…K, V vêm de…K, V come from…Para quêWhat for
Self-attention do encoderEncoder self-attentioncamada anterior do encoderprevious encoder layercamada anterior do encoderprevious encoder layerentender a frase de entradaunderstand the input sentence
Self-attention mascarada do decoderDecoder masked self-attentioncamada anterior do decoderprevious decoder layercamada anterior do decoderprevious decoder layergerar sem “colar” do futurogenerate without “peeking” at the future
Atenção encoder-decoderEncoder-decoder attentioncamada anterior do decoderprevious decoder layersaída do encoderencoder outputalinhar saída com entradaalign output with input

Máscara: o decoder não pode espiar o futuroMasking: the decoder cannot peek at the future

Ao treinar, o modelo recebe a frase de saída inteira de uma vez (para ser rápido). Se cada palavra pudesse olhar as seguintes, ela “copiaria a resposta”. Para impedir, o paper (seção 3.2.3) coloca −∞ nas pontuações das posições futuras antes do softmax; como e^(−∞) = 0, o peso delas vira exatamente zero.During training the model receives the whole output sentence at once (for speed). If each word could look at the following ones, it would “copy the answer”. To prevent that, the paper (section 3.2.3) puts −∞ on the scores of future positions before the softmax; since e^(−∞) = 0, their weight becomes exactly zero.

<s><s>EuEuamoamovocêvocê✓−∞−∞−∞✓✓−∞−∞✓✓✓−∞✓✓✓✓palavra que pergunta ↓asking word ↓palavra consultada →consulted word →
Matriz de atenção do decoder: cada linha só enxerga até a diagonal.Decoder attention matrix: each row only sees up to the diagonal.

No exemplo numérico anterior, se “cat” fosse a 2ª palavra de um decoder, só enxergaria “the” e “cat”: pontuações 0 e 0,71, pesos 0,33 e 0,67, e “sleeps” teria peso 0. A isso se chama propriedade auto-regressiva: cada palavra depende só das anteriores.In the earlier numeric example, if “cat” were the 2nd word of a decoder, it would only see “the” and “cat”: scores 0 and 0.71, weights 0.33 and 0.67, and “sleeps” would get weight 0. This is the auto-regressive property: each word depends only on the previous ones.

Passeio completo: traduzindo “I love you”Full walkthrough: translating “I love you”

Juntando as peças, veja o que acontece ao traduzir “I love you” para o português. (Valores ilustrativos; o paper não publica essa tradução.)Putting the pieces together, here is what happens when translating “I love you” into Portuguese. (Illustrative values; the paper does not publish this translation.)

  1. Tokenização. A frase vira pedaços (o paper usa byte-pair encoding / word-pieces): I | love | you.Tokenisation. The sentence is split into pieces (the paper uses byte-pair encoding / word-pieces): I | love | you.
  2. Embedding + posição. Cada token vira um vetor de 512 números; soma-se o vetor de posição 0, 1, 2.Embedding + position. Each token becomes a vector of 512 numbers; the position vector for 0, 1, 2 is added.
  3. Encoder (6 camadas). Em cada camada, “love” consulta “I” e “you” (quem ama? quem é amado?) e o resultado passa pela FFN. Ao final, cada token tem um vetor que já “sabe” do contexto.Encoder (6 layers). In each layer “love” queries “I” and “you” (who loves? who is loved?) and the result goes through the FFN. At the end each token has a vector that already “knows” its context.
  4. Decoder, passo 1. Entra o símbolo de início. A atenção encoder-decoder consulta a memória; o softmax final dá, por exemplo, “Eu” com a maior probabilidade.Decoder, step 1. The start symbol goes in. Encoder-decoder attention consults the memory; the final softmax gives, say, “Eu” the highest probability.
  5. Passo 2. Entra [início, Eu]. A self-attention mascarada deixa “Eu” ver só a si mesmo; a atenção ao encoder foca em “love”. Sai “amo”.Step 2. [start, Eu] goes in. Masked self-attention lets “Eu” see only itself; attention to the encoder focuses on “love”. Out comes “amo”.
  6. Passo 3 e fim. Entra [início, Eu, amo], sai “você”, depois um símbolo de fim. Pronto: “Eu amo você”.Step 3 and end. [start, Eu, amo] goes in, “você” comes out, then an end symbol. Done: “Eu amo você”.

Na inferência o decoder gera uma palavra por vez (não dá para paralelizar, porque cada palavra depende da anterior). O paper usa beam search com largura 4 e penalidade de comprimento α = 0,6: em vez de escolher só a palavra mais provável a cada passo, mantém as 4 melhores sequências parciais e fica com a melhor no fim.At inference the decoder produces one word at a time (it cannot be parallelised, because each word depends on the previous one). The paper uses beam search with beam size 4 and length penalty α = 0.6: instead of picking only the most likely word at each step, it keeps the 4 best partial sequences and returns the best at the end.

Por que a auto-atenção? (Tabela 1 do paper)Why self-attention? (the paper’s Table 1)

A seção 4 compara a auto-atenção com camadas recorrentes e convolucionais em três critérios. n é o tamanho da sequência, d o tamanho do vetor e k o tamanho do kernel da convolução.Section 4 compares self-attention with recurrent and convolutional layers on three criteria. n is the sequence length, d the vector size and k the convolution kernel size.

Tipo de camadaLayer typeCusto por camadaCost per layerOperações sequenciaisSequential operationsCaminho máximo entre 2 palavrasMaximum path between 2 words
Auto-atençãoSelf-attentionO(n² · d)O(1)O(1)
RecorrenteRecurrentO(n · d²)O(n)O(n)
ConvolucionalConvolutionalO(k · n · d²)O(1)O(logₖ n)
Auto-atenção restrita (vizinhança r)Restricted self-attention (neighbourhood r)O(r · n · d)O(1)O(n/r)
  • Operações sequenciais O(1): todas as palavras são processadas ao mesmo tempo. Na RNN são n passos em fila. É o ganho de velocidade de treino.Sequential operations O(1): all words are processed at the same time. In an RNN there are n steps in a queue. This is the training-speed gain.
  • Caminho máximo O(1): duas palavras, mesmo muito distantes, se conectam diretamente. Quanto mais curto o caminho, mais fácil aprender dependências de longa distância.Maximum path O(1): two words, however far apart, connect directly. The shorter the path, the easier it is to learn long-range dependencies.
  • O preço: n² · d. Cada palavra se compara com todas, então o custo cresce com o quadrado do tamanho da frase. O paper nota que, para frases típicas de tradução, n é menor que d, então a atenção sai mais barata que a RNN. Para sequências muito longas, sugere a versão restrita.The price: n² · d. Each word is compared with all the others, so cost grows with the square of the sentence length. The paper notes that for typical translation sentences n is smaller than d, so attention is cheaper than an RNN. For very long sequences it suggests the restricted version.
  • Bônus (paper): as cabeças de atenção costumam aprender comportamentos interpretáveis, ligados à sintaxe e à semântica das frases.Bonus (paper): attention heads often learn interpretable behaviours related to the syntax and semantics of sentences.

Treino e resultadosTraining and results

ItemItemNo paperIn the paper
DadosDataWMT 2014 inglês→alemão (≈ 4,5 mi de pares de frases) e inglês→francês (36 mi de frases)WMT 2014 English→German (≈ 4.5 M sentence pairs) and English→French (36 M sentences)
HardwareHardware1 máquina com 8 GPUs NVIDIA P1001 machine with 8 NVIDIA P100 GPUs
TempoTimeBase: 100 mil passos ≈ 12 horas. Big: 300 mil passos ≈ 3,5 diasBase: 100k steps ≈ 12 hours. Big: 300k steps ≈ 3.5 days
LoteBatch≈ 25 mil tokens de origem e 25 mil de destino por lote≈ 25k source and 25k target tokens per batch
OtimizadorOptimizerAdam (β₁ = 0,9; β₂ = 0,98; ε = 10⁻⁹)Adam (β₁ = 0.9; β₂ = 0.98; ε = 10⁻⁹)
Taxa de aprendizadoLearning ratesobe linearmente por 4000 passos (warmup) e depois cai com 1/√passorises linearly for 4000 steps (warmup), then decays with 1/√step
RegularizaçãoRegularisationdropout 0,1 (base) em cada sub-bloco e nas somas de embeddings; label smoothing 0,1dropout 0.1 (base) on each sub-block and on embedding sums; label smoothing 0.1

O warmup evita que o modelo dê passos enormes e instáveis no começo; o label smoothing impede o modelo de ficar 100% confiante (piora a perplexidade, mas melhora a acurácia e o BLEU, diz o paper).Warmup prevents huge, unstable steps at the start; label smoothing keeps the model from being 100% confident (it hurts perplexity but improves accuracy and BLEU, says the paper).

Resultados (Tabela 2)Results (Table 2)

ModeloModelBLEU EN→DEBLEU EN→FRCusto de treino (FLOPs, EN→DE)Training cost (FLOPs, EN→DE)
GNMT + RL24,624.639,9239.922,3·10¹⁹2.3·10¹⁹
ConvS2S25,1625.1640,4640.469,6·10¹⁸9.6·10¹⁸
MoE26,0326.0340,5640.562,0·10¹⁹2.0·10¹⁹
ConvS2S (ensemble)26,3626.3641,2941.297,7·10¹⁹7.7·10¹⁹
Transformer (base)27,327.338,138.13,3·10¹⁸3.3·10¹⁸
Transformer (big)28,428.441,841.82,3·10¹⁹2.3·10¹⁹

BLEU é uma nota de 0 a 100 que compara a tradução da máquina com traduções humanas de referência (quanto maior, melhor). No inglês→alemão, o Transformer big superou o melhor resultado anterior, inclusive conjuntos de modelos, em mais de 2 BLEU; mesmo o modelo base superou todos os anteriores, gastando uma fração do custo (≈ 3,3·10¹⁸ FLOPs, contra 10¹⁹ a 10²¹ dos concorrentes).BLEU is a 0–100 score comparing the machine translation with human reference translations (higher is better). On English→German, the big Transformer beat the previous best, including model ensembles, by more than 2 BLEU; even the base model beat all earlier ones at a fraction of the cost (≈ 3.3·10¹⁸ FLOPs, versus 10¹⁹ to 10²¹ for competitors).

O texto do paper cita 41,0 BLEU para o inglês→francês, mas a tabela e o resumo dizem 41,8. Usei o valor da tabela. Detalhe curioso para quem confere números.The paper’s body text cites 41.0 BLEU for English→French, but the table and abstract say 41.8. I used the table value. A curious detail for anyone checking numbers.

O paper ainda mostra que o Transformer generaliza para outra tarefa, a análise sintática (constituency parsing), sem ajustes específicos (seção 6.3).The paper also shows that the Transformer generalises to another task, constituency parsing, without task-specific tuning (section 6.3).

O que realmente importa? As ablações (Tabela 3)What really matters? The ablations (Table 3)

Os autores mudaram uma peça por vez no modelo base (N=6, d_model=512, d_ff=2048, h=8) e mediram no conjunto de desenvolvimento (BLEU 25,8 no base). Isso mostra o que é essencial:The authors changed one piece at a time in the base model (N=6, d_model=512, d_ff=2048, h=8) and measured on the dev set (base BLEU 25.8). This shows what is essential:

MudançaChangeBLEU (dev)LiçãoLesson
1 cabeça (em vez de 8)1 head (instead of 8)24,924.9várias cabeças ajudam (−0,9)several heads help (−0.9)
32 cabeças32 heads25,425.4cabeças demais também pioramtoo many heads also hurt
d_k reduzido para 16d_k reduced to 1625,125.1o “casamento” Q/K precisa de espaçoQ/K matching needs room
2 camadas (em vez de 6)2 layers (instead of 6)23,723.7profundidade importadepth matters
d_model = 256d_model = 25624,524.5modelos maiores são melhoresbigger models are better
d_model = 1024d_model = 102426,026.0...mas custam mais parâmetros (168 mi)...but cost more parameters (168 M)
d_ff = 4096d_ff = 409626,226.2FFN maior ajudaa bigger FFN helps
sem dropoutno dropout24,624.6dropout evita overfittingdropout prevents overfitting
posição aprendida em vez de senoidallearned position instead of sinusoidal25,725.7quase igualnearly identical

Em código: atenção em 15 linhasIn code: attention in 15 lines

Python puro, sem bibliotecas, reproduzindo o exemplo numérico acima. Rode e confira as saídas.Plain Python, no libraries, reproducing the numeric example above. Run it and compare the outputs.

import math

def softmax(row):
    m = max(row)                       # subtracting the max avoids overflow
    e = [math.exp(x - m) for x in row]
    s = sum(e)
    return [x / s for x in e]

def attention(Q, K, V, causal=False):
    d_k = len(K[0])
    out = []
    for i, q in enumerate(Q):
        # 1) score the query against every key, scaled by sqrt(d_k)
        scores = [sum(a * b for a, b in zip(q, k)) / math.sqrt(d_k) for k in K]
        # 2) mask the future (decoder only)
        if causal:
            scores = [s if j <= i else float("-inf") for j, s in enumerate(scores)]
        # 3) weights that sum to 1
        w = softmax(scores)
        # 4) blend the values
        out.append([sum(w[j] * V[j][c] for j in range(len(V))) for c in range(len(V[0]))])
    return out

X = [[1, 0], [0, 1], [1, 1]]           # the, cat, sleeps
print(attention(X, X, X))               # last row ≈ [0.752, 0.752]
print(attention(X, X, X, causal=True))  # "cat" now ignores "sleeps"

Em bibliotecas reais (PyTorch, JAX), a mesma conta é feita com matrizes em GPU: softmax(Q @ K.T / sqrt(d_k)) @ V. O PyTorch tem torch.nn.MultiheadAttention e torch.nn.Transformer prontos. O código oficial do paper, o Tensor2Tensor, está no endereço citado no artigo.In real libraries (PyTorch, JAX) the same computation is done with matrices on GPU: softmax(Q @ K.T / sqrt(d_k)) @ V. PyTorch ships torch.nn.MultiheadAttention and torch.nn.Transformer. The paper’s original code, Tensor2Tensor, is at the address cited in the article.

Depois do paper: o que veio a seguirAfter the paper: what came next

Esta seção é contexto geral, não vem do paper.This section is general context, not from the paper.
  • Só o encoder (ex.: BERT): bom para entender texto (classificação, busca).Encoder only (e.g. BERT): good at understanding text (classification, search).
  • Só o decoder (ex.: família GPT e os assistentes de IA atuais): geram texto palavra por palavra, com a máscara causal que você viu.Decoder only (e.g. the GPT family and today’s AI assistants): generate text word by word, with the causal mask you saw.
  • Visão e áudio: a mesma ideia foi aplicada a imagens (Vision Transformer) e fala.Vision and audio: the same idea was applied to images (Vision Transformer) and speech.
  • O limite do n²: o custo quadrático da atenção motivou muita pesquisa em contextos longos e atenções mais eficientes.The n² limit: attention’s quadratic cost drove much research on long contexts and more efficient attention.

Por isso o Transformer é a base dos modelos de linguagem atuais. Para ver como eles são usados na prática (tokens, prompts, RAG, agentes), veja a nota AI Engineering.That is why the Transformer underlies today’s language models. To see how they are used in practice (tokens, prompts, RAG, agents), see the AI Engineering note.

Cola e revisãoCheat sheet and review

ConceitoConceptEm uma fraseIn one sentence
Query / Key / Valuepergunta, lombada e conteúdo: a Query pontua as Keys e mistura os Valuesquestion, spine and contents: the Query scores the Keys and blends the Values
softmax(QKᵀ/√dₖ)Va equação da atenção; √dₖ evita softmax saturadothe attention equation; √dₖ avoids a saturated softmax
Multi-head8 atenções em paralelo com vetores de 64; custo ≈ 1 de 5128 parallel attentions with 64-dim vectors; cost ≈ one 512-dim
Codificação posicionalPositional encodingseno/cosseno somados aos embeddings para dar noção de ordemsines/cosines added to embeddings to give a sense of order
MáscaraMask−∞ nas posições futuras: o decoder não espia−∞ on future positions: the decoder does not peek
Add & Normresidual + LayerNorm em volta de cada sub-blocoresidual + LayerNorm around every sub-block
N=6, 512, 2048, h=8configuração do modelo base (65 mi de parâmetros); big: 1024, 4096, h=16 (213 mi)base model configuration (65 M parameters); big: 1024, 4096, h=16 (213 M)

Teste-seTest yourself

  1. Por que o Transformer treina mais rápido que uma RNN? (Resposta: sem dependência sequencial dentro da camada, tudo é multiplicação de matrizes em paralelo.)Why does the Transformer train faster than an RNN? (Answer: no sequential dependency inside a layer, everything is parallel matrix multiplication.)
  2. O que aconteceria sem a codificação posicional? (Resposta: o modelo veria a frase como um conjunto, sem ordem.)What would happen without positional encoding? (Answer: the model would see the sentence as a set, with no order.)
  3. Qual é a diferença entre a self-attention do decoder e a atenção encoder-decoder? (Resposta: na primeira, Q, K e V vêm do decoder e há máscara; na segunda, K e V vêm do encoder.)What is the difference between decoder self-attention and encoder-decoder attention? (Answer: in the first, Q, K and V come from the decoder and there is a mask; in the second, K and V come from the encoder.)
  4. Se a frase dobrar de tamanho, quanto cresce o custo da atenção? (Resposta: ≈ 4 vezes, por causa do n².)If the sentence doubles in length, how much does attention cost grow? (Answer: ≈ 4×, because of the n².)