Gigatoken:比 HuggingFace 快 1000 倍的开源分词器

7/22/2026开源AINLP

大语言模型训练的第一步是把文本切成 token。这个过程看似简单,实际上在万亿 token 级别的数据集上极其耗时。2026 年 7 月,斯坦福博士生 Marcel Rød 发布了开源分词器 Gigatoken,在主流 BPE 词表上实现了比 HuggingFace tokenizers 快 500 到 1000 倍的吞吐速度,比 OpenAI 的 tiktoken 快约 100 倍。

Marcel Rød 在 X 上发布 Gigatoken

这个数字听起来夸张,但 benchmark 数据支撑得相当扎实。在一颗 Apple M4 Max(16 线程)上,用 GPT-2 词表对 11.9 GB 的 OpenWebText 文本进行编码:

分词器吞吐速度相对 HF 加速比
Gigatoken8.79 GB/s1268×
tiktoken (OpenAI)62.8 MB/s
HF tokenizers6.9 MB/s基准

在 AMD EPYC 9565 双路 144 核服务器上,差距进一步拉大:Gigatoken 以 24.53 GB/s 的速度处理完 11.9 GB 文本只需 0.5 秒,而 HF tokenizers 处理同样数据的 100 MB 样本需要 4 秒。Rød 在 README 中给出了一个直观的比喻:按照 EPYC 的速度,对整个 Common Crawl(约 130 万亿 token,通常被认为是整个互联网的文本量)进行完整分词,只需要 6.5 小时。

为什么现有分词器这么慢

分词器的工作流程分两步。第一步是预分词(pretokenization),用正则表达式把原始文本切成词片段;第二步是对每个片段做字节对编码(BPE),将字节序列合并为词表中的 token。

当前主流分词器的瓶颈几乎全部在第一步。以 HuggingFace tokenizers 为例,虽然核心用 Rust 编写且支持多线程,但预分词阶段依赖的正则表达式引擎是通用实现,没有针对 BPE 的字符集做任何优化。tiktoken 情况类似。

Rød 的核心做法是用 SIMD(单指令多数据)指令手写了预分词逻辑。SIMD 允许一条指令同时处理多个字符,在现代 CPU 上,AVX-512 可以一次处理 64 字节,NEON(ARM)处理 16 字节。把正则匹配从逐字符处理改为批量操作后,预分词阶段的吞吐从 MB/s 级直接跃升到 GB/s 级。

第二个优化点是预分词缓存。自然文本中词的分布呈极长尾形态——少数高频词反复出现,大量低频词只出现一两次。Gigatoken 用并发数据结构维护一个预分词缓存,遇到已见过的词直接查表返回编码结果,跳过 BPE 合并过程。缓存的管理本身是个难题:缓存会快速膨胀,需要在内存占用和命中率之间找平衡。

第三个优化来自减少 Python 交互开销。Gigatoken 提供了原生 API(encode_files),让 Rust 直接从磁盘读取数据并分词,完全绕过 Python 层。兼容模式下虽然也能获得显著加速,但由于需要通过 Python 传参,性能会打折。

覆盖范围

Gigatoken 支持几乎所有主流 BPE 词表,包括:

词表族覆盖模型
GPT-2 / GPT-OSSGPT-2, GPT-OSS
Llama 3/3.1/3.2Llama 3 全系列, DeepSeek-R1-Distill-Llama, Hermes 3
Llama 3.3Llama 3.3, SmolLM3, Ultravox
Llama 4Llama 4 全系列
Qwen 2/2.5Qwen 2/2.5(含 Coder/VL), Qwen3-Coder, DeepSeek-R1 Qwen distill
Qwen 3Qwen 3(含 Embedding/Reranker), Qwen2.5-Omni
DeepSeek V3/R1/V4DeepSeek V3/V3.1/V3.2, R1, V4 Flash/Pro
GLM 4 / GLM 5GLM 4.1V/4.5/4.7, GLM 5/5.2
Phi-4 / Phi-4-miniPhi-4, Phi-4-mini, Phi-4-multimodal
Kimi K2Kimi K2/K2.5/K2.6/K2.7, Kimi-Linear, Kimi-VL
Gemma 3/4Gemma 3 (270M-27B), Gemma 4 全系列

