Все статьи
Артемий Мазаев·· 7 мин чтения

Токенизация: почему русский текст дороже английского 🔤💸

Разбираю BPE: как строится словарь субслов и почему кириллица режется на больше токенов, чем латиница. С токенизатором OpenAI и тренажёром BPE в браузере.

Токенизация: почему русский текст дороже английского 🔤💸

LLM не читает буквы и не читает слова. Она читает токены — куски слов, которые ей выдал токенизатор ещё до того, как текст попал в модель. И платишь ты тоже за токены, не за символы: OpenAI, Anthropic, любой другой провайдер выставляет счёт по счётчику токенов на входе и выходе.

Проблема в том, что этот счётчик не одинаковый для всех языков. Один и тот же смысл, сказанный по-русски, почти всегда превращается в больше токенов, чем та же мысль по-английски. Не потому что русский язык «сложнее», а потому что токенизатор учился считать в основном на английском тексте. Дальше разберём, почему так вышло, и дам два интерактивных инструмента: проверишь не на слово, а на своих примерах.

Что вообще токенизируем

Самый очевидный вариант — резать текст по словам. Не работает: словарь выйдет либо неподъёмно огромным (в языке миллионы словоформ, у русского с падежами и склонениями тем более), либо неполным, и любое незнакомое слово, опечатка или название модели превратится в <UNK>.

Другая крайность: резать по символам. Словарь маленький, незнакомых слов в принципе не бывает. Но последовательность становится в разы длиннее, а модели тяжелее держать в голове связи между далеко разнесёнными символами.

Компромисс, который победил везде — subword-токенизация: словарь из кусков слов, где частые слова остаются целыми токенами (the, и, модель), а редкие режутся на кусочки (token + ization, токен + изация). Практически все современные LLM используют один из вариантов BPE (Byte Pair Encoding): GPT, Claude, LLaMA, Qwen, DeepSeek различаются деталями и размером словаря, но алгоритм обучения один и тот же.

Как строится словарь: BPE шаг за шагом

Идея BPE до смешного простая. Берёшь корпус текста, сначала представляешь каждое слово как последовательность символов. Считаешь, какая пара соседних символов встречается чаще всего во всём корпусе. Склеиваешь эту пару в один новый токен. Повторяешь, но теперь считаешь частоты пар уже с учётом новых, более длинных токенов. Останавливаешься, когда словарь дорос до нужного размера (~100 000 токенов у GPT-4, ~200 000 у GPT-4o).

Ниже — тот самый пример из оригинальной статьи про BPE (Sennrich et al., 2016), проигранный по шагам: 4 слова, реальные частоты, реальные мерджи.

🧬 BPE изнутри: обучаем словарь на 4 словах
Корпус — тот самый пример из статьи Sennrich et al. про BPE: low (×5), lower (×2), newest (×6), widest (×3). Алгоритм на каждом шаге находит самую частую пару соседних символов и склеивает её в один токен. Точка «·» — маркер конца слова.
×5
low·
×2
lower·
×6
newest·
×3
widest·
Частоты соседних пар — сейчас смёрджится
e+s9→ «es»
s+t9
t+·9
w+e8
l+o7
шаг 0 из 8

Обрати внимание на четвёртый шаг: l+o побеждает o+w, хотя обе пары встретились одинаковое число раз — при равных частотах побеждает та пара, что раньше попалась при проходе по корпусу. На настоящих корпусах в миллиарды слов такие тай-брейки роли не играют, но на игрушечном примере это заметно.

Ключевой момент: то, что после десятка шагов слово newest уже свернулось почти в один токен, а какое-нибудь редкое слово из корпуса меньшинства осталось нарезанным на символы. Это не баг, а суть алгоритма. Частые последовательности получают короткие токены, редкие — длинные цепочки из мелких кусков. Держи это в голове для следующего раздела.

Токенизатор вживую

Хватит теории — вот настоящий токенизатор OpenAI (cl100k_base, словарь GPT-4/GPT-3.5-turbo), который работает прямо в браузере. Каждый цветной блок ниже — токен. Наведи курсор и посчитай сам.

🔤 Токенизатор вживую
Настоящий токенизатор OpenAI (cl100k_base — GPT-4/GPT-3.5) прямо в браузере. Одинаковая мысль на двух языках — сравни счётчики.
🇷🇺 Русский
Токенизация делит текст на части.
13 токенов · 33 симв.
🇬🇧 English
Tokenization splits text into pieces.
7 токенов · 37 симв.
Русский текст занял 1.86× больше токенов, чем тот же смысл по-английски

Теперь свой текст — что угодно, от бытовой фразы до куска кода:
Привет! Напиши что-нибудь своё увидишь, как это порежет токенизатор.
36 токенов
70 символов
$0.0720 за 1000 таких запросов (по $2/1M входных токенов — ориентир уровня GPT-4, не тариф конкретного провайдера)

Если гонял разные фразы, наверняка заметил: русский текст почти всегда красится на большее число токенов, чем аналогичный по смыслу английский. Разброс от примера к примеру ощутимый: на простых бытовых фразах разница обычно в 1.3–1.9 раза, на тексте с более редкими словоформами (длинные глаголы, специфичные термины) может доходить до 3 раз и больше: токенизатор просто не научился сворачивать в один токен то, что видел на обучении реже.

