Kandidát na tokenizers 1.0 kóduje text podle měření autorů třikrát až třicetkrát rychleji
Tokenizer je první krok každého jazykového modelu: rozseká text na kusy, které model umí číst. Hugging Face svou knihovnu tokenizers přepsal a u kandidáta na verzi 1.0 naměřil třikrát až třicetkrát rychlejší kódování než u dnešní 0.23. Hotové vydání to ale není a čísla platí pro balík v Rustu, režie vazeb pro Python v nich není.

Tokenizer převádí text na seznam celých čísel, který jazykový model čte. Dlouho to byl ten levný krok: než model spočítá jednu odpověď, tokenizer má dávno hotovo. Hugging Face teď tvrdí, že se poměr posunul, a vydal kandidáta na verzi 1.0 své knihovny tokenizers, kde je celá ta cesta přepsaná znovu.
Kandidát je v registru, doporučená verze zůstává stará
Balík 1.0.0-rc.2 přibyl na crates.io, registr knihoven jazyka Rust, 21. září 2026 v 11:14 světového času. O čtrnáct minut později se objevil na GitHubu označený jako předběžné vydání. Poslední stabilní verze je pořád 0.23.2 z 3. září a registr ji jako doporučenou nabízí dál; kandidáta dostane jen ten, kdo si o něj výslovně řekne příkazem cargo add tokenizers --pre.
Samotný převod běží ve čtyřech krocích. Normalizace srovná syrový text, třeba na malá písmena. Předběžné dělení ho rozseká na menší kusy. Model z každého kusu udělá tokeny a přiřadí jim čísla ze slovníku. Dokončení dopíše zvláštní tokeny, které model čeká. Osm z deseti rodin, na kterých Hugging Face měřil, používá ve třetím kroku byte pair encoding: začne se u jednotlivých bajtů a opakovaně se spojí ta sousední dvojice, která má nejvyšší pořadí, dokud žádná taková nezbude. Zbylé dvě jedou na WordPiece a Unigram.
Čtyři místa, kde se ubralo práce
Vzor, podle kterého se text dělí na kusy, je pevná součást modelu. Nemění se za běhu, takže ho nemusí při každém kódování znovu vykládat obecný stroj na regulární výrazy. Nová část s názvem bitcannon čte vstup jako souběžné proudy bitů a hranice hledá logickými operacemi nad celými registry; jedna taková operace rozhodne o 64 bajtech naráz. Stejný nápad stojí za projekty Parabix a simdjson.
Druhá změna je vyrovnávací paměť na slova. Týž kus textu dá vždycky stejné tokeny, takže si vlákno výsledek uloží a při příštím výskytu slučování přeskočí.
Třetí je samotná slučovací smyčka. Dřív si pro každé volání sahala o novou paměť a stavěla novou frontu; teď pracuje v nárazníku, který vlastní volající, a na alokátor nesáhne vůbec. Každý kandidát na sloučení je zabalený do jediného 64bitového čísla a pořadí sedí v horních bitech. Porovnat dva kandidáty tedy znamená porovnat dvě čísla a stav „tady se neslučuje“ je největší možná hodnota, takže smyčka najde další sloučení bez jediného větvení.
Čtvrtá změna je organizační. Z jednoho balíku je workspace: běhové jádro tk-encode je povinné, kdežto tk-serialize, tk-convert a tk-train se přilinkují, jen když je aplikace opravdu potřebuje. Podle poznámek k vydání je balík šestkrát menší a klesla i špičková spotřeba paměti. K tomu přibyla práce s vlákny: změna číslo 2365, sloučená 3. září a velká 230 přidaných řádků proti dvanácti ubraným, dala každému vláknu vlastní podskupinu pracovní paměti, takže se vlákna nemačkají na jednom zámku.
Třikrát až třicetkrát, ale ne u každého modelu
Napříč deseti rodinami modelů, které nová cesta pokrývá, kóduje kandidát text třikrát až třicetkrát rychleji než 0.23. Měřeno jedním vláknem na počítači s čipem Apple M4 Max; nejmenší zisk vyšel u t5-base, největší u gpt2. Přes osm souběžných pracovníků drží 76 procent toho, co by dalo dokonalé lineární škálování. Výstup se přitom nemění, kandidát dává stejná čísla tokenů jako vydaná knihovna.
Ten rozptyl má dvě příčiny a Hugging Face je popisuje sám. Ručně psané dělení funguje jen u vzorů, které knihovna pozná; hrstka gramatik pokrývá většinu bajtových BPE modelů, ale tokenizer s jiným vzorem zůstane na regulárním výrazu a z téhle změny nemá vůbec nic. A vyrovnávací paměť pomůže tam, kde se kusy textu opakují. U vstupu, kde se skoro nic neopakuje, se za hledání v ní platí, aniž by přicházely zásahy.
Čísla platí pro Rust, ne pro Python
Tuhle výhradu uvádí blog až v závěru, přestože určuje, na co se naměřená čísla vztahují. Všechno se měřilo na balíku v Rustu. Vazby pro Python obalují týž kód, jenže přidávají režii na každé volání a ta v měření není. Kolik dělá, blog neuvádí. Do knihovny transformers a do zbytku ekosystému, který na tokenizerech stojí, se má zlepšení dostat až potom, co se kandidáti ustálí.
Druhá poznámka pro ty, kdo jen kódují: trénování tokenizeru visí za funkcí, která je zapnutá ve výchozím stavu a táhne s sebou závislost v C++. Kdo ji nepotřebuje, vypne ji a nemusí ji vůbec stavět.
A za třetí: než bude z kandidáta verze 1.0.0, chce tým převést na novou slučovací smyčku další rodiny modelů. Kolik jich je a kdy to bude hotové, oznámení neříká.
Jak se měřilo
Měření běží z repozitáře tokbench a Hugging Face k němu vypsal pravidla. Všechny knihovny běží v jedné a téže časovací smyčce, nikdo nemá vlastní zkratku. Načtení slovníku se měří zvlášť a nikdy uvnitř kódování. Nad výstupem se počítá otisk FNV-1a, který se musí shodovat se základem, jinak se výsledek nepočítá. Každé opakování startuje v novém procesu a pracovníci se připínají na osm různých fyzických jader, ne na sourozenecká vlákna téhož jádra.
Jedna věta z metodiky stojí za přečtení i mimo tenhle případ. Opakovaně kódovat jeden dokument a kódovat proud pokaždé jiných dokumentů jsou dvě různé úlohy, jenže obojí se v testech běžně označuje za „zahřáté“. První měří stav, kdy je celý text už ve vyrovnávací paměti, druhé práci na novém vstupu. Hlavní čísla stojí na různých dokumentech a korpus je podle autorů příliš velký, než aby se do paměti vešel.
Zdroje
- tokenizers v1: encode, decode and scaling, measured, blog Hugging Face, 21. září 2026
- Seznam verzí knihovny tokenizers, crates.io
- Release candidate v1.0.0.rc.2, GitHub