一、格式处理
首先带大家梳理一下BPE词表中的一些知识。
- “normalizer”:设置正则化器,即文本在编码前先经过正则化处理,正则化主要是用于转换全角字符及汉字标点。常见的正则化器有‘NFKC’等,‘NFKC’能够有效转换全角字符,同时也能转换中文标点,但以下中文标点不做转换:句号。顿号、书名号《 》引号“ ” 以及各种方括号【】〖〗和六角括号〔〕,BPE训练时一般会先将语料正则化处理,再执行算法迭代,因此编码时也应加入正则化操作;
- 词表中的词表示一般区分词的位置,即是否为前缀(或后缀),同一个词在不同位置会对应不同id,因此tokenizer在使用词表分词前都会对序列进行预分词,即pretokenize,一般情况下pretokenize的依据是空格、制表、换行符和所有标点符号,此外special token也作为预切分依据,预分词后的文本会用于判断前后缀以生成不同表示,下一节会详细介绍常见的预分词器;
- special token在解码时会自动忽略,因此还原文本时也无需设置跳过规则。
- decode时的特殊情况:对于WordPiece解码器,如果一个id不属于前后缀类型的id,却位于序列的开头(结尾),则解码后会自动缀上“##”,其它情况下会按原样输出;如果一个id属于前后缀类型的,且其前(后)还有其他内容,则解码后会自动缀上空格符;
二、预分词器
一般在训练BPE词表时会对语料进行预分词,预分词后的文本可以更好地区分出前后缀。Tokenizer中常见的预分词器介绍如下:
1、Whitespace
Whitespace即连续字符分词器,采用正则表达式“\w+|[^\w\s]+
”进行原文匹配。通过表达式可以看出分词规则如下:将连续的字符(汉字、字母和数字)作为一个子词,也将连续的非字符和非空格(通常为标点等符号)作为一个子词来切分,空格(‘\s’)则会直接过滤;
2、BertPreTokenizer
其和1类似,也是按照空格和标点等符号做切分,只是遇到连续标点时会拆分为独立单元,例如三个点的省略号‘…’,按照1的方法切分后是‘…’,按该分词器切分则为三个‘.’;
3、Punctuation
按照标点切分,但不考虑空格,也不过滤空格,标点处理方法同2一样独立拆分;
4、CharDelimiterSplit
按照指定字符切分,函数包含delimiter参数,接受单个字符(不指定会报错),分词时以该字符为切分依据,并过滤字符使其不在分词结果中出现;
5、WhitespaceSplit
只按空格切分,其它标点等字符都会合并;
6、Split
函数输入一个正则表达式(由Regex类初始化,该类输入模式串),分词时按该表达式切分,函数包含‘behavior’参数,用于指定匹配出文本的处理方法,有切分、移除、与前驱词合并、与后继词合并四种选择(注:切分、前后合并模式下子词之间的匹配失败部分也作为一个子词,然后执行不同操作,移除模式下只移除匹配成功的子词);
7、Sequence
该分词器本身不具备分词功能,而是接受由分词器组成的列表类型,执行时会使用分词器表依次处理,每个分词器接受上一个分词器的输出,并将切分结果传给下一个分词器。列表中的分词器可以是上述所有分词器类型。