学习huggingface tokenizers 库。首先介绍三大类分词算法:词级、字符级、子词级算法;然后介绍五种常用的子词级(subword )算法:BPE、BBPE、WordPiece、Unigram、SentencePiece。
词表通常在模型预训练语料库上训练而成,包括不同的分词方式,例如对 “Don’t you love 🤗 Transformers? We sure do.” 进行分词。
spaCy 和 Moses ):[“Do”, “n’t”, “you”, “love”, “🤗”, “Transformers”, “?”, “We”, “sure”, “do”, “.”],缺点是词表会巨大,比如Transformer XL用的这种分词方式,词表大小达到了267735,导致embedding矩阵贼大,一般大模型词表没太有超过5w词的。dog 和 s。优点是既能降低词汇量,又能根据前后缀学习到语义。



接下来是几个常见的子词级 subword tokenization 算法:BPE、BBPE、WordPiece、Unigram、SentencePiece。
Byte-Pair Encoding (BPE):从字母开始,不断找词频最高、且连续的两个token合并(有点霍夫曼树内味儿了),直到达到目标词数。
("hug", 10), ("pug", 5), ("pun", 12), ("bun", 4), ("hugs", 5) ;并得到初始词表(base vocabulary) ["b", "g", "h", "n", "p", "s", "u"],("h" "u" "g", 10), ("p" "u" "g", 5), ("p" "u" "n", 12), ("b" "u" "n", 4), ("h" "u" "g" "s", 5)("h" "ug", 10), ("p" "ug", 5), ("p" "u" "n", 12), ("b" "u" "n", 4), ("h" "ug" "s", 5);("h" "ug", 10), ("p" "ug", 5), ("p" "un", 12), ("b" "un", 4), ("h" "ug" "s", 5);("hug", 10), ("p" "ug", 5), ("p" "un", 12), ("b" "un", 4), ("hug" "s", 5);所以,BPE算法得到的最终词表数 = base vocabulary原始词数 + 合并后的词数(可调参数)。比如GPT有 478 base characters 和 训练后的 40000 merges tokens,总词数就是 40478 个。
Byte-level BPE(BBPE):utf-8编码中,一个字符就是4bytes,unicode字符就13.8w个,这个算法就是合并的Byte编码
WordPiece:2012年提出的,BERT、DistilBERT 和 Electra都用的这个。跟BPE差不多,也是初始化字符词表,逐步学习给定数量的合并规则。区别是合并时,计算合并后的语言模型似然有没有增加。
Unigram:跟BPE相反,Unigram是从大到小的过程,先初始化一个大词表,然后逐步精简掉使loss损失最小的词。一般跟sentencepiece结合起来用。
SentencePiece:上面这些算法都假设以空格分割单词,但中文日文等并不是。为了解决这个问题,SentencePiece: A simple and language independent subword tokenizer and detokenizer for Neural Text Processing (Kudo et al., 2018) 将所有语言一视同仁,把空格也包含到字符集里,再用BPE或Unigram构造词表。
官方文档:https://huggingface.co/docs/transformers/tokenizer_summary#wordpiece