Construir um LLM do Zero 🧠

Construir um transformer completo do zero, da tokenização à inferência, é um exercício técnico e também uma estratégia de carreira. Um nanoGPT pequeno, entendido linha a linha, mostra mais sobre o raciocínio de engenharia de alguém do que a capacidade de recitar um paper.

A tese é simples: entrevistas de frontier labs testam por que cada peça existe. Um build com menos de 300 linhas de PyTorch pode ser suficiente para tornar essas respostas concretas, desde que não seja apenas código copiado.

As cinco partes do build

1. Tokenização e embeddings

Texto vira IDs de tokens por meio de BPE; os IDs entram numa tabela de lookup que produz vetores densos. Como o transformer não tem noção de ordem por padrão, o embedding posicional é incorporado. Implementações modernas usam RoPE, que rotaciona Query e Key por posição e preserva melhor a posição relativa.

2. Self-attention

Cada token gera três vetores por projeção linear: Query, Key e Value. A atenção calcula:

scores = Q · Kᵀ / √dₖ
weights = softmax(scores)
output = weights · V

O causal masking coloca infinito negativo nas posições futuras antes do softmax e garante a geração da esquerda para a direita. Dividir por √dₖ mantém a variância dos scores controlada; sem o scaling, o softmax satura e os gradientes quase desaparecem. Multi-head attention roda projeções diferentes em paralelo, permitindo que especializações de sintaxe, correferência e posição emerjam durante o treino.

3. O bloco transformer

O bloco empilhável segue pre-norm, atenção multi-head, conexão residual, outra normalização, feedforward e outra conexão residual:

x = x + Attention(LayerNorm(x))
x = x + FFN(LayerNorm(x))

A conexão residual preserva o fluxo de gradiente e permite profundidade. O bloco é essencialmente o mesmo num transformer de brinquedo e num modelo grande; o que muda é a escala, a quantidade de camadas e o treinamento.

4. Treino e loss

O objetivo é prever o próximo token. Cross-entropy mede a distância entre a probabilidade atribuída e o token correto; AdamW ajusta o learning rate por parâmetro e separa weight decay da regularização. Um schedule comum faz warmup linear e depois cosine decay. Acertar o schedule pode ser a diferença entre convergir e divergir.

5. Scaling e inferência

As scaling laws de Chinchilla sugerem aproximadamente 20 tokens de treino por parâmetro no regime ótimo. A loss segue uma lei de potência em relação ao compute, o que transforma tamanho, dados e orçamento em decisões ligadas.

Treino pode ser paralelo; inferência é sequencial, um token por vez. O KV cache reaproveita Keys e Values já calculados, reduzindo o custo por token de O(n²) para O(n). Temperature e top-p controlam o sampling, evitando a repetição típica de argmax puro.

A parte que vira carreira

  1. Construir o clone de nanoGPT duas vezes: a segunda confirma entendimento, não só memória muscular.
  2. Publicar um repositório com README que explique a matemática, as decisões de design, a curva de loss e a licença.
  3. Contatar pesquisadores cujo trabalho foi lido, enviando o build, uma mudança de design que você faria e uma pergunta específica sobre o paper.
  4. Responder à entrevista a partir do próprio código: scaling para estabilidade, residual para gradientes e AdamW para otimização.

O critério de sucesso

O build não precisa competir com um laboratório. Ele precisa ser pequeno o bastante para ser compreendido e completo o bastante para tornar visíveis as escolhas. A prova de competência está em explicar o mecanismo, prever seus efeitos e propor uma alteração com motivo técnico.

Adaptado de codard, “How to Build a Full LLM From Scratch & Break Into Anthropic”, X, 2026-07-18. Artigo original.