Позиционная кодировка



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



Если вы вспомните, как работает внимание, то увидите, что там никак не участвуют позиции токенов. Но языковые модели должны как-то их понимать, иначе при предсказании следующего токена контекст превратится в bag-of-tokens, что критично повлияет на качество предсказания. Ведь да? 😁



Конкретные задачи, где позиции важны:

- Подсчёт токенов

- Копирование кусков контекста

- Арифметика и код



Мини-квиз для читателя (перед открытием спойлера нужно ответить на все вопросы в голове)

- Может ли BERT хорошо работать на стандартных задачах (классификация текста) без позиционной кодировки? Нет, не может

- Может ли GPT хорошо работать на стандартных задачах (генерация текста) без позиционной кодировки? Да, может

- Может ли декодер с RoPE, обученный на контексте в 1024 токена, хорошо генерировать 2048 токенов? Может только после экстраполяции/интерполяции





Attention Is All You Need

Статья: https://arxiv.org/abs/1706.03762



В оригинальной статье о трансформерах с обычными эмбеддингам токенов перед первым слоем складываются позиционные эмбеддинги. При этом предлагается 2 типа позиционных эмбеддингов: синусоидальные или обучаемые. В случае обучаемых всё понятно и без лишних объяснений, а в случае синусоидальных работает всё так: мы берём пары фичей из эмбеддинга и каждой такой паре сопоставляем определённую частоту колебаний. Первое число пары - синус для данной позиции, второе - косинус. И так для каждой позиции токенов получаем разные чиселки на окружности.



Например, предположим, что у нас 4 чиселки в эмбеддинге, 1 секунда = 1 позиция, у первой пары частота 0.5 Гц, у второй - 0.25 Гц. Тогда на нулевой позиции будет такой эмбеддинг: [0, 1, 0, 1], на первой позиции: [0, -1, 1, 0]. Потому что для первая пара проходит полоборота за шаг, вторая - четверть. Формула, по которой расчитывается частота для разных пар: (10000^(-2i/d)) / 2π, где i - номер пары.



Почему 10000? Во-первых, кодировки любых позиций не повторяются. Во-вторых, так косинусное расстояние между двумя синусоидальным позиционными эмбеддингами монотонно увеличивается по мере наращивания дистанции.



Дополнительный материал: ссылка





RoFormer: Enhanced Transformer with Rotary Position Embedding

Статья: https://arxiv.org/abs/2104.09864



Есть свойство, которое нам хотелось бы получить: расстояние между 5 и 10 токеном должно быть таким же, как если бы мы поставили эти же токены на 10 и 15 позиции вместо 5 и 10. То есть оно не должно зависить от абсолютной позиции. Для синусоидальных эмбеддингов это не выполняется.



Чтобы это выполнялось, делаем так: каждую пару чиселок в уже готовых эмебеддингах токенов вращаем на плоскости матрицей поворота. Углы всё те же, что и были в синусоидальных эмбеддингах. В статье есть доказательство того, что желаемое свойство так действительно выполняется. А ещё мы делаем это в каждом слое.



Дополнительные материалы: раз, два, три





Transformer Language Models without Positional Encodings Still Learn Positional Information

Статья: https://arxiv.org/abs/2203.16634



А нужны ли нам вообще позиционные эмбеддинги? 😐

Вот оказывыется нет, для авторегрессионных декодеров никакие эмбеддинги вообще не нужны, модель сама выучивается их считать. Это ещё и легко проверяется: учим языковую модель без позиционных эмбеддингов и учим мини-сетку предсказывать позицию токена из активаций. В первых слоях ничего толкового не предскажется, а вот дальше информация агрегируется. Более того, она не только агрегируется, но и используется - если перемешать контекстные токены, финальный токен предсказывается гораздо хуже. Но для энкодеров это не работает, ключ к выучиванию - декодерная маска внимания.



Это всё подтверждается в нескольких последующих статьях: раз, два.



Так почему все до сих пор используют RoPE? Ну, NoPE (no positional embeddings) принципиально работает, но чуть хуже. Это видно и в этой статье.



Расширения RoPE будут дальше