Как языковая модель видит текст

Модель не читает ни буквы, ни слова — она работает с токенами. Разбираемся, откуда они берутся и почему русский текст обычно обходится дороже английского.

2 минуты чтения≈ 1 010 токенов#основы#токенизация

Когда вы отправляете модели запрос, первым делом его разрезают на куски и заменяют каждый кусок числом. Эти куски называются токенами, а программа, которая режет, — токенизатором. Всё, что модель «знает» о вашем тексте, она знает через последовательность этих чисел.

Токен — это не слово и не буква. Частое слово может целиком уместиться в один токен, редкое — рассыпаться на три-четыре фрагмента, а пробел обычно прилипает к началу следующего слова. Словосочетание «контекстное окно», например, могло бы разрезаться так: «кон», «текст», «ное», « ок», «но».

Откуда берётся словарь #

Большинство современных токенизаторов строят словарь алгоритмом BPE (byte pair encoding) или его родственниками. Идея простая:

  1. Начинаем с минимальных единиц — байтов или символов.
  2. Считаем, какая пара соседних единиц чаще всего встречается в обучающем корпусе.
  3. Сливаем эту пару в новую единицу и добавляем её в словарь.
  4. Повторяем, пока словарь не достигнет нужного размера — обычно десятков или сотен тысяч элементов.

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

Почему русский дороже #

Словарь отражает корпус, на котором его учили. Если в корпусе преобладал английский, частые английские слова получают собственные токены, а русские чаще собираются из нескольких частей. Кроме того, в UTF-8 каждая кириллическая буква занимает два байта против одного у латиницы, так что при нехватке готовых фрагментов разбиение получается ещё мельче.

В новых токенизаторах с большими многоязычными словарями разрыв заметно меньше, но полностью он обычно не исчезает. Проверить это на своих текстах несложно:

import tiktoken

enc = tiktoken.get_encoding("o200k_base")

for text in ["context window", "контекстное окно"]:
    ids = enc.encode(text)
    pieces = [enc.decode([i]) for i in ids]
    print(len(ids), pieces)

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

Что из этого следует на практике #

ЧтоПочему это связано с токенами
Цена запросаПровайдеры считают входные и выходные токены, а не символы
Лимит контекстаОкно измеряется в токенах, и один и тот же документ на разных языках занимает разный объём
Скорость ответаМодель генерирует текст по одному токену за шаг
Посимвольные задачиМодель не видит отдельных букв внутри токена, поэтому считать буквы или переворачивать слова ей трудно

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

Последняя строка таблицы объясняет многие «глупые» ошибки моделей. Вопрос «сколько букв р в слове» кажется тривиальным, но модель получает не буквы, а пару чисел, за которыми эти буквы спрятаны. Если задача требует работы с символами, надёжнее попросить модель написать и выполнить код. Например, так:

Система

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

Пользователь

Сколько раз буква «р» встречается в слове «прерогатива»?

Модель

Посчитаю кодом, чтобы не ошибиться: "прерогатива".count("р") возвращает 2.

Ответ: буква «р» встречается два раза.