
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 | 1× |
| GQA (Llama 3, grupos de 8) | par por grupo | ~500 KB | 8× |
| 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
- Welch Labs — How DeepSeek Rewrote the Transformer [MLA]
- DeepSeek-V3 Technical Report (MLA §2.1, latente + RoPE desacoplado)
- O que é uma rede neural?
- GPU vs TPU
- Como funcionam as placas de vídeo
- Deep Learning para iniciantes
- IA local no Linux com Ollama
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.