NLP中的Tokenization方法——BPE(Byte-Pair Encoding)

目录

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方法如下图

1. 字粒度 

         英文以单个字母为基本单位切分,如果遇到大小写不敏感的任务,可以先转小写再切分;中文以字为基本单位切分。

英文:i love eta apple  ------  i / l / o / v / e / e / t / a / a / p / p / l / e

中文:我爱吃苹果         ------ 我 / 爱 / 吃 / 苹 / 果

优点:词表很小(英文字母最多就是52个大小写字母 + 特殊字符);鲁棒性强,没有OOV问题。

缺点:大部分单字母或者单字没有语义意义;根据词表将文本或句子转换为模型输入,其输入长度可能会很长,额外增加模型需要学习的参数,不仅使模型难以训练,训练也更耗时耗力。

2. 词粒度

        与人类大脑理解文本的思路一致,例如中文里的“苹果”会被划分成一个字,这部分分词一般使用工具来完成,例如中文的 jieba、LTP等。

英文:i live in New York    ------       i / live / in / New York

中文:我爱吃苹果               ------       我 / 爱 / 吃 / 苹果

3. Subword 粒度

        这部分是需要重点了解的,因为在最新的transfomer、Bert、还有优化算法中用的比较多。

        Subword tokennizaiton算法基本基于同一个原则,出现频次少 / 稀有的词切分成有意义的多段子词,反过来讲,就是尽可能的合并出现频次多的词。

基于这样一个原则,即经常使用的词不应该被分割成更小的子词,而稀有词应该被分解成有意义的子词。

        在这里用的比较多的是BPE(Byte-Pair Encoding)WordPiece(Character-Level BPE)Byte-level BPE

3.1 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次合并后选择停止训练。

3.2 WordPiece (Character-Level BPE) 

        WordPiece在Bert中得到了应用;其遵循的原则和BPE不同。

        WordPiece 首先初始化词汇表,词汇表包含训练数据中的每个字符,然后同BPE一样,逐步学习固定次数的的合并规则。与 BPE 相反,WordPiece 并没有选择出现频次最大的符号对,而是基于最大化增加训练数据概率 or 似然的原则(似然值表示来两个子字的相关性),选择合并相关性最高的字符对加入词汇表中。

       接下来举例说明:最大化数据概率 和 似然,还有相关性的概念:

        假设初始语料S = \left ( t _{1},t _{2},t _{3},......,t _{n} \right ),由n个子词组成,假设各个子词之间独立,则语料S的语言模型似然值等价于所有子词概率的乘积:

logP(S) = \sum_{i = 1}^{n}logP(t_{i})

        假设把相邻位置的 和 两个子词进行合并为新子词 ,此时语料S的似然值的变化可表示为:

 logP(z) - (logP(x) + logP(y)) = log(P(z) / (P(x) * P(y)))​​​​​​​

        根据合并原则,若合并 x 和 y 为 z,引起似然值的变化所有字符对之间的最大的,将子词 z 加入到词汇表中!( 根据公式,也可以理解为 z 的出现概率,依次除以 x 的出现概率和 y 的出现概率,若其结果最大,则将 z 加入词汇表)

        总结:似然值的变化就是两个子词之间的互信息。WordPiece每次选择合并的两个子词,它们具有最大的互信息值,也就是两子词在语言模型上具有较强的关联性,它们经常在语料中以相邻方式同时出现。

WordPiece 步骤可以描述为:

1. 准备足够大的语料,并确定期望的词汇表大小(subword大小);

2. 将语料中的单词,拆分成字符序列;

3. 基于第2步的数据训练语言模型(这块我没明白?可以和各位探讨一下具体是做什么的

4. 从所有可能的subword 候选单元中,选择能似然值变化最大最大程度增加训练数据概率的新子词插入词汇表中;

5. 重复第4步,直到达到第一步中设定的subword词表大小 ,或概率/似然值 增量低于某一阈值。

3.3 Byte-level BPE

        这类BPE是在GPT2提出来的,听说源码还未公开,这部分让笔者先好好学一学,后续补上。​​​​​​​

猜你喜欢

转载自blog.csdn.net/xiao_ling_yun/article/details/129517312
今日推荐