Прямой ответ
Токенизация — разбиение текста на единицы (токены), которыми оперирует модель: части слов, целые слова или отдельные символы. Почти все современные модели используют субсловные алгоритмы — BPE (byte-pair encoding) или SentencePiece. Ключевой практический факт: токен ≠ символ и ≠ слово.
Ориентиры, которые стоит запомнить:
- для английского текста один токен ≈ 4 символа ≈ 0.75 слова;
- для русского текста расход выше: кириллица часто кодируется меньшим числом байт на токен, поэтому одно слово может занимать 2–3 токена;
- код расходует больше обычного текста из-за обилия пунктуации и отступов;
- редкие слова, опечатки и спецсимволы разбиваются на много мелких токенов.
Следствия для практики:
- Оценка «на глаз» по символам приводит к ошибкам на 30–60 %. Для лимитов контекста и расчёта стоимости нужен точный подсчёт токенизатором.
- Токенизатор привязан к модели. Счётчик от одной модели даёт неверный результат для другой: словари различаются.
- Служебные токены тоже считаются. Разделители ролей и шаблон чата добавляют десятки токенов на каждый запрос.
Как считать точно:
from transformers import AutoTokenizer
tok = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-7B-Instruct")
def count_tokens(text: str) -> int:
return len(tok.encode(text))
for s in ["Hello world", "Привет, мир", "def f(x): return x * 2"]:
print(repr(s), count_tokens(s), tok.tokenize(s))
Быстрая оценка без токенизатора (для прикидки, не для лимитов): len(text) / 3.5 для русского, len(text) / 4 для английского.
Практика: где токенизация влияет на решения
1. Планирование контекстного окна. Точный подсчёт позволяет уложить в лимит историю и данные, а не обрезать их «на удачу». Управление бюджетом — в статье про контекстное окно.
2. Расчёт стоимости. Для платных API цена считается по токенам входа и выхода. Для локального запуска стоимость выражается во времени и памяти, но зависимость та же: больше токенов — дольше генерация.
3. Оценка пропускной способности. Планирование нагрузки для LLM-сервиса невозможно без среднего числа токенов на запрос. Как переводить это в ресурсы — в статье про capacity planning.
4. Оптимизация промпта. Токенизация объясняет, почему сжатие формулировок экономит заметно больше, чем кажется: короткие частотные слова кодируются одним токеном, а длинные редкие — несколькими.
Проверка расходов в приложении:
def report(messages, tok):
total = 0
for m in messages:
n = len(tok.apply_chat_template([m], tokenize=True))
total += n
print(f"{m['role']:<9} {n:>5} токенов")
print("итого:", total)
Рекомендации:
- Логируйте токены, а не символы. Метрика
prompt_tokensиcompletion_tokensна запрос даёт картину расходов и помогает находить аномальные сценарии. - Учитывайте шаблон чата.
apply_chat_templateпоказывает реальный расход вместе со служебными токенами; ручная склейка строк его недооценивает. - Проверяйте поведение на кириллице и коде. Если продукт работает с русским текстом и исходниками, тестируйте именно их: оценки «по английскому образцу» занижают расход.
- Не токенизируйте «в лоб» большие документы. Для длинных текстов сначала делите на фрагменты, а затем считайте; иначе пиковое потребление памяти на кодирование станет неприятным сюрпризом.
Практический сценарий: запросы обрываются на 80 % лимита
Контекст: сервис суммаризации документов; при документе «на 6000 символов» ответ обрывается, хотя окно модели 8192 токена.
- Диагностика. Считаем токены реальным токенизатором: документ на 6000 кириллических символов занимает 4100 токенов, системный промпт — 700, шаблон чата и история — 900. Итого 5700, плюс запрошенный
max_tokens=3000— это 8700, то есть больше окна. - Ошибка в коде. Оценка длины шла по символам (
len(text) / 4), поэтому приложение считало вход равным 1500 токенам и не обрезало документ. - Исправление. Переходим на точный подсчёт токенизатором; вводим явный бюджет: система + данные + история ≤ 5500, резерв под ответ 1500, запас 500. Документы длиннее бюджета делятся на части с последующим объединением выжимок.
- Проверка. На наборе из 40 документов обрывы исчезают; метрика доли запросов у границы лимита падает с 35 % до 2 %.
- Профилактика. Добавляем юнит-тест на подсчёт токенов для кириллического текста и кода, чтобы возврат к оценке по символам был заметен сразу.
Вывод: точный подсчёт токенов — это не микрооптимизация, а условие корректности: от него зависят обрезка данных, стоимость и отсутствие обрывов ответа.
FAQ
Можно ли уменьшить расход токенов на русском тексте? Частично: выбирать модели с большим словарём и хорошей поддержкой кириллицы, избегать редких аббревиатур и опечаток, не передавать текст в верхнем регистре целиком (регистр влияет на разбиение). Существенно сократить расход помогает сжатие самих формулировок.
Почему код расходует больше токенов, чем проза? В коде много редких последовательностей: скобки, отступы, имена переменных, специальные символы. Они разбиваются на мелкие токены, поэтому страница кода часто «весит» больше страницы текста.
Нужно ли считать токены для локальной модели без оплаты API? Да: токены определяют время генерации, объём KV-кэша и допустимый параллелизм. На локальном железе это прямой компромисс с памятью, особенно при квантованных моделях — см. квантование.
Как токенизация связана с качеством ответов? Косвенно, но заметно: модели хуже работают с языками, которые представлены в словаре слабо, потому что текст распадается на короткие фрагменты без цельного смысла. При выборе модели под русский язык стоит проверять не только бенчмарки, но и то, как токенизатор разбивает типичные для вас тексты.
Источники: Transformers docs (tokenizer summary), SentencePiece, BPE paper — ссылки в шапке.