Como a DeepSeek reescreveu o Transformer

Tux de pé numa cidade de silício diante da baleia da DeepSeek e de um núcleo latente

Em janeiro de 2025 a DeepSeek soltou o R1 (e, semanas antes, o V3) competindo com o1 e GPT-4o em raciocínio — com uma fração do custo de treino e de inferência. Os pesos saíram abertos. O truque não é um truque de dataset: é uma reescrita do miolo do Transformer, o Multi-Head Latent Attention (MLA), atacando o gargalo que trava GPU na hora de gerar texto: o KV cache. Este texto segue o vídeo How DeepSeek Rewrote the Transformer [MLA], do Stephen Welch (Welch Labs).

A conta de fundo é a mesma do post o que é uma rede neural e do GPU vs TPU: MatMul. Aqui o problema é quantos bytes essa MatMul precisa puxar da HBM a cada token novo.

Atenção clássica e o custo do KV cache

O paper de 2017, Attention Is All You Need, projeta o embedding X em três matrizes:

Q = X W_Q     o que o token atual busca
K = X W_K     o rótulo que cada token oferece
V = X W_V     o conteúdo que sai se houver match

Attention(Q, K, V) = softmax( (Q K^T) / sqrt(d_k) + M ) V

Q K^T mede afinidade. M é a máscara causal (não espiar o futuro). Multiplicar por V mistura o que importou.

GPT-2 Small: 12 cabeças × 12 camadas = 144 padrões. DeepSeek-V3/R1: 128 cabeças × 61 camadas = 7.808.

A geração é autoregressiva: um token por vez, cola no prompt, roda de novo. Recalcular Q, K e V de todo o passado a cada passo seria O(N²) de conta. O atalho é o KV cache: K e V dos tokens velhos não mudam. Guarda na VRAM. O token novo só calcula a linha nova de Q (e o K/V dele) e busca no histórico.

tokens 1..t-1   K e V já prontos  →  KV cache (HBM)
token t         calcula Q_t       →  lê o cache inteiro

A conta cai. A conta de memória explode. No MHA:

KV cache = 2 × n_tokens × d_h × n_heads × L × bytes

V3/R1, por token (FP16):
  2 × 128 × 128 × 61 × 2 = 3.997.696 bytes   (~4 MB)

Janela de 100 mil tokens (um livro): ~400 GB lidos da HBM para emitir uma palavra. A GPU mais cara do mundo fica memory-bound — o mesmo muro do post das placas de vídeo.

MQA e GQA: encolher o cache, pagar em qualidade

  • MQA: as 128 cabeças da camada compartilham um par K/V. Cache ÷ 128 (~31 KB/token). As cabeças perdem especialização.
  • GQA (Llama 3): grupos — 8 cabeças, 1 K/V. Cache ÷ 8 (~500 KB/token). Compromisso. Ainda não é MHA.

MLA: comprimir o par, não as cabeças

A pergunta da DeepSeek: e se K e V forem projetados num espaço latente e a própria rede aprender a comprimir/descomprimir, em vez de forçar as cabeças a dividir a mesma chave?

entrada h_t
    │
    ▼
c_t^{KV}   vetor latente  (512)
k_t^R      chave RoPE     (64)
    │
    └─ os dois vão para o KV cache  →  576 números
         (~70 KB por token, 61 camadas, FP16)

na inferência as 128 cabeças reconstroem K e V
a partir do latente — sem guardar 128 pares

O tamanho do cache deixa de depender de n_heads. Só do latente (e do pedaço de RoPE que o paper desacopla, os 64). 576 × 61 × 2 bytes = 70.272 bytes ≈ 70 KB/token. Redução de ~57× contra o MHA de 4 MB.

Descomprimir 128 cabeças a cada token parecia conta extra. Associatividade da MatMul:

Q K^T = Q (c^{KV} W^{UK})^T
      = (Q (W^{UK})^T) (c^{KV})^T

W^{UK} e W^{UV} são fixos depois do treino. Absorvem na matriz de Q e na de saída W_O antes de servir. Na inferência a atenção opera direto no cache latente — sem a MatMul intermediária a cada passo. É o mesmo espírito do arranjo sistólico no post da TPU: não fique carregando o que pode ficar colado no peso.

Por token, lado a lado

Arquitetura K/V Cache/token Fator
MHA par por cabeça ~4 MB
GQA (Llama 3, grupos de 8) par por grupo ~500 KB
MQA 1 par por camada ~31 KB 128× (qualidade cai)
MLA (V3/R1) latente 576 + absorção ~70 KB 57×

Welch aponta geração mais de 6× mais rápida no R1 contra um Transformer “cheio” no mesmo recorte de memória: menos byte na HBM por milissegundo. Contexto 64k–128k deixa de exigir um cluster só para o cache de vários usuários. Nos testes da DeepSeek o MLA não só empata o MHA — em várias tarefas passa, a compressão latente funcionando como regularização.

O que isso muda no Linux de verdade

Servir V3/R1 local ainda pede VRAM de datacenter (671 B no total, 37 B ativos). O MLA é o que torna a janela longa cabível. Distro com llama.cpp/vLLM recente já fala MLA; quantização GGUF e o fluxo do llama-model ou do Ollama cobrem os destilados. Quatro V100 de 16 GB no servidor recondicionado não carregam o V3 cheio — carregam um 27B/32B. O MLA é o motivo de um 671 B aberto não implodir o cache no cluster de verdade.

Referências

O R1 não nasceu de um cluster maior. Nasceu de não carregar 4 MB de K/V por token quando 70 KB de latente, com a MatMul absorvida no peso, fazem o mesmo trabalho. O Transformer ainda tinha essa folga. A DeepSeek só fez a conta.