Phase 07 - Lesson 07

GPT — Modelagem de Linguagem Causal

This lesson includes a graded coding exercise that runs in your browser, unlocked with lifetime access.

O BERT vê ambos os lados. O GPT vê apenas o passado. A máscara triangular é a linha de código individual mais consequente na IA moderna.

Tipo: Build Linguagens: Python Pré-requisitos: Fase 7 · 02 (Self-Attention), Fase 7 · 05 (Full Transformer), Fase 7 · 06 (BERT) Tempo: ~75 minutos

O Problema

Um modelo de linguagem responde a uma pergunta: dados os primeiros t-1 tokens, qual é a distribuição de probabilidade sobre o token t? Treine nesse sinal — previsão do próximo token — e você obterá um modelo capaz de gerar texto arbitrário, um token por vez.

Para treiná-lo de ponta a ponta em uma sequência inteira em paralelo, você precisa que a previsão de cada posição dependa apenas das posições anteriores. Caso contrário, o modelo trapaceia trivialmente olhando para a resposta.

A máscara causal faz isso. É uma matriz triangular superior única de valores -inf adicionados aos scores de atenção antes do softmax. Após o softmax, essas posições tornam-se 0. Cada posição pode atentar apenas para si mesma e para as posições anteriores. E como você a aplica uma vez a toda a sequência, você obtém N previsões paralelas do próximo token em uma única passagem para a frente (forward pass).

GPT-1 (2018), GPT-2 (2019), GPT-3 (2020), GPT-4 (2023), GPT-5 (2024), Claude, Llama, Qwen, Mistral, DeepSeek, Kimi — todos eles são transformers causais apenas com decodificador (decoder-only) com o mesmo loop central. Apenas com dados maiores e melhores, e melhor RLHF.

O Conceito

A máscara causal cria uma matriz de atenção triangular

A máscara

Dada uma sequência de comprimento N, construa uma matriz N × N:

M[i, j] = 0       if j <= i
M[i, j] = -inf    if j > i

Adicione M aos scores de atenção brutos antes do softmax. exp(-inf) = 0, portanto, as posições mascaradas contribuem com peso zero. Cada linha da matriz de atenção é uma distribuição de probabilidade apenas sobre as posições anteriores.

Custo de implementação: uma única chamada a torch.tril(). Tempo de computação: nanossegundos. Impacto no campo: tudo.

Treinamento paralelo, inferência serial

Treinamento: execute o forward pass de toda a sequência (N, d_model) de uma vez, compute N perdas de entropia cruzada (uma por posição), some e faça o backprop. Paralelo ao longo da sequência. É por isso que o treinamento do GPT escala — você processa 1M de tokens em um lote (batch) em uma única passagem da GPU.

Inferência: você gera token por token. Alimente [t1, t2, t3], obtenha t4. Alimente [t1, t2, t3, t4], obtenha t5. Alimente [t1, t2, t3, t4, t5], obtenha t6. O cache KV (Lição 12) salva os estados ocultos (hidden states) de t1…tn para que você não os recompute a cada passo. Mas a profundidade serial na inferência = comprimento da saída. Esse é o imposto autorregressivo (autoregressive tax) e a razão pela qual a decodificação é o gargalo de latência de todo LLM.

A perda — deslocamento por um (shift-by-one)

Dados os tokens [t1, t2, t3, t4]:

  • Entrada: [t1, t2, t3]
  • Alvos: [t2, t3, t4]

Para cada posição i, compute -log P(target_i | inputs[:i+1]). Some. Esta é a entropia cruzada para toda a sequência.

Todo transformer LM que você conhece treina com essa perda. Pré-treinamento, ajuste fino (fine-tuning), SFT — mesma perda, dados diferentes.

Estratégias de decodificação

Após o treinamento, as escolhas de amostragem (sampling) importam mais do que as pessoas imaginam.

Método O que faz Quando usar
Greedy Argmax a cada passo Tarefas determinísticas, completamento de código
Temperatura Divide os logits por T, amostra Tarefas criativas, T maior = mais diversidade
Top-k Amostra apenas dos top-k tokens Elimina caudas de baixa probabilidade
Top-p (nucleus) Amostra do menor conjunto com prob acumulada ≥ p Padrão pós-2020; adapta-se ao formato da distribuição
Min-p Mantém tokens com p > min_p * max_p Pós-2024; melhor em rejeitar caudas longas do que o top-p
Decodificação especulativa Modelo de rascunho propõe N tokens, modelo grande verifica Redução de 2 a 3 vezes na latência com a mesma qualidade

Em 2026, min-p + temperatura 0.7 é um padrão razoável para modelos de pesos abertos (open-weights). A decodificação especulativa é um requisito básico para qualquer stack de inferência em produção.

O que fez a "receita do GPT" funcionar

  1. Apenas decodificador (Decoder-only). Sem o overhead do codificador (encoder). Uma passagem de atenção + FFN por camada.
  2. Escalonamento (Scaling). 124M → 1.5B → 175B → trilhões. As leis de escala de Chinchilla (Lição 13) dizem como gastar computação.
  3. Aprendizado em contexto (In-context learning). Surgiu em torno de 6B–13B. O modelo consegue seguir exemplos few-shot sem ajuste fino.
  4. RLHF. O pós-treinamento em preferências humanas converteu o texto bruto pré-treinado em assistentes de chat.
  5. Pre-norm + RoPE + SwiGLU. Treinamento estável em escala.

