메뉴
HN
Hacker News 6일 전

기가토큰: 기존 대비 최대 1000배 빠른 토크나이저

IMP
8/10
핵심 요약

최대 1000배 빠른 속도를 자랑하는 새로운 언어 모델 토크나이저인 '기가토큰(GigaToken)'이 공개되었습니다. 이 도구는 기존 허깅페이스(HuggingFace) 토크나이저의 코드를 거의 수정하지 않고도 완벽하게 호환되며, 초당 기가바이트(GB/s) 단위의 텍스트 데이터 처리를 가능하게 합니다. 대규모 언어 모델(LLM) 학습을 위한 방대한 데이터 전처리 시간을 혁신적으로 단축시킬 수 있어 AI 개발 실무자들에게 매우 유용한 솔루션입니다.

번역된 본문

기가토큰(GigaToken)은 허깅페이스(HuggingFace) 토크나이저보다 약 1000배 빠르며, 기존 코드와 바로 교체할 수 있는 완벽한 호환(drop-in replacement) 기능을 제공합니다. 텍스트 데이터를 초당 기가바이트(GB/s) 단위로 토큰화할 수 있습니다! 참고로 기존의 허깅페이스 토크나이저와 틱토큰(tiktoken) 역시 이미 멀티스레드를 지원하는 러스트(Rust)로 구동되고 있다는 점을 명심하세요.

기가토큰이란 무엇인가요? 기가토큰은 언어 모델링을 위한 가장 빠른 토크나이저입니다. 다양한 CPU 하드웨어와 거의 모든 일반적으로 사용되는 토크나이저를 지원합니다. 토크나이저와 CPU별 처리량에 대한 자세한 수치는 벤치마크 섹션을 참조하세요.

설치 pip install gigatoken

사용법 기가토큰은 자체 API를 사용하거나, 허깅페이스 토크나이저 또는 틱토큰과의 호환 모드(Compatibility Mode)를 통해 사용할 수 있습니다.

호환 모드 (가장 간편한 방법) import gigatoken as gt

기존 허깅페이스 토크나이저 사용법에서 최소한의 코드 수정 (호환 모드)

hf_tokenizer = ... tokenizer = gt.Tokenizer(hf_tokenizer).as_hf()

토크나이저는 기존 hf_tokenizer와 동일한 컨텍스트에서 사용될 수 있습니다.

tokens = tokenizer.encode_batch(["This is a test string", "And here is another"])

또는 틱토큰(tiktoken)과 함께 사용

tiktokenizer = ... tokenizer = gt.Tokenizer(tiktokenizer).as_tiktoken()

이제 기존 틱토큰 토크나이저처럼 작동합니다.

tokens = tokenizer.encode_batch(["This is a test string", "And here is another"])

이 설정에서 허깅페이스 토크나이저를 사용할 때와 완전히 동일한 출력 결과를 얻기 위해 상당한 노력을 기울였지만, 이는 성능 저하로 이어지는 편입니다. 물론 전반적으로 훨씬 빠른 성능을 기대할 수 있지만, 기가토큰 API를 사용할 때 기대할 수 있는 1000배의 속도에는 미치지 못합니다.

기가토큰 API (가장 빠른 방법) import gigatoken as gt tokenizer = gt.Tokenizer("Qwen/Qwen3-8B") # 허깅페이스 모델 이름을 인수로 받음 file_source = gt.TextFileSource(["owt_train.txt"], separator=b"<|endoftext|>") tokens = tokenizer.encode_files(file_source)

기가토큰 API를 사용하면 러스트(Rust) 구현체가 데이터를 직접 읽어오고, 최대한의 병렬 처리를 허용하는 동시에 모든 오버헤드를 최소화합니다. 단, 이 API를 통해 파이썬 데이터 구조를 전달하면 파이썬에서 데이터를 읽어오는 오버헤드가 여전히 발생한다는 점에 유의하세요.

