Track
Представьте, что вы читаете роман, где каждое слово на странице перемешано в случайном порядке. Даже если вы понимаете каждое отдельное слово, сюжет теряется, потому что смысл определяется порядком слов. Когда инженеры начали разрабатывать большие языковые модели (LLM), они столкнулись с похожей проблемой. Как научить модель понимать последовательность слов, если её основной механизм обрабатывает всё одновременно?
Здесь на помощь приходит позиционное кодирование. В этой статье мы разберём внутренние механизмы позиционного кодирования и то, как они дают трансформерам чувство порядка. Мы проследим его эволюцию — от исходных синусоидальных формул до современных ротационных встраиваний, — и покажем, как реализовать это в вашем следующем проекте машинного обучения. Если вы не знакомы с базовой архитектурой, советую начать с нашего руководства как работают трансформеры.
Что такое позиционное кодирование?
Позиционное кодирование — это приём, позволяющий нейронным сетям понимать последовательный порядок входных данных. Оно выступает в роли координат, представляющих относительную или абсолютную позицию токена, и объединяется с вашей стандартной репрезентацией данных.
Перед подачей текста в нейронную сеть слова преобразуются в непрерывные числовые форматы, называемые встраиваниями. Однако стандартные встраивания отражают только семантику: они не сообщают ничего о положении слова в тексте. Точно узнать, как работает этот процесс, вы можете на нашем курсе Introduction to Embeddings with the OpenAI API.
Позиционное кодирование — это дополнительный математический слой, добавляемый напрямую к этим токен-встраиваниям. Объединив семантическую репрезентацию с позиционной меткой, модель-трансформер может различать одинаковые слова, встречающиеся в разных частях предложения.
Проблема инвариантности к перестановкам
Последовательные данные критически зависят от порядка. В естественном языке предложение «the dog bit the man» имеет совершенно иной смысл, чем «the man bit the dog».

Исторически рекуррентные нейронные сети (RNN) и долгая краткосрочная память (LSTM) справлялись с этим по своей природе. Они обрабатывали токены последовательно, то есть сеть математически «съедала» второе слово только после первого. Аналогично, свёрточные нейросети (CNN) используют локальные скользящие окна, фиксируя пространственное расположение пикселей или соседних слов.
Трансформеры полностью отказываются от последовательной обработки. Они обрабатывают все токены параллельно. Движок трансформера — это механизм самовнимания, который вычисляет попарные оценки отношений между каждым токеном в последовательности одновременно. Математически самовнимание инвариантно к перестановке. Если перемешать входную последовательность, механизм самовнимания выдаст те же оценки внимания для пар слов.
Без механизма сохранения порядка модель полностью теряет информацию о последовательности. Семантика схлопывается в неупорядоченный «мешок слов». Позиционное кодирование решает проблему инвариантности, принудительно изменяя входные векторы так, чтобы механизм самовнимания по-разному регистрировал токены на позиции 1 и на позиции 10.
Как работает позиционное кодирование?
Позиционное кодирование действует, математически модифицируя векторы входных токенов до попадания в слои самовнимания. Это гарантирует, что модель вычисляет отношения с учётом и значения, и позиции.
Построим немного интуиции. Представьте стандартные токен-встраивания как бейджи на конференции. Бейдж говорит, кто этот человек, но место в зале не меняет его личность и отношения с другими. Позиционное кодирование — это как добавить номер места на этот бейдж. Вместе вы знаете и кто это, и где он сидит. Это добавляет контекст к потенциальным взаимодействиям на конференции.
В трансформере это сочетание обычно делается простой покомпонентной суммой. Модель берёт семантический вектор встраивания слова и добавляет к нему вектор позиционного кодирования того же размера. Получившийся вектор содержит лёгкую модуляцию, которую последующие слои учатся интерпретировать как пространственные координаты.
Пример вычисления
Рассмотрим упрощённый пример. Пусть у нас крошечное пространство встраиваний размерности 4. Мы хотим обработать слово «DataCamp», находящееся на позиции 0 в последовательности.
- Семантическое встраивание: Нейросеть извлекает встраивание для «DataCamp», например [0.51, -0.22, 0.88, 0.14].
- Позиционное кодирование: Позиционная формула генерирует вектор координат для позиции 0. Для примера предположим, что это [0.00, 1.00, 0.00, 1.00].
- Комбинация: Складываем два вектора покомпонентно.
- Итоговый вход: Прямой проход получает [0.51, 0.78, 0.88, 1.14].
Даже если тот же токен «DataCamp» встретится позже на позиции 5, вектор позиционного кодирования будет другим. Следовательно, итоговый входной вектор будет выглядеть для механизма самовнимания совершенно иначе.

