Что такое position encoding? RoPE vs абсолютные позиции vs относительные позиции?

Краткий тезис

Position encoding — это механизм, который добавляет информацию о порядке токенов в архитектуру трансформера, поскольку self-attention по своей природе инвариантен к перестановкам. Существует три основных подхода: абсолютные позиции (синусоидальные кодировки из оригинальной статьи), относительные позиции (bias, зависящий от разности позиций) и RoPE (Position Embedding), который кодирует позиции через вращение в комплексной плоскости и автоматически учитывает относительное расстояние. RoPE стал стандартом де-факто в современных LLM (Llama, PaLM, GPT-NeoX) благодаря лучшей обобщаемости на длинные контексты и эффективной реализации.


1. Зачем нужно position encoding?

Self-attention (механизм внимания без рекуррентности) вычисляет веса внимания как скалярное произведение между запросами и ключами. Если подать на вход только эмбеддинги токенов, модель не сможет различить последовательности «кошка съела мышь» и «мышь съела кошку» — порядок не учитывается. Position encoding (кодирование позиции) добавляет к эмбеддингам или модифицирует attention так, чтобы модель могла использовать информацию о порядке.

Термин «Position encoding» — это общее название для любого способа внедрения позиционной информации в трансформер. Различают absolute (абсолютные) и relative (относительные) кодировки.


2. Абсолютные позиции (sin/cos, GPT-2)

2.1. Синусоидальные кодировки (оригинальный Transformer)

В статье «Attention is All You Need» предложено добавлять к входным эмбеддингам вектор, состоящий из синусов и косинусов разных частот:

PE(pos, 2i) = sin(pos / 10000^(2i/d_model))
PE(pos, 2i+1) = cos(pos / 10000^(2i/d_model))

где pos — позиция токена, i — индекс измерения, d_model — размерность модели.

Преимущества

  • Не требует обучения (детерминировано).
  • Позволяет модели легко выучить относительные расстояния благодаря линейным преобразованиям синусов/косинусов.
  • Хорошо экстраполируется на длины, не виданные при обучении (теоретически).

Недостатки

  • Фиксированная сетка частот — при очень длинных контекстах (> 2048) значения становятся почти одинаковыми для соседних позиций.
  • Не различает начало и конец последовательности (симметрия sin/cos).

2.2. Обучаемые абсолютные позиции (GPT-2, BERT)

В GPT-2 и BERT используется обучаемая матрица позиционных эмбеддингов размером sequence length|max_seq_len x d_model. Каждой позиции сопоставляется вектор, который учится вместе с моделью.

Преимущества

  • Гибкость — модель сама решает, какую информацию о позиции хранить.

Недостатки

  • Не экстраполируется на длины больше sequence length|max_seq_len (нужно либо обрезать, либо дообучать).
  • Требует дополнительных параметров.

3. Относительные позиции (T5, DeBERTa)

Идея: вместо того чтобы кодировать абсолютную позицию каждого токена, в attention добавляется bias (смещение), зависящий от разности позиций i - j. Модель учится, насколько сильно токен на позиции i должен «обращать внимание» на токен на позиции j в зависимости от расстояния.

3.1. T5 (Raffel et al., 2020)

В T5 используется relative position bias — для каждой пары (i, j) вычисляется скаляр, который прибавляется к скалярному произведению запроса и ключа перед softmax. Bias задаётся таблицей, индексируемой min(i - j, max_distance). Параметры таблицы обучаются.

3.2. DeBERTa (He et al., 2020)

DeBERTa разделяет content (содержание) и position (позицию) в attention: вычисляются отдельные матрицы внимания по содержанию и по позиции, затем комбинируются.

Преимущества относительных позиций

  • Естественная экстраполяция на любую длину контекста (bias зависит только от разности, а не от абсолютной позиции).
  • Лучше подходят для задач, где важны локальные зависимости (например, NER).

Недостатки

  • Вычислительная сложность: bias нужно вычислять для каждой пары токенов (O(n²)), хотя можно оптимизировать.
  • Меньшая популярность в больших языковых моделях по сравнению с RoPE.

4. RoPE (Rotary Position Embedding)

RoPE (Rotary Position Embedding) — метод, предложенный в статье «RoFormer: Enhanced Transformer with Rotary Position Embedding» (Su et al., 2021). Он кодирует позиции через вращение векторов запросов и ключей в комплексной плоскости.

4.1. Как работает RoPE

Для каждого токена на позиции pos вектор запроса q и ключа k поворачиваются на угол, пропорциональный pos. Вращение выполняется отдельно для каждой пары измерений (2D-подпространства):

q'_2i = q_2i * cos(pos * θ_i) - q_(2i+1) * sin(pos * θ_i)
q'_(2i+1) = q_2i * sin(pos * θ_i) + q_(2i+1) * cos(pos * θ_i)

Аналогично для k. Углы θ_i обычно задаются как θ_i = 10000^(-2i/d_model) (как в sin/cos).

Ключевое свойство скалярное произведение между повёрнутыми q' и k' зависит только от разности позиций pos_q - pos_k. Это автоматически даёт относительное кодирование.

4.2. Преимущества RoPE

  • Относительность — attention зависит от расстояния, а не от абсолютных позиций.
  • Экстраполяция — может работать на длинах, превышающих обученные, с помощью техник NTK-aware scaling, YaRN и др.
  • Эффективность — не требует дополнительных параметров (кроме частот), легко реализуется через поэлементные операции.
  • Совместимость — хорошо сочетается с Flash Attention и другими оптимизациями.

