Токенизация: слова, символы и подслова (BPE)
Токенизация — самый первый шаг любой NLP-системы: превратить сплошной текст в список единиц, с которыми будет работать модель.
Токен — минимальная единица текста, которую обрабатывает модель: слово, символ или кусок слова. Токенизация — процесс разбиения текста на токены.
Зачем вообще разбивать текст
Модель не работает со сплошной строкой — ей нужен список единиц, которые можно пронумеровать и превратить в числа. От того, что мы считаем «единицей», зависит размер словаря, способность работать с редкими словами и качество модели. Есть три основных подхода.
Токенизация по словам
Самый интуитивный способ: разбить по пробелам и пунктуации. Каждое слово — токен.
import re
text = "NLP — это интересно! Очень интересно, правда?"
# вытаскиваем последовательности букв/цифр как слова
tokens = re.findall(r"\w+", text.lower())
print(tokens)
print("Токенов:", len(tokens))
Вывод:
['nlp', 'это', 'интересно', 'очень', 'интересно', 'правда'] Токенов: 6
Плюс: токены осмысленны, их немного на текст. Минус: словарь огромен (все формы всех слов), а незнакомое слово вообще не попадает в словарь — та самая проблема out-of-vocabulary.
Токенизация по символам
Другая крайность — каждый символ отдельный токен. Словарь крошечный (буквы, цифры, знаки), незнакомых символов почти не бывает.
text = "привет"
tokens = list(text)
print(tokens)
print("Размер словаря-алфавита очень мал, зато токенов на слово много:", len(tokens))
Вывод:
['п', 'р', 'и', 'в', 'е', 'т'] Размер словаря-алфавита очень мал, зато токенов на слово много: 6
Плюс: нет проблемы незнакомых слов, словарь минимален. Минус: последовательности становятся очень длинными, а отдельный символ почти не несёт смысла — модели труднее.
Золотая середина: подслова и BPE
Современные модели берут лучшее из двух миров — режут текст на подслова. Частые слова остаются целыми («кот», «и»), а редкие распадаются на куски («токенизатор» → «токен» + «иза» + «тор»). Так словарь остаётся управляемым, а незнакомое слово всегда можно собрать из кусочков.
Самый известный алгоритм — BPE (Byte Pair Encoding). Идея жадно простая: начинаем с отдельных символов и многократно склеиваем самую частую соседнюю пару в один новый токен. Покажем один шаг BPE на игрушечном корпусе.
from collections import Counter
# слова уже разбиты на символы (· — конец слова)
corpus = ["н и з к о ·", "н и з к и й ·", "н и з ·"]
pairs = Counter()
for word in corpus:
symbols = word.split()
for a, b in zip(symbols, symbols[1:]):
pairs[(a, b)] += 1
best = pairs.most_common(1)[0]
print("Частоты пар:", dict(pairs))
print("Самая частая пара:", best[0], "встретилась", best[1], "раза")
print("BPE склеит её в новый токен:", "".join(best[0]))
Вывод:
Частоты пар: {('н', 'и'): 3, ('и', 'з'): 3, ('з', 'к'): 2, ('к', 'о'): 1, ('о', '·'): 1, ('к', 'и'): 1, ('и', 'й'): 1, ('й', '·'): 1, ('з', '·'): 1}
Самая частая пара: ('н', 'и') встретилась 3 раза
BPE склеит её в новый токен: ни
Повторяя этот шаг тысячи раз на большом корпусе, BPE сам выучивает удобный словарь подслов: частые корни и приставки становятся целыми токенами, а редкое слово всегда разложится на известные куски. Именно так токенизируют текст GPT, BERT и почти все современные модели.
Сравнение подходов
| Подход | Размер словаря | Длина последовательности | Незнакомые слова |
| По словам | огромный | короткая | проблема (OOV) |
| По символам | крошечный | очень длинная | нет проблемы |
| По подсловам (BPE) | средний | средняя | собирается из кусков |
Итог
- Токенизация превращает текст в список токенов — единиц для модели.
- По словам: осмысленно, но огромный словарь и проблема незнакомых слов.
- По символам: нет OOV, но очень длинные последовательности.
- BPE/подслова: компромисс — частые слова целые, редкие из кусочков; стандарт современных моделей.