一句话:WordPiece 是一种子词(subword)分词方法:它不会把文本切成整词或单字,会切成词表里有限的一批常见片段,并被 BERT 系列模型用作默认分词器。
打个比方:你只有一盒块数固定的乐高积木,这就是词表,通常几万块。遇到一个从没见过的词,你不能说“不认识”,只能拿现有积木拼出来。WordPiece 就类似这套拼法说明书。
训练时,它自底向上合并:先把词拆成字符,再反复挑一对相邻片段合并。挑选标准针对“合并后整个语料的概率提升最大”,并非“谁出现得最多”;它用语言模型似然打分,因此偏向合并那些放在一起更可预测的片段。
实际编码时,它采用最长匹配优先(greedy longest-match-first):从词首开始,尽量在词表里找最长匹配片段,找不到就退一步用更短的,最后兜底成单字符。
关键在 ## 这个记号。它表示“我不是词的开头,紧贴在上一个片段后面,中间没有空格”。于是:
| 原词 | 切分结果 |
|---|---|
| playing | play + ##ing |
| lowest | low + ##est |
| tokenization | token + ##ization |
这样,没见过的词就不会直接变成 [UNK]。一个新品牌名或拼错的单词,会被拆成几个熟悉的碎片,模型仍能从碎片里拼出大致意思,所以 BERT 几乎不需要“未知词”标记。
和相邻概念的区别:
- 词级(word-level)分词:词表会爆炸,且总有词不在表里。
- 字符级(character-level):永不出现未登录词,但序列太长,单字符语义太弱。
- BPE(Byte Pair Encoding):同样产出子词,但合并准则是“最高频相邻对”,只看频次;WordPiece 看的是似然增益。产物长得像,理念不同。
- SentencePiece:一套训练工具/框架,可用 BPE 或 unigram 语言模型算法,常把空格标记成 ▁;WordPiece 则用 ## 标记续接。具体用哪个、词表长什么样,以模型卡和官方分词器文档为准。
对从业者的实际意义:
1. 长度按 token 算,不按字算。同一句中文,不同分词器切出的 token 数差别不小,估上下文成本、定截断位置都得按 token 来。
2. ## 影响下游对齐。做命名实体识别、抽取式问答时,要把预测的片段位置映射回原文(offset mapping);一个词被切成多块时,取首块预测或对片段聚合是常见做法。
3. 生僻专名、长数字容易被切碎,模型逐字“复制”原文的能力会下降,别指望它精确还原一个罕见编号。
4. 词表大小是超参,直接牵动 embedding 参数量和推理成本。
对普通人:分词就是模型看字的方式。它看到的并非词,是碎片。因此拼写错误不一定让它懵,反而会被拆成常见小块;但一个生僻名字在它眼里可能只是一堆零碎积木,容易记错、写错。