Синусоидальное позиционное кодирование
Исходная статья «Attention Is All You Need» представила блестящий способ генерации позиционных векторов с помощью базовой тригонометрии. Этот подход не требует обучаемых весов и полностью опирается на фиксированные математические функции.
Математическая основа
Синусоидальное позиционное кодирование использует синус и косинус на разных частотах для кодирования позиции. Исходная формула гласит, что для заданной позиции (pos) и конкретного индекса измерения (i) во векторе встраивания код вычисляется так:
-
Для чётных измерений (
2i):PE(pos, 2i) = sin(pos / 10000^(2i/dmodel)) -
Для нечётных измерений (
2i+1):PE(pos, 2i+1) = cos(pos / 10000^(2i/dmodel))
В этой формуле dmodel — общий размерность вектора встраивания. По мере перехода от индекса 0 к dmodel длина волны синусоидальных функций геометрически растёт.
Преимущества и свойства
Эта геометрическая прогрессия частот даёт ряд явных преимуществ.
- Значения синуса и косинуса строго ограничены интервалом от -1 до 1. Благодаря этому позиционные коды не «перебивают» по величине семантические встраивания.
- Функции периодичны. Из-за тригонометрических формул сложения линейное преобразование может легко представить позиционное кодирование будущей позиции (
pos + k) как функцию текущей (pos). Это свойство естественным образом позволяет модели изучать относительное позиционное кодирование. - Синусоидальное кодирование использует фиксированные параметры. Обучаемых весов ноль, что сильно снижает накладные расходы по памяти. Поскольку оно основано на непрерывной функции, модель теоретически способна к экстраполяции, то есть может отображать позиции для последовательностей длиннее обучающих.
Визуализация
Для понимания синусоидального кодирования полезно представить его в виде тепловой карты.