벤치마크 owt_train.txt (11.9 GB) 기반 인코딩 처리량 — AMD EPYC 9565 72-Core Processor x 2 sockets (144 cores)

  • GPT-2: 기가토큰 24.53 GB/s, HF 토크나이저 24.8 MB/s, 틱토큰 36.0 MB/s (대비 각각 989배, 681배 빠름)
  • Phi-4: 기가토큰 24.00 GB/s, HF 토크나이저 29.9 MB/s (대비 801배 빠름)
  • GPT-OSS: 기가토큰 23.96 GB/s, HF 토크나이저 49.7 MB/s, 틱토큰 42.8 MB/s (대비 각각 482배, 560배 빠름)
  • OLMo 2 / 3: 기가토큰 23.06 GB/s, HF 토크나이저 27.7 MB/s (대비 833배 빠름)
  • Nemotron 3: 기가토큰 22.79 GB/s, HF 토크나이저 49.4 MB/s (대비 462배 빠름)
  • Qwen 3: 기가토큰 22.16 GB/s, HF 토크나이저 34.2 MB/s (대비 648배 빠름)
  • Llama 3 / 3.1 / 3.2: 기가토큰 22.15 GB/s, HF 토크나이저 48.5 MB/s (대비 457배 빠름)
  • GLM 5: 기가토큰 20.97 GB/s, HF 토크나이저 74.8 MB/s (대비 280배 빠름)
  • Llama 3.3: 기가토큰 20.82 GB/s, HF 토크나이저 48.3 MB/s (대비 431배 빠름)
  • Llama 4: 기가토큰 20.77 GB/s, HF 토크나이저 72.7 MB/s (대비 286배 빠름)
  • GLM 4: 기가토큰 20.61 GB/s, HF 토크나이저 72.3 MB/s (대비 285배 빠름)
  • Phi-4-mini: 기가토큰 20.05 GB/s, HF 토크나이저 27.6 MB/s (대비 726배 빠름)
  • DeepSeek V3 / R1 / V4: 기가토큰 19.69 GB/s, HF 토크나이저 26.2 MB/s (대비 750배 빠름)
  • Qwen 2 / 2.5: 기가토큰 19.12 GB/s, HF 토크나이저 27.7 MB/s (대비 691배 빠름)
  • Kimi K2: 기가토큰 18.85 GB/s (비교군 없음)
  • Qwen 3.5 / 3.6: 기가토큰 15.49 GB/s, HF 토크나이저 27.7 MB/s (대비 558배 빠름)
  • Gemma 4: 기가토큰 4.82 GB/s, HF 토크나이저 334.1 MB/s (대비 14배 빠름)
  • ModernBERT: 기가토큰 4.18 GB/s, HF 토크나이저 26.9 MB/s (대비 155배 빠름)
  • Mistral 7B v0.3: 기가토큰 3.57 GB/s, HF 토크나이저 354.7 MB/s (대비 10배 빠름)
  • TinyLlama / Phi-3 (Llama 2): 기가토큰 3.48 GB/s, HF 토크나이저 323.6 MB/s (대비 11배 빠름)
  • CodeLlama: 기가토큰 3.47 GB/s, HF 토크나이저 347.4 MB/s (대비 10.0배 빠름)
  • Gemma 3: 기가토큰 3.43 GB/s, HF 토크나이저 357.2 MB/s (대비 9.6배 빠름)
  • Gemma 1: 기가토큰 2.51 GB/s, HF 토크나이저 342.2 MB/s (대비 7.3배 빠름)

