Ir para o conteúdo

O Bloco Transformer Revisitado

1. Por que revisitar o Transformer

A arquitetura introduzida por Vaswani et al. em 2017 tornou-se o substrato de fato para a modelagem de sequências, substituindo alternativas recorrentes e convolucionais em tradução automática, modelagem de linguagem e na maioria das tarefas de processamento de linguagem natural a jusante que a área julgava relevantes na época em que o artigo passou a ser citado em escala [src_012]. O mesmo modelo geral foi posteriormente expandido para visão, áudio, código e modelagem de proteínas, e as famílias encoder-only e decoder-only que vieram a dominar a modelagem de linguagem são mais bem compreendidas como restrições do projeto encoder-decoder original [src_012]. Um livro que examina o aprendizado profundo moderno precisa, portanto, de um ponto de referência claro contra o qual todo o restante deste volume possa ser comparado.

Esse ponto de referência é o que o Capítulo 1 constrói. Cada capítulo subsequente é mais economicamente descrito como um delta em relação ao bloco base de 2017: o rotary position encoding do Capítulo 2 substitui os esquemas absolutos sinusoidais e aprendidos, as escolhas de RMSNorm e SwiGLU do Capítulo 3 substituem LayerNorm e ReLU+linear, e os mecanismos de FlashAttention, GQA e MQA do Capítulo 4 alteram a forma como o attention é computado sem alterar o que ele computa. A arquitetura de 2017 não é mais utilizada sem modificações em escala; modelos de linguagem grandes modernos consistentemente trocam a codificação posicional, a normalização, a ativação e, frequentemente, o padrão de attention, mantendo intacto o esqueleto do residual stream [src_002]. Estabelecer esse esqueleto com precisão é o trabalho do presente capítulo.

O texto a seguir presume que o leitor já esteja familiarizado com os blocos básicos do aprendizado profundo — descida do gradiente, retropropagação, batch normalisation, conexões residuais, perda de entropia cruzada — no nível de um curso de pós-graduação em aprendizado de máquina ou de uma referência canônica de fundamentos como Bishop e Bishop [src_001]. Leitores que desejarem uma implementação executável a partir do zero de cada componente nomeado abaixo devem consultar os notebooks de Raschka em conjunto com este capítulo [src_010].

2. Notação e configuração

🎯 Intuição

Imagine o tensor de ativação \((B, T, D)\) como o fio condutor de toda passada para frente do Transformer: \(B\) sequências num batch, cada uma com \(T\) tokens, cada token um vetor \(D\)-dimensional. Cada bloco da pilha lê um tensor com essa forma e emite um tensor com a mesma forma — as conexões residuais forçam isso. As subcamadas de cada bloco (attention, FFN, normalização) são cada uma transformações que preservam a forma e operam ao longo do eixo \(D\), de modo que ler o capítulo inteiro reduz-se a: "o que cada subcamada faz ao eixo \(D\)?".

Comprometemo-nos com uma única tabela de notação para todo o livro. Seja \(B\) o tamanho do batch, \(T\) o comprimento da sequência, \(D\) a dimensão do modelo (do residual stream), \(h\) o número de cabeças de attention, e \(d_h = D/h\) a dimensão por cabeça; seja \(d_{ff}\) a largura oculta da camada feed-forward, relacionada a \(D\) por uma razão de expansão \(r\) tal que \(d_{ff} = r \cdot D\). O modelo possui \(L\) blocos empilhados. O estado oculto de um token na layer \(\ell\) é escrito \(x^{(\ell)} \in \mathbb{R}^{D}\), e o tensor de ativação completo que percorre a rede tem forma \((B, T, D)\).

Esta é a notação em estilo tensorial que se alinha de forma mais limpa com implementações modernas do Transformer e com os Capítulos 2 a 4 deste livro. A monografia de 2025 de Xiao e Zhu utiliza um conjunto equivalente de símbolos — \(m\) para o comprimento da sequência, \(d\) para o tamanho oculto, \(n_{\text{head}}\) para o número de cabeças, \(d_{ffn}\) para o tamanho oculto da FFN e \(L\) para a profundidade [src_002] — e traduzimos entre as convenções sempre que uma citação de Xiao-Zhu aparecer.

Para o exemplo trabalhado que percorre este capítulo, utilizamos a configuração base de Vaswani: \(L = 6\), \(D = 512\), \(h = 8\), \(d_h = 64\), \(d_{ff} = 2048\), de modo que a razão de expansão é \(r = 4\) [src_012]. A variante "big" do artigo de 2017 tem \(D = 1024\), \(h = 16\), \(d_{ff} = 4096\), novamente com \(L = 6\) [src_012].

