BPE算法详解
在NLP模型中,输入通常是一个句子,例如 I went to New York last week. 。传统做法:空格分隔,例如 ['i', 'went', 'to', 'New', 'York', 'last', 'week'] 。
这种做法存在问题:例如模型无法通过 old, older, oldest 之间的关系学到 smart, smarter, smartest 之间的关系。如果我们能将一个token分成多个subtokens,上面的问题就能很好地解慧颂决。本文将详述目前比较常用的 subtokens 算法 —— BPE(Byte-Pair Encoding)
现在性能比较好一些的 NLP 模型,例如 GPT、BERT、RoBERTa 等,族好在数据预处理的时候都会有 WordPiece 的过程,其主要的实现方式就是 BPE(Byte-Pair Encoding)。具体来说,例如 ['loved', 'loving', 'loves'] 这三个单词。其实本身的语义都是 "爱" 的意思,但是如果我们 以词为单位,那它们就算不一样的词 ,在英语中不同后缀的词非常的多,就会使得词表变的很大,训练速度变慢,训练的效果也不是太好。
BPE算法通过训练,能够把上面的3个单词拆分成["lov", "ed", "ing", "es"]几个部分,这样可以把词的本身的意思和时态分开,有效的减少了此表的数量。算法流程如下:
例如:
出现最频繁的字节对是 e 和 s ,共出现了 6+3 = 9次,因此将它们合并
出现最频繁的字节对是 es 和 t ,共出现了6+3=9次,所以将它们合并
出现最频繁的字节对是 est 和 </w> ,共出现了6+3=9次,因此将它们合并
出现最频繁的字节对是 l 和 o ,共出现了5+2 = 7 次,因此将它们合并
...... 继续迭代直到达到预设的 subwords 词表大小V 或 下一个最高频的字节对出现频率为 1 。这样我们就得到了更加合适的词表,这个词表可能会出现 一些不是单词的组合 ,但是其本身有意义的一种形式
停止符 </w> 的意义在于表示subword是词后缀。举例来说: st 不加 </w> 可以出现在词首,如 st ar ;加了 </w> 表明该子词位于词尾,如 wide st</w> ,二者意义截然不同。
输出如下
在之前的算法中,我们已经得到了 subword 的词表,对该词表按照字符个数 由多到少排序 。编码时,对于每个单词, 遍历排好序的子词词表寻找是否有 token 是当前单词的子字符串 ,如果有,则该 token 是表示单词的 tokens 之一
我们从最长的token迭代到最短的token,尝试将每个单词中的子字符串替换为token。最终,我们将迭代所有的tokens,并将所有子字符串替换为tokens。 如果仍然有子字符串没被替换但所有token都已迭代完毕,则将剩余的子词替前穗郑换为特殊token,如 <unk>
例如
将所有的tokens拼在一起即可,例如
输出如下
2024-11-30 广告