Tokenizer分词算法

94 阅读7分钟

定义

Tokenizer 可以将文本转换成独立的 token 列表,进而转换成输入的向量成为计算机可以理解的输入形式。

概述

  • 根据不同的切分粒度可以把tokenizer分为: 基于词的切分,基于字的切分和基于subword的切分。 基于subword的切分是目前的主流切分方式。
  • subword的切分包括: BPE(/BBPE), WordPiece 和 Unigram三种分词模型。其中WordPiece可以认为是一种特殊的BPE。
  • 完整的分词流程包括:文本归一化,预切分,基于分词模型的切分,后处理。
  • SentencePiece是一个分词工具,内置BEP等多种分词方法,基于Unicode编码并且将空格视为特殊的token。是当前大模型的主流分词方案。

202401291028.png

基于subword的切分

优点

  • 基于subword的切分能很好平衡基于词切分和基于字切分的优缺点。基于subword的切分包括:BPE,WordPiece 和 Unigram 三种分词模型。
  1. 词表规模适中,解码效率较高
  2. 不存在UNK,信息不丢失
  3. 能学习到词缀之间的关系
  • 基于词的切分,会造成:
  1. 词表规模过大
  2. 一定会存在UNK,造成信息丢失
  3. 不能学习到词缀之间的关系,例如:dog与dogs,happy与unhappy
  • 基于字的切分,会造成:
  1. 每个token的信息密度低
  2. 序列过长,解码效率很低

基本切分原则

  1. 高频词依旧切分成完整的整词
  2. 低频词被切分成有意义的子词,例如 dogs => [dog, ##s]

切分的一般流程

Tokenizer包括训练和推理两个环节。训练阶段指得是从语料中获取一个分词器模型。推理阶段指的是给定一个句子,基于分词模型切分成一连串的token。基本的流程如图所示,包括归一化,预分词,基于分词模型的切分,后处理4个步骤。

202401291107.png

归一化

这是最基础的文本清洗,包括删除多余的换行和空格,转小写,移除音调等。

input: Héllò hôw are ü?
normalization: hello how are u?

预分词

  • 预分词阶段会把句子切分成更小的词单元。可以基于空格或者标点进行切分。 不同的tokenizer的实现细节是不一样的。
input: Hello, how are  you?

pre-tokenize:
[BERT]: [('Hello', (0, 5)), (',', (5, 6)), ('how', (7, 10)), ('are', (11, 14)), ('you', (16, 19)), ('?', (19, 20))]

[GPT2]: [('Hello', (0, 5)), (',', (5, 6)), ('Ġhow', (6, 10)), ('Ġare', (10, 14)), ('Ġ', (14, 15)), ('Ġyou', (15, 19)), ('?', (19, 20))]

[t5]: [('▁Hello,', (0, 6)), ('▁how', (7, 10)), ('▁are', (11, 14)), ('▁you?', (16, 20))] 
  • 可以看到BERT的tokenizer就是直接基于空格和标点进行切分。
  • GPT2也是基于空格和标签,但是空格会保留成特殊字符“Ġ”。
  • T5则只基于空格进行切分,标点不会切分。并且空格会保留成特殊字符”▁”,并且句子开头也会添加特殊字符”▁”。

基于分词模型的切分

这里指的就是不同分词模型具体的切分方式。分词模型包括:BPE,WordPiece 和 Unigram 三种分词模型。

后处理

后处理阶段会包括一些特殊的分词逻辑,例如添加sepcial token:[CLS],[SEP]等。

BPE

概述

Byte-Pair Encoding(BPE)是最广泛采用的subword分词器。

  • 训练方法:从字符级的小词表出发,训练产生合并规则以及一个词表
  • 编码方法:将文本切分成字符,再应用训练阶段获得的合并规则
  • 经典模型:GPT, GPT-2, RoBERTa, BART, LLaMA, ChatGLM等

训练流程

在训练环节,目标是给定语料,通过训练算法,生成合并规则和词表。BPE算法是从一个字符级别的词表为基础,合并pair并添加到词表中,逐步形成大词表。合并规则为选择相邻pair词频最大的进行合并。

推理阶段

在推理阶段,给定一个句子,我们需要将其切分成一个token的序列。具体实现上需要先对句子进行预分词并切分成字符级别的序列,然后根据合并规则进行合并。

BBPE

概述

  • Byte-level BPE (BBPE)算法是上面BPE算法的进一步升级。核心思想是用byte来构建最基础的词表而不是字符。首先将文本按照UTF-8进行编码,每个字符在UTF-8的表示中占据1-4个byte。在byte序列上再使用BPE算法,进行byte level的相邻合并。
  • 通过这种方式可以更好的处理跨语言和不常见字符的特殊问题(例如,颜文字),相比传统的BPE更节省词表空间(同等词表大小效果更好),每个token也能获得更充分的训练。但是在解码阶段,一个byte序列可能解码后不是一个合法的字符序列,这里需要采用动态规划的算法进行解码,使其能解码出尽可能多的合法字符

WordPiece

概述

  • WordPiece分词与BPE非常类似,只是在训练阶段合并pair的策略不是pair的频率而是互信息。

202401291448.png

  • 一个pair的频率很高,但是pair的一部分的频率更高,这时候不一定需要进行该pair的合并。而如果一个pair的频率很高,并且这个pair的两个部分都是只出现在这个pair中,就说明这个pair很值得合并。
    • 训练方法:从字符级的小词表出发,训练产生合并规则以及一个词表
    • 编码方法:将文本切分成词,对每个词在词表中进行最大前向匹配
    • 经典模型:BERT及其系列DistilBERT,MobileBERT等

训练流程

  • 在训练环节,给定语料,通过训练算法,生成最终的词表。WordPiece算法也是从一个字符级别的词表为基础,逐步扩充成大词表。合并规则为选择相邻pair互信息最大的进行合并。
  • 在初始化字符级别词表的时候,如果字符不是不一个词的开始,需要添加上特殊字符"##"

推理阶段

在推理阶段,给定一个句子,需要将其切分成一个token的序列。具体实现上需要先对句子进行预分词,然后对每个词进行在词表中进行最大前向的匹配。如果词表中不存在则为UNK。

Unigram

概述

Unigram分词与BPE和WordPiece不同,是基于一个大词表逐步裁剪成一个小词表。通过Unigram语言模型计算删除不同subword造成的损失来衡量subword的重要性,保留重要性较高的子词。

  • 训练方法:从包含字符和全部子词的大词表出发,通过训练逐步裁剪出一个小词表,并且每个词都有自己的分数。
  • 编码方法:将文本切分成词,对每个词基于Viterbi算法求解出最佳解码路径。
  • 经典模型:AlBERT, T5, mBART, Big Bird, XLNet

训练流程

在训练环节,目标是给定语料,通过训练算法,生成最终的词表,并且每个词有自己的概率值。Unigram算法是从大词表为基础,逐步裁剪成小词表。裁剪规则是根据Unigram语言模型的打分依次裁剪重要度相对较低的词。

推理阶段

在推理阶段,给定一个句子,需要将其切分成一个token的序列。具体实现上先对句子进行预分词,然后对每个词基于Viterbi算法进行解码。

SentencePiece 分词工具

  • 内置BPE,Unigram,char和word的分词方法
  • 无需预分词,以unicode方式直接编码整个句子,空格会被特殊编码为▁
  • 相比传统实现进行优化,分词速度速度更快