Главная / Статьи / Почему индийские языки стоят больше токенов в LLM и как чинят токенизаторы

Почему индийские языки стоят больше токенов в LLM и как чинят токенизаторы

Одно и то же предложение занимает 5 токенов на английском и 34 на тамильском. Как к этому приводят обучающие данные BPE, что меняют перебалансировка и размер словаря и как работает расширение словаря.

1932 слов

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

Одно предложение, пять ценников

Измерения для одного короткого предложения:

Язык Символы Байты Слова Токены
Английский 18 18 4 5
Хинди 12 30 3 13
Телугу 17 45 3 20
Каннада 16 44 2 22
Тамильский 30 84 3 34

Смысл одинаковый. Важен последний столбец. Токены — это маленькие кусочки, которые модель на самом деле читает: целое слово, фрагмент или всего несколько символов. Английскому понадобилось примерно по токену на слово. Тамильскому — почти одиннадцать.

Дело вовсе не в том, что тамильский труднее понять. Разрыв появился из-за решения, принятого задолго до того, как кто-то набрал промпт: как был построен токенизатор модели. И последствия вполне реальны. Разговоры на индийских языках быстрее заполняют контекстное окно, дороже обходятся и медленнее возвращаются, даже когда говорят ровно то же, что англоговорящий пользователь говорит дешевле.

Дальше — почему этот разрыв существует, что небольшой эксперимент показывает о его сокращении и что нужно, чтобы починить токенизатор у уже обученной модели.

Что делает токенизатор

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

Эту нарезку никто не придумывает вручную. Она выучивается на огромной куче текста с помощью байтового BPE, сокращение от Byte Pair Encoding. Рецепт простой: начать с сырых байтов, найти пару, которая чаще всего встречается рядом в обучающем тексте, и слить её в новый токен. Повторить. Первые шаги выглядят так:

t h  →  th
th e →  the

После тысяч раундов получается словарь, где каждая запись заслужила место частотой. Кусочки вроде «the», «-ing» и «-tion» становятся отдельными дешёвыми токенами в корпусе с перевесом английского, потому что встречаются постоянно.

Почему байты — ложный след

Английские буквы занимают по одному байту. Большинство индийских письменностей, например деванагари, телугу, тамильское письмо и каннада, занимают по три байта на символ, потому что их наборы символов гораздо больше. Хочется сделать вывод, что три байта — это три токена, но это неверно. Байтовый токенизатор может слить несколько байтов в один токен, так что трёхбайтовый символ не обязательно стоит три. Его цена зависит от того, выучил ли токенизатор хорошее слияние для этой последовательности байтов, а это, в свою очередь, зависит от того, сколько текста на этом языке он видел.

Так что настоящее объяснение — обучающие данные, а не сложность письменности. Обучите на 90% английского и 10% всего остального, и английские паттерны получат тысячи шансов заработать эффективные однотокенные слияния. Индийские получат гораздо меньше и останутся мелкими дорогими кусками. Алгоритм не предвзят ни в каком моральном смысле. Частота — просто единственное, что оптимизирует BPE.

Эксперимент: помогает ли перебалансировка данных?

Чтобы проверить это, с нуля обучили три небольших токенизатора, меняя между ними только состав языков:

  • Токенизатор A: 90% английского и 10% индийских языков, как строятся многие реальные токенизаторы, ведь большая часть текста в интернете на английском
  • Токенизатор B: ровно 50/50 между английским и индийскими текстами
  • Токенизатор C: равные доли английского, хинди, телугу, тамильского и каннада

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

Токенов на слово на отложенных тестовых предложениях:

Язык A (90% английского) B (50/50) C (сбалансированный)
Английский 3.05 3.08 3.60
Хинди 5.34 4.32 4.34
Телугу 7.79 6.36 6.36
Тамильский 10.75 8.47 7.84
Каннада 8.86 7.34 7.07

Переход от A к B, который даёт индийским языкам более справедливую долю, снизил стоимость хинди примерно на 19%, телугу примерно на 18% и тамильского примерно на 21%, а английский почти не сдвинулся. Какое-то время перебалансировка даёт очень хорошую отдачу.