Ось X на визуализации — размерность встраивания, ось Y — позиция токена.
Нижние размерности слева быстро колеблются между отрицательными и положительными значениями, что позволяет различать близкие позиции токенов. По мере роста индекса размерности длина волны увеличивается, и код меняется более плавно. Эти размерности фиксируют позиционные различия на больших расстояниях.
Для 50 позиций, показанных здесь, многие старшие размерности выглядят почти как однородные вертикальные полосы. Это потому, что их длины волн настолько велики, что значения синуса остаются близкими к 0, а косинуса — близкими к 1 в пределах этой короткой последовательности, а не ровно 0 и 1 соответственно. Поэтому чередующиеся полосы отражают соседние синусо–косинусные размерности, а не простое двоичное кодирование. На более длинной последовательности эти размерности тоже начнут заметно меняться.
Вывод: разные частоты дают модели позиционную информацию на нескольких масштабах — быстро меняющиеся размерности фиксируют тонкие различия между близкими токенами, а медленные отслеживают общий прогресс по длинным последовательностям.
Обучаемое позиционное кодирование
Хотя фиксированные математические формулы элегантны, современные архитектуры глубокого обучения часто полагаются на данные при поиске оптимальных представлений. Обучаемые позиционные встраивания перекладывают всю задачу задания раскладки на этап обучения.
Идея и реализация
Вместо жёсткого задания позиций с помощью синуса и косинуса обучаемые позиционные встраивания трактуют координаты позиций как обычные обучаемые параметры.
Модель инициализирует полностью пустую матрицу встраиваний, где каждая строка соответствует конкретной позиции в последовательности. Во время стандартного цикла обучения с обратным распространением сеть обновляет эти позиционные веса наряду с семантическими встраиваниями токенов, чтобы минимизировать функцию потерь.
Сравнительные преимущества
Главное преимущество обучаемых позиционных встраиваний — крайняя гибкость. Модель имеет полную свободу выучить именно те позиционные представления, которые лучше всего подходят под конкретный датасет. Архитектуры вроде BERT и GPT-2 популяризировали этот подход благодаря его высокой адаптивности и сильным результатам на прикладных задачах.
Ограничения и проблемы
Самое серьёзное ограничение обучаемых позиционных встраиваний — жёсткая граница по длине последовательности. Если модель обучена максимум на 2 048 позиционных векторов, она физически не сможет обработать документ из 2 049 токенов.
Это ограничение резко сужает возможности экстраполяции по длине и часто требует дорогостоящего дообучения для расширения контекстного окна.
Относительное позиционное кодирование
По мере того как модели научились работать с более длинными документами, инженеры поняли, что абсолютная позиция слова часто менее важна, чем его относительная дистанция до других слов.
Переход к относительным позициям
Возьмём фразу «the rapid advancement of AI». Грамматическая связь между «advancement» и «AI» остаётся одинаковой, будь то в самом начале документа или в самом конце. Относительное позиционное кодирование отказывается от абсолютной сетки координат. Вместо этого оно полностью фокусируется на смещениях между взаимодействующими токенами.
Реализация в механизмах внимания
Чтобы реализовать относительные коды, инженеры модифицируют непосредственно вычисления оценок внимания, а не изменяют входные встраивания в самом начале сети.
При вычислении оценки внимания между матрицами «запросов» и «ключей» операция включает дополнительный обучаемый сдвиг, представляющий относительную дистанцию. Это изменение гарантирует инвариантность к сдвигу в тексте. Чтобы глубже понять работу этих матриц, прочитайте наше руководство по механизму внимания в LLM.
Практические компромиссы
Такой подход даёт очень точное понимание контекста, но вносит серьёзные вычислительные накладные расходы. Расчёт уникальных матриц относительных расстояний для каждой головы внимания резко увеличивает потребление памяти. Это также усложняет внутренние механизмы кэширования, используемые для ускорения генерации текста.
Абсолютная против относительной позиционной информации
Выбор между абсолютным и относительным кодированием зависит от конкретной задачи.
- Абсолютное кодирование отлично работает, когда пространственная раскладка жёсткая и важна скорость.
- Относительное кодирование гораздо лучше подходит для обработки длинных текстов, где грамматика полностью зависит от локальных дистанций, а не от абсолютных координат в документе.
Ротационные позиционные встраивания (RoPE)
В постоянном поиске идеальной архитектуры трансформеров исследователи предложили Rotary Position Embedding (RoPE). Он сочетает лучшие свойства абсолютного и относительного позиционного кодирования и быстро стал отраслевым стандартом.
Инновационный подход
RoPE объединяет абсолютное расположение и относительные расстояния с помощью вращательных преобразований. Вместо добавления вектора к встраиваниям или тяжёлых сдвигов к оценкам внимания RoPE отображает вектор встраивания на комплексную плоскость и поворачивает его на определённый угол. Величина этого угла строго определяется абсолютной позицией токена в последовательности.