3. Self-attention de produto escalar escalado

Uma camada de self-attention recebe uma sequência de \(T\) tokens, cada um representado como um vetor \(D\)-dimensional, e produz uma nova sequência de \(T\) vetores da mesma dimensão, em que cada vetor de saída é uma média ponderada de projeções de valor de cada vetor de entrada. O mecanismo introduzido por Vaswani et al. — e o único mecanismo de attention que este livro trata como primitivo — é o scaled dot-product attention [src_012].

Concretamente, seja \(X \in \mathbb{R}^{T \times D}\) a sequência de entrada (omitimos a dimensão de batch ao longo desta seção para aliviar a notação). Três projeções lineares aprendidas produzem queries, keys e values: $\(Q = X W_Q, \qquad K = X W_K, \qquad V = X W_V,\)$ com \(W_Q, W_K \in \mathbb{R}^{D \times d_k}\) e \(W_V \in \mathbb{R}^{D \times d_v}\). Na prática padrão \(d_k = d_v\), e escrevemos \(d_k\) para ambos. O scaled dot-product attention então computa $\(\text{Attention}(Q, K, V) = \mathrm{softmax}\!\left(\frac{Q K^{\top}}{\sqrt{d_k}}\right) V,\)$ em que a softmax é aplicada por linhas [src_012].

3.1 Por que a escala \(1/\sqrt{d_k}\)

O fator de escala não é cosmético. Ao longo desta seção, utilizamos regime informativo para designar o regime em que nenhuma entrada da softmax domina sozinha e o gradiente da softmax em relação às suas entradas é não evanescente — o oposto do regime saturado que este argumento de escala busca evitar. Suponha que os componentes de qualquer vetor de query \(q\) e vetor de key \(k\) sejam variáveis aleatórias independentes com média zero e variância um. Então seu produto escalar \(q \cdot k = \sum_{i=1}^{d_k} q_i k_i\) é uma soma de \(d_k\) produtos independentes de média zero e variância unitária, de modo que \(\mathrm{E}[q \cdot k] = 0\) e \(\mathrm{Var}[q \cdot k] = d_k\) [src_012]. Sem reescalonamento, a magnitude típica do logit pré-softmax cresce, portanto, como \(\sqrt{d_k}\), e à medida que \(d_k\) aumenta, a softmax satura: algumas poucas entradas dominam, as demais recebem peso evanescente, e o gradiente da softmax em relação às suas entradas colapsa para próximo de zero nas entradas saturadas.

🤔 Pause e pense

Antes de seguir: para \(d_k = 1\) versus \(d_k = 1024\), quanto a magnitude típica de \(q \cdot k\) muda, e o que isso implica para a linha da softmax que consome esses logits? (Não olhe adiante — escreva a resposta ou diga em voz alta.)

Concretamente, em \(d_k = 64\) o logit típico tem magnitude \(\sqrt{64} = 8\), de modo que um gap de logit de \(8\) entre duas linhas não é incomum — e passar esse gap por uma softmax por linha resulta em \(e^{8}/(e^{8} + e^{0}) \approx 0{,}9997\), um peso já saturado sobre a entrada maior. Em \(d_k = 8\) a magnitude típica é \(\sqrt{8} \approx 2{,}8\) e a softmax correspondente é muito mais suave. Dividir os logits por \(\sqrt{d_k}\) restaura a variância unitária e mantém a softmax em seu regime informativo [src_012]. Esse argumento é uma consequência de uma linha da intuição do teorema central do limite para produtos internos, e explica por que ablações que comparam dot-product attention com e sem a escala encontram uma grande diferença em \(d_k\) alto e uma pequena em \(d_k\) baixo [src_012].

💡 Resultado-chave

Escalar os logits pré-softmax por \(1/\sqrt{d_k}\) mantém a softmax em seu regime informativo independentemente da dimensão da cabeça.

🔄 Recapitulação

  • Complete a equação: se \(q\) e \(k\) têm entradas i.i.d. de variância unitária, então \(\mathrm{Var}[q \cdot k] = \;?\)
  • Explique por que uma linha de logits pré-softmax com magnitude típica \(\sqrt{d_k}\) produz uma softmax picada para \(d_k\) grande.
  • Preveja: se \(d_k\) dobra de \(64\) para \(128\), por qual fator cresce o logit pré-softmax típico? Qual fator de escala desfaz a mudança?

