Токенизация и эмбеддинги в NLP: что спрашивают на собеседованиях
- Введение
- Базовые понятия: токены, словарь, эмбеддинги
- Токенизация по словам
- Токенизация по символам
- Субсловная токенизация
- Причины применения субслов на production-решениях
- BPE и WordPiece: как устроены популярные субсловные токенизаторы
- Обучение BPE-словаря
- Токенизация нового текста
- Особенности BPE на практике
- Типичные вопросы на собеседовании
- Общая идея алгоритма
- Максимизация правдоподобия корпуса
- Обучение словаря
- Токенизация нового текста
- Лайфхаки для собеседований
- SentencePiece и Unigram LM
- Unigram Language Model: top-down подход к построению токенизации на уровне субслов
- Регуляризация токенов на уровне субслов
- Позиционные эмбеддинги: как модель «понимает» порядок токенов
- Абсолютные позиционные эмбеддинги
- Эмбеддинги и полисемия: статические vs контекстуальные представления
- Статические эмбеддинги
- Контекстуальные эмбеддинги
- Заключение
- Полезные ссылки
Введение
В прошлой статье мы разобрали популярные вопросы про attention и трансформеры — то, что происходит «внутри» модели. Но до того, как запрос попадает в self-attention, его нужно преобразовать из сырой строки в последовательность токенов и векторов фиксированной длины. За это отвечают токенизация и получение эмбеддингов.
На собеседованиях часто тему недооценивают: кандидаты уверенно рисуют схему трансформера, но теряются на вопросах про алгоритмы токенизации или позиционные эмбеддинги. В этой части гайда собрали частые вопросы и ответы на них, оформленные под «спойлерами».
Формат тот же: сначала попробуйте ответить сами, а потом изучите разбор и примеры 🙂
Базовые понятия: токены, словарь, эмбеддинги
❓ Что такое токенизация и зачем она нужна?
DL-модели для решения NLP-задач работают с векторами, а не сырыми строками по типу «Мама мыла раму». Токенизация — разбиение входного текста на последовательность токенов: слов (word-level), символов (char-level) или субслов (subword-level). Это первый шаг процесса преобразования текста в вектор. Давайте рассмотрим его на примере фразы: «Мама мыла раму».
Пусть задан словарь V фиксированного размера, например, 50k токенов (подробнее обсудим в следующих пунктах).
- После субсловной токенизации текст может быть преобразован в последовательность токенов из:
["Мама", "▁мы", "ла", "▁раму"]Где:- каждый токен принадлежит заданному словарю;
- символ
▁обозначает пробел / начало слова, что часто используется в SentencePiece-like токенизаторах.
- С помощью словаря каждому токену ставится в соответствие индекс в словаре, то есть целое число в диапазоне
[0, |V|)(где|V|— размер словаря), и последовательность токенов преобразуется в последовательность индексов:
[ 1012, 57, 840, 312 ]
На практике часто смешивают два шага ниже, и оба называют «токенизацией», при этом:
- Сегментация — как строка разделяется на токены;
- Кодирование в id — как каждому токену сопоставляется номер в словаре. Далее в статье под токенизацией мы будем иметь ввиду оба шага.
❓Что такое эмбеддинги токенов?
Эмбеддинг токена — обучаемый вектор фиксированной размерности, сопоставленный токену из словаря, который используется как входное представление токена в модели.
Построение эмбеддингов — второй шаг преобразования текста в вектор.
Базовый вариант построения (embedding lookup):
Внутри модели хранится обучаемая матрица эмбеддингов
Каждому token_id соответствует строка в этой матрице.
Для входной последовательности индексов:
Например, для токена с id = 57 будет взят
Это и есть вход в трансформер до добавления позиционных эмбеддингов.
Здесь речь идёт именно о входных эмбеддингах токенов. Ниже отдельно разберём контекстуальные представления, где вектор токена уже зависит от контекста.

