Phase 07 - Lesson 04
Codificação Posicional — Senoidal, RoPE, ALiBi
This lesson includes a graded coding exercise that runs in your browser, unlocked with lifetime access.
A atenção é invariante a permutações. "O gato sentou no tapete" e "tapete no sentou gato o" produzem a mesma saída sem um sinal posicional. Três algoritmos resolvem isso, cada um com uma aposta diferente sobre o que significa "posição".
Tipo: Build Linguagens: Python Pré-requisitos: Fase 7 · 02 (Self-Attention), Fase 7 · 03 (Multi-Head Attention) Tempo: ~45 minutos
O Problema
A atenção por produto escalar normalizado é cega à ordem. A matriz de atenção softmax(Q K^T / √d) V é calculada a partir de similaridades par a par. Embaralhe as linhas de X e as linhas da saída são embaralhadas da mesma forma. Nada dentro da atenção se importa com a posição.
Isso não é um bug em um modelo bag-of-words. Para linguagem, código, áudio, vídeo — qualquer coisa em que a ordem carrega significado — é fatal.
A correção é injetar a posição nos embeddings de alguma forma. Três eras de respostas:
- Senoidal absoluta (Vaswani 2017). Adicione
sin/cosda posição ao embedding. Simples, sem parâmetros aprendíveis, extrapola mal além dos comprimentos treinados. - RoPE — Rotary Position Embeddings (Su 2021). Rotacione os vetores Q e K por um ângulo proporcional à posição. Codifica a posição relativa diretamente no produto escalar. Dominante em 2026.
- ALiBi — Attention with Linear Biases (Press 2022). Pule os embeddings por completo; adicione uma penalidade linear por cabeça às pontuações de atenção com base na distância. Excelente extrapolação de comprimento.
Em 2026, essencialmente todo modelo aberto de fronteira usa RoPE: Llama 2/3/4, Qwen 2/3, Mistral, Mixtral, DeepSeek-V3, Kimi. Um punhado de modelos de contexto longo usa ALiBi ou suas variantes modernas. A senoidal absoluta é histórica.
O Conceito
Senoidal absoluta
Pré-compute uma matriz fixa PE de formato (max_len, d_model):
PE[pos, 2i] = sin(pos / 10000^(2i / d_model))
PE[pos, 2i+1] = cos(pos / 10000^(2i / d_model))
Então X' = X + PE[:N] antes da atenção. Cada dimensão é uma senoide em uma frequência diferente. O modelo aprende a ler a posição a partir do padrão de fase. Falha além de max_len: nada disse ao modelo o que acontece na posição 2048 quando ele só viu as posições 0–2047.
RoPE
Rotacione os vetores Q e K (não os embeddings). Para um par de dimensões (2i, 2i+1):
[q'_2i ] [ cos(pos·θ_i) -sin(pos·θ_i) ] [q_2i ]
[q'_2i+1 ] = [ sin(pos·θ_i) cos(pos·θ_i) ] [q_2i+1 ]
θ_i = base^(-2i / d_head), base = 10000 by default
Aplique a mesma rotação às chaves com a posição pos_k. O produto escalar q'_m · k'_n torna-se uma função apenas de (m - n). Ou seja: a pontuação de atenção depende somente da distância relativa, mesmo que a rotação tenha sido feita com base em posições absolutas. Um truque belíssimo.
Estendendo RoPE: base pode ser escalado (NTK-aware, YaRN, LongRoPE) para extrapolar para contextos mais longos sem retreinamento. O Llama 3 estendeu de 8K para 128K de contexto dessa forma.
ALiBi
Pule o truque do embedding. Aplique viés diretamente nas pontuações de atenção:
attn_score[i, j] = (q_i · k_j) / √d - m_h · |i - j|
Onde m_h é uma inclinação específica por cabeça (por exemplo, 1 / 2^(8·h/H)). Tokens mais próximos recebem reforço; tokens distantes recebem penalidade. Nenhum custo em tempo de treinamento. O artigo mostra que a extrapolação de comprimento supera a senoidal e iguala o RoPE em seu comprimento de treinamento original.
O que escolher em 2026
| Variante | Extrapolação | Custo de treinamento | Usada por |
|---|---|---|---|
| Senoidal absoluta | ruim | grátis | transformer original, BERT inicial |
| Absoluta aprendida | nenhuma | mínimo | GPT-2, GPT-3 |
| RoPE | boa com escalonamento | grátis | Llama 2/3/4, Qwen 2/3, Mistral, DeepSeek-V3, Kimi |
| RoPE + YaRN | excelente | etapa de fine-tune | Qwen2-1M, Llama 3.1 128K |
| ALiBi | excelente | grátis | BLOOM, MPT, Baichuan |
O RoPE venceu porque se encaixa na atenção sem alterar a arquitetura, codifica a posição relativa e seu hiperparâmetro base oferece um controle limpo para fine-tuning de contexto longo.
Construa
Passo 1: codificação senoidal
Veja code/main.py. Um cálculo de 4 linhas:
def sinusoidal(N, d):
pe = [[0.0] * d for _ in range(N)]
for pos in range(N):
for i in range(d // 2):
theta = pos / (10000 ** (2 * i / d))
pe[pos][2 * i] = math.sin(theta)
pe[pos][2 * i + 1] = math.cos(theta)
return pe
Adicione isso à matriz de embedding antes da primeira camada de atenção.
Passo 2: RoPE aplicado a Q, K
O RoPE opera in-place em Q e K. Para cada par de dimensões:
def apply_rope(x, pos, base=10000):
d = len(x)
out = list(x)
for i in range(d // 2):
theta = pos / (base ** (2 * i / d))
c, s = math.cos(theta), math.sin(theta)
a, b = x[2 * i], x[2 * i + 1]
out[2 * i] = a * c - b * s
out[2 * i + 1] = a * s + b * c
return out
Crucial: aplique a mesma função a Q na posição m e a K na posição n. O produto escalar deles ganha um fator cos((m-n)·θ_i) em cada par de coordenadas. A atenção aprende a posição relativa de graça.
Passo 3: inclinações e viés do ALiBi
def alibi_bias(n_heads, seq_len):
# slope_h = 2 ** (-8 * h / n_heads) for h = 1..n_heads
slopes = [2 ** (-8 * (h + 1) / n_heads) for h in range(n_heads)]
bias = []
for m in slopes:
row = [[-m * abs(i - j) for j in range(seq_len)] for i in range(seq_len)]
bias.append(row)
return bias # add to attention scores before softmax
Adicione bias[h] à matriz de pontuações de atenção (seq_len, seq_len) da cabeça h e, em seguida, aplique softmax.
Passo 4: verifique a propriedade de distância relativa do RoPE
Escolha dois vetores aleatórios a, b. Rotacione por (pos_a, pos_b). Depois por (pos_a + k, pos_b + k). Ambos os produtos escalares devem coincidir dentro do erro de ponto flutuante. Essa propriedade é o ponto central do RoPE — ele é invariante ao deslocamento absoluto, só a lacuna relativa importa.
Use
O PyTorch 2.5+ traz utilitários de RoPE em torch.nn.functional. A maior parte do código de produção usa flash_attn ou xformers, onde o RoPE é aplicado dentro do kernel de atenção.
from transformers import AutoModel
model = AutoModel.from_pretrained("meta-llama/Llama-3.2-3B")
# model.config.rope_scaling → {"type": "yarn", "factor": 32.0, "original_max_position_embeddings": 8192}
Truques de contexto longo em 2026:
- Interpolação NTK-aware. Reescale
baseparabase * (scale_factor)^(d/(d-2))ao estender de 4K para 16K+. - YaRN. Interpolação mais inteligente que preserva a entropia da atenção em contextos longos. O Llama 3.1 128K a usa.
- LongRoPE. Método de 2024 da Microsoft que usa busca evolutiva para escolher fatores de escala por dimensão. O Phi-3-Long o usa.
- Interpolação de posição + fine-tuning. Basta reduzir as posições pelo fator de extensão e fazer fine-tune por 1–5B tokens. Surpreendentemente eficaz.
Entregue
Veja outputs/skill-positional-encoding-picker.md. A skill escolhe uma estratégia de codificação para um novo modelo dado o comprimento de contexto alvo, as necessidades de extrapolação e o orçamento de treinamento.
Exercícios
- Fácil. Plote a matriz
PEsenoidal como um mapa de calor paramax_len=512, d=128. Confirme o padrão de "as listras ficam mais largas conforme o índice da dimensão cresce". - Médio. Implemente o escalonamento RoPE NTK-aware. Treine um LM minúsculo em sequências de comprimento 256, depois teste em comprimento 1024 com e sem escalonamento. Meça a perplexidade.
- Difícil. Implemente ALiBi e RoPE no mesmo módulo de atenção. Treine um transformer de 4 camadas em uma tarefa de cópia com sequências de comprimento 512. Extrapole para 2048 no tempo de teste. Compare a degradação.
Termos-Chave
| Termo | O que as pessoas dizem | O que realmente significa |
|---|---|---|
| Codificação posicional | "Informa à atenção sobre a ordem" | Qualquer sinal adicionado aos embeddings ou à atenção que codifica a posição. |
| Senoidal | "A original" | sin/cos em frequências geométricas adicionados aos embeddings; não extrapola. |
| RoPE | "Rotary embeddings" | Rotaciona Q, K por um ângulo dependente da posição; o produto escalar codifica a distância relativa. |
| ALiBi | "Truque do viés linear" | Adiciona `-m· |
| base | "O controle do RoPE" | O escalador de frequência no RoPE; aumente-o para estender o contexto na inferência. |
| NTK-aware | "Um truque de escalonamento do RoPE" | Reescala base para que as dimensões de alta frequência não sejam comprimidas quando o contexto expande. |
| YaRN | "O sofisticado" | Interpolação+extrapolação por dimensão que preserva a entropia da atenção. |
| Extrapolação | "Funciona além do comprimento treinado" | O esquema de posição consegue gerar saída correta além do max_len visto no treinamento? |
Leitura Adicional
- Vaswani et al. (2017). Attention Is All You Need §3.5 — senoidal original.
- Su et al. (2021). RoFormer: Enhanced Transformer with Rotary Position Embedding — artigo do RoPE.
- Press, Smith, Lewis (2021). Train Short, Test Long: Attention with Linear Biases Enables Input Length Extrapolation — ALiBi.
- Peng et al. (2023). YaRN: Efficient Context Window Extension of Large Language Models — estado da arte em escalonamento de RoPE.
- Chen et al. (2023). Extending Context Window of Large Language Models via Positional Interpolation — artigo de contexto longo do Llama 2 da Meta.
- Ding et al. (2024). LongRoPE: Extending LLM Context Window Beyond 2 Million Tokens — o método da Microsoft usado pelo Phi-3-Long e citado na seção Use.
- HuggingFace Transformers —
modeling_rope_utils.py— implementações de nível de produção de cada esquema de escalonamento RoPE (default, linear, dynamic, YaRN, LongRoPE, Llama-3).