A tese desta página: um Transformer é uma pilha de blocos idênticos, e o que muda entre eles é apenas o que cada um aprendeu a escrever no residual stream. Não há hierarquia declarada, nem módulo de sintaxe, nem módulo de semântica: há a mesma operação repetida, e uma esteira que atravessa tudo carregando as anotações acumuladas.
tudo nesta página é recalculado a partir dela
cortada em 12 tokens: a matriz fica ilegível antes disso
Explore cada etapa →
A matemática, num só lugar
As 4 contas que sustentam um bloco. Clique em qualquer uma para pular direto para a etapa que a explica.
Onde esta página começa
a fronteira com "Dentro de um LLM"
A etapa 4 daquela página mostra que existe atenção, com uma demonstração aproximada e sem fórmula: é a porta de entrada, e continua sendo o lugar certo para começar. Esta página mostra como a atenção funciona, com a conta rodando de verdade. Se você chegou aqui sem passar por lá e algo soar denso demais, o caminho de volta é aquele link.
Honestidade, antes de começar: as contas desta página rodam de verdade produto escalar, máscara, softmax, tudo calculado no seu navegador a partir da frase que você digitar. Mas os pesos são desenhados à mão, não extraídos de um modelo treinado. Escolhi quatro matrizes que produzem quatro comportamentos legíveis (vizinhança, token anterior, conteúdo, âncora) porque cabeças assim realmente aparecem em modelos reais e foram documentadas em trabalhos de interpretabilidade. Os padrões que você vai ver são plausíveis, não observados. Um modelo de verdade tem centenas de cabeças, a maioria sem interpretação simples nenhuma.
A primeira coisa a entender não é a atenção: é o que ela modifica. Cada token entra no modelo como um vetor e sai como um vetor do mesmo tamanho. Entre os dois, cada bloco soma uma contribuição nunca substitui. Essa esteira que atravessa o modelo inteiro é o residual stream, e é o objeto central da arquitetura.
Cada bloco soma um delta pequeno. Repare que a direção do vetor muda devagar a esteira carrega a identidade do token, e cada bloco escreve uma anotação nela. É por isso que dá para ler o estado intermediário de um modelo e ainda reconhecer de que token ele veio.
Por que somar, e não substituir
Porque somar cria um caminho direto da entrada até a saída. O gradiente do treino desce por esse caminho sem atravessar nenhuma multiplicação, o que impede que ele encolha exponencialmente com a profundidade. Foi essa ideia dos ResNets, em visão computacional, 2015 que destravou redes profundas de verdade. O Transformer a herdou inteira.
A esteira como memória compartilhada
Uma leitura útil: o residual stream é uma memória compartilhada de largura d_model. Cada bloco lê dela, calcula, e escreve de volta. Blocos diferentes usam direções diferentes dessa memória para não se atrapalhar, e a interpretabilidade moderna trata isso literalmente assim procurando quais direções carregam qual informação.
Q, K e V parecem três coisas diferentes e não são: são três projeções lineares do mesmo vetor x. Multiplicar x por três matrizes distintas produz três leituras dele a pergunta que ele faz, a etiqueta com que se anuncia, e o conteúdo que entrega. A analogia com busca é boa: consulta, chave e valor.
Escolha um token
Os três vetores saem do MESMO x, multiplicado por três matrizes diferentes. É só isso que separa "pergunta" de "resposta" aqui dentro.
Fórmula · as projeções
Q = x·WQK = x·WKV = x·WV
x é a matriz [n × d_model] saída do residual stream. Cada W é [d_model × d_head], e é aprendida no treino. O resultado são três matrizes [n × d_head]. Numa cabeça de um modelo real, d_head costuma ser 64 ou 128 repare que é pequeno: cada cabeça enxerga um subespaço estreito do residual stream, de propósito.
Detalhe que quase nunca aparece: com GQA, WK e WV são compartilhadas entre grupos de cabeças, enquanto WQ continua uma por cabeça. Cada cabeça continua fazendo a sua pergunta, mas várias consultam o mesmo conjunto de chaves. O ganho não está nos parâmetros está no KV-cache, que encolhe na mesma proporção. Foi a etapa 4 da página anterior.
Agora a conta inteira. Cada token multiplica a sua consulta pela chave de todos os outros, e sai uma matriz n×n de pontuações. O triângulo acima da diagonal é apagado nenhum token pode olhar para o futuro e o softmax transforma cada linha em pesos que somam 1.
A matriz de atenção
linhas = quem pergunta · colunas = quem responde · clique numa linha para abri-la
O softmax não escolhe: ele distribui. Uma pontuação 2 pontos maior vira um peso ~7 vezes maior, e todos somam 1. É por isso que a atenção quase nunca é "só um token" ela é uma média ponderada onde alguém domina.
Fórmula · a atenção inteira
Attn(Q,K,V) = softmax( (QKᵀ + M) / √dk ) · V
QKᵀ é a matriz [n × n] de pontuações: a posição (i,j) é o produto escalar da consulta de i com a chave de j. M é a máscara: 0 onde pode olhar, −∞ onde não pode e −∞ vira exatamente zero depois do softmax. A divisão por √dk não é enfeite: sem ela, produtos escalares de vetores de 128 dimensões ficam grandes demais, o softmax satura, e o gradiente morre. O resultado multiplica V: cada token recebe a média ponderada dos valores dos outros.
Armadilha de produção: a máscara é o que permite treinar de forma eficiente o modelo prevê todos os n tokens numa passada só, cada um enxergando apenas o seu passado. Se ela vazar por um bug de off-by-one, o treino converge lindamente e o modelo não generaliza nada: ele aprendeu a copiar o próximo token em vez de prevê-lo. O sintoma é loss de treino excelente com geração inútil. Desligue a máscara acima e veja a diagonal superior acender.
Uma cabeça só sabe fazer uma pergunta por vez, porque tem um só par WQ/WK. Se ela aprendeu a procurar o token anterior, é isso que ela faz sempre. A saída são várias cabeças em paralelo, cada uma com suas matrizes, olhando o mesmo x e chegando a conclusões diferentes.
Escolha uma cabeça
Por que não uma cabeça grande
Porque o softmax é um gargalo de uma escolha só. Com uma cabeça de 512 dimensões, a distribuição continua sendo uma: o modelo precisa decidir, para cada token, um único perfil de atenção. Com 8 cabeças de 64, ele obtém 8 distribuições independentes pelo mesmo custo de conta a multiplicação total é a mesma. Você não está gastando mais; está gastando melhor.
Honestidade · cabeças de verdade não são assim
As quatro cabeças aqui foram escritas para serem legíveis. Em modelos reais, cabeças de "token anterior" e de "âncora" (attention sink no primeiro token) realmente existem e estão documentadas mas são a minoria. A maior parte das centenas de cabeças de um modelo grande não tem interpretação simples: elas implementam pedaços de circuitos distribuídos que só fazem sentido em conjunto. Desconfie de qualquer visualização que dê nome a todas elas.
Repare num detalhe da conta anterior: em nenhum momento a posição do token entrou nela. Produto escalar é indiferente à ordem. Se você embaralhar a frase, a matriz sai a mesma com as linhas trocadas de lugar para a atenção pura, uma frase é um saco de palavras. A ordem precisa ser injetada de fora.
A mesma matriz, com e sem posição
A pontuação depende só da distância entre os dois tokens, não das posições absolutas. Essa é a propriedade que dá nome ao RoPE (Rotary Position Embedding): girar Q e K pelo ângulo da posição faz o produto escalar depender apenas da diferença dos ângulos.
Fórmula · RoPE
⟨Rθiq , Rθjk⟩ = ⟨q , Rθ(j−i)k⟩
R é uma rotação. O lado esquerdo gira a consulta pelo ângulo da posição i e a chave pelo ângulo de j; o lado direito mostra que o resultado só depende de j − i. Cada par de dimensões gira numa frequência diferente as rápidas resolvem distâncias curtas, as lentas distâncias longas. É por isso que esticar o contexto de um modelo com RoPE é possível (interpolando as frequências) e não é grátis: as frequências rápidas passam a ver ângulos que nunca viram no treino.
Armadilha de produção: "este modelo suporta 128K de contexto" costuma significar que o RoPE foi esticado para 128K, não que o modelo foi treinado com documentos de 128K. A degradação é silenciosa e gradual: nada quebra, a recuperação de informação no meio do contexto é que piora. Se o seu caso depende de achar um detalhe na posição 90.000, teste isso especificamente não confie no número da model card.
A atenção é a parte famosa, mas ela ocupa menos da metade do bloco. A outra metade é o MLP: uma rede de duas camadas aplicada a cada token isoladamente, sem nenhuma comunicação entre eles. Divisão de trabalho: a atenção move informação entre posições, o MLP processa o que chegou.
x → d_ff → x, para um token só
d_ff = 24
entra x
expande
volta
Onde mora o peso
É a mesma conta da etapa 2 da página anterior, agora vista de dentro do bloco. A atenção domina o tempo; o MLP domina os parâmetros. Confundir as duas dominâncias é a origem de metade das otimizações que não funcionam.
O MLP como memória de fatos
Uma leitura que ganhou força na interpretabilidade: o MLP funciona como um banco de chave-valor. A primeira matriz decide quais "neurônios" acendem para um padrão de entrada; a segunda decide o que cada neurônio aceso escreve de volta no residual stream. É nesse mecanismo que trabalhos de edição de modelo (ROME, MEMIT) intervêm quando querem trocar um fato específico sem retreinar nada.
Falta explicar por que empilhar 96 desses blocos não vira ruído. Duas peças resolvem isso, e nenhuma delas sozinha basta: o residual, que impede o sinal de morrer, e a normalização, que impede a esteira de explodir. Os três regimes abaixo rodam a mesma recorrência, mudando só isso.
24 blocos, três regimes
Fórmula · o bloco inteiro
x ← x + attn(norm(x)) ; x ← x + mlp(norm(x))
Repare na ordem: a norma é aplicada à entrada da subcamada, não à saída da soma. Isso se chama pré-norm, e é o que praticamente todo modelo moderno usa. O post-norm do artigo original de 2017 (x ← norm(x + attn(x))) põe uma normalização no caminho do residual, o que estraga justamente a autoestrada de gradiente que ele existia para criar treinar post-norm profundo exige aquecimento cuidadoso de learning rate, e muita gente descobriu isso do jeito difícil.
RMSNorm: a simplificação que venceu. A LayerNorm original subtrai a média e divide pelo desvio-padrão; a RMSNorm só divide pela raiz do valor quadrático médio, sem centralizar. Menos uma passada pelos dados, menos um buffer, e nenhuma perda de qualidade mensurável. É um bom exemplo do padrão que se repete nesta arquitetura: quase toda evolução do Transformer desde 2017 foi tirar coisa, não acrescentar.
Agora a conta que dói. A matriz de atenção tem n² posições para cada cabeça, de cada camada. Dobrar o contexto não dobra o trabalho: quadruplica. E é essa quadratura que separa "contexto longo funciona" de "contexto longo é viável".
A matriz, por contexto
n = 4.096 ·
Flash-attention: a matriz que não existe
A tabela acima mede a matriz se ela fosse materializada. O truque do flash-attention é nunca escrevê-la na memória: ele processa a atenção em blocos que cabem na SRAM da GPU e acumula o softmax de forma incremental. O custo de conta continua O(n²) isso é irredutível , mas o de memória cai para O(n). Foi essa engenharia, não uma arquitetura nova, que tornou contexto de 100K praticável.
A ponte para a próxima página
Durante a geração, cada token novo precisaria refazer toda a matriz. O KV-cache evita isso: as chaves e valores dos tokens anteriores não mudam, então guarda-se todas elas e o token novo só calcula a sua linha. O custo por token cai de O(n²) para O(n). E daí nasce a pergunta da próxima página: se o cache é tão valioso, por que jogá-lo fora entre uma requisição e outra?
O caminho inteiro
No fim: um bloco Transformer é uma esteira com duas anotações por camada. A atenção decide de onde vem a informação; o MLP decide o que fazer com ela; o residual garante que nada se perca no caminho e a norma garante que nada exploda. Tudo o mais GQA, RoPE, SwiGLU, flash-attention é engenharia em cima desse esqueleto, e quase toda ela existe para tornar a mesma conta mais barata, não diferente.
Continue na série
Cache de prompt o KV-cache virando dinheiro, e a regra de prefixo que decide tudo