🧠FFVAcademy
⚙️

Transformers e Mecanismo de Atenção

12 min de leitura·+60 XP
Pré-requisitos (0/2)0%

Recomendamos completar os pré-requisitos antes de seguir, mas nada te impede de continuar.

Em junho de 2017, oito pesquisadores do Google publicaram “Attention is All You Need” — um paper de 15 páginas que mudou a IA para sempre. A arquitetura que eles propuseram, o Transformer, é a base de GPT, Claude, Gemini, LLaMA e praticamente todo modelo de linguagem moderno. Neste artigo, você vai entender como ele funciona por dentro: da fórmula de atenção à máscara causal que torna a geração de texto possível.

⚠️
Pré-requisito real: você precisa entender redes neurais (forward pass, loss, backpropagation) e saber o que são tokens. Se não leu esses artigos, leia antes — sem isso, o Transformer vira decoreba.

O problema que o Transformer resolveu

Antes de 2017, modelos de linguagem usavam RNNs (Recurrent Neural Networks) e LSTMs (Long Short-Term Memory). Essas arquiteturas processavam texto token por token, em sequência. Dois problemas fatais:

ProblemaRNN/LSTMTransformer
ParalelizaçãoImpossível — token N depende do output de N-1Total — todos os tokens processados de uma vez
Dependências longasGradiente desaparece após ~100 tokensAtenção alcança qualquer posição na sequência
Velocidade de treinoLento — operações sequenciaisRápido — GPUs adoram operações matriciais paralelas
EscalabilidadeModelo com 1B params já era impraticávelGPT-4: ~1.7T params (estimado)

O Transformer resolveu tudo de uma vez: substituiu a recorrência por um mecanismo de atenção pura que processa toda a sequência em paralelo. Resultado: modelos 10-100× maiores treinados em fração do tempo.

Self-Attention: a ideia central

A pergunta que self-attention responde é simples: “para entender este token, quais outros tokens da sequência são relevantes?”

Para cada token, o modelo cria três vetores multiplicando o embedding por três matrizes de pesos aprendidas:

🗺️ Q, K, V — os três vetores do token "sentou"
📥Embeddingvetor de dimensão d
✖️× Wq / Wk / Wvmatrizes de pesos aprendidas
🔍Q — Query"o que eu procuro"
🔑K — Key"o que eu ofereço"
📖V — Value"meu conteúdo"

Analogia da biblioteca: Query = sua pergunta; Key = título de cada livro; Value = conteúdo do livro. Atenção = match(Query, Key) → pega Value.

Cada token gera seus próprios Q, K e V. A mágica acontece quando comparamos o Query de um token com as Keys de todos os outros tokens.

A fórmula: Attention(Q, K, V)

A fórmula completa de scaled dot-product attention é:

Attention(Q, K, V) = softmax( Q · Kᵀ / √dₖ ) · V

Passo a passo para “sentou” na frase “O gato sentou no tapete”:

🗺️ Atenção de 'sentou' para cada token (após softmax)
Ogatosentounotapete
sentou0.060.310.330.070.23
🗺️ Pipeline completo do Attention
🔢1. SCOREQ("sentou") · Kᵀ(todos)
📏2. SCALE÷ √dₖ para estabilidade
🎯3. SOFTMAXconverte em probs (soma=1)
4. COMBINEsoma V × peso de atenção
💡
Por que dividir por √dₖ? Quando a dimensão dₖ é grande (ex: 128), os dot products Q·K crescem em magnitude. Valores muito grandes no input do softmax produzem distribuições quase one-hot: quase toda atenção vai para um único token, e os gradientes ficam próximos de zero. Dividir por √dₖ mantém a variância estável — é a diferença entre treinar e não treinar.

Forma matricial: processando tudo de uma vez

Na prática, Q, K e V não são vetores individuais — são matrizes onde cada linha é o vetor de um token. Para uma sequência de n tokens com dimensão dₖ:

🗺️ Dimensões das matrizes (n=5 tokens, d=512, dₖ=64)
📊Embeddings Xℝ⁵ˣ⁵¹²
✖️× Wq/Wk/Wv(512→64)
📐Q, K, Vℝ⁵ˣ⁶⁴ cada
🔢Q·Kᵀ Scoresℝ⁵ˣ⁵ — custo O(n²)
📤Outputℝ⁵ˣ⁶⁴

Custo: O(n²·dₖ) — quadrático no comprimento da sequência. Para n=8192, ~67 milhões de scores por camada.