3.2 Causal masking

A self-attention escrita acima é equivariante a permutações nas keys e values: cada posição de saída pode atender a cada posição de entrada. Para decoders autorregressivos isso é incorreto, pois a previsão na posição \(i\) não pode depender de tokens nas posições \(j > i\). O artigo de 2017 implementa a restrição dentro da softmax: antes de a softmax por linhas ser aplicada, as entradas de \(QK^{\top}/\sqrt{d_k}\) correspondentes a conexões não permitidas são definidas como \(-\infty\), o que envia seus pesos pós-softmax a zero [src_012]. Referiremo-nos a isso ao longo do livro como causal self-attention. Xiao e Zhu descrevem o mesmo mecanismo e observam explicitamente que masking é o que permite que um único bloco Transformer seja utilizado tanto bidirecionalmente (como em BERT — prevendo todas as posições de uma vez dadas o contexto completo ao redor) quanto autorregressivamente (como em GPT — prevendo uma posição por vez condicionada ao prefixo), com a diferença reduzida a uma máscara binária [src_002].

🔗 Conexão

A separação encoder-only / decoder-only / encoder-decoder que essa leitura via máscara binária antecipa é tratada no Capítulo 7, onde cada família é examinada como uma restrição do esqueleto encoder-decoder de 2017.

4. Multi-head attention

Uma única cabeça de attention com dimensionalidade plena \(D\) tem apenas um subespaço compartilhado no qual comparar queries e keys. Vaswani et al. argumentam que isso é restritivo, e propõem substituir a única cabeça por \(h\) cabeças paralelas operando em projeções de menor dimensão [src_012]. Com \(h\) cabeças de dimensão por cabeça \(d_h = D/h\), a layer computa $\(\text{MultiHead}(Q, K, V) = \mathrm{Concat}(\text{head}_1, \ldots, \text{head}_h)\, W_O,\)$ em que cada \(\text{head}_i = \text{Attention}(Q W_Q^{(i)}, K W_K^{(i)}, V W_V^{(i)})\) utiliza suas próprias projeções aprendidas \(W_Q^{(i)}, W_K^{(i)} \in \mathbb{R}^{D \times d_h}\) e \(W_V^{(i)} \in \mathbb{R}^{D \times d_h}\), e \(W_O \in \mathbb{R}^{D \times D}\) é uma projeção final de saída [src_012]. Como o custo por token de cada cabeça é \(\mathcal{O}(T^2 d_h) = \mathcal{O}(T^2 D / h)\) e as cabeças operam em paralelo, o custo computacional total do multi-head attention é comparável ao do single-head attention com dimensionalidade plena \(D\) [src_012].

O ganho qualitativo que Vaswani et al. atribuem a múltiplas cabeças é a capacidade de atender a informações de diferentes subespaços de representação em diferentes posições; com uma única cabeça, a média que ocorre dentro da softmax inibe esse tipo de roteamento multicanal [src_012]. O modelo base de 2017 utiliza \(h = 8\), \(d_h = 64\) e, portanto, \(D = h \cdot d_h = 512\); a variante big utiliza \(h = 16\) e \(D = 1024\) com o mesmo \(d_h\) [src_012].

5. Rede feed-forward por posição

Cada bloco Transformer contém uma rede feed-forward de duas camadas aplicada por posição, de forma independente e idêntica a cada posição de token: $\(\text{FFN}(x) = \max(0, x W_1 + b_1)\, W_2 + b_2,\)$ com \(W_1 \in \mathbb{R}^{D \times d_{ff}}\), \(W_2 \in \mathbb{R}^{d_{ff} \times D}\) e uma ReLU pontual entre elas [src_012]. A layer é "por posição" no sentido de que os mesmos parâmetros \(W_1, b_1, W_2, b_2\) são compartilhados entre as posições dentro de um bloco, mas cada bloco possui sua própria cópia [src_012]. Equivalentemente, a FFN é um par de convoluções \(1 \times 1\) com uma ReLU entre elas [src_012].

O modelo base de 2017 define \(D = 512\) e \(d_{ff} = 2048\), que é a razão de expansão canônica de \(4\times\): \(r = d_{ff} / D = 4\) [src_012]. Xiao e Zhu descrevem a mesma convenção como o ajuste típico em BERT e em Transformers anteriores aos LLMs, \(d_{ffn} \approx 4d\) em sua notação [src_002].