4.3. Почему RoPE стал стандартом

  • Llama, Llama 2, Llama 3, Mistral, Mixtral, PaLM, GPT-NeoX, Qwen, Yi — все используют RoPE.
  • Превосходит абсолютные позиции по экстраполяции, а относительные — по простоте и скорости.
  • Позволяет легко увеличивать контекстное окно (например, с 4K до 32K) без дообучения с нуля.

5. Сравнительная таблица

КритерийАбсолютные (sin/cos)Абсолютные (обучаемые)Относительные (T5)RoPE
Экстраполяция на длинуТеоретически да, на практике плохоНет (только до max_len)Да (зависит от bias)Да (с дополнительными техниками)
ПараметрыНетДа (max_len x d_model)Да (таблица bias)Нет (только частоты)
Сложность реализацииНизкаяНизкаяСредняяСредняя
Популярность в LLMИсторическаяBERT, GPT-2T5, DeBERTaLlama, Mistral, PaLM
ОтносительностьНет (абсолютная)НетДаДа (автоматически)
Вычислительная нагрузкаМинимальнаяМинимальнаяO(n²) biasМинимальная (встраивается в QK)

6. Влияние на длинные контексты и RAG

В Agentic RAG модели часто работают с контекстами, содержащими множество извлечённых чанков (до 100K+ токенов). Position encoding напрямую влияет на способность модели удерживать информацию из середины и конца контекста.

  • Абсолютные позиции (особенно обучаемые) приводят к lost-in-the-middle — модель хуже запоминает информацию из середины длинного контекста.
  • RoPE с NTK-aware scaling или YaRN позволяет расширять контекст до 128K и более, сохраняя качество.
  • Относительные позиции (T5) тоже хорошо работают, но менее распространены в современных LLM.

Для RAG-системы выбор position encoding важен: если модель плохо экстраполирует длину, придётся либо обрезать контекст, либо дообучать с большим окном.


7. Реализация RoPE на Python (пример с PyTorch)

import torch
import math

def precompute_freqs_cis(dim: int, end: int, theta: float = 10000.0):
    freqs = 1.0 / (theta ** (torch.arange(0, dim, 2)[: (dim // 2)].float() / dim))
    t = torch.arange(end, device=freqs.device)
    freqs = torch.outer(t, freqs).float()
    freqs_cis = torch.polar(torch.ones_like(freqs), freqs)  # комплексные числа
    return freqs_cis

def apply_rotary_emb(xq: torch.Tensor, xk: torch.Tensor, freqs_cis: torch.Tensor):
    # xq, xk: (batch, seq_len, n_heads, head_dim)
    # freqs_cis: (seq_len, head_dim//2)
    xq_ = torch.view_as_complex(xq.float().reshape(*xq.shape[:-1], -1, 2))
    xk_ = torch.view_as_complex(xk.float().reshape(*xk.shape[:-1], -1, 2))
    freqs_cis = freqs_cis.unsqueeze(0).unsqueeze(2)  # (1, seq_len, 1, head_dim//2)
    xq_out = torch.view_as_real(xq_ * freqs_cis).flatten(3)
    xk_out = torch.view_as_real(xk_ * freqs_cis).flatten(3)
    return xq_out.type_as(xq), xk_out.type_as(xk)

Этот код предвычисляет частоты и применяет вращение к запросам и ключам. В реальных реализациях (например, в Llama) используется оптимизированная версия.


8. Ограничения и альтернативы

  • ALiBi (Press et al., 2021) — ещё один метод относительного позиционирования, где к attention добавляется линейный bias, пропорциональный расстоянию. Проще RoPE, но хуже экстраполирует.
  • xPos (Sun et al., 2022) — улучшение RoPE для длинных контекстов с экспоненциальным затуханием.
  • NoPE (Kazemnejad et al., 2023) — показано, что трансформеры могут выучить позиции без явного кодирования, если использовать causal masking и достаточную глубину. Однако на практике RoPE всё равно даёт лучшие результаты.

9. Пет-проект для закрепления

Задача Реализовать мини-трансформер с тремя вариантами position encoding (абсолютные sin/cos, относительные T5, RoPE) и сравнить их на задаче предсказания следующего токена для последовательностей разной длины.

Инструменты PyTorch, небольшой датасет (например, тексты книг или случайные последовательности символов).

Шаги:

  1. Написать класс PositionalEncoding для каждого метода.
  2. Собрать простой трансформер с одним слоем encoder, 4 heads, d_model=128.
  3. Обучить на коротких последовательностях (длина 64).
  4. Протестировать на длинных (длина 256, 512) — измерить perplexity.
  5. Визуализировать attention maps для каждого метода.

Ожидаемый результат RoPE и T5 покажут меньшее падение качества на длинных последовательностях по сравнению с sin/cos. Attention maps для RoPE будут более «гладкими» по диагонали.


10. Связь с другими вопросами

ВопросТема
652Что такое attention и self-attention?
654Как работает Flash Attention?
655Что такое long-context LLM и как они достигаются?
660Как вы обрабатываете длинные контексты в RAG?
648Какие архитектуры трансформеров вы знаете?
670Что такое NTK-aware scaling и YaRN?

Навигация