owt_train.txt (11.9 GB) 기반 인코딩 처리량 — Apple M4 Max (16 cores)

  • GPT-2: 기가토큰 8.79 GB/s, HF 토크나이저 6.9 MB/s, 틱토큰 62.8 MB/s (대비 각각 1,268배, 140배 빠름)
  • Nemotron 3: 기가토큰 7.82 GB/s, HF 토크나이저 10.9 MB/s (대비 715배 빠름)
  • Phi-4: 기가토큰 7.76 GB/s, HF 토크나이저 7.7 MB/s (대비 1,012배 빠름)
  • Llama 3 / 3.1 / 3.2: 기가토큰 7.60 GB/s, HF 토크나이저 11.2 MB/s (대비 676배 빠름)
  • OLMo 2 / 3: 기가토큰 7.56 GB/s, HF 토크나이저 5.8 MB/s (대비 1,299배 빠름)
  • Llama 3.3: 기가토큰 7.50 GB/s, HF 토크나이저 15.7 MB/s (대비 479배 빠름)
  • Phi-4-mini: 기가토큰 6.97 GB/s, HF 토크나이저 7.2 MB/s (대비 964배 빠름)
  • Kimi K2: 기가토큰 6.88 GB/s (비교군 없음)
  • Llama 4: 기가토큰 6.81 GB/s, HF 토크나이저 11.6 MB/s (대비 590배 빠름)
  • Qwen 2 / 2.5: 기가토큰 6.37 GB/s, HF 토크나이저 5.8 MB/s (대비 1,105배 빠름)
  • Qwen 3: 기가토큰 6.36 GB/s, HF 토크나이저 6.9 MB/s (대비 918배 빠름)
  • Qwen 3.5 / 3.6: 기가토큰 6.31 GB/s, HF 토크나이저 6.3 MB/s (대비 994배 빠름)
  • GPT-OSS: 기가토큰 6.20 GB/s, HF 토크나이저 20.2 MB/s, 틱토큰 87.2 MB/s (대비 각각 306배, 71배 빠름)
  • GLM 4: 기가토큰 6.17 GB/s, HF 토크나이저 15.8 MB/s (대비 392배 빠름)
  • DeepSeek V3 / R1 / V4: 기가토큰 5.68 GB/s, HF 토크나이저 7.2 MB/s (대비 788배 빠름)
  • GLM 5: 기가토큰 5.55 GB/s, HF 토크나이저 12.2 MB/s (대비 456배 빠름)
  • ModernBERT: 기가토큰 2.64 GB/s, HF 토크나이저 5.8 MB/s (대비 452배 빠름)
  • Mistral 7B v0.3: 기가토큰 1.99 GB/s (비교군 수치 생략)