SentencePiece 类词表(Gemma 1-3、Mistral、CodeLlama 等)目前支持但优化程度较低,加速比在 7-21 倍之间。Rød 在 README 中说明这是低优先级,因为使用 SentencePiece 的模型数量正在减少。

跨硬件表现

Gigatoken 在三种代表性 CPU 上都展现了稳定的加速效果。以下是 GPT-2 词表在三种硬件上的对比:

CPUGigatokenHF tokenizerstiktoken加速比 (vs HF)
AMD EPYC 9565 (144 核)24.53 GB/s24.8 MB/s36.0 MB/s989×
Apple M4 Max (16 核)8.79 GB/s6.9 MB/s62.8 MB/s1268×
AMD Ryzen 7 9800X3D (16 核)6.27 GB/s59.0 MB/s92.1 MB/s106×

在消费级 8 核 Ryzen 上 106 倍的加速比远低于服务器和工作站级别。Rød 解释这是因为在核心数少的场景下,Python 调用开销和线程同步成本占比更高。

对于不同词表,加速比也有差异。Llama 3 词表在 M4 Max 上达到 676 倍加速,而 Gemma 3(SentencePiece)只有 17 倍。DeepSeek V3 词表达到 788 倍加速。

使用方式

Gigatoken 提供两种模式。兼容模式改动最小,一行代码替换现有 HF 或 tiktoken 分词器:

python
import gigatoken as gt

hf_tokenizer = ...  # 现有 HF tokenizer 实例
tokenizer = gt.Tokenizer(hf_tokenizer).as_hf()
tokens = tokenizer.encode_batch(["This is a test string"])

原生 API 性能最高,直接读文件分词:

python
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)

安装方式也极简:

bash
pip install gigatoken

实际影响

分词器速度对哪些场景有实质影响?

大规模数据集预处理是最大的受益场景。训练万亿 token 级别的模型时,数据预处理管线中的分词步骤过去需要数天。用 Gigatoken 后,同样工作可以在数小时内完成。这对频繁迭代训练数据的研究团队来说直接缩短了实验周期。

长上下文推理的输入编码是第二个场景。当上下文窗口扩展到百万 token 级别时,输入文本的分词时间不再是可忽略的常数项。Gigatoken 将这部分开销压到了接近零。

在线服务和实时应用同样受益。高并发 API 场景下,每请求的分词延迟降低意味着更低的 P99 延迟和更高的吞吐。对于需要实时处理大量文本输入的应用(如检索增强生成系统中的文档切分),这意味着架构设计上可以去掉预分词缓存层。

a16z 合伙人 Guido Appenzeller 在 X 上的评价是:"Tokenization is now free."(分词的成本归零了。)这个判断虽然带营销色彩,但方向上没有问题——当分词速度从 MB/s 跨入 GB/s,它在 LLM 推理和训练管线的总耗时占比从显著项变为噪音项。

技术背景

Marcel Rød 是斯坦福大学三年级博士生,研究方向是机器学习与系统交叉领域,同时担任 CS336(Language Modeling from Scratch)课程的助教。该课程由 Tatsu Hashimoto 和 Percy Liang 教授开设,内容涵盖从数据获取到模型训练的完整 LLM 工程链路。Gigatoken 正是从课程实践中孵化出的项目——CS336 要求学生从头实现完整的语言模型训练管线,分词作为第一步,其性能瓶颈直接暴露在了学生面前。

Gigatoken 用 Rust 编写,MIT 许可证开源。代码库的主要部分由 Rød 手写完成,AI 辅助集中在 API 设计、跨架构 SIMD 移植(AVX-512/AVX2/NEON 之间)和最后的性能调优阶段。项目目前在 GitHub 上获得超过 1000 stars。

Gigatoken 项目地址:github.com/marcelroed/gigatoken

PyPI 包:pip install gigatoken

推荐阅读