⚠️
O custo O(n²) é o grande gargalo dos Transformers. Context windows de 128k tokens significam n²=16 bilhões de scores por camada. Por isso existem otimizações como KV Cache (próximo artigo), Flash Attention, e sparse attention.

Multi-Head Attention: olhar de múltiplos ângulos

Uma única cabeça de atenção aprende um tipo de relação. Mas linguagem tem muitas dimensões: sintaxe, semântica, correferência, posição relativa. A solução: múltiplas cabeças em paralelo, cada uma operando em um subespaço diferente.

🗺️ Multi-Head Attention — d=512, h=8 cabeças, dₖ=64
INPUT (512)
Embedding de cada token
Dimensão d = 512
H CABEÇAS EM PARALELO
Head 1: Wq₁,Wk₁,Wv₁ → Attn
Head 2: Wq₂,Wk₂,Wv₂ → Attn
...
Head 8: Wq₈,Wk₈,Wv₈ → Attn
Cada head: 512→64 dims
OUTPUT (512)
Concat [out₁|...|out₈]
× Wo (512×512)
Output final d=512
CASOS DE USO
Head 1: sujeito→verbo
Head 3: pronome→referência
Head 5: adj→substantivo
Head 7: posição relativa

O custo computacional é o mesmo que single-head: h cabeças de dimensão d/h = uma multiplicação matricial de dimensão d. Mas o modelo ganha capacidade expressiva massivamente superior.

Positional Encoding: ensinando ordem ao Transformer

Self-attention é invariante à ordem: “gato mordeu cachorro” e “cachorro mordeu gato” produzem os mesmos scores de atenção (os mesmos tokens, os mesmos dot products). Isso é um problema sério — ordem muda significado.

A solução: somar ao embedding de cada token um vetor que codifica sua posição na sequência. O paper original usou funções seno/cosseno com frequências diferentes:

🗺️ Positional Encoding — valores PE para os primeiros 4 tokens (d=8)
dim0dim1dim2dim3dim4dim5dim6dim7
pos 00.001.000.001.000.001.000.001.00
pos 10.840.540.100.990.011.000.001.00
pos 20.91-0.420.200.980.021.000.001.00
pos 30.14-0.990.300.960.031.000.001.00

Frequências altas (dim0–1) mudam rápido entre posições; frequências baixas (dim6–7) mudam devagar — o modelo aprende a ler posição a partir do padrão combinado. Embedding final = token_embedding + positional_encoding.

Tipo de PEComo funcionaUsado em
Sinusoidal (fixa)Funções sin/cos com frequências diferentes; não treinávelTransformer original (2017)
Learned (aprendida)Vetor treinável por posição; mais flexívelGPT-2, BERT
RoPE (Rotary)Rotação no espaço complexo; extrapola para sequências maioresLLaMA, GPT-NeoX, Claude
ALiBiBias linear na atenção proporcional à distância; sem PE no embeddingBLOOM, MPT

Modelos modernos preferem RoPE porque ela permite extrapolar para sequências mais longas do que as vistas no treino — essencial para context windows de 100k+ tokens.

Bloco Transformer completo

Cada bloco Transformer (também chamado de “layer”) combina atenção com uma rede feed-forward e usa duas técnicas cruciais: conexões residuais e layer normalization.

🗺️ Um bloco Transformer (repetido N vezes)
📥Inputn × d
Embeddings dos tokens + positional encoding (ou output do bloco anterior)
👁️Multi-Head Self-AttentionMHA
Cada token atende a todos os outros (ou só anteriores, se decoder). Produz representação contextualizada.
ADD & NORM
Residual + LayerNormestabilidade
output = LayerNorm(input + MHA(input)). A conexão residual permite gradientes fluírem direto; LayerNorm estabiliza escala.
FFN
🧠Feed-Forward Network (FFN)MLP
Duas camadas lineares com ativação (GELU): FFN(x) = GELU(xW₁ + b₁)W₂ + b₂. Dimensão interna tipicamente 4× a do modelo (ex: 512→2048→512).
ADD & NORM
Residual + LayerNormestabilidade
output = LayerNorm(x + FFN(x)). Mesmo padrão: residual + normalização.
📤Outputn × d
Representação refinada de cada token. Vai para o próximo bloco (ou para a camada de predição no último bloco).
💡
Pre-LN vs Post-LN: o paper original coloca LayerNorm depois da soma residual (Post-LN). Modelos modernos (GPT-3+, LLaMA, Claude) usam Pre-LN: LayerNorm antes da atenção/FFN. Pre-LN treina de forma mais estável com learning rates maiores.

