Tokenizer 设计哲学:BPE、WordPiece 与 Unigram 的权衡

深入剖析 LLM Tokenizer 的核心算法、设计决策和实际影响,覆盖 BPE/WordPiece/Unigram/SentencePiece 的原理对比和中文场景的特殊考量。

深度解析 Tokenizer BPE 分词 LLM

Tokenizer 是 LLM 中最被低估的组件之一。它决定了模型 “看到” 什么、如何表示文本,直接影响模型的效率、能力和成本。一个好的 Tokenizer 设计可以让模型事半功倍,而一个差的设计则可能成为瓶颈。

一、为什么 Tokenizer 如此重要

1.1 Tokenizer 的角色

Tokenizer 是文本和模型之间的桥梁——它将连续的文本序列切分为离散的 token 序列,每个 token 对应词表(vocabulary)中的一个 ID。

输入文本: "大模型改变了世界"
         ↓  Tokenizer
Token 序列: ["大", "模型", "改变", "了", "世界"]
         ↓  Embedding
向量序列: [v₁, v₂, v₃, v₄, v₅]
         ↓  Transformer
...

1.2 Tokenizer 影响全局

Tokenizer 的设计决策会波及整个系统:

影响维度具体表现
模型能力token 粒度决定了模型的最小理解/生成单位
训练效率相同文本,不同 Tokenizer 产生的 token 数差异可达 2-5 倍
推理成本token 数量直接决定计算量和延迟
上下文长度同样的 4K context,不同 Tokenizer 能装下的文本量不同
API 定价按 token 计费,Tokenizer 效率直接影响成本
多语言公平性低效的 Tokenizer 会 “惩罚” 某些语言的用户

1.3 Tokenizer Tax

一个生动的概念是 “Tokenizer Tax”——同样的含义,不同语言或不同 Tokenizer 下需要的 token 数不同:

"Hello, how are you?"
├── GPT-4 (cl100k): 6 tokens
├── LLaMA:         6 tokens
└── GPT-2:         6 tokens

"你好,最近怎么样?"
├── GPT-4 (cl100k): 7 tokens  (1.17x)
├── LLaMA:         11 tokens  (1.83x)  ← 中文效率很低
└── Qwen:          5 tokens   (0.83x)  ← 中文优化

LLaMA 的 Tokenizer 对中文非常不友好——同样含义的中文文本需要将近 2 倍的 token,这意味着中文用户的推理成本翻倍、有效上下文长度减半。

二、核心算法详解

2.1 Byte-Pair Encoding (BPE)

原理:BPE 最初是一种数据压缩算法,后来被引入 NLP。

训练过程:

  1. 初始化:将每个字符(或字节)作为基础 token
  2. 统计所有相邻 token 对的出现频率
  3. 将出现频率最高的 token 对合并为新 token
  4. 重复步骤 2-3,直到达到目标词表大小

示例:

初始: l o w </w>  (出现 5 次)
      l o w e r </w>  (出现 2 次)
      n e w e s t </w>  (出现 6 次)

合并 1: (e, s) → es  (频率: 6+...)
合并 2: (es, t) → est  (频率: 6)
合并 3: (l, o) → lo  (频率: 7)
...

变体:Byte-Level BPE

GPT-2/GPT-4 使用的是 Byte-Level BPE——基础单位不是字符而是字节(256 个),这样可以表示任何 Unicode 文本而不需要 UNK token。

优点:

  • 简单直观,实现容易
  • 压缩效率好
  • 是目前最主流的方法

缺点:

  • 贪心算法,不一定全局最优
  • 合并顺序是确定性的(同一文本只有一种切分方式)

2.2 WordPiece

原理:由 Google 提出,BERT 使用。与 BPE 类似,但合并策略不同。

关键区别:

  • BPE 合并频率最高的对
  • WordPiece 合并使得语言模型似然最大的对

score(t1,t2)=freq(t1t2)freq(t1)×freq(t2)\text{score}(t_1, t_2) = \frac{\text{freq}(t_1 t_2)}{\text{freq}(t_1) \times \text{freq}(t_2)}

这意味着 WordPiece 偏好合并那些 “共现概率高于独立出现概率” 的 token 对——即信息论意义上的高互信息对。

特点:

  • 子词以 ## 前缀标记(如 “playing” → [“play”, “##ing”])
  • 主要在 BERT 系列中使用
  • 理论上比 BPE 更优,但实际差异通常很小

2.3 Unigram Language Model

原理:由 Kudo(SentencePiece 作者)提出,是一种完全不同的思路。

