Почему взялись за производительность
Токенизация должна занимать мало времени и справляться с ростом нагрузки. Разработчики хотят, чтобы графические процессоры не простаивали, ожидая, пока центральный процессор обработает текст.
В этой статье авторы сравнивают скорость v1 с v0.23: в ряде случаев новая версия быстрее на десятки раз.
Работа стала возможной благодаря усилиям сообщества. Токенизация — активное направление открытой разработки; библиотеки gigatoken, tiktoken, kitoken, tokie, fastokens, wordchipper и ai-tokenizer, а также другие проекты помогли продвинуть представления о быстром токенизаторе. Авторы изучили их решения, и некоторые идеи в этой статье появились благодаря тому, что другие проекты показали: их стоит попробовать.
До переработки tokenizers заметно уступала возможному уровню производительности, поэтому у разработчиков могло не быть причин вносить в неё вклад. Авторы надеются, что после изменений станет понятнее: они хотят превратить tokenizers в библиотеку, в которую стоит вкладываться.
Также авторы благодарят IBM, NVIDIA и команду ExecuTorch за исправления и помощь в тестировании на широком наборе оборудования, что позволило расширить поддержку платформ.
Результаты тестов
Авторы приводят результаты для кандидата на выпуск tokenizers v1 и сравнивают его с другими широко используемыми решениями. Они проверяют скорость в одном и нескольких потоках, масштабирование при увеличении числа потоков, разницу между моделями и языками, задержку, пропускную способность декодирования, использование памяти в куче и размер пакета.
Тесты запускаются из репозитория tokbench. Авторы добавили команду, с помощью которой результаты можно проверить на собственном оборудовании.
Что такое v1
v1 выдаёт те же идентификаторы токенов, что и v0.23. Задача разработчиков заключалась в том, чтобы сохранить выходные данные, API, словарь и ранги слияния, улучшив всё остальное. Библиотека остаётся универсальной для разных семейств токенизаторов, а не специализируется только на BPE, поэтому v1 загружает всё, что загружала v0.23.
Токенизатор превращает текст в последовательность целых чисел, которую читает модель. В tokenizers эта обработка состоит из четырёх этапов:
Большая часть описанных в статье изменений касается этапа модели. Восемь из десяти семейств, измеренных авторами, используют кодирование парами байтов, или BPE. Оно начинает с байтов претокена и снова и снова объединяет соседнюю пару с наивысшим рангом — пока таких пар не останется. Ранги определяются при обучении токенизатора и входят в его состав, поэтому один и тот же текст всегда даёт одинаковые идентификаторы. Слияние не пересекает границы претокенов. В двух других семействах используются WordPiece и Unigram — ещё два типа моделей, которые поддерживает библиотека.
Четыре этапа описаны на странице о пайплайне токенизации, а алгоритмы BPE, WordPiece и Unigram — в документации об алгоритмах токенизации.
Разработчики работали над каждым этапом. Ниже — изменения, которые повлияли на результат.
Разбиение без регулярных выражений
Модели BPE используют регулярное выражение, чтобы разделить исходный текст на небольшие фрагменты, которые проще обрабатывать, — претокены. Слияния происходят внутри претокена и никогда не переходят его границы, поэтому от разбиения зависит, что попадёт на следующие этапы пайплайна.
Регулярное выражение — неизменный параметр модели: оно поставляется вместе с токенизатором и не меняется во время работы. Поэтому при каждом кодировании необязательно запускать универсальный обработчик регулярных выражений. Для известного шаблона модели можно один раз написать эквивалентную функцию разбиения вручную.
Такая функция может использовать инструкции SIMD современного процессора. Они выполняют одну операцию сразу над несколькими байтами и хорошо подходят для текста в UTF-8. В bitcannon входные байты рассматриваются как параллельные потоки битов: границы определяются логическими операциями над целыми регистрами, а не последовательным просмотром символов. За одну операцию с регистром алгоритм обрабатывает 64 байта. Похожий подход применяют Parabix для обработки текста и simdjson для JSON.
Ускорение зависит от того, распознаёт ли алгоритм шаблон. Большинство моделей BPE на уровне байтов используют несколько распространённых грамматик. Если шаблон токенизатора не входит в их число, он продолжает работать через регулярное выражение и не получает этого ускорения. Этим авторы объясняют, почему результаты так сильно различаются.
Кэш слов
В обычном тексте часто встречаются повторяющиеся слова. Поскольку BPE всегда выдаёт для одного претокена одинаковые идентификаторы токенов, v1 может сохранить результат первой обработки. Потоковый кэш сопоставляет байты каждого претокена его идентификаторам, и при повторе алгоритму уже не нужно выполнять слияния.
Чем длиннее текст, тем медленнее может расти число уникальных слов по сравнению с общим числом слов. Поэтому повторы занимают всё большую долю входных данных. Новые слова всё равно появляются — из-за них в анимации иногда случаются промахи кэша.
Воспроизвести результат для общего префикса можно командой:
tokbench measure prefix-sharing \
--engine pipeline \
--engine hf-tokenizers \
--compare-to pipeline-no-cache \
--corpus agentic_sweКэш эффективнее, когда вход содержит много повторяющихся претокенов. Если повторов мало, затраты на поиск в кэше могут не окупиться.
Цикл слияния
Следующие по величине затраты приходятся на цикл слияния BPE. Для каждого претокена он снова и снова ищет соседнюю пару с наивысшим приоритетом и объединяет её. Прежняя реализация выделяла новую память при каждом вызове и создавала отдельную очередь с приоритетами для каждого претокена.
В v1 используется повторно временный буфер, которым владеет вызывающий код, поэтому повторные выделения памяти не нужны. Символы хранятся в плоском массиве, а соседние элементы связаны позициями в нём — это удешевляет обновления при слиянии. Кроме того, одна модель обрабатывает пакет претокенов за один вызов.
Каждая возможная пара также упаковывается в одно 64-битное значение, где ранг слияния записан в старших битах. Чтобы сравнить две пары, достаточно сравнить два целых числа. Значение «слияния здесь нет» представлено максимально возможным числом, поэтому цикл находит следующее слияние без ветвления.
Методика измерений
Небольшие отличия в методике тестирования могут сильно повлиять на производительность токенизатора. Авторы использовали следующие правила, чтобы сравнение разных движков было последовательным.
Повторное кодирование одного документа может оказаться быстрее, чем обработка потока разных документов в одной и той же сборке. В первом случае измеряется работа, когда документ уже целиком находится в кэше. Во втором — обработка новых входных данных с сохранением в кэше ранее встречавшихся претокенов.
Оба режима иногда называют «прогретыми», хотя они описывают разные нагрузки. Основные результаты в статье получены на разных документах, а весь корпус слишком велик, чтобы поместиться в кэше. В бенчмарках токенизаторов важно указывать, какой режим используется: выбор может сильнее всего повлиять на итог.
Насколько выросла скорость
Для десяти семейств моделей, поддерживаемых путём кодирования v1, новая версия обрабатывает текст на Apple M4 Max в 3–30 раз быстрее v0.23 при использовании одного потока. Нижняя граница относится к t5-base, верхняя — к gpt2. При восьми рабочих потоках библиотека достигает 76% от линейного масштабирования. Несмотря на изменения, v1 выдаёт в точности те же идентификаторы токенов, что и выпущенная версия.
Общий прирост складывается из нескольких улучшений: ручного разбиения вместо движка регулярных выражений, кэша повторяющихся слов, цикла слияния без обращений к распределителю памяти и обработки пакета претокенов одним вызовом модели вместо отдельного вызова для каждого элемента. Каждое изменение сокращает работу на своём участке пайплайна.
Следующий приоритет — поддержка новых семейств моделей. До версии 1.0.0 разработчики планируют перенести дополнительные модели на новый цикл слияния. Когда кандидаты на выпуск стабилизируются, они начнут внедрять улучшения в библиотеку transformers и другие проекты, которые используют tokenizers.
Статья построена на результатах tokbench и будет обновляться по мере расширения поддержки.
Установка и использование
Кандидат на выпуск v1 доступен на crates.io. API остаётся прежним: меняется только установленная сборка.
Обычная установка:
cargo add tokenizers --preОбучение включено через функцию, активированную по умолчанию; она добавляет зависимость на C++. Если вам нужно только кодирование, отключите обучение, чтобы не включать его реализацию:
cargo add tokenizers --pre --no-default-features --features httpКодирование не изменилось: вызов и идентификаторы те же.
В исходном примере токенизатор загружается для модели deepseek-ai/DeepSeek-V4-Flash, кодирует фразу The tokenizer is no longer the bottleneck. и выводит идентификаторы и соответствующие им токены. Полученный список идентификаторов:
[671, 17840, 9160, 344, 1119, 5827, 270, 111127, 16]А список токенов:
["The", "Ġtoken", "izer", "Ġis", "Ġno", "Ġlonger", "Ġthe", "Ġbottleneck", "."]Для обработки пакета документов между ядрами используется encode_batch. Именно этот вызов измеряет представленный выше график масштабирования.
let encodings = tokenizer.encode_batch(documents, false)?;Все результаты в статье получены с помощью этого пакета. Привязки для Python используют тот же код и собираются из bindings/python, но добавляют накладные расходы на каждый вызов — в измерениях они не учитываются.
Что осталось до v1
В бенчмарках описана завершённая работа для кандидата на выпуск. В следующих разделах перечислены задачи до версии 1.0.0 и направления, которые разработчики планируют изучить позже.
Кандидат на выпуск: сделано
Работа доступна в предварительной версии Rust-пакета на crates.io:
cargo add tokenizers --pretk-encode, tk-serialize, tk-convert и tk-train, чтобы приложение подключало только нужные части.STAGE_POST: #2182.role_to_token: #2343.Версия 1.0.0
tk-encode, чтобы обучение и инференс не давали разных результатов токенизации.После версии 1.0.0
Читайте также
ИИ-девушки воруют шутки у комиков, чтобы набрать просмотры на возбуждающих роликах
ИИ угрожает демократии. Но мы не бессильны: вот как дать отпор
Вирусный успех Cal AI обеспечила целая армия инфлюенсеров — и это окупилось
Google хочет, чтобы роботам хватало одной модели ИИ — Gemini 4 Argon
GPT-6-Astra решает 49 из 50 задач по физике за $2,40 за каждую
Жители отвергают выплату по $10 000 за согласие разместить в их посёлке дата-центр
Bluesky расширила возможности приложения Attie на базе ИИ: теперь в нём каждый может создавать сайты, игры и не только
Muse Spark Open — ответ Meta на Qwen, GLM и Kimi в гонке открытых моделей с весами
Bank of America направил 4 тысячи человек устранять уязвимости, найденные Mythos от Anthropic и другими ИИ-моделями
Anthropic рассказала о независимых оценщиках
FLUX 3 Image Klein от Black Forest Labs работает на видеокартах для обычных ПК с 8 ГБ видеопамяти
Google запустила в США инструмент для покупок Universal Cart
Arcade.dev: новая система подбора инструментов снижает расходы компаний на входные токены на 37%
Magnetar подтверждает корректность программ для вычислений общего назначения с помощью доказательств
ИИ-агенты появятся в автомобилях Rivian
NVIDIA дообучила Nemotron 3.5 Super VL, и она обошла Claude Opus 5 и GPT-6.1 Sol в тестах специализированных задач
Илон Маск признался, что столкнулся с ИИ-психозом
Если ИИ-модели и правда обладают сознанием, как не раз намекала Anthropic, заставлять их работать — чудовищное рабство
Bee от Amazon выпустила два новых персональных ИИ-устройства: цены начинаются от $75
Выручка Anthropic в третьем квартале достигла $16,8 млрд, но рост замедлился перед запланированным на ноябрь IPO
Ежедневные новости об ИИ
Каждый день отбираем важные новости об ИИ и рассказываем главное — без хайпа и воды. Если хотите понимать, что происходит в ИИ раньше остальных, — подписывайтесь.
Только важное — каждый день
В Telegram