Encoder vs Decoder: as três arquiteturas

O paper original propôs encoder + decoder juntos (para tradução). Mas a comunidade descobriu que cada metade funciona sozinha para tarefas diferentes.

🗺️ Três variantes de Transformer
ENCODER-ONLY
Self-Attention BIDIRECIONAL
Cada token vê todos os outros
Representações contextuais ricas
BERT · RoBERTa · DeBERTa
CASOS DE USO
Classificação
NER
Embeddings
DECODER-ONLY
Masked Self-Attention
CAUSAL (←) — só vê anteriores
Gera token por token
GPT · Claude · LLaMA · Gemini
CASOS DE USO
Geração de texto
Chat
Código
ENCODER-DECODER
Encoder: bidirecional
Decoder: causal + cross-attention
Cross-attn lê output do encoder
T5 · BART · Whisper · Flan-T5
CASOS DE USO
Tradução
Sumarização
Speech-to-text

Máscara causal: como o decoder gera texto

O decoder precisa gerar tokens um de cada vez, da esquerda para a direita. Mas self-attention, por padrão, permite que cada token veja a sequência inteira — incluindo tokens futuros. Isso seria “trapacear”.

A solução é a máscara causal: antes do softmax, setamos -∞ em todas as posições futuras. Após o softmax, elas viram 0 — atenção zero.

🗺️ Atenção após máscara causal — frase "O gato sentou"
Ogatosentou
O1.000.000.00
gato0.290.710.00
sentou0.050.600.35

Posições bloqueadas (futuro) recebem score -∞ antes do softmax → atenção 0 após softmax. “O” só vê a si mesmo; “sentou” vê os três tokens.

Durante o treinamento, a máscara permite processar toda a sequência em paralelo (teacher forcing). Durante a inferência, o modelo gera token por token, e a máscara garante que cada novo token é condicionado apenas nos anteriores.

Cross-Attention: encoder fala com decoder

No Transformer original (encoder-decoder), o decoder tem uma camada extra entre self-attention e FFN: cross-attention. Nela, o Query vem do decoder mas Key e Value vêm do output do encoder.

🗺️ Cross-Attention — como encoder e decoder se comunicam
ENCODER
"The cat sat"
→ [e₁, e₂, e₃]
Representações bidirecionais
Fornece K e V
CROSS-ATTENTION
Q vem do decoder (d₁, d₂)
K e V vêm do encoder (e₁-e₃)
"gato" atende a "cat" → alta attn
"gato" atende a "The" → baixa attn
DECODER
"O gato" → self-attn
→ [d₁, d₂]
Consulta encoder para gerar
Fornece Q

Modelos decoder-only como GPT e Claude não precisamde cross-attention porque não têm encoder. Toda a informação (input + output) vive na mesma sequência — o prompt é o “encoder”.

Por que GPT é decoder-only?

Uma das decisões mais impactantes da história recente da IA: por que não usar encoder?

FatorEncoder-DecoderDecoder-Only
Complexidade2 stacks separados, cross-attention1 stack, mais simples de escalar
EscalaParâmetros divididos entre encoder e decoderTodos os parâmetros focados em uma direção
TreinamentoPrecisa de pares (input, output)Treina em texto contínuo — dados infinitos na web
VersatilidadeEspecializado em seq2seq (tradução, resumo)Qualquer tarefa formulada como "completar texto"
Few-shot/ICLDifícil — encoder e decoder têm papéis fixosNatural — exemplos vão no prompt como contexto
EmergênciaEscala até ~10B params com retornos decrescentesCapacidades emergentes em escala (>100B params)

📋 Qual arquitetura para um LLM de uso geral?

Decoder-only

Simplicidade de escalar + treino em texto da web sem supervisão + versatilidade de prompt = dominância total desde GPT-3 (2020). O mercado validou: GPT, Claude, LLaMA, Gemini — todos decoder-only.

Alt: Encoder-only (BERT)Ainda usado para embeddings, classificação e busca semântica onde bidirecionalidade importa.

Alt: Encoder-decoder (T5)Usado em tradução, speech-to-text (Whisper) e tarefas com input/output claramente separados.

Escala: dos 65M aos 1.7T parâmetros