A intuição para o papel da FFN é que a self-attention sozinha é uma operação linear nos values — toda saída de uma camada de attention é uma combinação convexa de projeções de value das entradas — de modo que uma pilha apenas com camadas de attention saturaria em expressividade após o encadeamento de quantidade suficiente delas. A não-linearidade pontual da FFN é o que impede essa degeneração de representação [src_002]. Na contabilidade de Xiao e Zhu, a FFN também concentra a maior parte do orçamento de parâmetros: com \(r = 4\), somente as duas matrizes da FFN respondem por \(2 \cdot 4 \cdot D^2 = 8 D^2\) parâmetros por bloco, contra \(4 D^2\) para as quatro projeções de attention combinadas, de modo que dois terços dos pesos por bloco residem na FFN [src_002].

⚠️ Armadilha

"Linear nos values" é uma afirmação sobre os values, não sobre a camada de attention como um todo — a softmax sobre \(QK^\top\) é a única não-linearidade dentro da subcamada de attention, e ela atua sobre os pesos (que misturam vetores de value), não sobre os values em si. Empilhar blocos somente de attention compõe, portanto, uma sequência de operações de mistura ponderada cuja expressividade de fato satura, mas a afirmação precisa é mais delicada do que "linear nos values" sugere.

A escolha \(r = 4\) é convencional, e não derivada de princípios. Vaswani et al. apresentam o valor sem justificar a razão; Xiao e Zhu apresentam \(r \approx 4\) como o ajuste típico sem oferecer ablação [src_012, src_002]. LLMs decoder-only modernos com FFNs com gating (SwiGLU e seus parentes) reduzem a razão para aproximadamente \(8/3 \approx 2.67\) a fim de manter a contagem total de parâmetros da FFN comparável à do baseline ungated \(4\times\), dado que FFNs com gating utilizam três matrizes em vez de duas; o relatório técnico do Llama 2 documenta explicitamente esse rebalanceamento como a convenção adotada pela família decoder-only moderna [src_029]. O Capítulo 3 desenvolve em detalhe a derivação da FFN com gating e a contabilidade de parâmetros.

🔗 Conexão

A derivação da FFN com gating (SwiGLU, GeGLU) e o rebalanceamento \(r \approx 8/3\) em relação ao baseline ungated \(4\times\) são tratados no Capítulo 3, que também cobre como a terceira matriz altera a contabilidade de parâmetros com orçamento total da FFN constante.

6. Conexões residuais, LayerNorm e o residual stream

Cada subcamada no Transformer de 2017 — attention ou FFN — é envolvida por uma conexão residual seguida de uma normalização de camada. Na formulação original, a saída de uma subcamada é $\(\text{LayerNorm}(x + \text{Sublayer}(x)),\)$ e, para tornar a soma residual dimensionalmente consistente, cada subcamada, incluindo a embedding de entrada, produz vetores de dimensão \(D = 512\) no modelo base [src_012]. Isso coloca a normalização fora do caminho residual; retornaremos a essa escolha de projeto na Seção 7.

🎯 Intuição

A LayerNorm recentra um vetor oculto \(h \in \mathbb{R}^D\) para média zero ao longo de suas \(D\) features, depois reescala-o para variância unitária, e então reaplica um ganho e um viés aprendíveis por feature. Geometricamente: projeta-se o vetor sobre a hiperesfera unitária no espaço de features (subtraindo a média e dividindo pelo desvio-padrão) e em seguida estica-se e desloca-se cada coordenada de volta com parâmetros que a rede aprende.

A própria LayerNorm, na forma utilizada no Transformer, computa a média e a variância de um vetor oculto \(h \in \mathbb{R}^D\) ao longo de seu eixo de features, $\(\mu = \frac{1}{D}\sum_{i=1}^{D} h_i, \qquad \sigma^2 = \frac{1}{D}\sum_{i=1}^{D} (h_i - \mu)^2,\)$ e então reescala e desloca o vetor padronizado com ganho aprendível por feature \(\alpha \in \mathbb{R}^D\) e viés \(\beta \in \mathbb{R}^D\): $\(\text{LayerNorm}(h) = \alpha \odot \frac{h - \mu}{\sqrt{\sigma^2 + \epsilon}} + \beta,\)$ em que \(\odot\) é o produto elementar e \(\epsilon\) é uma pequena constante para estabilidade numérica [src_002]. Diferentemente da batch normalisation, a LayerNorm é computada por token de forma independente do batch e, portanto, é tão bem-definida no tempo de inferência sobre um único exemplo quanto no tempo de treinamento sobre um batch grande [src_002].

