《分词算法大揭秘:BPE、BBPE、WordPiece、ULM常见方法介绍》
分词算法是自然语言处理(NLP)中的一个重要预处理步骤,它将文本分割成更小的单元(如单词、子词或字符)。以下是几种常见的分词算法:Byte Pair Encoding (BPE)、Byte-level BPE (BBPE)、WordPiece 和 Unigram Language Model (ULM)
1. Byte Pair Encoding (BPE)
论文摘要
- 标题:Neural Machine Translation of Rare Words with Subword Units
- 连接:点击这里阅读论文全文
核心思想
从一个基础小词表开始,通过不断合并最高频的连续token对来产生新的token。
详细可参考BPE 算法原理及使用指南【深入浅出】
具体做法
- 准备基础词表,如英文中26个字母加上各种符号,并初始化ID。
- 基于基础词表将准备的语料拆分为最小单元,末尾添加</ w>(示例中使用_)。
- 在语料上统计单词内相邻单元对的频率,选择频率最高的单元对进行合并。
- 重复第3步直到达到预先设定的subword词表大小或下一个最高频率为1。
优缺点
- 优点:可以有效地平衡词汇表大小和编码步数。
- 缺点:
- 无法提供带概率的多个分词结果。
- 局部高频对合并可能破坏全局更有意义的组合。
2. Byte-level BPE (BBPE)
论文信息
- 标题:Neural Machine Translation with Byte-Level Subwords
- 链接:https://arxiv.org/pdf/1909.03341
核心思想
该论文提出了一种名为BBPE(Byte-level BPE)的新型机器翻译方法,将传统BPE的字符级操作扩展到字节级别,直接处理UTF-8编码的字节序列。此举有助于避免传统字符级BPE中稀有字符(如生僻汉字)占用词表空间的问题。
具体做法
- 使用基础词表,采用256的字节集,UTF-8编码。
优点
- 与BPE相媲美,但词表大为减小。
- 可在多语言间通过字节级别的子词实现更好的共享。
- 即使字符集不重叠,也可通过字节层面的共享实现良好的迁移。
- 高效的压缩效果,根据文本中的重复模式和常见片段来动态生成词汇表,尤其适用于大量重复内容的文本数据。
- 适用于多种类型的数据,包括文本、图像等,因其基于字节级别的编码方法。
- 无损压缩,确保压缩后的数据与原始数据无信息损失。
- 可解码性,可轻松将编码后的数据解码回原始数据。
- 灵活性高,可根据需求调整压缩效果和词汇表大小。
缺点
- 编码序列时可能略长于BPE,计算成本更高。
- 由byte解码时可能会遇到歧义,需要通过上下文信息和动态规划进行解码,确保输出有效句子。
BBPE和BPE的关键区别
3. WordPiece
论文:Fast WordPiece Tokenization
- 链接:https://arxiv.org/pdf/2012.15524
核心思想
与BPE类似,Fast WordPiece Tokenization 从基础小词表出发,通过合并子词来生成最终词表。不同之处在于,WordPiece 选择合并的token对时基于token间的互信息而非频率。这里的互信息衡量的是两个子词同时出现的概率相比于它们各自独立出现的概率。
具体做法
-
输入:训练语料和词表大小 V。
-
准备基础词表,如英文字母和符号。
-
使用基础词表将语料拆分为最小单元。
-
基于拆分后的数据训练语言模型,可以是 unigram 语言模型,通过极大似然估计。
-
选择能最大程度增加训练数据概率的 token 对进行合并。假设句子由 N 个子词组成 S = ( t 1 , t 2 , . . . , t N ) S = (t_1, t_2, ..., t_N) S=(t1,t2,...,tN),句子的似然值为所有子词概率的乘积:
log P ( s ) = ∑ i = 1 N log P ( t i ) \log P(s) = \sum_{i=1}^{N} \log P(t_i) logP(s)=i=1∑NlogP(ti)
合并相邻两个子词 x 和 y 产生新的子词 z,句子的似然值变化为两个子词之间的互信息:
log P ( t z ) − ( log P ( t x ) + log P ( t y ) ) = log P ( t z ) P ( t x ) P ( t y ) \log P(t_z) - (\log P(t_x) + \log P(t_y)) = \log \frac{P(t_z)}{P(t_x)P(t_y)} logP(tz)−(logP(tx)+logP(ty))=logP(tx)P(ty)P(tz)
每次选择互信息最大的两个子词合并,基于子词在语言模型上的关联性,得分计算公式为:
score = P ( t z ) P ( t x ) P ( t y ) \text{score} = \frac{P(t_z)}{P(t_x)P(t_y)} score=P(tx)P(ty)P(tz) -
重复第 5 步直到达到预设的子词表大小或概率增量低于阈值。
优点
- 能平衡词表大小和 OOV 问题
缺点
- 可能产生一些不合理的子词或错误划分
- 拼写错误敏感
- 对前缀支持不够好
一种解决方案是将复合词和前缀拆开处理。
4. Unigram Language Model (ULM)
核心思想
初始化一个大词表,然后通过unigram语言模型计算删除不同subword造成的损失来代表subword的重要性,保留loss较大或者说重要性较高的subword。ULM会倾向于保留那些以较高频率出现在很多句子的分词结果中的子词,因为这些子词如果被删除,其损失会很大。
具体做法
-
输入训练语料和词表大小V
-
准备基础词表:初始化一个很大的词表,比如所有字符+高频ngram,也可以通过BPE算法初始化
-
针对当前词表,用语言模型(unigram lm)估计每个子词在语料上的概率,比如EM算法,维特比算法寻找最优分割
-
计算删除每个subword后对总loss的影响,作为该subword的loss
-
将子词按照loss大小进行排序,保留前x%的子词;注意,单字符不能被丢弃,以免OOV
-
重复步骤2到4,直到词表大小减少到设定值
优点
- 使用的训练算法可以利用所有可能的分词结果,这是通过data sampling算法实现的
- 提出一种基于语言模型的分词算法,这种语言模型可以给多种分词结果赋予概率,从而可以学到其中的噪声
- 使用时也可以给出带概率的多个分词结果
缺点
- 效果与初始词表息息相关,初始的大词表要足够好,比如可以通过BPE来初始化
- 略显复杂