训练过程:

  1. 从一个非常大的候选词表开始
  2. 训练一个 Unigram 语言模型:P(X)=∏i=1nP(xi)P(X) = \prod_{i=1}^{n} P(x_i)
  3. 计算每个候选 token 的 “价值”(移除它会增加多少 Loss)
  4. 移除价值最低的 token
  5. 重复步骤 2-4,直到达到目标词表大小

关键优势:概率化切分

Unigram 可以为同一文本输出多种切分方式,每种有不同的概率:

"unaffable"
├── ["un", "aff", "able"]     P = 0.45
├── ["una", "ff", "able"]     P = 0.25
├── ["un", "a", "ff", "able"] P = 0.15
└── ...

这在训练时可以做 子词正则化(Subword Regularization)——每次训练随机采样一种切分,增加训练数据多样性,类似数据增强。

2.4 SentencePiece

SentencePiece 不是一种新的分词算法,而是一个语言无关的分词框架:

  • 支持 BPE 和 Unigram 两种算法
  • 直接处理原始文本(不需要预分词)
  • 将空格作为特殊字符 ▁ 处理
  • 语言无关——对中文、日文等无空格语言同样适用

LLaMA、T5、PaLM 等都使用 SentencePiece。

三、词表设计决策

3.1 词表大小

词表大小是最重要的设计参数之一:

模型词表大小特点
GPT-250,257早期标准
LLaMA-132,000精简词表
LLaMA-232,000同上
LLaMA-3128,256大幅扩展
GPT-4 (cl100k)100,256大词表
Qwen-2151,936超大词表
DeepSeek-V2102,400大词表

词表大小的权衡:

小词表 (32K)                    大词表 (128K+)
├── Embedding 矩阵小            ├── Embedding 矩阵大
├── 需要更多 token 表示文本      ├── 更少的 token
├── 训练需要更多步               ├── 训练步数更少
├── 对小模型友好                 ├── 对大模型友好
└── 多语言表示效率低             └── 多语言表示效率高

关键计算:

Embedding 参数量 = 词表大小 × 隐藏维度

词表d_modelEmbedding 参数占总参数比例 (7B)
32K4096131M1.9%
100K4096410M5.9%
128K4096524M7.5%
152K4096622M8.9%

对于大模型(>7B),Embedding 参数占比很小,因此大词表的代价相对不高。但对于小模型(<1B),大词表会显著增加参数量。

3.2 特殊 Token 设计

Token用途示例
<bos>序列开始标记序列起点
<eos>序列结束标记序列终点(也用于停止生成)
<pad>填充批处理时对齐长度
<unk>未知Byte-level BPE 通常不需要
`<im_start>`
`<im_end>`
[INST] [/INST]指令标记LLaMA 格式
<tool_call>工具调用Function Calling

特殊 Token 的设计直接影响模型的交互格式和功能边界。

3.3 预分词(Pre-tokenization)

在 BPE/WordPiece 之前,通常需要一步预分词来确定基本边界:

GPT-2/4 的正则表达式:

pat = r"""'s|'t|'re|'ve|'m|'ll|'d| ?\p{L}+| ?\p{N}+| ?[^\s\p{L}\p{N}]+|\s+(?!\S)|\s+"""

这个正则表达式的作用:

  • 常见缩写保持完整(‘s, ‘t, ‘re 等)
  • 连续字母作为一个单元
  • 连续数字作为一个单元
  • 空格作为下一个词的一部分

SentencePiece 的做法:

  • 不做预分词,直接处理原始字节流
  • 将空格编码为特殊字符 ▁
  • 语言无关,不依赖任何语言特定的规则

四、中文 Tokenizer 的特殊挑战

4.1 中文的独特性

中文在分词上面临几个独特挑战:

  1. 无空格:中文词之间没有空格分隔
  2. 字词粒度:一个汉字可以是独立的词,也可以是词的一部分
  3. 字符集庞大:常用汉字约 4,000-6,000 个,总量超过 80,000
  4. 编码效率:UTF-8 中每个汉字占 3 个字节

4.2 不同粒度的比较

文本: "自然语言处理是人工智能的核心技术"

字级切分:  自/然/语/言/处/理/是/人/工/智/能/的/核/心/技/术
词级切分:  自然语言处理/是/人工智能/的/核心技术
BPE 切分:  自然/语言/处理/是/人工/智能/的/核心/技术  (典型)

4.3 中文优化策略

为中文优化 Tokenizer 的常见策略:

1. 增加中文 Token:

  • 在词表中显式添加高频中文词和字
  • Qwen 的词表中有大量中文 token,效率极高
  • 典型做法:在基础词表外额外训练一个中文 BPE

2. 词表扩展(Vocabulary Expansion):

  • Chinese LLaMA 的做法:在 LLaMA 词表基础上新增 20,000 中文 token
  • 扩展后初始化新 token 的 Embedding(用相关 token 的平均值)
  • 然后做中训练让新 token 的 Embedding 收敛

3. 混合粒度:

  • 高频词保持完整(“人工智能”、“机器学习”)
  • 低频词切分为字或子词
  • 通过 BPE 自然实现

4.4 压缩率对比

不同 Tokenizer 对中文的压缩效率(bytes per token):

Tokenizer中文 Bytes/Token英文 Bytes/Token中文效率
GPT-2 (50K)1.54.2差
LLaMA (32K)1.84.5很差
GPT-4 cl100k (100K)3.44.2中等
Qwen-2 (152K)4.14.3好
DeepSeek (100K)3.84.2较好
Yi (64K)3.54.2中等偏上

越高越好——意味着每个 token 编码了更多的原始信息。

LLaMA 的 1.8 Bytes/Token 意味着平均一个中文字符(3 bytes)需要 1.67 个 token——极其低效。而 Qwen 的 4.1 Bytes/Token 意味着平均 1.37 个中文字符才用一个 token——效率极高。

五、Tokenizer 训练实践

5.1 训练数据的选择

Tokenizer 的训练数据直接决定了词表的构成:

关键原则:

  1. 代表性:训练数据应该代表模型将要处理的文本分布
  2. 多样性:覆盖所有目标语言和领域
  3. 质量:避免噪声数据影响词表
  4. 规模:通常 10-100GB 文本足够

常见错误:

  • 只用英文数据训练 → 中文效率极低
  • 只用正式文本训练 → 对口语/网络用语效率低
  • 训练数据太小 → 低频词的合并模式不稳定

5.2 词表大小的选择

经验法则:

模型规模推荐词表大小理由
< 1B32K - 64KEmbedding 占比大,不宜过大
1B - 10B64K - 128K平衡点
> 10B100K - 200KEmbedding 占比小,大词表提升效率
多语言 (>10种)128K - 256K每种语言都需要足够的 token

5.3 评估 Tokenizer 质量

定量指标:

  1. 压缩率(Compression Ratio):Bytes per Token,越高越好
  2. 续写困惑度(Fertility):平均一个词被切成多少个 token,越低越好
  3. 覆盖率:多少比例的常见词可以用单个 token 表示
  4. UNK 率:出现 UNK token 的比例(Byte-level 应为 0)

定性检查:

  • 常见词是否被合理切分
  • 专业术语是否被保留
  • 数字和标点是否合理处理
  • 代码是否合理切分(缩进、操作符等)

六、前沿研究方向

6.1 无 Tokenizer 模型

一个激进的方向是完全抛弃 Tokenizer,直接在字节级别建模:

  • MegaByte(Meta, 2023):多尺度 Transformer 处理字节序列
  • ByT5(Google, 2022):字节级别的 T5

优势:彻底消除 Tokenizer 偏见,对所有语言公平 挑战:序列长度大幅增加(4-5倍),计算成本显著上升

6.2 动态词表

固定词表的一个问题是不能适应新出现的词汇。动态词表方向探索了:

  • 在推理时根据输入自适应调整切分粒度
  • 定期用新数据更新词表

6.3 多模态 Tokenizer

将文本、图像、音频统一到一个 Token 空间:

  • 图像通过 VQ-VAE 或 CLIP 离散化
  • 音频通过 Encodec 等编码器离散化
  • 统一的词表实现多模态生成

七、总结

算法原理主要使用者特点
BPE频率贪心合并GPT 系列, LLaMA最主流,简单高效
WordPiece似然最大合并BERT理论更优,实际差异小
Unigram概率化切分T5, PaLM (via SP)支持子词正则化
SentencePiece语言无关框架LLaMA, T5, mT5支持 BPE + Unigram

核心建议:

  1. 新项目首选 SentencePiece + BPE/Unigram
  2. 词表大小至少 64K,多语言场景 128K+
  3. 训练数据必须覆盖所有目标语言
  4. 认真评估中文等非拉丁语系的效率
  5. 词表设计是一次性决策——后续几乎不可能更改(除非重新预训练)

Tokenizer 是 LLM 的 “视网膜”——它决定了模型能 “看到” 什么。选好了,事半功倍。