❓ Какие есть подходы к токенизации и почему сейчас используют субслова?
Исторически в NLP пробовали три основных подхода к токенизации: слова, символы и субслова. Современные LLM почти всегда используют именно субсловные токены — это компромисс между размером словаря, длиной последовательности и устойчивостью к OOV (out of vocabulary). Давайте рассмотрим каждый из вариантов.
Токенизация по словам
Текст разбивается по пробелам и знакам препинания, например:
"Я люблю NLP" → ["Я", "люблю", "NLP"]
Плюсы:
- простота реализации;
- удобно интерпретировать: каждый токен соответствует входному слову.
Минусы:
- огромный размер словаря: для русского / английского со всеми формами (времена, падежи и др.) словарь может состоять из миллионов слов;
- OOV (out of vocabulary): множество слов вне словаря превращаются в один токен, которого там нет (например,[UNK]). К примеру, разные формы одного слова (дом, дома, домикам) становятся разными токенами, что увеличивает словарь и делает модель менее устойчивой к OOV;
- малая встречаемость наименее частотных слов: их эмбеддинги хуже обучены.
На практике у подхода есть значимые недостатки: нужны гигантские эмбеддинг-матрицы, и всё равно часто получаем OOV.
Токенизация по символам
Другой вариант: каждый символ (или байт) — отдельный токен, например:
"мама" → ["м", "а", "м", "а"]
"I love NLP" → ["I", " ", "l", "o", "v", "e", " ", "N", "L", "P"]
Плюсы:
- маленький словарь: только символы (или байты);
- отсутствие OOV: любую строку можно представить.
Минусы:
- последовательности сильно длиннее, чем при токенизации на уровне субслов или слов: некоторые вычисления, например, self-attention с квадратичной сложностью по длине последовательности, становятся значительно дороже по сравнению с ситуацией, когда потокенная длина входа меньше;
- символ не несёт семантики: модели нужно «собирать смысл» из длинной цепочки слоёв.
Токенизация на уровне символов или байтов полезна для шумных данных (OCR, опечатки, транслит), но для больших LLM часто проигрывает субсловной токенизации по соотношению качества и вычислительных затрат: последовательности получаются длиннее, значит, инференс и обучение становятся дороже.
Субсловная токенизация
Субслова — компромисс между словами и символами.
Идея: частые слова и морфемы — отдельные токены, редкие слова разбиваются на несколько субслов.
Примеры:
"the" → ["the"]
"unbelievable" → ["un", "believ", "able"]
"красивейший" → ["красив", "ейший"]
"tokenization" → ["token", "ization"]
"неоптимизируемый" → ["не", "оптимизируем", "ый"]
Субсловная токенизация реализуется разными алгоритмами, например, BPE (Byte Pair Encoding), WordPiece, Unigram LM (SentencePiece).
Плюсы субслов:
- можно задать целевой размер словаря |V| (например, 50k);
- риск OOV ниже в типичных субворд-токенизаторах: если слово не найдено целиком, его часто можно разложить на известные субслова, символы или байты;
- уменьшают длину последовательности по сравнению с уровнем символов (на примере «unbelievable»: 12 символов vs 3 субслова) и размер словаря по сравнению с уровнем слов → компромисс по памяти / скорости;
- морфология частично захватывается автоматически (корни, суффиксы, приставки часто становятся токенами).
Поэтому и современные модели (GPT, LLaMA, T5, mBERT и др.) почти всегда используют субсловные токенизаторы (BPE-like или Unigram-like).
Причины применения субслов на production-решениях
- Компромисс по latency и стоимости вычислений:
- уровень символов выдаёт множество токенов, следовательно, повышается время вычисления self-attention, так как сложность квадратично зависит от длины входной последовательности;
- уровень слов выдаёт большой словарь, что приводит к необходимости embedding/LM-head слоёв больших размерностей.
- Универсальность: одним словарем поддерживать разные языки, домены и др.
- Стабильность и воспроизводимость:
- один токенизатор можно переиспользовать между моделями и версиями в виде артефакта: vocab + merges (BPE/WordPiece, например, GPT-2 tokenizer) или sentencepiece.model (SentencePiece/Unigram);
- легко портировать между библиотеками (HuggingFace, TensorRT), потому что формат токенизатора стандартизирован и широко поддержан. А токенизация на уровне слов больше зависит от препроцессинга.
BPE и WordPiece: как устроены популярные субсловные токенизаторы
❓ Как работает алгоритм Byte Pair Encoding (BPE)?
На уровне интуиции BPE многократно склеивает самые частые соседние пары в «новые токены». В итоге получается словарь субслов, который хорошо покрывает частые куски слов, но при этом всегда может «откатиться» до символов / байтов.
BPE автоматически находит полезные морфемоподобные куски (суффиксы, приставки и т.д.) без лингвистических правил. Оригинально такой подход предложили Sennrich et al. для машинного перевода.
Алгоритм работает в два этапа: обучение словаря и токенизация нового текста, начинает с базовых единиц (символы или байты).
Обучение BPE-словаря
- Старт с базового алфавита:
- либо набор символов (буквы, цифры, знаки пунктуации);
- либо байты (0–255), как в GPT-подобных моделях, чтобы поддерживать любые языки и Unicode.
Также до обучения BPE обычно отдельно обрабатывают спецтокены (<bos>, <eos>, <pad>, <unk>, <end_of_text>): их заранее резервируют в словаре и не разбивают на символы / байты, чтобы BPE не пытался мерджить их части.
- Корпус представляется как последовательность базовых единиц, например:
low → l o w
lower → l o w e r
lowest → l o w e s t
- Рассчитываются частоты пар соседних токенов:
(l, o): 3
(o, w): 3
(w, e): 2
(e, r): 1
(e, s): 1
(s, t): 1
- Находится самая частая пара, например,
o w, далее:
- новый токен
owдобавляется в словарь,
- во всём корпусе
o wзаменяется наow.
low→l ow
lower→l ow e r
lowest → l ow e s t
- Шаги 3–4 повторяются, пока выполняются условия:
- текущий размер словаря меньше целевого (например, 50k);
- частоты оставшихся пар больше порога.
В итоге после обучения получается два артефакта:
vocab: отображениеtoken → id;merges: список правил слияния (пары токенов) в порядке мержа.
Токенизация нового текста
Для токенизации нового слова:
- Входное слово разбивается на базовые символы / байты.
- Жадно применяется обратный список мерджей (аналогично могут последовательно использоваться выученные merge-правила в том же порядке, что и при обучении, пока можем склеивать):
- находим самую длинную последовательность в словаре;
- «склеиваем» её в один токен;
- повторяем шаги, пока всё слово не будет представлено токенами.
Пример: в словаре есть
low,lowestнет.
lowest→l o w e s t
знаем мерджи
l+ow→low,e+s→es, получаемlow es t.
Если каких-то кусочков слов нет в словаре — BPE всегда может разбить до букв / байтов: модель никогда не увидит [UNK], а просто получит более длинную последовательность токенов.
Особенности BPE на практике
- GPT-подобные модели часто используют BPE поверх байтов, а не символов, чтобы:
- избежать проблем с Unicode и нормализацией;
- поддержать смешанные алфавиты, эмодзи без специальных костылей.
- Для мультиязычных моделей BPE даёт кросс-языковые субслова (например, общие латинские корни), что помогает переносить знания между языками.
Примеры моделей, использующих BPE-подобные схемы: GPT-2/3, RoBERTa, OpenAI CLIP.
Типичные вопросы на собеседовании
- «BPE просто объединяет самые частые символы» — не верно, объединяются пары токенов, и после первых итераций токены — уже не символы.
- «BPE даёт фиксированное разбиение?» — да, но только при фиксированном словаре и списке мерджей. Если переобучать на другом корпусе, токенизация может заметно поменяться.
❓ Как работает WordPiece и чем отличается от BPE?
Есть и другой популярный алгоритм субсловной токенизации — Wordpiece, который активно применялся в Google NMT и стал основой токенизации в BERT.
Общая идея алгоритма
- стартуем с небольшого базового словаря: обычно это отдельные символы и специальные токены для продолжения слов (например, в WordPiece для BERT используются варианты с префиксом ##);
- новые субслова итеративно добавляются в словарь;
- критерий выбора следующего субслова связан не просто с частотой, а с тем, насколько оно улучшает описание корпуса (максимизация правдоподобия корпуса или его аппроксимация)
Максимизация правдоподобия корпуса
Пусть есть корпус C , текущий словарь субворд-токенов V , и каждое слово / строка разбивается на последовательность subword-токенов \(u_1\), ..., \(u_k\) .
WordPiece рассматривает модель, которая задаёт вероятность токенизированной последовательности через вероятности субслов (или их комбинаций в простой LM).
Тогда качество словаря можно оценивать через лог-правдоподобие корпуса:
где \(C\) — корпус, а
Идея обучения словаря следующая:
- на каждом шаге рассматриваем кандидатов на добавление нового subword;
- выбираем тот, который даёт наибольший прирост
L(V)(или сильнее всего уменьшает-log p(corpus)).
Обучение словаря
- Пусть есть текущий набор субслов V:
- спецтокены (
[PAD],[UNK], …); - символы (или символы + служебные префиксы для продолжения слова);
- часто отдельно кодируют «начало слова» / «продолжение слова» (например, в BERT continuation-токены пишутся с
##).
- спецтокены (
- Токенизируем корпус текущим словарём: С текущим словарём V прогоняем корпус и получаем текущую сегментацию (разбиение на субслова). На этом шаге получаются:
- частоты токенов;
- частоты соседних пар токенов.
- Собираются кандидаты на добавление: кандидаты — пары соседних токенов (a, b), которые можно склеить в новый токен ab.
- Выбирается токен, который даёт наибольший прирост правдоподобия корпуса
L(V)(или сильнее всего уменьшает\(-log\ p(corpus)\) ).
💡 В инженерных реализациях это часто заменяют на приближения и вычисления прокси, так как пересчитывать полное правдоподобие корпуса для каждого кандидата слишком дорого.
- Лучший кандидат добавляется в словарь, после чего пересчитывается токенизация корпуса.
- Шаги 2-5 повторяются до критерия остановки:
- достигли целевого размера словаря;
- прирост по целевой функции стал слишком маленьким (ниже порога);
- разумные кандидаты на добавление закончились.
На собеседовании обычно хотят услышать не просто: «Это другой токенизатор», а именно различие в критерии обучения словаря: BPE выбирает по частоте, а WordPiece — по улучшению качества описания корпуса (или его аппроксимации).
Токенизация нового текста
Обычно используется жадный по длине подход:
- идём слева направо по строке;
- на каждом шаге берётся самый длинный подстроковый токен в словаре;
- если ничего не нашлось — возвращается
[UNK].
В BERT дополнительно используется префикс ## для «хвостов» слов:
playing→play,##ing;unbelievable→un,##believ,##able.
Это помогает модели различать начало слова и продолжение, а также упрощает восстановление текста.
WordPiece применялся в Google NMT (ранние системы) [2], BERT [18] и ряде encoder-only моделей.
Лайфхаки для собеседований
Частый вопрос: «В чём разница между BPE и WordPiece?» — хочется услышать именно разницу в критерии обучения словаря, а не только «разные реализации».
Главная разница между BPE и WordPiece — критерий, по которому выбираются новые токены при построении словаря.
- BPE жадно объединяет пары по частоте;
- WordPiece жадно выбирает добавление токена так, чтобы улучшить правдоподобие корпуса (или его практичную аппроксимацию).
SentencePiece и Unigram LM
❓ Что такое SentencePiece и как работает Unigram токенизация?
SentencePiece [5] — библиотека от Google для обучения субсловных токенизаторов, в которой реализованы алгоритмы BPE и Unigram LM. Ключевая идея алгоритмов, реализованных в библиотеке, — работать с сырым текстом без предварительного разбиения по пробелам.
В классическом пайплайне токенизации тест сначала делится по пробелам на слова, а затем к ним применяется BPE / WordPiece. В SentencePiece пробел считается таким же символом, как остальные, и словарь с субсловами обучается сразу поверх строки.
Технические детали:
- вход для алгоритмов из SentencePiece — просто строка в Unicode;
- пробел преобразуется в спецсимвол (обычно
▁), который тоже может входить в субслова, например,▁Hello,▁world,▁New,York; - механизм универсален: работает как для языков с пробелами (английский, русский, испанский), так и без них (японский, китайский).
Unigram Language Model: top-down подход к построению токенизации на уровне субслов
BPE и WordPiece работают по принципу bottom-up — идут от символов к более длинным кускам.
Unigram LM [7] работает по обратному принципу — реализует подход top-down.
На уровне интуиции Unigram LM оставляет в словаре только те субслова, которые дают заметный вклад в правдоподобие корпуса.
Алгоритм:
- Стартуем с большого словаря кандидатов (десятки / сотни тысяч субслов). В практических реализациях кандидаты собираются из корпуса эвристически: частые подстроки (до некоторой длины), n-граммы, куски после первичной нормализации и т.п. (десятки / сотни тысяч).
- Каждому субслову u приписывается вероятность p(u).
- Для заданного слова / предложения любая сегментация \((u_1, \dots, u_n)\) имеет вероятность: \(p(u_1, \dots, u_n) = \prod_i p(u_i)\).
- Вероятность предложения — сумма вероятностей всех возможных сегментаций (на практике используют приближенные алгоритмы — Viterbi / Forward [6]).
- Максимизируется правдоподобие корпуса по параметрам p(u) при помощи EM-подобного алгоритма [8]:
- На E-шаге для каждого слова оценивается, какие варианты разбиения на субслова наиболее вероятны при текущих вероятностях \(p(u)\). Из этого получаем ожидаемое число использований каждого субслова в корпусе.На M-шаге вероятности субслов \(p(u)\) обновляются так, чтобы субслова, которые часто используются в вероятных разбиениях, получали больший вес.
- После этого выполняется pruning: удаляется часть токенов с низким вкладом в правдоподобие и повторяется 2–5 итераций. Остановка, когда достигнут целевой размер словаря
|V|, и / или улучшение правдоподобия стало малым, или достигнут лимит итераций.
SentencePiece и Unigram LM подробно описаны в работе Kudo & Richardson [3].
Регуляризация токенов на уровне субслов
Благодаря устройству алгоритма Unigram LM даёт распределение по сегментациям, а не одно жадное разбиение.
Например, internationalization можно разбить как:
international,ization;inter,national,ization;intern,ation,al,ization.
Unigram LM даёт этим вариантам разные вероятности.
На практике есть два режима:
- на инференсе или в базовом варианте обучения можно брать наиболее вероятную сегментацию;
- в режиме субворд регуляризации на обучении можно не фиксировать лучшую сегментацию, а сэмплировать один из допустимых вариантов пропорционально его вероятности. В таком случае модель на разных шагах видит слово в разных разбиениях, что и работает как регуляризация.
Unigram / SentencePiece используется в T5 [9], ALBERT [10], некоторых версиях BART / XLNet [11] и многих продовых системах от Google и не только.
Позиционные эмбеддинги: как модель «понимает» порядок токенов
❓ Что такое позиционные эмбеддинги в трансформерах и зачем они нужны?
Self-attention перестановочно-инвариантен: если для его входа поменять токены местами, то без позиционной информации он увидит тот же набор векторов и не поймёт, где было «первое слово», а где — «последнее».
Поэтому в трансформерах нужно добавлять информацию о позиции в представления токенов. Классический подход — добавить позиционный вектор к каждому эмбеддингу:
\(x_i = e_i + p_i\)
где:
\(e_i\) — эмбеддинг для i-го токена \(t_i\);
\(p_i\) — позиционный вектор для i-го эмбеддинга;
\(x_i\) — вход для self-attention слоя.
Позиционный вектор может быть:
- фиксированным (синусы / косинусы, как в оригинальном Transformer);
- обучаемым (таблица параметров);
- относительным (RoPE, Shaw-style relative positions и др.).
Без позиции модель бы не различала порядок слов, не понимала грамматику и не могла учить длинные зависимости.
Позиции токена — «пространственные координаты» токена в предложении.
💡Важно отметить: есть работы, где модели умеют работать и без явных позиционных эмбеддингов (или их можно частично убрать после предобучения), но в типичном пайплайне позиционный сигнал сильно помогает со сходимостью и качеством. Например, встречаются подходы «No Position Encoding (NoPE)» и работы, где позиционные эмбеддинги можно удалять после предобучения с короткой донастройкой (идея похожа на «drop positional embeddings») [12].

❓ Какие бывают способы позиционного кодирования и как они работают?
Позиции можно разделить на два класса:
- Абсолютные, например, «токен t стоит на позиции i».
- Относительные, например, «токен j находится на смещении (j − i) относительно токена i».
Абсолютные позиционные эмбеддинги
- Фиксированные синусоидальные (как в оригинальном Transformer)
Интуиция:
- разные частоты синусов / косинусов позволяют однозначно кодировать позицию;
- разность позиций можно выразить через линейную комбинацию этих векторов ⇒ модель может косвенно учить и относительные сдвиги;
- синусы / косинусы легко считать для любых
pos, поэтому схема формально определена и для последовательностей длинее, чем в обучении;
В классической статье «Attention Is All You Need» [0] предлагают задавать позиции аналитически:
\(\text{PE}(pos, 2i+1) = \cos\Big(\frac{pos}{10000^{2i / d_{\text{model}}}}\Big)\)
Где:
pos— индекс позиции (0, 1, 2, …);i— индекс компоненты эмбеддинга (номер измерения вектора);\(d_{model}\) — размерность эмбеддингов.

Плюсы:
- не нужно хранить таблицу max_len × d_model: позиция считается «по формуле»;
- формула определена для любых
pos.
Минусы:
- позиционный сигнал фиксирован зарнее: модель не может адаптировать его форму под конкретные данные и задачу. Поэтому обучаемые позиционные эмбеддинги могут лучше подстраиваться под распределение обучающего корпуса.
- Обучаемые абсолютные эмбеддинги
Другой вариант — завести отдельную матрицу \(P∈R^{max_{len}×d_{model}}\), где каждая строка — обучаемый вектор для позиции pos.
Такое позиционирование используется, например, в BERT: к токен-эмбеддингу добавляется позиционный + сегмент-эмбеддинг (token type) — дополнительный вектор, который отличает токены из сегмента A и сегмента B. Например, в задачах на пары предложений: первое предложение помечается как сегмент A, второе — как сегмент B.
Плюсы:
- модель сама учит удобные представления позиций.
Минусы:
- есть фиксированный
max_len(нужно придумывать костыли длинных последовательностей больше max_len).
Относительные позиционные эмбеддинги
Идея: учим представления через смещение j − i между токенами i и j.
Один из популярных подходов (Shaw-style relative positions предложен в Shaw et al. 2018 и использован в последующих работах) — в формуле attention-логитов добавляется слагаемое, зависимое от относительного сдвига \((i − j)\):
Плюсы:
- проще для длины больше обучающей: важна разница позиций, а не абсолютный номер.
Минусы:
- реализация сложнее, чем у абсолютных позиционных эмбеддингов;
- в некоторых вариантах нужно отдельно ограничивать диапазон относительных смещений или аккуратно проектировать bias / эмбеддинг для больших расстояний.
RoPE (Rotary Position Embedding)
RoPE (Rotary Position Embedding) — один из самых популярных вариантов относительного кодирования, который используется в LLaMA-подобных моделях и многих современных LLM.
Идея:
- разбиваем вектора \(q\) и \(k\) на пары координат и интерпретируем их как комплексные числа — поворачиваем на угол, зависящий от позиции;
- каждую пару умножаем на
\(e^{i\theta(pos)}\) — это поворот на угол, зависящий от позиции (поворачиваем вектора в пространстве на угол, зависящий отpos); - после скалярное произведение \(⟨q, k⟩\) эффективно кодирует разность позиций \((i − j)\).
RoPE применяется для векторов \(q\) и \(k\) прямо перед вычислением \(QK^\top\) и не требует отдельной таблицы max_len × d_model. Для расширения контекстного окна у RoPE-моделей используют отдельные техники масштабирования и интерполяции, например, YaRN и родственные NTK-aware подходы [22], [23].

Существуют и другие методы:
- ALiBi [19]: добавляет к attention-логитам линейный штраф, зависящий от расстояния, чем дальше токен, тем больше штраф;
- гибридные схемы (например, DeBERTa [20] / TUPE[21]): часть позиционного сигнала задаётся явно, а часть — через относительные смещения в attention.
Эмбеддинги и полисемия: статические vs контекстуальные представления
❓Чем отличаются статические и контекстуальные эмбеддинги? Как модели учитывают многозначность (полисемию) слов?
Статические эмбеддинги
В классических подходах (word2vec, GloVe, fastText и др.) каждому токену из словаря сопоставляется один вектор эмбединга \(e(token)\). Он обучается на большом корпусе по принципу распределительной гипотезы (distributional hypothesis): «слова, которые встречаются в похожих контекстах, должны иметь похожие эмбеддинги».
Плюсы:
- простота работы алгоритма: независимо от контекста получаем вектор по слову ;
- удобно использовать как готовые признаки;
- fastText за счёт субсловных n-грамм частично умеет обрабатывать морфологию и редкие слова.
Минусы:
- полисемия: все значения слова
bank(берег реки / банк) «схлопываются» в один вектор. Следовательно, модель на входе получает «среднее» по всем смыслам слов. В downstream-задачах это может мешать: ближайшие соседи вектора будут смесью разных смыслов.
Контекстуальные эмбеддинги
Контекстуальные представления (ELMo, BERT, GPT-подобные) зависят от контекста и строятся следующим образом:
- Модель читает последовательность текста целиком;
- На каждом слое \(\ell\) модели токен \(i\) имеет своё скрытое состояние \(h_i^{\ell}\) ;
- В качестве контекстуального представления токена может браться его скрытое состояние на верхнем слое \(L\) или агрегация по нескольким слоям (а не исходный lookup-эмбеддинг) \(h_i^{(L)} = f(t_1, \dots, t_n)_i\) где
h_i— скрытое состояние i-го токена после моделиf(трансформер / biLM и др.);
Например, есть 2 предложения:
- «He sat on the bank of the river»;
- «He took a loan from the bank».
В статических эмбеддингах оба bank будут представлены одним и тем же эмбеддингом.
В контекстуальных: в первом случае вектор будет ближе к «river», «shore», а во втором — к «loan», «money», «credit» и др.
ELMo показал первый массовый успех таких представлений поверх BiLSTM LM, а BERT/LLM — уже на трансформерах.
Есть практический нюанс: современные LLM работают на субсловных токенах, а не на словах.
Важно отметить: под многозначностью часть имеют в виду уровень слов. Даже при субсловной токенизации контекстуальные эмбеддинги по-прежнему решают проблему полисемии:
- слово может разбираться на 2–3 токена (
play,##ing), а модель выдаёт скрытые состояния для каждого субслова; - для получения эмбеддинга слова можно взять скрытое состояние первого субслова или усреднить / сконкатенировать несколько субслов. В итоге каждый токен (или группа токенов слова) получает свой вектор в зависимости от контекста.
Заключение
Итак, в этой статье мы разобрали ключевые темы вокруг токенизации и эмбеддингов, которые часто затрагиваются на собеседованиях:
- зачем нужна токенизация и какие бывают уровни (слова / символы / субслова);
- как работают BPE, WordPiece, SentencePiece и Unigram LM;
- зачем нужны позиционные эмбеддинги в трансформерах и какие они бывают;
- в чём разница между статическими и контекстуальными эмбеддингами, и как модели справляются с многозначностью слов.
Вместе с первой частью (гайд по attention и трансформерам) это даёт хороший бенефит для подготовки к интервью на позиции ML/DL/NLP-инженера: от представления текста до его обработки внутри трансформеров. Пользуйтесь! 🙂
Полезные ссылки
Субсловная токенизация
[6] Viterbi algorithm , Forward algorithm
[7] Subword Regularization: Improving Neural Network Translation Models with Multiple Subword Candidates
[8] Expectation–maximization algorithm
[9] T5: Exploring the Limits of Transfer Learning with a Unified Text-to-Text Transformer
[10] ALBERT: A Lite BERT for Self-supervised Learning of Language Representations
[12] Transformer Language Models without Positional Encodings Still Learn Positional Information
Позиционные эмбеддинги
[13] Ashish Vaswani et al. Attention Is All You Need.
[14] Peter Shaw, Jakob Uszkoreit, Ashish Vaswani. Self-Attention with Relative Position Representations.
[15] Jianlin Su et al. RoFormer: Enhanced Transformer with Rotary Position Embedding.
[16] Ofir Press, Noah A. Smith. Train Short, Test Long: Attention with Linear Biases.
Контекстуальные эмбеддинги
[17] Matthew E. Peters et al. Deep Contextualized Word Representations (ELMo).
[19] ALiBi: Train Short, Test Long: Attention with Linear Biases Enables Input Length Extrapolation
[20] DeBERTa: Decoding-enhanced BERT with Disentangled Attention
[21] TUPE: Rethinking Positional Encoding in Language Pre-training
[22] Bowen Peng et al. YaRN: Efficient Context Window Extension of Large Language Models.
[23] Yikai Zhang et al. Extending LLMs’ Context Window with 100 Samples.
Практика
[24] Hugging Face LLM Course: Tokenization