📅 Evolução dos Transformers
2017
Transformer original
65M params, 6 blocos encoder + 6 decoder. Tradução inglês→alemão.
2018
GPT-1 + BERT
GPT-1: 117M (decoder). BERT: 340M (encoder). Proof que pré-treino funciona.
2019
GPT-2
1.5B params. "Too dangerous to release." Geração coerente de texto longo.
2020
GPT-3
175B params. Few-shot learning emerge — o modelo faz tarefas sem fine-tune.
2022
ChatGPT (GPT-3.5)
RLHF transforma GPT em assistente. 100M usuários em 2 meses.
2023
GPT-4 / Claude 2 / LLaMA
GPT-4: ~1.7T params (MoE). Claude: segurança. LLaMA: open weights.
2024
Claude 3.5 / GPT-4o / LLaMA 3
Context windows de 128k-200k. Multimodal. Tool use nativo.
2025
Claude 4 / GPT-4.5 / DeepSeek v3
Reasoning, code agents, context >1M tokens. MoE generalizado.

O padrão é claro: a mesma arquitetura (Transformer decoder-only) escala de 117M a 1.7T parâmetros com capacidades emergentes previsíveis. A inovação não está mais na arquitetura — está nos dados, no treinamento (RLHF, DPO) e na infraestrutura (MoE, Flash Attention, KV Cache).

Código real: self-attention em PyTorch

python
import torch
import torch.nn.functional as F

def scaled_dot_product_attention(Q, K, V, mask=None):
    """Attention(Q, K, V) = softmax(QKᵀ / √dₖ) V"""
    d_k = Q.size(-1)
    scores = torch.matmul(Q, K.transpose(-2, -1)) / (d_k ** 0.5)

    if mask is not None:
        scores = scores.masked_fill(mask == 0, float('-inf'))

    weights = F.softmax(scores, dim=-1)
    return torch.matmul(weights, V), weights

# Exemplo: sequência de 5 tokens, dimensão 64
Q = torch.randn(1, 5, 64)  # (batch, seq_len, d_k)
K = torch.randn(1, 5, 64)
V = torch.randn(1, 5, 64)

# Máscara causal: triângulo inferior
mask = torch.tril(torch.ones(5, 5))  # [[1,0,0,0,0],[1,1,0,0,0],...]

output, attn_weights = scaled_dot_product_attention(Q, K, V, mask)
print(f"Output shape: {output.shape}")       # (1, 5, 64)
print(f"Attn weights shape: {attn_weights.shape}")  # (1, 5, 5)
print(f"Attn weights[0,0]: {attn_weights[0,0]}")
# → tensor([1.0, 0.0, 0.0, 0.0, 0.0]) ← token 0 só atende a si

Perguntas e respostas

Se atenção é O(n²), como modelos processam 128k tokens?

Várias otimizações: Flash Attention (reordena cálculos para minimizar acessos à memória HBM — mesma complexidade, 2-4× mais rápido), KV Cache (reutiliza K e V de tokens já processados na inferência), sparse attention (cada token atende só a um subconjunto), e sliding window attention (Mistral — cada token atende aos N tokens mais próximos + alguns globais).

O que são as 'camadas' de um Transformer? Quando alguém diz 'GPT-3 tem 96 layers', o que significa?

Cada “layer” é um bloco Transformer completo: MHA + residual + FFN + residual. GPT-3 tem 96 desses blocos empilhados. O token passa por todos sequencialmente. As primeiras camadas capturam padrões locais e sintáticos; as últimas, semânticos e abstratos.

Feed-forward tem 4× a dimensão do modelo. Por quê?

O FFN é onde o modelo “pensa” — transforma as representações da atenção. A expansão 4× (512→2048→512) cria um “espaço de trabalho” mais rico para combinações não-lineares. Pesquisas recentes (SwiGLU, usado em LLaMA) usam 8/3× em vez de 4× com ativação gated, com resultados superiores.
O que você aprendeu: como self-attention funciona com Q/K/V, por que dividir por √dₖ, como multi-head atenção aprende relações diferentes em paralelo, o papel do positional encoding, a diferença entre encoder e decoder, como a máscara causal torna geração de texto possível, e por que decoder-only dominou. Você agora entende a arquitetura que roda o mundo da IA. Próximo passo: como fazer essa arquitetura funcionar de forma eficiente com KV Cache.
🧩

Quiz rápido

4 perguntas · Acerte tudo e ganhe o badge 🎯 Gabarito

Continue lendo