6.1 O residual stream como ponto de vista

A conexão residual somada à LayerNorm é o que torna pilhas profundas de blocos Transformer treináveis na prática: sem o residual, o sinal do gradiente na profundidade \(L\) teria de se propagar através de \(L\) multiplicações de matriz e \(L\) softmaxes, ao passo que, com o residual, o termo identidade transporta o gradiente de volta sem atenuação [src_001, src_012]. Um arcabouço conceitual útil, devido a trabalhos posteriores de interpretabilidade mecanicista, é pensar nas ativações que percorrem o caminho residual como um residual stream: uma representação corrente \(D\)-dimensional por token, na qual cada bloco escreve aditivamente uma pequena edição e da qual lê via projeções de attention e FFN. O bloco base computa, portanto, $\(x \mapsto x + \text{Attn}(x), \qquad x \mapsto x + \text{FFN}(x),\)$ a menos da posição da LayerNorm. A imagem do residual stream já está implícita na formulação de residual mais LayerNorm de Vaswani e é tornada explícita na discussão de Xiao e Zhu sobre por que o residual é o que torna a profundidade possível [src_002].

⚠️ Armadilha

A leitura via residual stream é mais limpa sob o posicionamento pre-norm que a Seção 7 introduzirá; sob o posicionamento post-norm da formulação original de Vaswani, a LayerNorm fica atravessada na soma residual e obscurece parcialmente a semântica de "identidade-mais-edições". A imagem funciona como heurística em ambos os casos, mas sua limpidez teórica depende da escolha de posicionamento.

🔗 Conexão

O Capítulo 3 trata da RMSNorm como substituição direta da LayerNorm; a imagem do residual stream estabelecida aqui é o enquadramento prerequisito sob o qual a escolha de posicionamento da RMSNorm (e sua compatibilidade com pre-norm) se torna legível.

7. Pre-norm versus post-norm

A formulação \(\text{LayerNorm}(x + \text{Sublayer}(x))\) do artigo de 2017 hoje é chamada de formulação post-norm, porque a normalização é aplicada após a soma residual [src_012, src_002]. Uma alternativa amplamente utilizada, a formulação pre-norm, aplica a normalização dentro do residual: $\(x \mapsto x + \text{Sublayer}(\text{LayerNorm}(x)).\)$ Xiao e Zhu apresentam ambas e observam que o projeto post-norm é o original utilizado por Vaswani et al. e adotado pela família encoder-only de estilo BERT, enquanto o projeto pre-norm tornou-se a escolha dominante para Transformers modernos profundos [src_002].

🤔 Pause e pense

Compare \(\text{LayerNorm}(x + \text{Sublayer}(x))\) e \(x + \text{Sublayer}(\text{LayerNorm}(x))\). Em qual das formulações o gradiente flui pelo termo identidade sem atenuação, e o que isso implica para o treinamento de uma pilha profunda na inicialização? (Preveja antes de ler o próximo parágrafo.)

A razão pela qual a maioria dos modelos de linguagem grandes modernos utiliza pre-norm é a estabilidade de treinamento. A análise de campo médio (mean-field analysis) de Xiong et al. (2020) — uma análise das normas de gradiente esperadas na inicialização, em que se acompanha a magnitude típica do gradiente em relação a cada parâmetro em vez do seu valor exato — mostra que, na inicialização, o Transformer post-norm coloca gradientes esperados desproporcionalmente grandes sobre os parâmetros próximos à layer de saída, o que é o que torna necessário um cronograma de warmup cuidadosamente ajustado (um cronograma de warmup faz a taxa de aprendizagem subir gradualmente de quase zero até seu valor de pico ao longo dos primeiros milhares de passos, antes de decair); a mesma análise mostra que os gradientes do pre-norm são bem-comportados na inicialização, e Transformers pre-norm treinados sem warmup igualam os baselines post-norm com warmup, exigindo menos tempo de treinamento e ajuste de hiperparâmetros [src_049]. Em termos do residual stream, o caminho residual do pre-norm é não normalizado: os gradientes fluem diretamente através do termo identidade, a magnitude das ativações ao longo do caminho residual é controlada pelo efeito cumulativo das saídas aditivas das subcamadas, em vez de por normalizações repetidas, e o treinamento sem warmup torna-se, portanto, viável em profundidade [src_049, src_002]. Xiao e Zhu, consequentemente, recomendam pre-norm para Transformers profundos e documentam que a escolha tornou-se quase universal em LLMs modernos [src_002].

