分词器
3 秒看懂
分词器(Tokenizer)是大型语言模型将原始文本转化为模型可运算的离散符号(token)序列的核心组件。它定义了模型的“词汇量”,直接决定模型如何理解每个字符、单词与上下文,并影响推理成本、多语言能力以及最大有效上下文长度。
3 分钟产业解释
在 ChatGPT、LLaMA、文心一言等大模型中,用户输入的任意文本并不能直接被 Transformer 计算。Tokenizer 就是那座桥梁:它先把文本规范化(例如处理全半角、大小写),再按照一个学好的子词词表,将文本切割成 token 序列,最后将每个 token 映射为一个整数 ID,送入嵌入层。
主流的子词分词方案包括 BPE(字节对编码)、WordPiece、Unigram 和 SentencePiece。这些算法的目标是在“词汇量不宜过大(以免嵌入矩阵巨重)”与“尽可能保留完整单词语义”之间取得平衡。分词器的词汇量通常设定在 3 万到 10 万之间,多语言模型会用到 25 万甚至更多。对于未知字符,现代分词器会回退到字节级的表示(byte‑level BPE),彻底杜绝 <UNK>(未知词标记)的出现。
产业中,分词器不仅是模型训练的一个预处理环节,更渗透到服务和商业模型:API 调用按 token 计费、上下文窗口以 token 数衡量、Prompt 设计需要计算 token 长度。一套高效、一致的分词器库(如 HuggingFace tokenizers、OpenAI tiktoken)已成为大模型生态的标配基础设施。
15 分钟专家深入
Tokenization 流水线
一个完整的文本到 token 的流水线通常包括:
- 规范化(Normalization):统一字符形式,例如全角转半角、大小写折叠、Unicode 正规化(NFKC/NFD)。
- 预分词(Pre‑tokenization):将文本初步拆分为“词”或“字符”段。常见方法是按空格和标点分割,或者基于正则表达式。
- 分词模型(Tokenization Model):在预分词的基础上,应用子词合并或分割算法,将每个段进一步划分为更小的 token。这是整个系统的核心。
- 后处理(Post‑processing):添加特殊 token(如 [CLS]、[SEP]、<s>、</s>、<pad>),并生成 attention mask 等。
主流子词算法概览
- BPE(Byte Pair Encoding):从字符开始,反复合并出现频率最高的符号对,直到达到设定的词汇量。GPT‑2、RoBERTa 均使用 BPE。因其基于频率,确定性强,且易于实现。
- WordPiece:类似 BPE,但合并的依据是最大化训练语料的似然(即选择能最大提升语言模型概率的符号对)。BERT 采用此方案,词汇量通常设为 30k 左右。
- Unigram Language Model:从一个大的种子词汇表出发,通过 EM 算法估算每个子词的概率,然后反复删除低概率子词,直到达到目标词汇量。T5、XLNet 使用这种分词器,训练时容易通过子词正则化(Subword Regularization)引入随机性,提升鲁棒性。
- SentencePiece:一种实现框架,将输入文本视为原始字节流,内部同时处理分词和去分词,语言完全无关。它既可以搭配 BPE,也可以搭配 Unigram。LLaMA 系列即基于 SentencePiece 的 BPE。
字节级回退(Byte‑level Fallback)
GPT‑2 之后的模型普遍将最小单元下沉到字节(共 256 个字节 token),所有 Unicode 字符都可以用 UTF‑8 字节序列表示。这样,任何生僻字或代码都不会出现 <UNK>。合并时在这些字节 token 上进行 BPE,最终词汇量 = 256 + 合并出的符号数。
工程视角
- Fast vs Slow Tokenizer:HuggingFace 提供了 Rust 实现的高速 tokenizer,并可以直接与 Python 绑定,速度提升数十倍。
- 训练成本:训练一个分词器本身不需要 GPU,但需要遍历大规模语料进行频率统计或 EM 迭代。词汇量越大,所需语料越多,否则许多子词得不到有意义的学习。
- 与模型训练的耦合:Tokenizer 的词汇量直接决定了模型嵌入层的大小(
V × d),通常在训练前固定,之后不可更改。因此分词器被视为模型权重的一部分,分发模型时需严格配套。
技术原理
BPE 的合并过程(确定性)
假设语料中只有单词 “low”、“lower”、“newest”。初始词汇为所有出现过的字符:{l,o,w,e,r,n,s,t}(空格作为单词分隔符,不参与合并)。
- 遍历语料,统计每个单词内部相邻符号对的频率。例如在 “l o w” 中,
l o出现了 1 次,“o w” 出现了 1 次;在 “l o w e r” 中,“o w” 出现 1 次等。找出最高频的符号对,如o w在 “low” 和 “lower” 中共出现 2 次,为最高频之一。 - 将最高频符号对(比如
o w)合并成一个新符号ow,更新词汇表并将语料中所有o w替换为ow。 - 重复步骤 1‑2,直到词汇表大小达到设定的
V(例如 32,000)。
代码化伪逻辑:
vocab = set(all characters)
pairs = count_bigram_freq(corpus)
while len(vocab) < target_vocab_size:
best_pair = max(pairs, key=pairs.get)
vocab.add(best_pair)
corpus = merge_corpus(corpus, best_pair)
pairs = recount_pairs(corpus)
WordPiece 的概率合并
不是根据频率,而是计算一个语言模型下的似然增益。假设现有词汇表 V,对每个候选合并符号对 (a, b) 组成新符号 ab,计算:
score = (freq(ab) / (freq(a) * freq(b)))
选择使训练集对数似然上升最多的合并。因此 WordPiece 更容易保留常见且不可分割的组合,而 BPE 可能因高频噪声合并错误。
Unigram 模型与 Viterbi 分割
Unigram 假设每个 token 独立出现:
P(x) = ∏_{i=1}^n p(x_i)
给定一个文本序列,用 Viterbi 算法寻找使 P 最大的分割方案。训练时,通过 EM 算法交替更新每个子词的概率,并逐渐删去概率低于阈值的子词,直至词汇量 V。训练完成后,可使用子词正则化:在 Viterbi 生成的多个合理分割中按概率采样,增加模型对分词变异性的鲁棒性。
Byte‑level BPE 示例
输入“你好”的 UTF‑8 编码为 \xe4\xbd\xa0\xe5\xa5\xbd(6 个字节)。初始字节 token 对应 256 个 ID。经过 BPE 合并,可能形成 “\xe4\xbd” 和 “\xe5\xa5” 等复合字节 token。最终词表包含这些字节组合。无论什么语言、表情符号、代码,都能表示为 token 序列。
关键参数
vocab_size:目标词汇量,影响嵌入矩阵体积和子词粒度。character_coverage:在 Unigram 种子中,覆盖多少比例的字符种类,影响稀有字符的处理。max_sentencepiece_length:SentencePiece 限制的 token 长度,防止过长的字节序列合并。byte_fallback:是否启用字节级回退,若启用则不会产生<UNK>。
(注:具体数值因模型而异,未列明硬规格,以上为机制定性描述。)
技术演进史
- 基于词的分词(2013 以前):使用预先定义的词典,将文本按空格和切词规则分成词。致命缺陷:词表巨大,OOV 严重。
- 字符级分词:每个字符为一个 token。词汇量小但序列极长,模型难以捕获长距离语义,训练慢。
- BPE 引入机器翻译(Sennrich et al., 2016):将 BPE 从数据压缩迁移到 NLP,有效缓解了稀有词翻译问题,拉开子词时代序幕。
- WordPiece 被 BERT 采纳(Devlin et al., 2019):沿袭语音搜索中的 WordPiece,BERT 的 30,522 词汇量成为事实标准之一,推动预训练分词器普及。
- Unigram 与 SentencePiece(Kudo, 2018; Kudo & Richardson, 2018):提出语言完全无关的一体化方案,支持子词正则化,被 T5、ALBERT、LLaMA 等众多后续模型所使用。
- 字节级 BPE(Radford et al., 2019):GPT‑2 直接将字节作为最小单位,消除了
<UNK>,使模型能够处理任意 Unicode 文本,成为后续 GPT‑3、GPT‑4 分词器的基础。 - 现代化的专用实现:HuggingFace
tokenizers(Rust, 2020)提供超高速无状态分词,OpenAItiktoken为 GPT‑3.5/4 提供确定性且高效的分词,并与 API 计费体系紧耦合。 - Token‑free 范式的探索:ByT5、CANINE 等尝试直接以字节或像素为输入,但尚未动摇子词分词器的主导地位。
技术路线对比
| 方案 | 代表模型 | 底层算法 | 最小单元 | 词汇量典型范围(1) | 是否可逆(2) | 多语言友好 | 去词 (detokenization) |
|---|---|---|---|---|---|---|---|
| BPE | GPT‑2, RoBERTa | 频率合并的 BPE | 字符/字节 | 50k‑60k | 需空格处理 | 一般(未统一) | 需还原空格 |
| WordPiece | BERT | 似然合并的 BPE | 字符 | 约30k | 需处理 ## 前缀 | 一般 | 拼接后去前缀 |
| Unigram (SentencePiece) | T5, XLNet | 概率语言模型剪枝 | 字符/字节 | 32k‑64k | 是(可重建) | 好(语言无关) | 直接拼接 |
| Byte‑level BPE (SentencePiece) | LLaMA 2, GPT‑4(3) | BPE 在字节流上 | 字节 | 32k‑100k(4) | 是(字节级恢复) | 极好(无OOV) | 字节拼回 UTF‑8 |
| 无分词(token‑free) | ByT5 | 直接处理字节序列 | 字节 | 256 | 是 | 完美 | 字节还原 |
注:(1) 根据相关论文常见配置及社区实践估算; (2) 指是否可以从 token 序列无损恢复原始文本字节;(3) GPT‑4 分词器未完全开源,但基于字节级 BPE,词汇量超过 100k [据 OpenAI 技术报告/API 文档];(4) 具体以模型发布版本为准。
上下游
上游:语料与工具
- 训练语料:分词器需先在目标领域的大规模无标注文本上进行训练,语料规模通常与后续预训练语料相同或更大范围。语料质量直接影响子词合并的合理性和稀有词的覆盖度。
- 开发工具库:
HuggingFace tokenizers:Rust 实现,支持 BPE、WordPiece、Unigram,提供快速训练和批量编码。SentencePiece(Google):内置 BPE 和 Unigram,C++ 核心,命令行和 Python 接口。tiktoken(OpenAI):为 GPT 系列定制的 Python 库,仅用于推断,不支持训练新分词器。YouTokenToMe等第三方库:追求更快的 BPE 训练。
- 训练过程:需要统计全语料的符号对频率或采用在线增量训练。BPE 训练 I/O 密集,SentencePiece 可实时训练。
下游:模型与推理
- 预训练/微调:分词器与模型权重绑定,任何模型权重分发必须包含对应的分词器配置(
tokenizer.json或sp.model)。 - 推理服务:用户 Query 先经 tokenizer 编码为 IDs,模型推理生成 token IDs,再由 tokenizer 解码为可读文本。
- Token 计数与计费:OpenAI、Anthropic 等 API 按 token 总量计费,需用官方提供的分词器准确计数,一套 prompt+completion 消耗的 token 数直接影响成本。
- 上下文窗口截断:当输入 token 数超过模型最大上下文长度时,需按分词器决定如何截断(保留最近或最重要的部分)。
关键指标
- 词汇量大小 (V):通常在 3 万~10 万。V 越大,每个 token 承载的语义更丰富,但嵌入矩阵参数量
V*d更重。 - 未知词率(OOV rate):现代字节级分词器可做到 0%,不再出现
<UNK>。 - 平均 token 长度(压缩率):以平均每个单词被拆成多少个 token 来度量。英文 BPE 词汇量 50k 时,典型值约为 1.3
1.5 个 token/词。中文每个汉字可能 12 个 token。压缩率影响同等文本所需的 token 数,进而影响推理成本和延迟。 - 分词速度:通常用 token/sec 衡量,Rust 实现的 tokenizer 可达 GB/s 级别,对实时服务影响很小。
- 跨平台一致性:同一模型的 tokenizer 在不同运行环境(Python、Rust、移动端)的解码结果必须完全一致,否则会导致输出错乱。
- 嵌入参数量:
V * d_model,当 V 较大时,这部分参数占模型总参数的比例在不同规模模型中差异很大:对于BERT-base等中小模型,嵌入参数可能占20%左右;而对于GPT-3等超大模型,占比可低至0.1%以下,直接增加 GPU 显存开销。
供需与市场数据
分词器本身是软件库,不形成独立市场交易,但其演进受大模型生态的强烈需求驱动:
- 需求端:所有部署大模型的企业都需要配套分词器。高效的多语言分词器成为模型出海和覆盖多语种的关键,能直接提升非英语用户的体验。云服务商按 token 计费的模式使得分词效率(同样语义消耗更少 token)可转化为成本优势。
- 供给端:开源生态高度成熟,HuggingFace tokenizers 库已被数千个模型采用,月下载量极高。Google 的 SentencePiece 也是 Linux 发行版及众多深度学习框架的默认组成部分。OpenAI tiktoken 虽然只服务于自家模型,但其设计思路影响了后续闭源模型的分词器选型。
- 竞争动态:字节级 BPE + 大规模词汇量(100k 级)已成为领先模型的标配,新进入者若采用过小词表或缺乏字节回退,会在多语言评测中显著落后。因此,分词器的选择和定制逐渐成为大模型技术栈中不容忽视的一环。
代表公司与资本映射
- OpenAI:开发
tiktoken,内置于 GPT‑3.5、GPT‑4 体系。虽然库本身开源,但分词器配置绑定其闭源模型,构筑了与 API 计费体系紧密耦合的护城河。 - Meta:LLaMA 系列使用基于 SentencePiece 的 BPE 分词器,并在开源模型中与权重一并发布,影响了大量衍生模型的标准。
- Google:研发并开源 SentencePiece,被 T5、PaLM、Gemini 等内部模型及大量外部模型采用,奠定了语言无关子词分词的事实标准。
- HuggingFace:通过维护
tokenizers(Rust)与transformers深度集成,成为开源模型分发的默认枢纽。其生态控制力部分体现在几乎所有社区模型都使用 HF tokenizer 格式。 - 其他大模型厂商(Anthropic、百度、阿里等):通常基于 BPE 或 Unigram 自研分词器,与自身训练数据对齐,构建差异化语言覆盖能力。
资本映射层面,分词器并非独立投资标的,而是评估一家 AI 公司技术自洽性和工程能力的窗口。拥有自研高效分词器并成功封装为模型服务能力的企业,在成本控制和多语言拓展上具备潜在优势。
投资逻辑
- token 经济模型:API 按 token 计费,分词器的压缩率直接影响每一条请求的收费 token 数。若某家厂商的分词器能使同等语义消耗更少 token,则其 API 定价在同等效果下更具竞争力,或能获取更高利润。
- 多语言能力与市场扩张:一个优秀的字符层级或字节级分词器能平滑支持上百种语言,无需为每种语言独立调优。此类技术积累可加速全球化产品落地,影响游戏、社交、跨境电商等出海赛道。
- 模型分发标准:HuggingFace 生态的分词器格式已成为事实标准,其背后的商业化路径(如 Inference Endpoints、AutoTrain)可绑定用户。投资于平台型工具链(虽不一定直接上市)可关注相关开源公司的商业化进展。
- 风险与替代:token‑free 架构或新型分词范式若在保持性能的同时大幅简化流水线,可能削弱现有分词器壁垒。但短期内,子词分词器仍为主流,相关投入具备确定性的技术红利。
常见误读纠偏
- “分词器只是简单切词,模型好坏主要看 Transformer 架构” 实际上,分词器定义了模型最基本的输入单元,大量下游问题(如代码补全、多语言拼写、数字运算)若在 tokenization 层面被不合理拆分,会导致模型难以学习。错误的词汇表可能直接使模型对某些任务“致盲”。
- “词表越大越好” 词表增大会增加嵌入矩阵的参数量和训练开销。过大的词表使每个 token 出现频率更低,其 token embedding 训练不充分,反而损害泛化。极端情况下,冗余 token 浪费显存且降低批处理效率。因此必须基于语料统计在粒度与稀疏性之间折中。
- “Unigram 分词器每次结果固定” 当应用子词正则化时,Unigram 会从概率分布中采样分割方案,相同的输入可得到不同的 token 序列。这实际上是训练时的一种数据增强,而非缺陷,但推理时需固定为最佳分割(关闭采样)。
- “detokenization 完全可逆” 许多分词器在规范化阶段会丢失信息(如去掉特殊空白字符),导致去分词后无法保留原始格式。只有严格基于字节级且规范化可逆的方案才能恢复原始字节流。
学习路径
- 快速上手:使用 HuggingFace
tokenizers库,加载bert-base-uncased或gpt2分词器,观察编码输出、token 到 ID 的映射、attention mask 生成。 - 训练自定义分词器:选择一个中文或混合语言语料,训练 BPE tokenizer,调整
vocab_size和min_frequency参数,对比不同词汇量下编码长度与罕见字覆盖率。 - 理解核心论文:
- Sennrich et al. (2016) “Neural Machine Translation of Rare Words with Subword Units” – BPE 在 NLP 的创始论文。
- Kudo (2018) “Subword Regularization: Improving Neural Network Translation Models with Multiple Subword Candidates” – Unigram 及正则化。
- Kudo & Richardson (2018) “SentencePiece: A simple and language independent subword tokenizer and detokenizer for Neural Text Processing” – 框架设计。
- 深入代码:阅读
tokenizers的 Rust 源码中 BPE 的Trainer和Model部分,理解优先级队列、checkpointing 及并行化实现。 - 排查工程问题:在推理服务中解决 tokenizer 与模型不匹配、版本不一致导致的输出乱码;使用
tiktoken准确估算 token 数以优化 prompt 设计。
一句话总结
分词器是大模型的“文字感知器”,它以无懈可击的字节回退和精妙的子词平衡,将人类语言的流变符号转化为数学模型可以计算的固定颗粒度信号,其设计水准直接封印着模型的多语言智慧与成本边界。
延伸阅读与来源
- Sennrich, R., Haddow, B., & Birch, A. (2016). Neural Machine Translation of Rare Words with Subword Units. ACL.
- Schuster, M., & Nakajima, K. (2012). Japanese and Korean voice search. ICASSP. (WordPiece 起源)
- Kudo, T. (2018). Subword Regularization: Improving Neural Network Translation Models with Multiple Subword Candidates. EMNLP.
- Kudo, T., & Richardson, J. (2018). SentencePiece: A simple and language independent subword tokenizer and detokenizer for Neural Text Processing. EMNLP.
- Radford, A., et al. (2019). Language Models are Unsupervised Multitask Learners. OpenAI Blog.
- HuggingFace Tokenizers: https://github.com/huggingface/tokenizers
- OpenAI tiktoken: https://github.com/openai/tiktoken