Математические соображения
В 2D-пространстве вращение выполняется с помощью стандартной 2D-матрицы поворота. В более высоких размерностях RoPE просто группирует компоненты встраивания попарно и применяет к каждой паре уникальный 2D-поворот, зависящий от абсолютного индекса позиции.
Благодаря геометрическим свойствам матриц поворота скалярное произведение повернутого вектора запроса и повернутого вектора ключа в итоге зависит только от относительного угла между ними. Таким образом, RoPE использует абсолютное отображение позиций, чтобы естественным образом кодировать относительную дистанцию между токенами.
RoPE против синусоидального кодирования
Как видно на графике выше, синусоидальное кодирование меняет и величину, и направление исходного вектора. RoPE же сохраняет информацию о величине и для понимания относительной дистанции нуждается лишь в угле между двумя позициями.
Attention With Linear Biases (ALiBi)
В то время как RoPE опирается на сложную вращательную математику, другая техника — Attention with Linear Biases (ALiBi) — идёт совершенно другим путём.
Простота и эффективность
ALiBi полностью отказывается от идеи добавлять позиционную информацию к начальному встраиванию токенов. Словесные встраивания поступают в трансформер без изменений.
Вместо этого ALiBi вмешивается на самом последнем шаге вычисления внимания. Прямо перед тем, как логиты внимания проходят через функцию softmax, ALiBi вычитает статическое штрафное значение, пропорциональное расстоянию между двумя токенами. Чем дальше слова друг от друга, тем больше штраф вычитается из их оценки внимания.
Производительность
Метод прост в реализации и очень эффективен. Его главное преимущество — выдающаяся способность к экстраполяции по длине. Модель, обученная с ALiBi на последовательностях из 1 024 токенов, может без труда генерировать связный текст на вдвое больших последовательностях, не «падая».
Тем, кто хочет изучить другие продвинутые техники для быстрой генерации текста и инференса, рекомендуем наше руководство по speculative decoding.
Когда какое позиционное кодирование использовать
Начните с того, что вы строите, и подберите подходящий метод — иногда один, иногда несколько.
- Нужен простой базовый вариант без параметров: синусоидальное (фиксированные формулы, ничего обучать).
- Длина последовательности фиксирована, и важна максимальная точность на конкретном датасете: обучаемое.
- Нужно обрабатывать последовательности длиннее обучающих: RoPE — самый сильный вариант среди техник, способных к экстраполяции.
- Грамматика зависит от расстояния между токенами, а не их абсолютной позиции: относительное или RoPE.
- Вы строите современную универсальную LLM: RoPE.
- Экстраполяция по длине — ваш главный приоритет, и важна максимально простая реализация: ALiBi.
- Нужны преимущества относительных позиций без накладных расходов по памяти и кэшированию: RoPE (относительные коды дают выгоду, но дороже).
Практическая реализация и архитектурные соображения
Чтобы связать теорию с практикой, важно понимать, как интегрировать позиционное кодирование в реальные кодовые базы и учитывать архитектурные ограничения.
Реализация позиционного кодирования в трансформерах
Чтобы добавить позиционные коды в трансформер во фреймворках вроде PyTorch, разработчики обычно создают отдельный модуль. Этот модуль один раз генерирует матрицу кодирования и регистрирует её как буфер, чтобы она случайно не обновлялась во время обратного распространения.
Ниже — стандартная практическая реализация прямого прохода с синусоидальными кодами. Коды один раз вычисляются по формулам синуса и косинуса и не меняются в обучении, поэтому они хранятся в буфере, а не как обучаемые параметры (и потому не увеличивают стоимость обучения).
import torch
import torch.nn as nn
import math
class PositionalEncoding(nn.Module):
def __init__(self, d_model: int, max_len: int = 5000):
super().__init__()
pe = torch.zeros(max_len, d_model)
position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1)
# Calculate the division term for frequencies
div_term = torch.exp(torch.arange(0, d_model, 2).float() * (-math.log(10000.0) / d_model))
# Apply sine to even indices and cosine to odd indices
pe[:, 0::2] = torch.sin(position * div_term)
pe[:, 1::2] = torch.cos(position * div_term)
pe = pe.unsqueeze(0)
# Register as a buffer
self.register_buffer('pe', pe)
def forward(self, x: torch.Tensor) -> torch.Tensor:
# Add positional encoding directly to the input embeddings
seq_len = x.size(1)
x = x + self.pe[:, :seq_len, :]
return x
В __init__ модуль предварительно вычисляет таблицу кодов до max_len позиций: position — это столбец индексов (0, 1, 2, …), а div_term — частоты, равные 1 / 10000^(2i/d_model), так что младшие размерности получают быстрые волны, а старшие — медленные.
Применение sin к чётным размерностям (0::2) и cos к нечётным (1::2) заполняет таблицу. Затем forward делает единственную работу во время выполнения: он срезает таблицу до длины входной последовательности и добавляет её к токен-встраиваниям покомпонентно. Обратите внимание, что модуль предполагает формат с батчем первым: [batch, seq_len, d_model], поэтому forward делает срез по размерности 1.
Позиционный сдвиг и эффект «потерянного посередине»
Непреднамеренным последствием работы с длинными последовательностями является позиционный сдвиг. Он часто проявляется как эффект «потерянного посередине». При обработке больших документов языковые модели лучше запоминают факты с самого начала или самого конца запроса, чем из середины. Это может показаться знакомым, ведь человеческая память работает схожим образом (по крайней мере у меня; не говорите, что я единственный, кто запоминает начало и конец книг лучше остального!).
Считается, что это происходит потому, что механизм внимания перегружается нерелевантным контекстом и естественным образом «якорится» на ранних токенах (которые задают инструкцию) и последних токенах (которые наиболее свежи в памяти). Чтобы ослабить этот сдвиг, разработчики используют продвинутые стратегии чанкинга и системы семантического поиска.
Позиционное кодирование для специализированных доменов
Трансформеры больше не ограничиваются только текстом. Концепция позиционного кодирования быстро адаптируется под разные типы данных в разных доменах.
Для визуальных трансформеров изображения режутся на сетку патчей. Простое одномерное кодирование последовательности не улавливает близость в 2D-пространстве. Поэтому визуальные модели часто используют двумерные обучаемые позиционные встраивания, учитывающие координаты X и Y патча изображения.
Схожие адаптации существуют для непрерывных временных рядов, где специальные коды отслеживают временные дистанции, сезонность и метки времени.
Дальнейшие исследования позиционного кодирования
По мере ускорения гонки за большими контекстными окнами уточнение того, как модели понимают позицию, остаётся крайне активной и важной областью исследований в машинном обучении.
Экстраполяция по длине и расширение контекста
Сегодня пользователи требуют огромные контекстные окна, чтобы обрабатывать целые кодовые базы или серии романов разом. Поскольку обучение моделей с нуля на гигантских длинах слишком дорого, исследователи полагаются на техники расширения контекста.
Методы вроде позиционной интерполяции математически сжимают позиционные координаты гораздо более длинной последовательности в рамки исходной обучающей длины. Адаптивные методы, такие как YaRN, динамически настраивают частоту вращения параметров RoPE, плавно растягивая понимание дистанции моделью.
Трансформеры без явного позиционного кодирования
Удивительно, но некоторые исследования показывают, что явное позиционное кодирование не всегда строго необходимо. В каузальных языковых моделях «только декодер» стандартное каузальное маскирование (механизм, заставляющий токены смотреть только назад) по самой своей природе «подсказывает» информацию о временном порядке.
Это означает, что возможно неявно выучить позиционные правила только из каузальной маски при грамотной настройке температуры и архитектурных корректировках.
Проблемы и направления развития
Ключевая дилемма — устойчивый компромисс между жёсткой адаптацией (оптимизацией под конкретную длину) и безупречной экстраполяцией (способностью обобщать бесконечно).
Перспективные направления активно сосредоточены на мультимодальном кодировании. Создание универсальных позиционных представлений, объединяющих 3D-координаты видео с текстовыми и аудиопотоками, — одна из целей следующего поколения моделей искусственного интеллекта.
Заключение
Позиционное кодирование соединяет параллельную обработку с последовательным пониманием и позволяет создавать модели, способные обрабатывать большие объёмы данных в порядке следования. Мы рассмотрели, как обучаемые и относительные встраивания обеспечивают гибкость, а современные инновации — RoPE и ALiBi — оптимизируют одновременно математическую изящность и вычислительную эффективность.
По мере расширения контекстных окон от нескольких тысяч токенов до миллионов простое математическое действие — сообщить нейросети, где именно что расположено, — останется в самой основе проектирования моделей.
Если хотите углубиться и получить практический опыт, рекомендую записаться на наш трек навыков Developing Large Language Models.
Частые вопросы о позиционном кодировании
Что такое позиционное кодирование в машинном обучении?
Позиционное кодирование — это математический приём, который предоставляет нейронным сетям информацию о порядке данных в последовательности.
Зачем моделям-трансформерам нужно позиционное кодирование?
В отличие от старых рекуррентных сетей, которые обрабатывают данные шаг за шагом, трансформеры обрабатывают всё сразу с помощью механизма самовнимания. Поскольку самовнимание по природе инвариантно к перестановкам, оно относится к вводу как к неупорядоченному «мешку слов». Позиционное кодирование решает это, внедряя последовательные координаты напрямую в данные до того, как модель их обработает.
В чём разница между абсолютным и относительным позиционным кодированием?
Абсолютное позиционное кодирование назначает токену фиксированные координаты на основе его точного индекса в последовательности. Относительное позиционное кодирование игнорирует точное расположение в сетке и вместо этого вычисляет расстояние между двумя взаимодействующими токенами, фокусируясь исключительно на их контекстном смещении.
Что такое Rotary Position Embedding (RoPE)?
RoPE — это широко используемый метод кодирования, который отображает встраивания токенов на комплексную плоскость и поворачивает их на угол, определяемый абсолютной позицией. Когда модель вычисляет оценки внимания, отношение между двумя повернутыми векторами полностью зависит от их относительной дистанции.
Что такое обучаемые позиционные встраивания?
Вместо использования фиксированных математических формул вроде синуса и косинуса обучаемые позиционные встраивания рассматривают пространственные координаты как обучаемые веса. Модель инициализирует пустую матрицу позиций и обновляет эти координаты в ходе обучения, чтобы выучить оптимальные пространственные представления для конкретного датасета.