💡 Resultado-chave

Pre-norm é o padrão moderno; a imagem do residual stream é o que torna esse padrão natural.

🔄 Recapitulação

  • Explique com suas próprias palavras por que Transformers post-norm exigiam um cronograma de warmup ajustado na inicialização.
  • Compare: em qual das formulações (post-norm ou pre-norm) o caminho residual permanece não normalizado, e o que isso significa para a leitura via residual stream?
  • Preveja: se você trocar um encoder post-norm por um encoder pre-norm de mesma profundidade, qual hiperparâmetro se torna menos sensível?

🔗 Conexão

O posicionamento pre-norm estabelecido aqui é o pré-requisito para o tratamento de RMSNorm no Capítulo 3 — RMSNorm é uma variante de LayerNorm com menos parâmetros que só faz sentido como componente pre-norm, não como post-norm.

8. Codificação posicional: sinusoidal e aprendida

A self-attention é equivariante a permutações: embaralhar os tokens de entrada embaralha os tokens de saída de modo idêntico, de modo que um Transformer sem informação posicional auxiliar não consegue distinguir "the cat sat on the mat" de "the mat sat on the cat" [src_012]. Vaswani et al. injetam informação de posição adicionando uma codificação posicional \(PE \in \mathbb{R}^{T \times D}\) às embeddings de token de entrada antes do primeiro bloco.

🎯 Intuição

A imagem é a de um sistema de coordenadas, não a de um sinal aprendido. Cada posição é codificada como um vetor fixo de senos e cossenos cujos comprimentos de onda cobrem uma faixa geométrica ampla — de poucos tokens em um extremo a cerca de \(60{,}000\) tokens no outro. Posições próximas recebem codificações quase idênticas (fases semelhantes em todos os comprimentos de onda); posições distantes recebem codificações quase ortogonais. O modelo pode então consultar esse sistema de coordenadas por meio de buscas aditivas comuns, sem precisar aprender nenhum parâmetro específico de posição.

O artigo de 2017 utiliza sinusoides fixos com comprimentos de onda espaçados geometricamente: $\(PE(\text{pos}, 2i) = \sin\!\left(\frac{\text{pos}}{10000^{2i/D}}\right), \qquad PE(\text{pos}, 2i+1) = \cos\!\left(\frac{\text{pos}}{10000^{2i/D}}\right),\)$ em que \(\text{pos}\) é a posição absoluta e \(i\) indexa a dimensão da embedding [src_012]. Os comprimentos de onda formam uma progressão geométrica de \(2\pi\) a \(10000 \cdot 2\pi\), escolhida porque os autores hipotetizaram que o modelo poderia aprender a atender por offsets relativos — para qualquer deslocamento fixo \(k\), \(PE(\text{pos}+k)\) é uma função linear de \(PE(\text{pos})\), de forma que uma cabeça que deseje implementar um offset relativo tem um alvo simples [src_012].

O artigo de 2017 também experimentou com embeddings posicionais absolutos aprendidos, em que \(PE\) é uma matriz treinável de forma \(T_{\max} \times D\), em vez de uma tabela sinusoidal fixa. A ablação na Tabela 3, linha (E), relata qualidade de tradução praticamente idêntica entre embeddings posicionais sinusoidais e aprendidos no conjunto de desenvolvimento WMT 2014 inglês-alemão, e os autores mantiveram a versão sinusoidal porque esperavam que ela extrapolasse melhor para comprimentos de sequência além do intervalo de treinamento [src_012]. A família encoder-only que se seguiu ao BERT adotou, em vez disso, embeddings posicionais absolutos aprendidos como prática padrão [src_002].

Em LLMs modernos, ambos os esquemas foram suplantados. As embeddings sinusoidais não extrapolaram para contextos mais longos do que os de treinamento de forma tão limpa quanto Vaswani et al. esperavam; embeddings absolutos aprendidos precisam ser retreinados ou extrapolados sempre que a janela de contexto cresce. Ambos são agora rotineiramente substituídos por codificações relativas ou rotativas, sendo o rotary position encoding (RoPE) a escolha dominante nos LLMs decoder-only atuais [src_002]. O Capítulo 2 trata o RoPE em detalhe; para os fins deste capítulo, basta registrar que as codificações posicionais absolutas — sinusoidal e aprendida — eram o baseline de 2017 e que esse baseline mudou.