A arquitetura principal não mudou muito desde o GPT-2. Tudo de interessante aconteceu em dados, escala e pós-treinamento.

Build It

Passo 1: a máscara causal

Veja code/main.py. Uma única linha:

def causal_mask(n):
    return [[0.0 if j <= i else float("-inf") for j in range(n)] for i in range(n)]

Adicione aos scores de atenção antes do softmax. Esse é todo o mecanismo.

Passo 2: um modelo estilo GPT de 2 camadas

Empilhe dois blocos decodificadores (self-attention mascarado + FFN, sem atenção cruzada/cross-attention). Adicione um embedding de token, uma codificação posicional (positional encoding) e um unembedding (vinculado à matriz de embedding de token — um truque padrão desde o GPT-2).

Passo 3: previsão do próximo token, ponta a ponta

Em um vocabulário de brinquedo de 20 tokens, produza logits em cada posição. Compute a perda de entropia cruzada em relação ao alvo deslocado por um. Sem gradiente — esta é uma verificação de sanidade do forward pass.

Passo 4: amostragem

Implemente os métodos greedy, temperatura, top-k, top-p e min-p. Execute cada um em um prompt fixo e compare os resultados. Uma função de amostragem tem cerca de 10 linhas.

Use It

PyTorch, estilo de 2026:

from transformers import AutoModelForCausalLM, AutoTokenizer
model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-3.2-3B-Instruct")
tok = AutoTokenizer.from_pretrained("meta-llama/Llama-3.2-3B-Instruct")

prompt = "Attention is all you need because"
inputs = tok(prompt, return_tensors="pt")
out = model.generate(
    **inputs,
    max_new_tokens=64,
    temperature=0.7,
    top_p=0.9,
    do_sample=True,
)
print(tok.decode(out[0]))

Por baixo dos panos, generate() executa o forward pass, extrai os logits da posição final, amostra o próximo token, o anexa e repete. Cada stack de inferência de LLM em produção (vLLM, TensorRT-LLM, llama.cpp, Ollama, MLX) implementa o mesmo loop com otimizações pesadas — prefill em lote (batched prefill), loteamento contínuo (continuous batching), paginação de cache KV (KV cache paging) e decodificação especulativa.

GPT vs BERT, uma linha cada: O GPT prevê P(x_t | x_{<t}). O BERT prevê P(x_masked | x_unmasked). A perda determina se o modelo é capaz de gerar.

Ship It

Veja outputs/skill-sampling-tuner.md. A habilidade (skill) escolhe os parâmetros de amostragem para uma nova tarefa de geração e sinaliza quando a decodificação determinística é necessária.

Exercícios

  1. Fácil. Execute code/main.py e verifique se a matriz de atenção causal é triangular inferior após o softmax. Verificação rápida: a linha 3 deve ter pesos apenas nas colunas 0 a 3.
  2. Médio. Implemente a busca por feixe (beam search) com largura 4. Compare a perplexidade do beam-4 versus greedy em 10 prompts curtos. O beam sempre vence? (Dica: geralmente sim para tradução, mas não para chat aberto.)
  3. Difícil. Implemente a decodificação especulativa: use um modelo minúsculo de 2 camadas como rascunho (draft) e um modelo de 6 camadas como verificador. Meça a aceleração de tempo de relógio (wall-clock speedup) em 100 conclusões de comprimento 64. Confirme se as saídas correspondem à decodificação greedy do verificador.

Termos-Chave

Termo O que as pessoas dizem O que realmente significa
Máscara causal "O triângulo" Matriz triangular superior de -inf adicionada aos scores de atenção para que a posição i veja apenas as posições ≤ i.
Previsão do próximo token "A perda (loss)" Entropia cruzada da distribuição do modelo em relação ao verdadeiro próximo token em cada posição.
Autorregressivo "Gerar um por vez" Alimentar a saída de volta como entrada; paralelismo apenas durante o treinamento, não durante a geração.
Logits "Scores pré-softmax" Saída bruta da cabeça do LM (LM head) antes do softmax; a amostragem ocorre sobre estes valores.
Temperatura "Botão de criatividade" Divide os logits por T; T→0 = greedy, T→∞ = uniforme.
Top-p "Amostragem de núcleo (nucleus)" Trunca a distribuição para o menor conjunto cuja soma seja ≥p; amostra a partir do que resta.
Min-p "Melhor que top-p" Mantém os tokens onde p ≥ min_p × max_p; adapta o corte à nitidez da distribuição.
Decodificação especulativa "Rascunho + verificação" Modelo barato propõe N tokens; modelo grande verifica em paralelo.
Teacher forcing "Truque de treinamento" Durante o treinamento, alimenta o verdadeiro token anterior, não a previsão do modelo. Padrão para todo LM seq2seq.

Leitura Adicional

0 lifetime access. Curriculum based on AI Engineering from Scratch by Rohit Ghumare (MIT, used under attribution).