很多人学大模型时,会把 tokenizer 当成一个“预处理工具”:反正文本最后都会被切成 token,似乎只是工程细节。这个看法很危险。tokenization 决定了模型看到世界的最小单位,也决定了序列长度、词表大小、稀有词处理方式、训练成本,甚至还影响模型对不同语言和代码的偏好。
从某种意义上说,模型并不是在直接学“文字”,而是在学“token 序列”。所以第一步怎么切,后面几乎所有东西都会跟着变。
这一篇我们就把这个问题从根上讲清楚:为什么不能直接按词切,也不能简单按字符切;BPE、WordPiece、SentencePiece 到底有什么差别;为什么今天主流大模型大多选择“子词为主、字节兜底”的折中路线。
一、先问最根本的问题:模型到底在预测什么
一个语言模型训练时做的是 next-token prediction。那“token”是什么?
直觉上你可能会想到三种答案:
- 一个词;
- 一个字 / 一个字符;
- 介于词和字符之间的某种子词片段。
这三种答案分别对应三种世界观。
1.1 按词切:最符合人类直觉,但很快崩
最朴素的想法是把一句话切成词:
I love machine learning
-> [I] [love] [machine] [learning]
这看起来很自然,因为词似乎就是语言的基本单位。但一上真实数据就会出问题:
- 词表会爆炸,几十万、几百万都不够;
- 稀有词太多,长尾极重;
- 新词、拼写变体、专有名词、网址、代码标识符全部容易 OOV(out of vocabulary)。
中文也类似。按“词”切还额外依赖分词器,而分词本身就是个会犯错的上游任务。
1.2 按字符切:永远不 OOV,但序列太长
另一种极端是按字符切:
learning -> [l] [e] [a] [r] [n] [i] [n] [g]
好处很明显:
- 词表极小;
- 理论上永远不会 OOV;
- 新词可以由字符组合出来。
但代价也同样明显:
- 序列长度暴涨;
- self-attention 的成本跟长度平方相关;
- 模型要跨很多步才能拼出一个词义单元;
- 对英文、代码这种长标识符文本尤其不友好。
对 Transformer 来说,这几乎是直接把最贵的那部分计算放大。
1.3 子词:不是完美解,但通常是最好的折中
于是出现第三条路:把高频词保留为整体,把低频词拆成更小片段。
例如:
unbelievable -> [un] [believ] [able]
这样做的目标很明确:
- 高频常用词不要拆太碎;
- 长尾低频词能被拆出来组合;
- 词表控制在可训练的大小;
- 序列长度不要太夸张。
这就是子词 tokenization 的基本思想。后面几乎所有主流方法,都是在这个折中框架里选不同实现。
二、BPE:最经典也最容易理解的子词算法
子词分词里最经典的是 BPE(Byte Pair Encoding)。Sennrich 等人在 2016 年把它引入神经机器翻译之后,几乎成了那一代 Transformer 和 GPT 之前模型的默认方案。
2.1 BPE 的核心直觉:把最常一起出现的片段合并
BPE 的起点非常朴素:先把每个词拆成字符,然后不断统计语料里最常出现的相邻符号对,把它们合并成一个新符号。
一个玩具例子:
low
lower
newest
widest
开始时,词表是字符级:
l o w
l o w e r
n e w e s t
w i d e s t
如果语料里 l o 很常见,就先合成
lo;如果 lo w 很常见,再合成
low;如果 e s 常见,就合成
es,再合 est。
重复若干轮之后,你会得到一张“既有字符,也有高频子词”的词表。
2.2 BPE 的训练过程本质上是贪心合并
它没有复杂目标函数,核心就是:
- 统计当前词表中相邻符号对的频率;
- 选出最频繁的一对;
- 合并成新 token;
- 重复直到达到预设词表大小。
这让 BPE 有两个很实用的特性:
- 训练快;
- 结果直观,可解释性强。
2.3 它为什么在机器翻译里特别有用
因为机器翻译里长尾词很多:人名、地名、形态变化、复合词、拼写变体。按词切时,这些东西要么 OOV,要么词表大得离谱;BPE 则可以把它们拆成常见子片段。
例如德语长复合词特别多,BPE 对这类语言非常自然。
2.4 但 BPE 不是“懂语言”,它只懂共现频率
这点要看清。BPE 的合并标准纯粹基于统计频率,不理解词法边界、语义边界,也不关心语言学上的 morpheme 是否完整。所以它切出来的子词有时很合理,有时只是“高频片段”。
这不是 bug,而是设计取向:它追求的是工程上可用,不是语言学上优雅。
三、WordPiece:看起来像 BPE,但优化目标不一样
WordPiece 常被说成“BPE 的另一个版本”,这话不算错,但不够精确。
3.1 它的代表应用是 BERT
BERT 采用的就是 WordPiece。很多后来做 encoder-only 预训练的模型也沿用了这条线。
WordPiece 的基本结果和 BPE 很像:也是产生一套子词词表,也是常见词不拆、稀有词拆成更小单位。但它挑选 merge 的标准不是“谁最频繁”,而是更接近“谁最能提高当前语言模型目标”。
3.2 关键差别:不是单纯按频率合并
直观地说,BPE 只看“这两个片段经常挨在一起”;WordPiece 更像在问“把这两个片段合成一个 token,对当前语料建模是不是更划算”。
因此:
- BPE 更像频率驱动的压缩算法;
- WordPiece 更像语言模型驱动的词表选择。
这让 WordPiece 在某些语料上会得到比 BPE 更平衡的词表,但训练与实现也更复杂一点。
3.3
## 这种 continuation 标记只是编码约定
很多人第一次看 BERT tokenizer,会看到:
playing -> [play] [##ing]
这里 ##
不是算法本质,只是一个标记方式:告诉你后一个片段不是新词起点,而是前一个
token 的延续。换一种实现,完全可以不用这个符号。
真正关键的是“词边界内子词如何编码”,不是具体显示格式。
四、SentencePiece:把“先分词再子词化”这一步也拿掉
SentencePiece 的重要性,常常被低估。它最关键的贡献不是发明了新 tokenizer,而是改变了输入假设:不要求你先把文本按词切好。
4.1 它直接从原始文本训练
对英文这种空格分词语言,BPE / WordPiece 往往默认你已经有词边界;SentencePiece 则把空格也当成普通符号的一部分,直接从原始文本学。
这带来两个非常现实的好处:
- 跨语言更统一,尤其是中文、日文这类本来就没有天然空格分词的语言;
- 整个 pipeline 更简单,不必依赖额外分词器。
4.2 它不仅支持 BPE,还支持 Unigram LM
很多人会把 SentencePiece 直接等同于 BPE,其实不对。SentencePiece 是一个框架,里面至少支持两类主流算法:
- BPE 模式;
- Unigram Language Model 模式。
Unigram 的思路和前面两种相反:不是从小到大不断 merge,而是从一个较大的候选词表开始,不断删掉那些对整体似然贡献较小的 token,最后留下最优子集。
4.3 为什么 T5、LLaMA 这类模型爱用它
因为它对多语言、无空格语言、复杂文本清洗流程都比较友好,而且训练和部署链路统一。今天很多开源大模型的 tokenizer 背后,直接或间接都能看到 SentencePiece 这套思想。
五、Byte-level:为什么现代大模型越来越喜欢“字节兜底”
到这里你可能会问:既然子词已经解决了 OOV,为什么后来的 GPT-2、tiktoken 这些方案还要强调 byte-level?
答案是:子词降低了 OOV,但没有从定义上消灭 OOV;字节级编码可以。
5.1 字节兜底意味着任何字符串都能编码
如果 tokenizer 的底层单位包含 256 个字节,那么任何输入——不管是稀奇古怪的 Unicode、表情、二进制片段、网址、代码、拼错的词——理论上都能被编码。
这在开放互联网语料里太重要了。真实数据从来不干净,模型不可能只见到规范词汇。
5.2 这不是回到字符级,而是“子词之下还有安全网”
现代 byte-level BPE 的思路不是“永远按字节切”,而是:
- 常见片段仍然合成高效子词;
- 真遇到陌生模式时,退回字节级保证可编码。
所以它兼顾了:
- 子词的压缩效率;
- 字节级的开放词汇能力。
这也是为什么 GPT-2 之后,大量通用 LLM tokenizer 都往这条路线靠。
六、词表大小和序列长度,是一组硬约束
tokenizer 设计里最常被忽略的,是词表大小和序列长度的 trade-off。
6.1 词表越大,embedding / softmax 越贵
词表大小 \(V\) 决定:
- embedding 矩阵大小:\(V \times d\);
- 输出层 logits 大小:每个位置都要投到 \(V\) 维。
词表太大,会直接抬高参数量和输出层计算。
6.2 token 越碎,序列越长,attention 越贵
token 越小,表示同一段文本需要的 token 数越多;而 attention 的计算复杂度 roughly 是 \(O(n^2)\)。所以把 tokenizer 切得过碎,会把 Transformer 最贵的地方继续放大。
6.3 好 tokenizer 不是“切得最像语言学”,而是“在计算和表达之间平衡”
这也是为什么:
- 没有人真的想回到纯词级;
- 也很少有人愿意纯字符化;
- 主流最后都落在“几万到十几万词表的子词方案”附近。
这不是巧合,是计算约束和语言开放性共同压出来的工程平衡点。
七、BPE、WordPiece、SentencePiece 到底该怎么比较
把前面讲的东西压成一张表,会比较清楚:
| 方法 | 基本单位 | 词表构造思路 | 优点 | 代价 |
|---|---|---|---|---|
| BPE | 字符起步的子词 | 频率最高的相邻符号不断 merge | 简单、快、直观 | 纯频率驱动,不一定最优 |
| WordPiece | 子词 | 更接近语言模型目标的词表选择 | 词表更平衡 | 训练更复杂 |
| SentencePiece-BPE | 原始文本上的子词 | 不依赖预分词的 BPE | 多语言友好、pipeline 简单 | 仍继承 BPE 的频率偏好 |
| SentencePiece-Unigram | 原始文本上的子词 | 从大词表删减到最优子集 | 统计上更灵活 | 训练更复杂 |
| Byte-level BPE | 子词 + 字节兜底 | 子词压缩 + 开放字符覆盖 | 几乎无 OOV,通用性强 | 某些文本会切得更碎 |
如果你非要问“谁最好”,那答案通常不是绝对的,而是看语料和场景:
- 机器翻译时代,BPE 非常够用;
- BERT 时代,WordPiece 很自然;
- 多语言和现代开源 LLM,SentencePiece / byte-level 更常见。
八、tokenizer 会怎样反过来影响模型能力
这件事比很多人想的更深。
8.1 对中文、代码、数字尤其敏感
- 中文如果切分不合理,常用词会被拆得太碎,长度飙升;
- 代码里的长标识符、缩进、符号组合,对 tokenizer 很敏感;
- 数字、日期、URL、邮箱这类模式,如果切得太随机,会降低模型的模式抽取效率。
8.2 训练数据分布和 tokenizer 是耦合的
一个 tokenizer 在网页文本上学出来的高频片段,不一定适合代码语料;一个偏英文的 tokenizer,不一定适合中日韩混合语料。很多模型“对某类输入特别不友好”,源头之一其实就在 tokenizer。
8.3 后处理与模板也会受影响
聊天模板里的特殊 token、system/user/assistant 标记、函数调用边界、图像占位符,本质上都在利用 tokenizer 词表里的特殊符号设计。这说明 tokenizer 不是训练前的一次性步骤,而会贯穿整个产品协议层。
九、几个常见误解
9.1 “token 就等于词”
不对。现代大模型里的 token 更常是子词、字节片段或特殊符号。一个词可能对应 1 个 token,也可能是 5 个。
9.2 “词表越大越好,因为切得更少”
不一定。词表越大,embedding 和输出层越贵,长尾稀疏也更严重。切得少和整体效率不是一回事。
9.3 “有了子词就没有 OOV”
对子词方案来说只是大幅缓解,不是从定义上消灭。真正意义上的“任何输入都能编码”通常还要靠字节兜底。
9.4 “tokenizer 只是预处理,对模型能力影响不大”
错。它直接决定最小预测单位、序列长度和开放词汇能力,对训练和推理都有实质影响。
9.5 “SentencePiece 就是 BPE”
不对。SentencePiece 是工具和框架,既可以跑 BPE,也可以跑 Unigram LM。
十、结语
tokenization 真正要解决的,不是“怎么把句子切一切”这么简单,而是一个更硬的工程问题:在开放词汇、有限词表、可承受序列长度和多语言泛化之间,找一个可训练的最小单位。 词级太大,字符级太碎,子词因此成了现实世界里的主流折中。
理解了这件事,你再看 GPT、BERT、LLaMA 的 tokenizer 选择,就不会只看到工具差异,而会看到背后的训练目标和数据分布假设。下一篇我们继续顺着这条线走:既然文本已经被切成 token 了,模型到底该用什么目标去学这些 token 序列?这就进入预训练目标本身。
十一、参考文献
- Sennrich, R., Haddow, B., Birch, A. “Neural Machine Translation of Rare Words with Subword Units.” ACL 2016. 把 BPE 引入神经机器翻译的代表论文。
- Schuster, M., Nakajima, K. “Japanese and Korean Voice Search.” ICASSP 2012. WordPiece 的早期来源之一。
- Wu, Y. et al. “Google’s Neural Machine Translation System: Bridging the Gap between Human and Machine Translation.” arXiv:1609.08144, 2016. GNMT 使用 wordpiece models 的经典工程案例。
- Kudo, T., Richardson, J. “SentencePiece: A simple and language independent subword tokenizer and detokenizer for Neural Text Processing.” EMNLP 2018. SentencePiece 的原始论文。
- Kudo, T. “Subword Regularization: Improving Neural Network Translation Models with Multiple Subword Candidates.” ACL 2018. Unigram LM 与子词正则化的重要工作。
- Radford, A. et al. “Language Models are Unsupervised Multitask Learners.” OpenAI Technical Report, 2019. byte-level BPE 在 GPT-2 中的大规模应用。
← 上一篇:28|原论文实验结果 | 下一篇:30|预训练目标 →
同主题继续阅读
把当前热点继续串成多页阅读,而不是停在单篇消费。
【Transformer 与注意力机制】38|GPT 系列:从 GPT-1 到 GPT-4 的路线演进
GPT 路线的关键不是某个模型名字,而是 Decoder-only Transformer、next-token prediction、规模扩展、上下文学习、指令微调和人类反馈逐步合流。本文从 GPT-1 讲到 GPT-4,只使用公开可确认信息,解释为什么自回归语言模型最终成为大语言模型时代的主线。
【Transformer 与注意力机制】39|T5:把所有 NLP 任务统一成 Text-to-Text
T5 的核心不是又发明了一种 Transformer,而是把翻译、摘要、分类、问答都改写成“输入文本到输出文本”的统一格式。本文解释 T5 为什么选择 Encoder-Decoder 架构,span corruption 和 BERT/GPT 的目标有什么差异,C4 和系统化消融实验为什么让 T5 成为迁移学习路线的重要基准。
【Transformer 与注意力机制】40|三大路线之争:为什么大模型几乎都是 Decoder-only
Transformer 不是只有一种形态。Encoder-only、Encoder-Decoder、Decoder-only 分别对应理解、条件生成和自回归生成三类信息流。本文横向比较 BERT、T5、GPT 代表的三条路线,解释为什么通用大模型时代 Decoder-only 占主流,以及为什么这不意味着另外两条路线失去价值。
【Transformer 与注意力机制】41|位置编码演进:Sinusoidal → Learned → RoPE → ALiBi
Transformer 本身没有递归和卷积,如果不注入位置信息,它只会看到一袋 token。本文从原始正弦位置编码讲到 learned embedding、相对位置、RoPE 和 ALiBi,解释位置编码为什么从“给 token 加坐标”演进到“让 attention 感知相对距离”,以及长上下文为什么让位置外推变成核心问题。