Sobes.tech
Senior
16

Расскажи про виды позиционного кодирования, в частности про Rotary Positional Encoding (RoPE).

Компании, где спрашивали
ozon_tech

Ответ от нейросети

sobes.tech AI

Позиционное кодирование — это способ добавить информацию о порядке элементов в последовательности, что важно для моделей трансформеров, которые сами по себе не учитывают порядок слов.

Виды позиционного кодирования:

  1. Синусоидальное позиционное кодирование (Sinusoidal PE) — классический метод из статьи Vaswani et al. (2017). Каждому положению соответствует вектор, элементы которого вычисляются через синусы и косинусы с разными частотами. Это позволяет модели обобщать на последовательности большей длины.

  2. Обучаемое позиционное кодирование (Learned PE) — позиционные векторы инициализируются случайно и обучаются вместе с моделью. Позволяет модели адаптироваться к конкретной задаче, но хуже обобщает на длинные последовательности.

  3. Relative Positional Encoding (Относительное позиционное кодирование) — кодирует относительные расстояния между элементами, а не абсолютные позиции. Это улучшает способность модели учитывать контекст.

  4. Rotary Positional Encoding (RoPE) — относительно новый метод, который внедряет позиционную информацию через вращение (ротацию) векторов признаков. Идея в том, что позиционная информация кодируется как вращение векторного пространства, что позволяет эффективно учитывать относительные позиции и сохранять свойства трансляционной инвариантности.

Как работает RoPE?

  • Каждому элементу последовательности соответствует позиционный индекс.
  • Векторы признаков разбиваются на пары и к каждой паре применяется двумерное вращение на угол, зависящий от позиции.
  • Это вращение реализуется через умножение на матрицу поворота, параметризованную синусами и косинусами, аналогично синусоидальному PE, но применяется к самим признакам, а не добавляется.

RoPE хорошо интегрируется с механизмом внимания, позволяя модели учитывать относительные позиции без явного вычисления разностей индексов.

Пример применения RoPE в трансформерах:

import torch
import math

def rotary_positional_encoding(x):
    # x: [seq_len, dim]
    seq_len, dim = x.shape
    assert dim % 2 == 0
    pos = torch.arange(seq_len).unsqueeze(1)  # [seq_len, 1]
    dim_range = torch.arange(dim // 2)  # [dim/2]
    inv_freq = 1.0 / (10000 ** (2 * dim_range / dim))
    angles = pos * inv_freq  # [seq_len, dim/2]
    sin, cos = angles.sin(), angles.cos()
    x1, x2 = x[:, 0::2], x[:, 1::2]
    x_rotated = torch.stack([x1 * cos - x2 * sin, x1 * sin + x2 * cos], dim=-1)
    return x_rotated.flatten(1)

Таким образом, RoPE обеспечивает более гибкое и эффективное позиционное кодирование, особенно полезное для длинных последовательностей и задач, где важны относительные позиции.