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.
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.
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.
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ᵀ: 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.
- ÷ √dₖ: divide pelo tamanho do vetor de Key. Explicado logo abaixo.÷ √dₖ: divide by the size of the Key vector. Explained right below.
- 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.
- × 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, sleeps | Pesos (softmax)Weights (softmax) | SaídaOutput |
|---|---|---|---|
| the | 0,71 · 0,00 · 0,710.71 · 0.00 · 0.71 | 0,40 · 0,20 · 0,400.40 · 0.20 · 0.40 | [0,80 ; 0,60][0.80 ; 0.60] |
| cat | 0,00 · 0,71 · 0,710.00 · 0.71 · 0.71 | 0,20 · 0,40 · 0,400.20 · 0.40 · 0.40 | [0,60 ; 0,80][0.60 ; 0.80] |
| sleeps | 0,71 · 0,71 · 1,410.71 · 0.71 · 1.41 | 0,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.
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.
| ItemItem | Valor no paper (modelo base)Paper value (base model) | O que significaWhat it means |
|---|---|---|
| d_modeld_model | 512 | tamanho do vetor que representa cada palavra, em todo o modelosize of the vector representing each word, throughout the model |
| hh | 8 | número de cabeçasnumber of heads |
| d_k = d_v | 64 (= 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çãoPosition | dim 0 (sin) | dim 1 (cos) | dim 2 (sin) | dim 3 (cos) |
|---|---|---|---|---|
| 0 | 0,0000.000 | 1,0001.000 | 0,0000.000 | 1,0001.000 |
| 1 | 0,8410.841 | 0,5400.540 | 0,0100.010 | 1,0001.000 |
| 2 | 0,9090.909 | −0,416−0.416 | 0,0200.020 | 1,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.
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.
Cada camada do encoder tem 2 sub-blocosEach encoder layer has 2 sub-blocks
- 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.
- 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
- 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).
- 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.
- 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)
| OndeWhere | Q vem de…Q comes from… | K, V vêm de…K, V come from… | Para quêWhat for |
|---|---|---|---|
| Self-attention do encoderEncoder self-attention | camada anterior do encoderprevious encoder layer | camada anterior do encoderprevious encoder layer | entender a frase de entradaunderstand the input sentence |
| Self-attention mascarada do decoderDecoder masked self-attention | camada anterior do decoderprevious decoder layer | camada anterior do decoderprevious decoder layer | gerar sem “colar” do futurogenerate without “peeking” at the future |
| Atenção encoder-decoderEncoder-decoder attention | camada anterior do decoderprevious decoder layer | saída do encoderencoder output | alinhar 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.
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.)
- 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. - 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.
- 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.
- 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.
- 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”. - 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 type | Custo por camadaCost per layer | Operações sequenciaisSequential operations | Caminho máximo entre 2 palavrasMaximum path between 2 words |
|---|---|---|---|
| Auto-atençãoSelf-attention | O(n² · d) | O(1) | O(1) |
| RecorrenteRecurrent | O(n · d²) | O(n) | O(n) |
| ConvolucionalConvolutional | O(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
| ItemItem | No paperIn the paper |
|---|---|
| DadosData | WMT 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) |
| HardwareHardware | 1 máquina com 8 GPUs NVIDIA P1001 machine with 8 NVIDIA P100 GPUs |
| TempoTime | Base: 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 |
| OtimizadorOptimizer | Adam (β₁ = 0,9; β₂ = 0,98; ε = 10⁻⁹)Adam (β₁ = 0.9; β₂ = 0.98; ε = 10⁻⁹) |
| Taxa de aprendizadoLearning rate | sobe linearmente por 4000 passos (warmup) e depois cai com 1/√passorises linearly for 4000 steps (warmup), then decays with 1/√step |
| RegularizaçãoRegularisation | dropout 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)
| ModeloModel | BLEU EN→DE | BLEU EN→FR | Custo de treino (FLOPs, EN→DE)Training cost (FLOPs, EN→DE) |
|---|---|---|---|
| GNMT + RL | 24,624.6 | 39,9239.92 | 2,3·10¹⁹2.3·10¹⁹ |
| ConvS2S | 25,1625.16 | 40,4640.46 | 9,6·10¹⁸9.6·10¹⁸ |
| MoE | 26,0326.03 | 40,5640.56 | 2,0·10¹⁹2.0·10¹⁹ |
| ConvS2S (ensemble) | 26,3626.36 | 41,2941.29 | 7,7·10¹⁹7.7·10¹⁹ |
| Transformer (base) | 27,327.3 | 38,138.1 | 3,3·10¹⁸3.3·10¹⁸ |
| Transformer (big) | 28,428.4 | 41,841.8 | 2,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 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çaChange | BLEU (dev) | LiçãoLesson |
|---|---|---|
| 1 cabeça (em vez de 8)1 head (instead of 8) | 24,924.9 | várias cabeças ajudam (−0,9)several heads help (−0.9) |
| 32 cabeças32 heads | 25,425.4 | cabeças demais também pioramtoo many heads also hurt |
| d_k reduzido para 16d_k reduced to 16 | 25,125.1 | o “casamento” Q/K precisa de espaçoQ/K matching needs room |
| 2 camadas (em vez de 6)2 layers (instead of 6) | 23,723.7 | profundidade importadepth matters |
| d_model = 256d_model = 256 | 24,524.5 | modelos maiores são melhoresbigger models are better |
| d_model = 1024d_model = 1024 | 26,026.0 | ...mas custam mais parâmetros (168 mi)...but cost more parameters (168 M) |
| d_ff = 4096d_ff = 4096 | 26,226.2 | FFN maior ajudaa bigger FFN helps |
| sem dropoutno dropout | 24,624.6 | dropout evita overfittingdropout prevents overfitting |
| posição aprendida em vez de senoidallearned position instead of sinusoidal | 25,725.7 | quase 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
- 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
| ConceitoConcept | Em uma fraseIn one sentence |
|---|---|
| Query / Key / Value | pergunta, 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ₖ)V | a equação da atenção; √dₖ evita softmax saturadothe attention equation; √dₖ avoids a saturated softmax |
| Multi-head | 8 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 encoding | seno/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 & Norm | residual + LayerNorm em volta de cada sub-blocoresidual + LayerNorm around every sub-block |
| N=6, 512, 2048, h=8 | configuraçã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
- 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.)
- 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.)
- 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.)
- 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².)