1. Tokenization 概述

各位同学好,我是这节课的讲师。Tokenization 这东西,说白了就是怎么把自然语言拆成模型能啃的小块。

我当年刚接触 NLP 时,以为分词就是按空格切一切。后来发现,中文根本不吃这套。再后来做多语言模型,英语、日语混在一起,才知道 Tokenization 才是真正的第一道坎。今天咱们就把这事聊透。

1.1 什么是 Tokenization

Tokenization 就是把一段文本切分成若干个小单元()的过程。每个 可以是单词、子词,甚至字符。

举个例子:

输入:I love NLP.
Word 级:["I", "love", "NLP", "."]
BPE 级:["I", "love", "NL", "P", "."]

你看,同样一句话,不同切法得到的 列表完全不同。模型就是要拿这些 去查对应的 ID 表。

我记得有一次调试一个翻译模型,发现"自然语言处理"这个短语被切成了 7 个 ,而英语 version 只有 4 个。原因就是中文子词切得太碎了。从那以后,我养成了一个习惯 —— 训练前先看一眼 Tokenizer 产出的样例,确认没有意外切割。

1.2 为什么需要 Tokenization

现在问题来了:为什么不能直接把词扔给模型?原因有三:

  • 词汇表爆炸 — 全世界词汇上百万,模型不可能全记住。Tokenization 让词汇表控制在几万以内。
  • 处理未登录词 — 遇到生僻词怎么办?BPE 这类方法可以拆成已知子词,保证模型至少能猜出部分含义。
  • 保持语义单元 — 直接按字符切会丢失词义,按词切又太大。子词级 Tokenization 找到了平衡点。
⚠ 注意: 你选的 Tokenizer 直接决定模型的上限。我见过有人把日文用空格分词,结果一半 都是乱码。别忘了先确认文本格式。

1.3 常见 Tokenization 方法对比

目前工业界主流方法有四种:WordPiece、BPE、Unigram 和 SentencePiece。咱们一个一个过。

1.3.1 BPE(Byte Pair Encoding)

BPE 最开始用来压缩文本,后来被 和 HuggingFace 搬到 NLP。原理很简单:反复合并出现频率最高的相邻字节对,直到达到预设词汇表大小。

优点:实现简单,训练快。适合英文和西欧语言。
缺点:对中文不友好,因为汉字本身已经是单元,合并意义不大。

1.3.2 WordPiece

WordPiece 和 BPE 很像,但合并标准不一样。它看的是合并后能提升多少语言模型概率。Google 的 BERT 用的就是 WordPiece。

优点:子词边界更合理,模型困惑度通常更低。
缺点:训练计算量比 BPE 大一点。

1.3.3 Unigram

Unigram 是反着来的:先搞一个大词表,然后一步步去掉最没用的子词,直到词表大小符合要求。SentencePiece 的底层算法就包含 Unigram。

优点:能自动确定最佳合并顺序,更灵活。
缺点:训练流程比较复杂。

1.3.4 SentencePiece

严格说 SentencePiece 不是一种编码方法,而是一个完整的工具包。它把输入统一当作字节流处理,不需要预先空格分词。即插即用,尤其适合多语言场景。

💡 实用建议: 如果是新项目,我个人习惯直接上 SentencePiece + Unigram。省去预处理分词的麻烦,效果好,而且能处理所有语言。

下面是四种方法的对比表:

方法 合并/剪枝策略 需预分词 首选语言 代表模型
BPE 频率合并 是 英语、西欧 系列
WordPiece 概率提升 是 英语、中文 BERT
Unigram 似然剪枝 否 任意 ALBERT
SentencePiece (框架) 不依赖 多语言 T5、XLNet

1.4 方法选择建议

你怎么选?我一般按这三步:

  1. 看语言 — 纯英文项目直接用 BPE 或 WordPiece;多语言或中文项目优先 SentencePiece。
  2. 看场景 — 快速验证选 BPE,生产环境精度优先选 WordPiece 或 Unigram。
  3. 看生态 — 如果复用 BERT 的预训练权重,必须用 WordPiece;如果自己从头训,随意。
💡 避坑指南: 我曾经为了省时间直接用了默认的 BPE 词表做中文 NER,结果"北京"被切成了"北"和"京"两个 ,导致模型学不到城市概念。后来我手动合并了一些高频词组,效果才上来。嗯,这里一定要注意。

好了,讲到这你应该对 Tokenization 有了整体认识。下面我用一张图把核心流程串一遍:

Tokenization 流程与核心方法 输入文本 Tokenizer 选择 BPE / WordPiece 子词级 字符级 → ID 映射 输入模型 💡 选对 Tokenizer 决定模型收敛速度

这张图帮助理解整个流程:输入文本经过 Tokenizer 选择,切分为子词或字符级 ,最后映射成 ID 喂给模型。你可以看到,中间的“方法选择”是关键分岔点。

好,这一章就聊到这。下次咱们动手写一个自己的 Tokenizer,你会看到每一步的代码实现。