⚠️ Armadilha

Vaswani et al. mantiveram as embeddings sinusoidais esperando melhor extrapolação; o registro empírico mostra o oposto. Nem embeddings sinusoidais nem embeddings absolutos aprendidos extrapolam de forma limpa para contextos mais longos, e é por isso que LLMs modernos substituíram ambos por esquemas relativos ou rotativos.

🔗 Conexão

O Capítulo 2 trata o rotary position encoding (RoPE) em detalhe, incluindo sua relação com attention de posição relativa e seu comportamento de extrapolação além do comprimento de contexto de treinamento.

9. Juntando as peças: bloco encoder, bloco decoder, encoder-decoder

O encoder do Transformer de 2017 é uma pilha de \(L = 6\) layers idênticas. Cada layer tem duas subcamadas em série: uma subcamada de multi-head self-attention e uma subcamada FFN por posição, cada uma envolvida em uma conexão residual e em uma LayerNorm na formulação post-norm [src_012]. Todas as subcamadas e a embedding de entrada produzem vetores de dimensão \(D = 512\), de modo que as somas residuais são bem-definidas em toda a pilha [src_012].

O decoder também é uma pilha de \(L = 6\) layers idênticas, mas cada layer possui três subcamadas em vez de duas. A primeira é uma subcamada de multi-head self-attention mascarada (causal), que atende somente às posições até e incluindo a atual. A segunda é uma subcamada de cross-attention encoder-decoder multi-head, em que as queries vêm da layer anterior do decoder, mas as keys e values vêm da saída da pilha do encoder — é isso que permite que cada posição do decoder enxergue toda a sequência de entrada. A terceira é a FFN por posição. Como no encoder, cada subcamada é envolvida em residual + LayerNorm [src_012].

O modelo base de 2017 tem \(L = 6\), \(D = 512\), \(h = 8\), \(d_k = d_v = 64\) e \(d_{ff} = 2048\); o modelo big tem \(L = 6\), \(D = 1024\), \(h = 16\) e \(d_{ff} = 4096\) [src_012]. A arquitetura encoder-decoder completa é o substrato a partir do qual modelos encoder-only (estilo BERT — descartar o decoder, descartar o masking, treinar com modelagem de linguagem mascarada) e modelos decoder-only (estilo GPT — descartar o encoder, manter o masking, treinar com previsão do próximo token) são obtidos por restrição [src_002]. O Capítulo 7 trata essas três famílias por seu próprio mérito; aqui registramos somente que elas compartilham o mesmo esqueleto em nível de bloco.

🔗 Conexão

As famílias encoder-only, decoder-only e encoder-decoder compartilham o esqueleto por bloco documentado acima; o Capítulo 7 trata-as por seu próprio mérito, incluindo as escolhas específicas de masking e de objetivo de treinamento que distinguem cada família.

9.1 Implementação de referência

Uma implementação Python de referência de cada componente nomeado acima — scaled dot-product attention, multi-head attention com a disposição padrão de projeção, a FFN por posição, o envoltório residual+LayerNorm, codificação posicional sinusoidal, o bloco encoder completo e o bloco decoder, e o laço encoder-decoder — aparece nos notebooks abertos de Raschka que acompanham este livro [src_010].

10. Exemplo trabalhado: o modelo base de 2017

Para ancorar a notação abstrata em números concretos, traçamos o orçamento de parâmetros e de computação do Transformer base de 2017 na granularidade de um bloco.

Com \(D = 512\), \(h = 8\), \(d_h = 64\), a subcamada de multi-head attention contém quatro matrizes \(D \times D\) — três para \(W_Q, W_K, W_V\) (cada uma implementada como a concatenação de \(h\) projeções \(D \times d_h\) por cabeça, totalizando \(D \times D\)) e uma para a projeção de saída \(W_O\) — totalizando \(4 D^2 = 4 \cdot 512^2 \approx 1.05 \times 10^6\) parâmetros [src_012]. A subcamada FFN contém duas matrizes de formas \(D \times d_{ff}\) e \(d_{ff} \times D\) com \(d_{ff} = 2048\), de modo que sua contagem de parâmetros é \(2 D d_{ff} = 2 \cdot 512 \cdot 2048 \approx 2.10 \times 10^6\) parâmetros [src_012]. A FFN, portanto, carrega aproximadamente o dobro do orçamento de parâmetros da subcamada de attention em \(r = 4\) — a razão de dois terços na FFN que a Seção 5 derivou em forma simbólica [src_002].

