1 O que é um Transformer?
A arquitetura que mudou tudo em 2017 — e por que ela substituiu RNNs.
O paper que mudou tudo
Em junho de 2017, pesquisadores do Google publicaram "Attention is All You Need". A ideia central: abandonar completamente RNNs e CNNs para processamento de linguagem, usando apenas mechanisms de atenção.
❌ RNN/LSTM (antes)
Processamento: sequencial (token por token)
Dependências longas: difíceis de capturar
Paralelização: impossível
Lento e limitado para sequências longas.
✅ Transformer (depois)
Processamento: paralelo (todos os tokens)
Dependências longas: capturadas diretamente
Paralelização: total (usa GPUs eficientemente)
Rápido, escalável, captura contexto de longo alcance.
Por que Transformers dominaram?
Paralelização total
Todos os tokens processados simultaneamente. Treinamento 10x mais rápido que RNNs.
Self-attention
Cada token conecta-se diretamente a qualquer outro, independente da distância.
Escalabilidade
Pode ser empilhado em centenas de camadas (GPT-3 tem 96).
Versatilidade
Funciona para texto, imagem, áudio, vídeo — qualquer sequência.
2 Self-Attention — o coração do Transformer
Como cada token "olha" para todos os outros e decide o que é relevante.
A fórmula da atenção
# Self-attention (simplificado) Attention(Q, K, V) = softmax(Q * K^T / √d_k) * V # Onde: # Q (Query) = "o que estou procurando?" # K (Key) = "o que eu tenho?" # V (Value) = "qual meu conteúdo?" # d_k = dimensão dos vetores (normalização) # Para cada token: # 1. Calcula Q, K, V (projeções lineares do token) # 2. Q * K^T = scores de atenção (similaridade com todos) # 3. softmax = normaliza para probabilidades (soma = 1) # 4. Multiplica por V = combinação ponderada dos valores
🎮 Simulador: Matriz de Atenção
Cada célula mostra quanto a palavra da linha "olha" para a palavra da coluna. Valores mais claros = mais atenção. Clique em uma célula para ver detalhes.
Frase: "O contrato que assinamos em janeiro venceu"
Interpretação: note como "venceu" olha fortemente para "contrato" (sujeito), e "que" olha para "contrato" (pronome relativo).
Exemplo prático: resolvendo ambiguidade
# Frase ambígua "O banco que fica na esquina faliu." # Self-attention descobre: # - "banco" olha para "faliu" → contexto financeiro # - "banco" NÃO olha fortemente para "esquina" # - Conclusão: "banco" = instituição financeira, não assento # Comparação com RNN: # - RNN processa sequencialmente # - Quando chega em "faliu", já processou "banco" há 5 tokens # - Informação pode ter se perdido # - Transformer: "faliu" olha diretamente para "banco"
3 Multi-Head Attention — múltiplas perspectivas
Em vez de uma única atenção, várias "cabeças" capturando diferentes tipos de relações.
🎮 Simulador: diferentes cabeças, diferentes padrões
Clique nas abas para ver como cada "cabeça" do Transformer foca em padrões diferentes da mesma frase.
O que cada cabeça aprende?
Cabeças de Referência
Pronomes ("ele", "ela") olhando para seus antecedentes. Resolve ambiguidade de coreferência.
Cabeças de Posição
Tokens olhando para vizinhos próximos. Captura sintaxe local e padrões adjacentes.
Cabeças Semânticas
Palavras relacionadas por significado (sinônimos, tópicos). Captura relações de conteúdo.
Cabeças Sintáticas
Sujeito-verbo, modificadores distantes. Captura estrutura gramatical.
Código Python: Multi-Head Attention
import torch import torch.nn as nn import torch.nn.functional as F class MultiHeadAttention(nn.Module): def __init__(self, d_model=512, num_heads=8): super().__init__() self.d_model = d_model self.num_heads = num_heads self.d_k = d_model // num_heads # 64 por cabeça # Projeções lineares para Q, K, V self.W_q = nn.Linear(d_model, d_model) self.W_k = nn.Linear(d_model, d_model) self.W_v = nn.Linear(d_model, d_model) self.W_o = nn.Linear(d_model, d_model) def forward(self, x): batch_size = x.size(0) # 1. Projeções lineares Q = self.W_q(x) # (batch, seq_len, d_model) K = self.W_k(x) V = self.W_v(x) # 2. Reshape para múltiplas cabeças Q = Q.view(batch_size, -1, self.num_heads, self.d_k).transpose(1, 2) K = K.view(batch_size, -1, self.num_heads, self.d_k).transpose(1, 2) V = V.view(batch_size, -1, self.num_heads, self.d_k).transpose(1, 2) # 3. Attention scores scores = torch.matmul(Q, K.transpose(-2, -1)) / (self.d_k ** 0.5) attn = F.softmax(scores, dim=-1) # 4. Aplica atenção aos valores out = torch.matmul(attn, V) # 5. Concatena cabeças e projeta out = out.transpose(1, 2).contiguous().view(batch_size, -1, self.d_model) return self.W_o(out) # Uso mha = MultiHeadAttention(d_model=512, num_heads=8) x = torch.randn(1, 10, 512) # 10 tokens, 512 dimensões out = mha(x) print(out.shape) # torch.Size([1, 10, 512])
4 Positional Encoding — a ordem importa
Como Transformers sabem a ordem das palavras, já que processam tudo em paralelo.
A fórmula
# Positional Encoding (original do paper) PE(pos, 2i) = sin(pos / 10000^(2i/d_model)) PE(pos, 2i+1) = cos(pos / 10000^(2i/d_model)) # Onde: # pos = posição do token na sequência (0, 1, 2, ...) # i = índice da dimensão (0, 1, 2, ..., d_model/2) # d_model = dimensão do modelo (ex: 512, 768) # Resultado: cada posição tem um vetor único # Adiciona ao embedding do token: token_with_pos = token_embedding + positional_encoding
Por que sin/cos?
Relativo
Permite ao modelo aprender a atender a posições relativas (ex: "2 tokens antes").
Escalável
Funciona para sequências de qualquer comprimento (não precisa treinar para cada posição).
Único
Cada posição tem um vetor único, permitindo distinguir "João ama Maria" de "Maria ama João".
Exemplo prático
# Frase: "O gato dormiu" # Sem positional encoding: # - "O gato dormiu" e "dormiu gato O" → mesma representação # - Modelo não sabe a ordem! # Com positional encoding: token_0 = embed("O") + PE(0) token_1 = embed("gato") + PE(1) token_2 = embed("dormiu") + PE(2) # Agora "O gato dormiu" ≠ "dormiu gato O" # Cada token sabe sua posição na sequência
5 Arquitetura: Encoder vs Decoder
Duas variantes principais: BERT (encoder) e GPT (decoder) — e quando usar cada uma.
🏗️ As duas arquiteturas
🔵 Encoder (BERT)
Uso: classificação, NER, embeddings, QA.
🟢 Decoder (GPT)
Uso: geração de texto, chatbots, LLMs.
A diferença crucial: masking
🔵 Encoder (BERT) — bidirecional
Cada token vê todos os outros (antes e depois).
Ex: "gato" em "O gato dormiu" vê "O" E "dormiu".
✅ Ótimo para entender contexto completo.
🟢 Decoder (GPT) — unidirecional
Cada token vê só os anteriores (máscara causal).
Ex: "dormiu" em "O gato dormiu" vê "O" e "gato", mas não o que vem depois.
✅ Essencial para geração (não trapacear olhando o futuro).
Modelos famosos e suas arquiteturas
| Modelo | Arquitetura | Ano | Uso principal |
|---|---|---|---|
| BERT | 🔵 Encoder | 2018 | Classificação, NER, embeddings |
| RoBERTa | 🔵 Encoder | 2019 | BERT melhorado |
| GPT-2 | 🟢 Decoder | 2019 | Geração de texto |
| T5 | 🔵+🟢 Encoder-Decoder | 2019 | Tradução, sumarização |
| GPT-3 | 🟢 Decoder | 2020 | LLM generativo |
| Claude | 🟢 Decoder | 2023 | LLM assistente |
| Llama 3 | 🟢 Decoder | 2024 | LLM open-source |
6 Outras peças do quebra-cabeça
Feed-forward, LayerNorm, residual connections — o que mais compõe um Transformer.
Feed-Forward Network (FFN)
Após a atenção, cada token passa por uma rede neural simples (2 camadas lineares com ativação no meio). É onde o modelo "pensa" sobre a informação coletada pela atenção.
# Feed-Forward Network (posição por posição) FFN(x) = ReLU(x * W1 + b1) * W2 + b2 # Tipicamente: # - W1 expande: 512 → 2048 (4x) # - ReLU ativa # - W2 comprime: 2048 → 512
Layer Normalization
Normaliza os valores ao longo da dimensão das features. Estabiliza o treinamento e acelera convergência.
# LayerNorm (simplificado) LayerNorm(x) = γ * (x - μ) / √(σ² + ε) + β # Onde: # μ = média dos valores do token # σ² = variância # γ, β = parâmetros aprendíveis # ε = pequena constante para estabilidade
Residual Connections (Skip Connections)
# Residual connection output = x + SubLayer(x) # Em vez de: output = SubLayer(x) # O "+ x" permite que o gradiente flua diretamente # mesmo se SubLayer for problemático
O bloco completo do Transformer
# Um bloco do encoder (BERT) x = x + MultiHeadAttention(LayerNorm(x)) # atenção + residual x = x + FeedForward(LayerNorm(x)) # FFN + residual # Um bloco do decoder (GPT) x = x + MaskedMultiHeadAttention(LayerNorm(x)) x = x + FeedForward(LayerNorm(x)) # Empilha N desses blocos (12, 24, 96...)
7 Conexão com RAG
Como tudo que você aprendeu aqui se aplica ao Módulo 7 (RAG).
Conceitos que se conectam
| Conceito de Transformers | Aplicação em RAG |
|---|---|
| Self-Attention | Permite que embeddings capturem contexto completo do chunk. "timeout" olha para "endpoint" e entende o significado. |
| Multi-Head Attention | Diferentes cabeças capturam diferentes aspectos: sintaxe, semântica, referências. Embeddings ricos. |
| Encoder (BERT) | Modelos de embedding (nomic-embed-text) são encoders. Geram vetores que representam chunks inteiros. |
| Decoder (GPT) | LLMs que geram respostas (Llama, Claude) são decoders. Recebem contexto do RAG e geram texto. |
| Positional Encoding | Preserva ordem das palavras nos chunks. Importante para chunks longos com dependências distantes. |
| Context Window | Limite de tokens que o Transformer pode processar. Define tamanho máximo dos chunks em RAG. |
O pipeline RAG com Transformers
# Pipeline completo usando Transformers # 1. Indexação (usa ENCODER) chunks = chunk_document(doc) encoder = load_model("nomic-embed-text") # baseado em BERT for chunk in chunks: embedding = encoder(chunk) # self-attention captura contexto vector_db.add(embedding, chunk) # 2. Consulta (usa ENCODER + DECODER) question = "Qual o timeout do endpoint /v2/sync?" q_embedding = encoder(question) # mesmo modelo de embedding chunks = vector_db.search(q_embedding, top_k=5) # 3. Geração (usa DECODER) llm = load_model("llama3.1:8b") # decoder Transformer prompt = format_prompt(chunks, question) answer = llm.generate(prompt) # gera token por token
Por que o tamanho do contexto importa?
Transformers têm um limite de tokens que podem processar (context window):
- BERT: 512 tokens
- GPT-3: 4096 tokens
- Claude 3: 200.000 tokens
- GPT-4 Turbo: 128.000 tokens
Isso define o tamanho máximo dos chunks em RAG. Chunks muito grandes não cabem; chunks muito pequenos perdem contexto.
🎯 Quiz — teste seu conhecimento
Clique em uma alternativa para ver se acertou.
→ O que vem a seguir?
Agora que você entende Transformers, vamos mergulhar nos Grandes Modelos de Linguagem.
Conceitos que vamos construir aqui
Pré-treinamento
Next token prediction em trilhões de tokens.
Fine-tuning (SFT)
Ajuste supervisionado para tarefas específicas.
RLHF
Alinhamento com preferências humanas.
Temperature
Controlando criatividade vs determinismo.