Почему кириллица дороже

Две причины, и обе — следствие того, как обучали токенизатор, а не что-то принципиальное про сам язык.

Причина 1: байты. BPE у OpenAI работает не над символами Unicode, а над байтами UTF-8. Латинские буквы в UTF-8 — 1 байт на символ. Кириллица — 2 байта на символ. Ещё до всякого обучения словаря русский текст в сыром виде уже вдвое «длиннее» английского на уровне байтов, с которыми работает алгоритм.

Причина 2: корпус обучения токенизатора. Словарь BPE учится на реальном тексте из интернета, а он сильно перекошен в сторону английского. Значит, у токенизатора было гораздо больше практики сворачивать частые английские последовательности в короткие токены, чем для русских. tokenization: один токен. токенизация: пять (т, ок, ени, з, ация, смотри пример в плейграунде выше). Не потому что русское слово длиннее по смыслу, а потому что модель реже видела именно эту последовательность байтов на обучении словаря.

Это касается не только русского

Систематическое исследование «The Tokenizer Tax» по 24 европейским языкам показывает: для нелатинских скриптов (кириллица, греческий) эффективность токенизации может падать до ~1/3 от английской: текст режется втрое мельче при том же смысле. Украинский (тоже кириллица) в этом исследовании показал разброс от 2.16× до 3.62× в зависимости от токенизатора модели: GPT-4o и Llama-Maverick оказались заметно эффективнее, чем Qwen3.

~1/3Эффективность кириллицы

Токенизация нелатинских скриптов в среднем настолько эффективнее английской — по данным исследования по 24 языкам Европы.

200KСловарь GPT-4o

У o200k_base (GPT-4o) словарь вдвое больше, чем у cl100k_base (GPT-4) — и заметно лучше справляется с не-английскими языками.

Сравнение по моделям

Живой токенизатор выше — это конкретно cl100k_base. У остальных моделей свои словари и своя эффективность на кириллице; повторить вживую для каждой в браузере не вышло (нет лёгких JS-библиотек под большинство из них), но по независимым замерам и данным вендоров картина стабильная:

Модель / токенизаторОтносительная эффективность на кириллице
GPT-4o (o200k_base)Одна из лучших среди распространённых моделей — заметно лучше предшественника
Llama 4 MaverickВ измерениях держится на уровне GPT-4o или лучше
GPT-4 / GPT-3.5 (cl100k_base)Хуже, чем o200k_base — старый словарь, меньше многоязычных токенов
Qwen3Хуже среднего на кириллице — словарь заточен в первую очередь под китайский и английский
DeepSeekАналогично Qwen — сильны на CJK-языках, слабее на кириллице

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

Посчитай сам

Питон, tiktoken (та же библиотека, на которую опирается официальный OpenAI SDK):

import tiktoken

enc = tiktoken.get_encoding("cl100k_base")

ru = "Токенизация делит текст на части."
en = "Tokenization splits text into pieces."

print(len(enc.encode(ru)), "токенов —", ru)
print(len(enc.encode(en)), "токенов —", en)

JS/TS, gpt-tokenizer (тот же пакет, на котором работает плейграунд выше):

import { encode } from 'gpt-tokenizer/encoding/cl100k_base';

const ru = 'Токенизация делит текст на части.';
const en = 'Tokenization splits text into pieces.';

console.log(encode(ru).length, 'токенов —', ru);
console.log(encode(en).length, 'токенов —', en);

Оба варианта посчитают одинаково — tiktoken и gpt-tokenizer реализуют один и тот же словарь cl100k_base.

Что с этим делать на практике

  • Не прикидывай контекстное окно по символам. «Влезет ли промпт в 128K токенов» — не то же самое для русского и английского текста при одинаковом числе символов. Считай токенизатором, не на глаз.
  • Закладывай больший token budget под русскоязычные промпты и системные инструкции. Если система написана на русском, а лимит подобран из расчёта на английский — упрёшься в него раньше, чем ожидал.
  • Для мультиязычных проектов эффективность токенизатора — реальный критерий выбора модели, не только качество ответов. Модель с чуть худшим бенчмарком, но с современным мультиязычным словарём, может выйти дешевле в проде на русскоязычном трафике.
  • Код в целом токенизируется предсказуемо независимо от языка комментариев — сама грамматика языков программирования преимущественно ASCII, разница в стоимости проявляется в основном в комментариях и строковых литералах.

TL;DR

LLM видит не буквы и не слова, а токены — куски слов, которые BPE выучил на корпусе, где английского текста было больше всего. Из-за этого частые английские последовательности сворачиваются в короткие токены, а кириллица (вдвое длиннее уже на уровне UTF-8-байтов, да ещё и реже встречавшаяся на обучении словаря) режется мельче: на бытовых фразах в 1.3–1.9 раза, на тексте с редкими словоформами и больше. Новые токенизаторы вроде o200k_base у GPT-4o заметно сокращают разрыв по сравнению со старым cl100k_base, но не убирают его целиком. Хочешь точную цифру для своего текста? Не верь оценке «раз в 1.5 дороже» — проверь плейграундом выше на собственном промпте.