- Unterstützt verschiedene CPUs und gängige Tokenizer und ist als Alternative zu Tiktoken und HuggingFace Tokenizers gedacht, die Text mit GB/s verarbeiten kann
- Optimiert die sonst von der Regex-Engine übernommene Vor-Tokenisierung mit SIMD, reduziert Branches, Thread-Kommunikation und Python-Interaktionen und cached Token-Zuordnungen für bereits gesehene Wörter effizient
- Im 11,9-GB-OpenWebText-Benchmark erreichte der GPT-2-Durchsatz auf einem AMD EPYC 9565 24,53GB/s, auf einem Apple M4 Max 8,79GB/s und auf einem Ryzen 7 9800X3D 6,27GB/s
- Die HuggingFace- und Tiktoken-kompatiblen Modi lassen bestehenden Code fast unverändert, verlieren aber durch die Kosten exakter Ausgabeübereinstimmung an Performance; die Gigatoken API, bei der Rust Dateien direkt liest, bietet die höchste Parallelität und Geschwindigkeit
- WordPiece und Dateiausgabe werden noch nicht unterstützt, außerdem fehlen Optimierungen für SentencePiece und ausreichende Windows-Validierung; aktuell eignet es sich daher besser für BPE-Tokenizer und Umgebungen mit Linux, macOS oder WSL
Unterstützungsumfang und Verwendung
- Gigatoken ist ein Hochgeschwindigkeits-Tokenizer für Sprachmodelle und zielt auf moderne x86- und ARM-CPUs sowie nahezu alle gängigen Tokenizer
- Die Installation erfolgt mit
pip install gigatoken; bereitgestellt werden eine eigene API sowie Kompatibilitätsmodi für HuggingFace Tokenizers und Tiktoken - Die Kompatibilitätsmodi kapseln bestehende Tokenizer und konvertieren sie jeweils mit
.as_hf()oder.as_tiktoken()- Dafür wird erheblicher Aufwand betrieben, damit die Ausgabe exakt mit HuggingFace Tokenizers übereinstimmt
- Diese Kompatibilität verursacht spürbare Performance-Kosten, erreicht also nicht die etwa 1.000-fache Beschleunigung der eigenen API, ist insgesamt aber dennoch schneller als bestehende Implementierungen
- Die eigene API nimmt HuggingFace-Modellnamen wie
"Qwen/Qwen3-8B"undTextFileSourceentgegen und kodiert Dateien direkt- Die Rust-Implementierung liest Daten direkt ein, überspringt unnötigen Overhead und maximiert die Parallelität
- Werden Python-Datenstrukturen übergeben, bleibt der Aufwand für das Lesen der Daten in Python bestehen
Implementierung für mehr Geschwindigkeit
- Die größte Verbesserung kommt meist daher, dass die Vor-Tokenisierung, die sonst von einer Regex-Engine übernommen wird, SIMD-basiert direkt optimiert wurde
- Branches werden minimiert, und der Cache für Vor-Token-Zuordnungen, der Kodierungstoken bereits gesehener Wörter nachschlägt, wurde gezielt optimiert
- Der Cache wächst schnell und die Verteilung der Vor-Token hat einen Long-Tail, was die Optimierung erschwert
- Zusätzliche Performance wird durch weniger Interaktion mit Python und weniger Kommunikation zwischen Threads gewonnen
- Die Implementierung ist nicht auf eine einzelne CPU oder einen einzelnen Tokenizer zugeschnitten; stattdessen wurden Kombinationen aus modernen x86-/ARM-CPUs und mehreren Tokenizern jeweils optimiert, mit konsistenten Ergebnissen über CPUs und Tokenizer hinweg
11,9-GB-OpenWebText-Benchmark
- In einer Umgebung mit AMD EPYC 9565 und 144 Kernen erreicht GPT-2 einen Durchsatz von 24,53GB/s, also 989-mal schneller als die 24,8MB/s von HuggingFace Tokenizers und 681-mal schneller als die 36,0MB/s von Tiktoken
- Wichtige BPE-Familien liegen meist bei etwa 15,49 bis 24,00GB/s
- Auf SentencePiece basierende Einträge sind mit etwa 2,51 bis 4,82GB/s relativ langsamer
- Auf einem Apple M4 Max mit 16 Kernen erreicht GPT-2 8,79GB/s, also 1.268-mal so viel wie HuggingFace und 140-mal so viel wie Tiktoken
- OLMo 2/3 erreicht 1.299-mal, Qwen 2/2.5 1.105-mal die HuggingFace-Leistung
- Auf einem AMD Ryzen 7 9800X3D mit 16 Kernen erreicht GPT-2 6,27GB/s, also 106-mal so viel wie HuggingFace und 68-mal so viel wie Tiktoken
- Wichtige BPE-Familien liegen bei etwa 4,21 bis 6,09GB/s, relativ weniger optimierte Familien bei etwa 1,12 bis 2,84GB/s
Messbedingungen und Einordnung
- OWT (OpenWebText) wurde als Benchmark-Datensatz gewählt, weil es den Text grob repräsentiert, der nach dem Extrahieren von Common-Crawl-Dokumenten entsteht
- Gigatoken verarbeitet ganze Dateien ohne vorherige Aufteilung und übernimmt daher auch selbst das Finden von Split-Grenzen und die automatische Parallelisierung
- Die Vergleichssysteme verarbeiten Daten, die vorab anhand von
<|endoftext|>aufgeteilt wurden- HuggingFace
encode_batch_fastverwendet die ersten 100MB - Tiktoken
encode_ordinary_batchverwendet das erste 1GB - Da beide Implementierungen kein Caching nutzen und die Verarbeitungsgeschwindigkeit deshalb weitgehend konstant bleibt, wurde diese Vergleichsbedingung gewählt
- HuggingFace
- Tiktoken-Ergebnisse sind nur für offiziell unterstützte Tokenizer enthalten
- Jede Zeile repräsentiert einen eindeutigen Tokenizer mit identischem Vokabular, identischen Merges und identischem Vor-Tokenizer
- Mehrere Versionen und abgeleitete Modelle aus den Familien Llama, Qwen, DeepSeek, GLM, Nemotron, Kimi, Phi und Gemma sind derselben Tokenizer-Zeile zugeordnet
- Die langsamsten Einträge sind SentencePiece-basierte Tokenizer, die in Gigatoken noch nicht ausreichend optimiert sind
Verifizierung der Unterstützung und Verarbeitung großer Datenmengen
- Mit dem Befehl
uvx --with tokenizers gigatoken benchkann die Tokenisierung eines HuggingFace-Modell-Repositories auch ohne Installation verifiziert und zeitlich gemessen werden - Im GPT-2-Verifizierungsbeispiel stimmte die Ausgabe für 20.401 Dokumente überein
- Auf einem Apple M4 Max wurden 11.920,51MB in 1,432 Sekunden mit 8.327,05MB/s verarbeitet, also 1.353,13-mal schneller als HuggingFace
- Auf einem AMD EPYC 9565 wurden dieselben Daten in 0,486 Sekunden mit 24.532,45MB/s verarbeitet, also 989,21-mal schneller
- Mit dem EPYC-Durchsatz ließe sich der gesamte Common Crawl im Umfang von 13 Billionen Tokens in weniger als 6,5 Stunden tokenisieren
- Im Beispiel wird das Stanford CS336 OWT Sample verwendet; die CLI nutzt standardmäßig die ersten 100MB der Datei für Verifikation und HuggingFace-Vergleich
- Beim ersten Start unter macOS kann Rust-Code wegen Sicherheitsprüfungen langsamer laufen; für genaue Messungen sollte der Befehl daher eventuell zweimal ausgeführt werden
- Bei Ausgabedifferenzen oder langsamen Fällen wird darum gebeten, diese als GitHub Issue zu melden
Bekannte Einschränkungen
- Iterative Python-Verarbeitung läuft zwar in Rust, verwendet aber ABI3, das langsamer ist als die internen CPython-APIs je Python-Version
- Versionsspezifische Optimierungen für Python sind geplant; in ersten Experimenten verdoppelte sich die Geschwindigkeit in Fällen, in denen der Overhead dominierte
- In der Gigatoken API ist noch kein Dateiausgabe-Sink implementiert
- WordPiece wird nicht unterstützt
- Auf SentencePiece basierende Tokenisierung ist weniger stark optimiert als typisches BPE
- Da vor allem Google-Modelle und die BERT-Familie dies verwenden, hat das aktuell auch eine geringere Priorität
- Windows wurde noch nicht ausreichend getestet; derzeit wird daher die Nutzung von WSL empfohlen
Umfang des AI-Einsatzes
- Der Großteil der Codebasis wurde ohne AI direkt geschrieben; das lässt sich im Git-Verlauf des Projekts nachvollziehen
- In der Schlussphase des Projekts wurde AI für folgende Aufgaben eingesetzt
- Implementierung der API für Nutzer
- Generalisierung und Portierung des Vor-Tokenizers für mehr Tokenizer sowie Ausbau der Kompatibilität
- Unterstützung für Padding, Trunkierung und Unicode-Normalisierung
- Portierung von SIMD-Strategien zwischen AVX512, AVX2 und NEON
- Die letzten etwa 4x Leistungssteigerung durch Entfernen von Branches und Verbesserungen an den Vor-Token-Cache-Ebenen
- Refactoring und Verbesserung der Code-Wiederverwendung
1 Kommentare
Hacker-News-Kommentare
Die Aussage „Der Großteil des Codes wurde direkt ohne KI geschrieben, und das lässt sich auch in der Git-Historie überprüfen“ lässt die Verkündung menschliches Programmieren ist vorbei ziemlich verblassen
Es wurde nicht nur ein bestimmter CPU- und Tokenizer-Fall optimiert, sondern die gesamte Kombination aus aktuellem x86·ARM und mehreren Tokenizern übermäßig stark optimiert, um konsistente Leistung zu erzielen
Die sonst meist einer Regex-Engine überlassene Pre-Tokenisierung wurde per SIMD direkt optimiert und Verzweigungen wurden minimiert; außerdem wurde der Cache für Pre-Token-Mappings verbessert, damit sich die Encoding-Ergebnisse bereits gesehener Wörter schnell nachschlagen lassen. Caches in diesem Bereich wachsen schnell und haben eine Long-Tail-Verteilung, was sie schwer handhabbar macht
Auch die Interaktion mit Python und die Kommunikation zwischen Threads wurden minimiert
Das erinnert an simdjson, das mit kreativem Programmieren kaum glaubhafte Geschwindigkeit erreicht. Wenn es breit eingesetzt würde, könnte das Strom, Kosten und CO2-Ausstoß deutlich senken; ein Rust-Crate wäre daher sehr willkommen, und falls nötig würde ich gern selbst mithelfen
Wenn man Wirtschaftlichkeit und Umwelt betrachtet, bringt Batching von Requests deutlich mehr. Das teuerste Problem ist eine schlechte GPU-Auslastung, und wenn man Arbeit an Batch-Formate anpasst, lassen sich selbst bei OAI derzeit 50 % einsparen. Wenn nicht jede Antwort sofort gebraucht wird, können manche auch ein paar Tage warten, Tool-Calls laufen nicht in Timeouts, und für das LLM selbst existiert keine Wall-Clock-Zeit
Ich habe das Repository geklont und angeschaut; der Ersatz der Pre-Tokenisierungs-Regex und die Cache-Optimierung sind allgemein nützliche Ansätze. Das ist so gute Arbeit, dass die gesamte Tokenisierungs-Community wissen wollen dürfte, wie diese Geschwindigkeitssteigerung erreicht wurde
Großartige Leistung, aber Tokenisierung macht normalerweise weniger als 0,1 % der gesamten Inferenzzeit aus. Für Anwendungen, die Tokenisierung selbst benötigen, dürfte es aber sehr nützlich sein
Je kleiner das Modell oder je schneller die GPU, desto größer der Effekt; vor einer Aufnahme ins README ist aber noch zusätzliche Validierung nötig. Die Benchmarks stammen von fastokens
Quelle: https://www.gartner.com/en/newsroom/press-releases/2026-07-2...
Es wirkt nützlicher für die Offline-Vorbereitung von Pretraining-Daten als für den Inferenzzeitpunkt. Wenn man mehrere Terabyte Text für einen Trainingskorpus tokenisiert, spart das Zeit und Kosten und verkürzt auch den Iterationszyklus beim Abstimmen des Datensatzes
Ingenieurskunst darauf zu verwenden, einen Teil, der 0,1 % der Gesamtlaufzeit ausmacht, 1.000-mal schneller zu machen, ist wohl die softwareentwicklertypischste Handlung überhaupt
https://x.com/mitchellh/status/2074225453217505494
LLMs liegen den Grenzen einer 1.000-fachen Verbesserung viel näher, aber selbst grundlegende PyTorch-Operationen sind oft doppelt so langsam wie eine simple Neuschreibung, und bessere Scheduling-Algorithmen bringen teils 5- bis 10-fache Verbesserungen. Schnelle Tokenisierung könnte andere Funktionen ermöglichen, die bisher ignoriert wurden, weil sie nicht realisierbar war
Die Leistung ist so unglaubwürdig hoch, dass man lange auf die Zahlen im Diagramm schauen muss, um sie zu begreifen
Genau so etwas wird auch in ClickHouse gebraucht; wir wollen es unter https://github.com/ClickHouse/ClickHouse/issues/108247 testen
Das README könnte die Leistung pro Kern stärker betonen, und ich frage mich, ob vollständiges Hash-Table-Matching dem eigentlichen Algorithmus helfen würde
Dann fragt man sich, wie viele 1.000-fache Optimierungschancen in anderen Teilen der Inferenz-Pipeline noch übrig sind