i
Новости
Новости · 2026-10-16

tokenizers v1: измерили скорость кодирования, декодирования и масштабирования

@neuronium_ai @neuronium_ai

По мере ускорения моделей и роста нагрузки токенизатор может стать узким местом: при обучении на больших наборах данных, обслуживании множества запросов или обработке длинных входов он не успевает передавать данные модели. В релиз-кандидате tokenizers v1 разработчики ускорили кодирование текста — на Apple M4 Max оно работает в 3–30 раз быстрее, чем в v0.23, при этом выдаёт те же идентификаторы токенов. Библиотека также масштабируется до восьми потоков с эффективностью 76% от линейной. Авторы описали изменения, сравнили производительность с другими токенизаторами и выложили команды для повторного запуска тестов.

Обложка: tokenizers v1: измерили скорость кодирования, декодирования и масштабирования

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

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

В этой статье авторы сравнивают скорость 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 эта обработка состоит из четырёх этапов:

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

Большая часть описанных в статье изменений касается этапа модели. Восемь из десяти семейств, измеренных авторами, используют кодирование парами байтов, или 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 --pre
Разделение рабочей области: единый пакет разделён на tk-encode, tk-serialize, tk-convert и tk-train, чтобы приложение подключало только нужные части.
bitcannon: регулярное выражение для разбиения текста на пути кодирования заменено операциями с битовыми потоками для GPT-2, cl100k, o200k, Tekken и DeepSeek. Это решение пришло на смену конечным автоматам, которые были включены в первую версию: #2201 и #2317.
WordCache: повторно используются идентификаторы токенов уже обработанных претокенов: #2262, af5a3e3.
Ускоренные структуры поиска и слияния: добавлены FlatCache, MPHF RankStore, инкрементальное слияние и BucketVocabStore: #2190, #2188.
Повторно используемая память модели: временное состояние модели перенесено во временные буферы, чтобы токенизатор не выделял память при каждом вызове: #2175, #2183.
Постобработка в пайплайне: постобработка открыта как этап пайплайна STAGE_POST: #2182.
Пакетные вызовы модели: за один вызов обрабатываются несколько отрезков с претокенами: #2304.
Ускоренное декодирование: декодированные байты записываются прямо в повторно используемый буфер; промежуточные строки и копирования исключены; поиск токенов ускорен; добавлена потоковая обработка с буферизацией и параллельное декодирование пакетов.
Поддержка role_to_token: #2343.
Привязки для Node.js: #2281.

Версия 1.0.0

Единая реализация кодирования: при проверке обучения будет использоваться tk-encode, чтобы обучение и инференс не давали разных результатов токенизации.
Необязательные смещения и маски: эти метаданные будут вычисляться только по запросу и не затронут путь, который возвращает только идентификаторы токенов.
Переработка нормализаторов.
Поддержка bitnorm на основе atomnorm: #2209.
Предварительно скомпилированный spm.
Упрощение привязок для Python: разработчики хотят сократить блокировки, типы-обёртки и написанный вручную код диспетчеризации, сохранив поддержку наследования классов, сериализации, пользовательских декодеров, изменения поведения и свободнопоточного CPython.
Привязки на C и C++ только для инференса для ExecuTorch и llama.cpp. В дальнейшем могут появиться привязки для JVM, Swift и Go.

После версии 1.0.0

tok-devices: изучение кодирования на графическом процессоре и пакетного декодирования с хранением текста и идентификаторов токенов на устройстве. Декодер будет загружать словарь один раз, параллельно вычислять позиции выходных данных и собирать соответствующие байты на графическом процессоре. Это будет необязательный компонент для больших пакетов; его разработка зависит от дальнейшего прототипирования и измерений.
ИИ-девушки воруют шутки у комиков, чтобы набрать просмотры на возбуждающих роликах ИИ угрожает демократии. Но мы не бессильны: вот как дать отпор Вирусный успех 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