원문 보기
원문 보기 (영어)
Gigatoken ~1000x faster than HuggingFace's tokenizers, drop-in replacement. Tokenize your text data at GB/s! Note that both HF tokenizers and tiktoken are already running multithreaded Rust! What is Gigatoken? Gigatoken is the fastest tokenizer for language modeling. It supports a wide range of CPU hardware, and nearly all commonly used tokenizers. See the Benchmarks section for detailed throughput numbers across tokenizers and CPUs. Installation pip install gigatoken Usage Gigatoken can be used with its own API, or in compatibility mode with HuggingFace Tokenizers or Tiktoken. Compatibility Mode (Easiest) import gigatoken as gt # Minimum change from existing HuggingFace tokenizers usage (compatibility mode) hf_tokenizer = ... tokenizer = gt . Tokenizer ( hf_tokenizer ). as_hf () # tokenizer can be used in the same contexts as hf_tokenizer tokens = tokenizer . encode_batch ([ "This is a test string" , "And here is another" ]) # OR with tiktoken tiktokenizer = ... tokenizer = gt . Tokenizer ( tiktokenizer ). as_tiktoken () # Now works like existing tiktoken tokenizers tokens = tokenizer . encode_batch ([ "This is a test string" , "And here is another" ]) A substantial amount of effort has been put into making sure the outputs match exactly with what you would get with HuggingFace Tokenizers in this setting, but this is at a non-negligible cost to performance. You can still expect way faster performance across the board, but not quite the 1000x you will get with the Gigatoken API. Gigatoken API (Fastest) import gigatoken as gt tokenizer = gt . Tokenizer ( "Qwen/Qwen3-8B" ) # Accepts HF model names file_source = gt . TextFileSource ([ "owt_train.txt" ], separator = b"<|endoftext|>" ) tokens = tokenizer . encode_files ( file_source ) Using the Gigatoken API lets the Rust implementation read data directly, and skips as much overhead as possible while allowing for maximum parallelism. Keep in mind that passing Python data structures through this API still incurs the overhead of reading from Python. Benchmarks Encoding throughput on owt_train.txt (11.9 GB) — AMD EPYC 9565 72-Core Processor x 2 sockets (144 cores) Tokenizer gigatoken HF tokenizers tiktoken vs HF vs tiktoken GPT-2 24.53 GB/s 24.8 MB/s 36.0 MB/s 989× 681× Phi-4 24.00 GB/s 29.9 MB/s — 801× — GPT-OSS 23.96 GB/s 49.7 MB/s 42.8 MB/s 482× 560× OLMo 2 / 3 23.06 GB/s 27.7 MB/s — 833× — Nemotron 3 22.79 GB/s 49.4 MB/s — 462× — Qwen 3 22.16 GB/s 34.2 MB/s — 648× — Llama 3 / 3.1 / 3.2 22.15 GB/s 48.5 MB/s — 457× — GLM 5 20.97 GB/s 74.8 MB/s — 280× — Llama 3.3 20.82 GB/s 48.3 MB/s — 431× — Llama 4 20.77 GB/s 72.7 MB/s — 286× — GLM 4 20.61 GB/s 72.3 MB/s — 285× — Phi-4-mini 20.05 GB/s 27.6 MB/s — 726× — DeepSeek V3 / R1 / V4 19.69 GB/s 26.2 MB/s — 750× — Qwen 2 / 2.5 19.12 GB/s 27.7 MB/s — 691× — Kimi K2 18.85 GB/s — — — — Qwen 3.5 / 3.6 15.49 GB/s 27.7 MB/s — 558× — Gemma 4 4.82 GB/s 334.1 MB/s — 14× — ModernBERT 4.18 GB/s 26.9 MB/s — 155× — Mistral 7B v0.3 3.57 GB/s 354.7 MB/s — 10× — TinyLlama / Phi-3 (Llama 2) 3.48 GB/s 323.6 MB/s — 11× — CodeLlama 3.47 GB/s 347.4 MB/s — 10.0× — Gemma 3 3.43 GB/s 357.2 MB/s — 9.6× — Gemma 1 2.51 GB/s 342.2 MB/s — 7.3× — Encoding throughput on owt_train.txt (11.9 GB) — Apple M4 Max (16 cores) Tokenizer gigatoken HF tokenizers tiktoken vs HF vs tiktoken GPT-2 8.79 GB/s 6.9 MB/s 62.8 MB/s 1,268× 140× Nemotron 3 7.82 GB/s 10.9 MB/s — 715× — Phi-4 7.76 GB/s 7.7 MB/s — 1,012× — Llama 3 / 3.1 / 3.2 7.60 GB/s 11.2 MB/s — 676× — OLMo 2 / 3 7.56 GB/s 5.8 MB/s — 1,299× — Llama 3.3 7.50 GB/s 15.7 MB/s — 479× — Phi-4-mini 6.97 GB/s 7.2 MB/s — 964× — Kimi K2 6.88 GB/s — — — — Llama 4 6.81 GB/s 11.6 MB/s — 590× — Qwen 2 / 2.5 6.37 GB/s 5.8 MB/s — 1,105× — Qwen 3 6.36 GB/s 6.9 MB/s — 918× — Qwen 3.5 / 3.6 6.31 GB/s 6.3 MB/s — 994× — GPT-OSS 6.20 GB/s 20.2 MB/s 87.2 MB/s 306× 71× GLM 4 6.17 GB/s 15.8 MB/s — 392× — DeepSeek V3 / R1 / V4 5.68 GB/s 7.2 MB/s — 788× — GLM 5 5.55 GB/s 12.2 MB/s — 456× — ModernBERT 2.64 GB/s 5.8 MB/s — 452× — Mistral 7B v0.3 1.99 GB/s 95.1 MB/s — 21× — Gemma 4 1.82 GB/s 85.2 MB/s — 21× — CodeLlama 1.73 GB/s 80.2 MB/s — 22× — TinyLlama / Phi-3 (Llama 2) 1.69 GB/s 80.1 MB/s — 21× — Gemma 1 1.42 GB/s 85.7 MB/s — 17× — Gemma 3 1.38 GB/s 82.2 MB/s — 17× — Encoding throughput on owt_train.txt (11.9 GB) — AMD Ryzen 7 9800X3D 8-Core Processor (16 cores) Tokenizer gigatoken HF tokenizers tiktoken vs HF vs tiktoken GPT-2 6.27 GB/s 59.0 MB/s 92.1 MB/s 106× 68× Phi-4 6.09 GB/s 55.4 MB/s — 110× — OLMo 2 / 3 6.06 GB/s 55.4 MB/s — 109× — Phi-4-mini 5.80 GB/s 54.6 MB/s — 106× — GPT-OSS 5.68 GB/s 79.6 MB/s 112.7 MB/s 71× 50× Qwen 3 5.34 GB/s 54.4 MB/s — 98× — Qwen 2 / 2.5 5.30 GB/s 51.7 MB/s — 103× — Llama 3.3 5.26 GB/s 79.9 MB/s — 66× — Llama 3 / 3.1 / 3.2 5.24 GB/s 79.5 MB/s — 66× — Kimi K2 5.23 GB/s — — — — Qwen 3.5 / 3.6 5.22 GB/s 51.6 MB/s — 101× — Nemotron 3 5.20 GB/s 79.0 MB/s — 66× — GLM 5 5.05 GB/s 79.5 MB/s — 63× — GLM 4 5.04 GB/s 79.5 MB/s — 63× — Llama 4 5.03 GB/s 78.2 MB/s — 64× — DeepSeek V3 / R1 / V4 4.21 GB/s 51.6 MB/s — 82× — ModernBERT 2.84 GB/s 52.1 MB/s — 54× — Mistral 7B v0.3 1.47 GB/s 91.6 MB/s — 16× — Gemma 4 1.45 GB/s 78.8 MB/s — 18× — CodeLlama 1.38 GB/s 85.2 MB/s — 16× — TinyLlama / Phi-3 (Llama 2) 1.37 GB/s 84.9 MB/s — 16× — Gemma 1 1.14 GB/s 84.9 MB/s — 13× — Gemma 3 1.12 GB/s 83.0 MB/s — 13× — Benchmark details OWT (openwebtext) was chosen because it's roughly representative of the text you get after extraction from CommonCrawl documents. Gigatoken encodes the whole file un-split, and is thus doing more work than the other tokenizers to find the split boundaries and automatically parallelize. HuggingFace tokenizers ( encode_batch_fast ) gets the first 100 MB and tiktoken ( encode_ordinary_batch ) the first 1 GB, both presplit on <|endoftext|> . This is fair because neither of the compared tokenizers do caching, meaning the speed is roughly uniform throughout processing. Tiktoken rows are currently only filled in for tokenizers with official support. The slowest rows are the SentencePiece-based tokenizers, which are not well optimized in Gigatoken. Each row is one distinct tokenizer (identical vocab/merges/pretokenizer), measured on a representative repo. If you don't see your tokenizer here, it's likely based on some existing one. For instance: Llama 3 / 3.1 / 3.2 — Llama 3 / 3.1 / 3.2, DeepSeek-R1-Distill-Llama, Hermes 3, Saiga, and other Llama-3 finetunes Llama 3.3 — Llama 3.3, Llama-3.1-Nemotron-Nano-VL, SmolLM3, Kanana 1.5, jina-embeddings-v5, Ultravox Qwen 2 / 2.5 — Qwen 2 and 2.5 (incl. Coder and VL), Qwen3-Coder, Qwen3-VL, DeepSeek-R1 Qwen distills, MiMo V2.5, MiniCPM-o 2.6, InternVL3 Qwen 3 — Qwen 3 (incl. Embedding and Reranker), Qwen2.5-Omni, Qwen3-VL-Embedding, MiMo V2.5 Pro, jina-reranker-m0, pplx-embed, MOSS-TTS, Zeta DeepSeek V3 / R1 / V4 — DeepSeek V3 / V3.1 / V3.2, R1, V4 Flash and Pro, DeepSeek-VL2 GLM 4 — GLM 4.1V, 4.5, and 4.7 GLM 5 — GLM 5 / 5.2 and GLM-4.7-Flash Nemotron 3 — Nemotron 3 Nano, Super, and Ultra Kimi K2 — Kimi K2 / K2.5 / K2.6 / K2.7, Kimi-Linear, Kimi-VL, Moonlight Phi-4-mini — Phi-4-mini and Phi-4-multimodal TinyLlama / Phi-3 (Llama 2) — TinyLlama, Phi-3-mini, Phi-3.5-mini and Phi-3.5-vision (the Llama 2 vocab) Gemma 3 — Gemma 3 (270M–27B) and EmbeddingGemma Gemma 4 — Gemma 4 (dense, MoE, and E-series) and DiffusionGemma FAQ Q: Did you just way over-optimize for a specific CPU and tokenizer? How is it so fast? No, I way over-optimized for every combination of these! The results are very consistent across CPUs (modern x86 and ARM), and across specific tokenizers. The major improvements are in optimizing heavily an implementation that usually is outsourced to a Regex engine (pretokenization) using SIMD, minimizing branching and other tricks, as well as heavily optimizing caching of pretoken mappings (if a word has been seen before, look it up its encoded tokens efficiently). Caching is a very hard problem in this domain since the cache grows very quickly, and pretoken distributions are very long-tailed. Some ga