在前面几章中,我们已经介绍了 Transformer、Self-Attention 和 GPT 为什么使用 Decoder-only 架构。到这里,一个非常基础但容易被忽略的问题出现了:
文本到底是如何进入大语言模型的?
我们平时看到的是一句自然语言:
大语言模型正在改变人工智能的发展方式。但是模型不能直接处理中文、英文或代码字符串。对模型来说,输入必须先被转换成数字 ID,再经过 embedding 层变成向量,最后才能进入 Transformer。这个过程就是Tokenization,负责执行这个过程的工具就是Tokenizer。
简单来说:
原始文本 ↓ Tokenizer ↓ token 序列 ↓ token ID 序列 ↓ Embedding ↓ Transformer所以,Tokenizer 是大语言模型的第一道入口。它决定了文本如何被切分,也直接影响模型的词表大小、序列长度、训练效率、多语言能力、代码能力和长上下文成本。
本文重点讲三个常见概念:
BPE WordPiece SentencePiece它们都是大语言模型和预训练语言模型中非常重要的分词方法。
一、为什么大语言模型需要 Tokenizer?
语言模型的训练目标通常是预测下一个 token。
例如 GPT 类模型要学习:
给定前面的 token,预测下一个 token假设一句话是:
我喜欢机器学习如果按字切分,可以得到:
我 / 喜 / 欢 / 机 / 器 / 学 / 习如果按词切分,可以得到:
我 / 喜欢 / 机器学习如果按子词切分,可能得到:
我 / 喜欢 / 机器 / 学习这些切分方式都会影响模型看到的输入序列。
Tokenizer 的核心作用有三个。
第一,把文本切成适合模型处理的基本单位。
第二,把每个 token 映射成一个整数 ID。
第三,控制词表规模和序列长度之间的平衡。
例如:
文本:大语言模型 token:大 / 语言 / 模型 token ID:[1024, 2356, 987]模型真正看到的不是“语言”这个汉字字符串,而是它对应的 ID。之后 embedding 层会把这个 ID 映射成向量。
所以,在大语言模型中:
Tokenizer 决定文本如何被模型“看见”。
二、为什么不能简单按词或按字切分?
最直观的分词方式有两种:按词切分和按字符切分。但这两种方式都有明显问题。
1. 按词切分的问题
如果按词切分,英文句子:
I like machine learning.可以切成:
I / like / machine / learning看起来很自然。
但是按词切分会遇到词表爆炸问题。因为自然语言中的词非常多,尤其是英文中存在大量词形变化:
learn learns learned learning learner如果每个词都放进词表,词表会非常大。更麻烦的是,模型很容易遇到训练集中没见过的新词。例如:
DeepSeek-V3 Qwen2.5-VL ChatGPT-like bioinformatics如果词表中没有这些词,就会出现 OOV,也就是 out-of-vocabulary 问题。
2. 按字符切分的问题
另一种极端方式是按字符切分。例如:
learning切成:
l / e / a / r / n / i / n / g这样几乎不会有 OOV,因为任何词都可以由字符组成。但是问题是序列会变得很长。
例如:
internationalization如果按词看是 1 个 token,如果按字符切分就会变成很多 token。序列越长,Transformer 的计算成本越高。标准 Self-Attention 的复杂度大致是:
O(n²)其中 n 是 token 数量。所以,按字符切分虽然避免了 OOV,但会显著增加序列长度和计算成本。
3. 子词切分是折中方案
因此,现代大语言模型通常采用子词切分,也就是 subword tokenization。它介于“词”和“字符”之间。常见词可以作为完整 token:
learning罕见词可以拆成多个子词:
bio / informatics或者:
un / believable子词切分的核心思想是:
常见片段尽量合并,罕见词可以拆开表示。
这样既避免了词表过大,又减少了字符级切分导致的序列过长问题。
三、BPE:从字符开始,不断合并高频片段
BPE,全称是Byte Pair Encoding。
它最初是一种数据压缩思想,后来被引入到神经机器翻译中,用来解决罕见词和开放词表问题。BPE 的核心思想很简单:
从最小单位开始,反复合并出现频率最高的相邻片段,直到达到设定的词表大小。
为了理解 BPE,我们看一个简化例子。假设语料中有几个词:
low lower lowest一开始可以拆成字符:
l o w l o w e r l o w e s t统计相邻字符对的频率,发现:
l + o o + w经常一起出现。于是 BPE 可能先把:
l + o → lo再把:
lo + w → low这样,“low” 就变成了一个子词 token。继续合并后,可能得到:
low er est于是:
lower → low / er lowest → low / est这样,模型既能保留常见词根,又能处理不同词形变化。BPE 的训练过程可以概括为:
1. 把文本拆成初始符号,通常是字符或字节 2. 统计所有相邻符号对的出现频率 3. 合并频率最高的符号对 4. 更新语料表示 5. 重复合并,直到达到目标词表大小BPE 的优点是:
简单直观 容易实现 能有效缓解 OOV 适合开放词表建模它的局限是:
主要基于频率合并,不一定符合语言学意义 对空格、标点、多语言文本的处理需要额外设计 不同训练语料会得到不同词表在大语言模型中,BPE 及其变体非常常见。GPT 系列中就广泛使用了 BPE 或 byte-level BPE 思路。
四、WordPiece:BERT 常用的子词切分方法
WordPiece 和 BPE 很像,也是一种子词分词方法。BERT 使用的就是 WordPiece 词表。WordPiece 的基本目标也是把词拆成更小的子词单元。例如:
unbelievable可能被切成:
un / ##believable或者:
un / ##believ / ##able这里的##表示这个子词不是一个新词的开头,而是接在前一个子词后面。例如:
playing → play / ##ing其中:
play是词的开头,而:
##ing表示它是后缀片段。WordPiece 在推理时通常采用 longest-match-first,也就是最长匹配优先策略。例如模型要切分:
unaffable它会从词表中寻找最长的可匹配子词。如果整个词不在词表中,就尝试匹配较长前缀,再继续处理剩余部分。可以简单理解为:
从左到右 每一步尽量匹配词表中最长的子词 匹配不到就继续拆得更细WordPiece 的特点是:
适合 BERT 这类预训练语言模型 使用 ## 标记词内子词 推理时常用最长匹配 能够处理未登录词它和 BPE 的区别可以粗略理解为:
BPE 更强调频繁相邻片段的逐步合并 WordPiece 更强调基于词表的子词匹配与概率建模思想不过从使用者角度看,二者都属于 subword tokenization,都在解决“词表大小”和“未登录词”之间的平衡问题。
五、SentencePiece:不是一种单独算法,而是一套更通用的分词框架
SentencePiece 很容易被误解。很多人会把它和 BPE、WordPiece 并列,认为它们是三种同级别算法。但更准确地说:
SentencePiece 是一个语言无关的 tokenizer 工具框架,它可以实现 BPE,也可以实现 Unigram Language Model。
它最大的特点是:
可以直接从原始文本训练 tokenizer 不要求文本预先按空格切词 适合中文、日文等没有天然空格分隔的语言传统英文分词方法往往默认文本中有空格。例如:
I love machine learning.空格天然分隔单词。但是中文没有这种空格:
我喜欢机器学习如果 tokenizer 强依赖空格,处理中文、日文等语言时就会比较麻烦。SentencePiece 的做法是把文本当作普通字符序列处理,并把空格也视为一种普通符号。它常用特殊符号:
▁来表示空格。例如英文句子:
I love NLP可能被表示为:
▁I / ▁love / ▁NLP这里的▁表示词前空格。这样做的好处是:
分词和反分词更统一 不依赖外部预分词器 对多语言更友好 可以直接从 raw text 训练SentencePiece 支持两种常见模型:
BPE Unigram Language Model其中 Unigram 方法不是从小片段不断合并,而是先准备一个较大的候选子词集合,然后通过概率模型逐步筛选出更优词表。
所以,SentencePiece 更像是一个统一工具:
你可以用 SentencePiece 训练 BPE tokenizer 也可以用 SentencePiece 训练 Unigram tokenizer很多大模型和多语言模型都会使用 SentencePiece 或其变体,因为它对多语言和无空格语言更加友好。
六、BPE、WordPiece、SentencePiece 对比
现在我们把三者放在一起比较。
| 方法 | 常见代表 | 核心思想 | 主要特点 |
|---|---|---|---|
| BPE | GPT 系列、很多生成模型 | 从小单位开始,不断合并高频相邻片段 | 简单、高效、适合开放词表 |
| WordPiece | BERT | 基于子词词表进行最长匹配 | 常用##表示词内片段 |
| SentencePiece | T5、LLaMA 等模型常见 | 从原始文本直接训练 tokenizer,可实现 BPE 或 Unigram | 语言无关,适合多语言和无空格语言 |
可以这样理解:
BPE 更像是一种子词合并算法 WordPiece 更像是 BERT 系列常用的子词词表方法 SentencePiece 更像是一套 tokenizer 工具框架三者都不是简单的“按词分词”,而是通过子词单位在词表规模和表达能力之间做平衡。
如果用一句话总结:
BPE 关注高频片段合并,WordPiece 关注词表内最长子词匹配,SentencePiece 关注从原始文本端到端训练语言无关 tokenizer。
七、Tokenizer 对大语言模型有什么影响?
Tokenizer 看起来只是预处理工具,但它对模型影响很大。
1. 影响序列长度
同一句话,不同 tokenizer 切出来的 token 数量可能不同。
例如:
DeepSeek-V3 is powerful.一个 tokenizer 可能切成:
DeepSeek / - / V / 3 / is / powerful另一个 tokenizer 可能切成:
Deep / Seek / - / V / 3 / is / power / fultoken 数量越多,模型处理成本越高。对于 Transformer 来说,token 数量还会影响注意力计算成本。
2. 影响多语言能力
如果词表主要由英文语料训练得到,那么中文、日文、阿拉伯文等语言可能会被切得很碎。
例如中文:
人工智能如果 tokenizer 不适合中文,可能会切成非常细的单位,导致同样一句中文占用更多 token。这会影响模型的训练效率和推理成本。
3. 影响代码能力
代码中有大量特殊符号:
def get_user_info(user_id): return user_dict[user_id]如果 tokenizer 不能很好处理下划线、缩进、括号、运算符、变量名,代码会被切得很碎。因此,代码大模型通常需要特别关注 tokenizer 对代码语料的适配能力。
4. 影响长上下文成本
大模型的上下文长度通常按 token 计算,而不是按字符或汉字计算。例如模型支持:
128K tokens这不等于支持 128K 个汉字或 128K 个英文单词。如果 tokenizer 对某种语言切得很碎,那么同样长度的文本会占用更多 token,从而更快达到上下文上限。
5. 影响未知词和新词处理
大语言模型会不断遇到新词,例如:
新模型名称 论文缩写 变量名 网络热词 专有名词好的 tokenizer 应该能把这些词拆成合理片段,而不是全部变成未知符号。现代子词 tokenizer 的一个重要优势就是减少[UNK]的出现。
八、本文小结
本文介绍了大语言模型中的 Tokenizer,并重点比较了 BPE、WordPiece 和 SentencePiece。Tokenizer 的作用是:
把原始文本转换成 token ID 序列完整流程是:
文本 ↓ Tokenizer ↓ token ↓ token ID ↓ Embedding ↓ Transformer按词切分会导致词表过大和未登录词问题,按字符切分又会导致序列过长。因此,现代大语言模型通常采用子词切分。BPE 的核心思想是:
从字符或字节开始,不断合并高频相邻片段。WordPiece 是 BERT 常用的子词方法,推理时通常采用最长匹配优先,并使用##表示词内子词。SentencePiece 更像是一套语言无关的 tokenizer 框架,它可以直接从原始文本训练 tokenizer,并支持 BPE 和 Unigram 等方法,因此更适合多语言场景。
三者的关系可以简单概括为:
BPE:一种高频合并式子词算法 WordPiece:BERT 系列常用的子词词表方法 SentencePiece:语言无关的 tokenizer 工具框架Tokenizer 虽然不是 Transformer 的主体结构,但它直接影响模型的输入形式、序列长度、多语言能力、代码能力和推理成本。如果说 Transformer 决定了模型如何处理 token,那么 Tokenizer 决定了:
什么样的文本会被切成什么样的 token。