目录
1. 字粒度
2. 词粒度
3. Subword 粒度
3.1 BPE 字节对编码
3.2 WordPiece (Character-Level BPE)
3.3 Byte-level BPE
我们知道很多NLP模型(Transformer, Bert)输入的其中一部分是句子的token,然后结合位置编码进入到Mutil-Head Self Attention Layer,后者大家都很熟悉,但如何获得token,却很少有人讲解,这一部分也一度令我疑惑。
获得句子的token,操作被称为:tokenization。是NLP任务中最基础、最先需要进行的一步,该操作的目的是将输入文本分割成单独的部分,然后结合词典进一步转化为token。
在tokenization中理想的切分具有4种特质:1. 所有token都具有正确的表义 2. 构建的新词表不是很大 3. 不存在遗漏(OOV)问题 4. 根据新的词表构建输入时,输入长度合理。
常见的tokenization方法如下图:
英文以单个字母为基本单位切分,如果遇到大小写不敏感的任务,可以先转小写再切分;中文以字为基本单位切分。
英文:i love eta apple ------ i / l / o / v / e / e / t / a / a / p / p / l / e
中文:我爱吃苹果 ------ 我 / 爱 / 吃 / 苹 / 果
优点:词表很小(英文字母最多就是52个大小写字母 + 特殊字符);鲁棒性强,没有OOV问题。
缺点:大部分单字母或者单字没有语义意义;根据词表将文本或句子转换为模型输入,其输入长度可能会很长,额外增加模型需要学习的参数,不仅使模型难以训练,训练也更耗时耗力。
与人类大脑理解文本的思路一致,例如中文里的“苹果”会被划分成一个字,这部分分词一般使用工具来完成,例如中文的 jieba、LTP等。
英文:i live in New York ------ i / live / in / New York
中文:我爱吃苹果 ------ 我 / 爱 / 吃 / 苹果
这部分是需要重点了解的,因为在最新的transfomer、Bert、还有优化算法中用的比较多。
Subword tokennizaiton算法基本基于同一个原则,出现频次少 / 稀有的词切分成有意义的多段子词,反过来讲,就是尽可能的合并出现频次多的词。
基于这样一个原则,即经常使用的词不应该被分割成更小的子词,而稀有词应该被分解成有意义的子词。
在这里用的比较多的是BPE(Byte-Pair Encoding),WordPiece(Character-Level BPE),Byte-level BPE。
遵循的基本原则是:从基本词汇表中选择组合在一起出现频次最高的两个符号中,并将其合成一个新的符号,加入基础词汇表,直到达到提前设定好的词汇量为止(词汇表大小是超参数)。
1. 使用单词划分库(Moses,Spacy 或 ftfy),将语料切分为单词,并且统计单词出现频率,这一步被称为pre - tokennizaiton。
2. BPE创建基本词汇表,该词汇表由去重后的单词集中的所有符号组成(“符号”我的理解是最小单位是字母 或者 特殊单独的字符),即包含词汇表数据中的每个字符。
3. 统计每个符号对的出现频率,将出现频次最高的两个符号对合并成一个新符号,然后新符号加入词汇表(两个旧符号是保留的)。
4. 重复步骤3,直到词汇量达到设定值 或者 组合频次最高的符号序列对频次为1。
举个实际例子,例子来源:关于 NLP 中的 tokenize 总结-CSDN博客
假设在 pre-tokenization + 去重,确定如下一组单词 + 出现频率:
a . ("hug", 10), ("pug", 5), ("pun", 12), ("bun", 4), ("hugs", 5)
分解单词,得到基本词汇:[“b”、“g”、“h”、“n”、“p”、“s”、“u”],利用这个表分解所有单词。
b. ("h" "u" "g", 10), ("p" "u" "g", 5), ("p" "u" "n", 12), ("b" "u" "n", 4), ("h" "u" "g" "s", 5)
观察到,加粗部分的邻接字符“u” 和 “g”,组合在一起出现的频次10 + 5 + 5 = 20,最高!因此,tokenzier 学习的第一个合并规则是将邻接的“u” 和 “g”合并在一起,然后在词汇表中添加“ug”。
c. ("h" "ug", 10), ("p" "ug", 5), ("p" "u" "n", 12), ("b" "u" "n", 4), ("h" "ug" "s", 5)
循环 b ~ c 这个过程,在第二轮合并规则学习中,“u” 和 “n” 出现频次16次,最高,合并 + 添加;第三轮中,“h” 和 “ug” 出现频次15,最高,合并 + 添加。经过三轮合并学习。
此时词汇表如下:
经过三轮合并后的词汇表 :[ “b”、“g”、“h”、“n”、“p”、“s”、“u”、“ug”、“un”、“hug” ]
假设,BPE算法到这里截止,此时在真实环境使用中有两种情况。第一种:新出现的单词可以用词汇表中的词表示,例如 “bug”,单词没有直接出现在词汇表中,但可以用“b” + “ug” 表示,因此被识别成 [“b”,“ug”];第二种 :新出现的单词不能被完全表示或者完全不能表示,例如 “ab”,单词将会被识别成 [“”,“b”]。
需要注意1:上述不能被表示的情况不会出现在英文字符中,但是特殊字符的概率会稍大。
需要注意2:词汇量的设定值是超参数,需要提前设置,大小由两部分组成(基础词汇表大小 + BPE算法合并次数);例如,GPT的词汇量为40478,因为有478个基本字符,在40000次合并后选择停止训练。
WordPiece在Bert中得到了应用;其遵循的原则和BPE不同。
WordPiece 首先初始化词汇表,词汇表包含训练数据中的每个字符,然后同BPE一样,逐步学习固定次数的的合并规则。与 BPE 相反,WordPiece 并没有选择出现频次最大的符号对,而是基于最大化增加训练数据概率 or 似然的原则(似然值表示来两个子字的相关性),选择合并相关性最高的字符对加入词汇表中。
接下来举例说明:最大化数据概率 和 似然,还有相关性的概念:
假设初始语料,由n个子词组成,假设各个子词之间独立,则语料S的语言模型似然值等价于所有子词概率的乘积:
假设把相邻位置的 x 和 y 两个子词进行合并为新子词 z ,此时语料S的似然值的变化可表示为:
根据合并原则,若合并 x 和 y 为 z,引起似然值的变化是所有字符对之间的最大的,将子词 z 加入到词汇表中!( 根据公式,也可以理解为 z 的出现概率,依次除以 x 的出现概率和 y 的出现概率,若其结果最大,则将 z 加入词汇表)
总结:似然值的变化就是两个子词之间的互信息。WordPiece每次选择合并的两个子词,它们具有最大的互信息值,也就是两子词在语言模型上具有较强的关联性,它们经常在语料中以相邻方式同时出现。
WordPiece 步骤可以描述为:
1. 准备足够大的语料,并确定期望的词汇表大小(subword大小);
2. 将语料中的单词,拆分成字符序列;
3. 基于第2步的数据训练语言模型(这块我没明白?可以和各位探讨一下具体是做什么的)
4. 从所有可能的subword 候选单元中,选择能似然值变化最大 或 最大程度增加训练数据概率的新子词插入词汇表中;
5. 重复第4步,直到达到第一步中设定的subword词表大小 ,或概率/似然值 增量低于某一阈值。
这类BPE是在GPT2提出来的,听说源码还未公开,这部分让笔者先好好学一学,后续补上。