Empilhada em \(L = 6\) camadas de encoder e \(L = 6\) camadas de decoder (com o decoder tendo uma subcamada extra de cross-attention por camada), e incluindo as tabelas de embedding, o modelo base totaliza aproximadamente \(65 \times 10^6\) parâmetros — consistente em ordem de grandeza com a linha "base" da Tabela 3 de Vaswani et al. [src_012]. O orçamento de computação por passo de treinamento é dominado, nos comprimentos de sequência modestos utilizados para tradução, pelas multiplicações de matriz da FFN; em comprimentos de sequência longos, o termo \(\mathcal{O}(T^2 D)\) da self-attention ultrapassa o termo \(\mathcal{O}(T D^2)\) da FFN, o que é a pressão empírica que motiva o trabalho de attention eficiente do Capítulo 4 [src_012].

🔗 Conexão

A transição assintótica em que o \(\mathcal{O}(T^2 D)\) da attention ultrapassa o \(\mathcal{O}(T D^2)\) da FFN é exatamente o regime que o Capítulo 4 aborda, com FlashAttention, grouped-query e multi-query attention, e padrões de janela deslizante.

11. Prévia: o que vem a seguir

Este capítulo estabelece a arquitetura de referência de 2017 como o baseline contra o qual cada capítulo posterior deste livro é mais bem lido. O Capítulo 2 substitui as codificações posicionais absolutas sinusoidais e aprendidas pelo rotary position encoding (RoPE), que injeta informação de posição relativa por meio de uma rotação no espaço de query-key, em vez de uma embedding aditiva [src_002]. O Capítulo 3 substitui LayerNorm por RMSNorm e ReLU+linear por SwiGLU, em ambos os casos abrindo mão de parâmetros e computação que evidências empíricas sugerem não serem essenciais [src_002]. O Capítulo 4 trata de FlashAttention, grouped-query attention (GQA), multi-query attention (MQA) e padrões de janela deslizante — implementações e aproximações que alteram o custo da self-attention sem alterar o que ela computa [src_002]. Em conjunto, esses três capítulos descrevem o Transformer decoder-only moderno; o leitor que desejar um mapa completo deverá tratar o presente capítulo como a origem e o Capítulo 8 como o destino.

🔄 Recapitulação

  • Complete: cada bloco numa pilha Transformer recebe e emite um tensor de forma ____.
  • Explique por que a subcamada FFN, e não a subcamada de self-attention, concentra a maior parte do orçamento de parâmetros de um bloco em \(r = 4\).
  • Compare o bloco encoder (duas subcamadas) com o bloco decoder (três subcamadas): qual subcamada extra o decoder carrega, e o que ela consome?
  • Preveja: em comprimentos de sequência \(T\) longos, o custo computacional de qual subcamada começa a dominar, e qual capítulo trata da solução?

Referências

  • src_001 — Christopher M. Bishop and Hugh Bishop. Deep Learning: Foundations and Concepts. Springer, 2024. https://www.bishopbook.com/
  • src_002 — Tong Xiao and Jingbo Zhu. Foundations of Large Language Models. arXiv:2501.09223v2, 2025. https://arxiv.org/pdf/2501.09223
  • src_010 — Sebastian Raschka. Build a Large Language Model (From Scratch). Manning, 2024. https://github.com/rasbt/LLMs-from-scratch
  • src_012 — Ashish Vaswani, Noam Shazeer, Niki Parmar, Jakob Uszkoreit, Llion Jones, Aidan N. Gomez, Łukasz Kaiser, and Illia Polosukhin. Attention Is All You Need. In Advances in Neural Information Processing Systems (NIPS 2017), 2017. https://arxiv.org/pdf/1706.03762
  • src_029 — Hugo Touvron, Louis Martin, Kevin Stone, et al. Llama 2: Open Foundation and Fine-Tuned Chat Models. arXiv:2307.09288, 2023. https://arxiv.org/pdf/2307.09288
  • src_049 — Ruibin Xiong, Yunchang Yang, Di He, Kai Zheng, Shuxin Zheng, Chen Xing, Huishuai Zhang, Yanyan Lan, Liwei Wang, and Tie-Yan Liu. On Layer Normalization in the Transformer Architecture. In Proceedings of the 37th International Conference on Machine Learning (ICML 2020), 2020. https://arxiv.org/pdf/2002.04745