Дальнейший переход к полностью сбалансированному составу дал убывающую отдачу для индийских языков и откусил кусок у английского (с 3.08 до 3.60). Так что больше баланса — не всегда лучше. Есть оптимальная точка, а не прямая линия.

Исправит ли это словарь побольше?

На том же сбалансированном корпусе перебрали размер словаря. Токенов на слово:

Язык 300 800 1,500 3,000
Английский 5.28 3.70 3.70 3.70
Хинди 6.75 3.55 3.55 3.55
Телугу 9.64 6.42 6.42 6.42
Тамильский 10.72 7.78 7.78 7.78
Каннада 10.17 7.17 7.17 7.17

Переход с 300 на 800 сильно помог всем языкам. Дальше ничего не менялось, потому что в крошечном корпусе закончились частые паттерны, которые стоило бы превращать в новые токены. В промышленном масштабе стоит ждать кривой той же формы по родственной причине: каждый новый слот захватывает всё более редкие паттерны, так что выигрыш сжимается. В любом случае словарь побольше не лучше автоматически. Он раздувает таблицу эмбеддингов и выходной слой, так что это реальная цена, а не бесплатный апгрейд.

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

Почему токенизатор нельзя просто заменить

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

Обучение даёт каждому токену собственный эмбеддинг — вектор, который обозначает смысл этого токена, и все остальные слои работают с этими векторами. Допустим, ID 1234 соответствует эмбеддингу для «hello». Если новый токенизатор отдаст 1234 приветствию на хинди, эмбеддинг в этом слоте всё равно будет означать «hello». Ничто не сообщает трансформеру, что смысл изменился. Вывод становится бессвязным, потому что выученные знания модели по-прежнему привязаны к старым ID, а эта связь тихо оборвалась.

Как команды добавляют языки задним числом: расширить словарь, заморозить веса

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

  1. Не трогать существующий словарь. Ни один текущий ID токена не переназначается, ведь именно переназначение вызывает рассогласование.
  2. Дописать новые токены для целевых языков. Свежий набор слияний, часто обученный на многоязычном или языковом корпусе, добавляется новыми ID после существующих, так что ничего не заменяется. Словарь на 32K может вырасти за 100K.
  3. Инициализировать новые эмбеддинги. Случайные значения работают, но усреднение родственных эмбеддингов даёт более тёплый старт, потому что чисто случайный вектор ничего не говорит совершенно новому токену.
  4. Заморозить исходные веса и сначала обучать только новые эмбеддинги. На этом шаге держится весь подход. Всё, что модель уже знает об английском, рассуждениях и коде, остаётся заблокированным. Меняться могут только новые строки эмбеддингов и часто новые строки выходного слоя. Модель узнаёт, что значат новые токены, не рискуя катастрофическим забыванием — известным сбоем, когда новое обучение перезаписывает старые знания.
  5. Продолжить предобучение на текстах на новых языках, по-прежнему держа большую часть модели замороженной, пока новые эмбеддинги не наберут достаточно смысла, чтобы замороженные слои могли ими пользоваться.
  6. Размораживать постепенно. Иногда сначала верхние слои, иногда всё сразу, и обучение продолжается, чтобы вся сеть приспособилась к увеличенному словарю.

Представьте, что к дому пристраивают новые комнаты, а не сносят его и строят заново. Существующие знания на ранних этапах остаются нетронутыми, пока новые комнаты обставляют отдельно, и только потом весь дом перестраивается вокруг них.

Это же показывает, почему изменения словаря касаются не только входа. Модель должна читать новые токены, и это работа входных эмбеддингов, а ещё порождать их в ответах. Это задача выходного слоя, иногда его называют LM head, который оценивает каждую запись словаря как возможный следующий токен. Обучение должно охватывать оба конца, а делят ли эти два слоя веса, зависит от архитектуры.

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

Чего это не доказывает

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

Вся цепочка целиком

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

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

Для многоязычных LLM токенизатор — не второстепенная предобработка. Это часть экономики языка, и правильно починить его после обучения — настоящая инженерная работа, а не просто данные получше. Помните, что цифры выше получены на игрушечной конфигурации BPE, построенной так, чтобы менять одну вещь за раз, и ничего не говорят о том, как работает какой-либо реальный токенизатор.