1.引言
在文本输入embedding层之前,以中文文本为例,首先对文本进行分词并进行one-hot编码,分词肯定是根据词表来进行分词,那构建一个合适的词表就显得至关重要,过大或者过小都会对后续模型的训练效果产生影响。所以这里介绍当前各个大模型的词表构建方法。
2.技术基础
在介绍具体的词表构建方法之前,我们首先了解一下什么是分词器(Tokenizer)。
什么是分词器?简单点说就是将字符序列转化为数字序列,对应模型的输入。
通常情况下,Tokenizer有三种粒度:word/char/subword
- word: 按照词进行分词,如: Today is sunday. 则根据空格或标点进行分割[today, is, sunday, .]
- character:按照单字符进行分词,就是以char为最小粒度。 如:Today is sunday. 则会分割成[t, o, d,a,y, .... ,s,u,n,d,a,y, .]
- subword:按照词的subword进行分词。如:Today is sunday. 则会分割成[to, day,is , s,un,day, .]
可以看到这三种粒度分词截然不同,各有利弊。
对于word粒度分词:
优点:词的边界和含义得到保留;
缺点:
1)词表大,稀有词学不好;
2)OOV(可能超出词表外的词);
3)无法处理单词形态关系和词缀关系,会将两个本身意思一致的词分成两个毫不相同的ID,在英文中尤为明显,如:cat, cats。
对于character粒度分词:
优点:词表极小,比如:26个英文字母几乎可以组合出所有词,5000多个中文常用字基本也能组合出足够的词汇;
缺点:
1)无法承载丰富的语义,英文中尤为明显,但中文却是较为合理,中文中用此种方式较多。
2)序列长度大幅增长;
最后为了平衡以上两种方法,又提出了基于subword进行分词:它可以较好的平衡词表大小与语义表达能力,当前大模型均是采用这种力度的分词方法。
所以如何构造一个subword力度的词表就很重要。
3.类别比较和说明
常见的子词算法有Byte-Pair Encoding (BPE) / Byte-level BPE(BBPE)、Unigram LM、WordPiece、SentencePiece等。
- BPE:即字节对编码。其核心思想是从字母开始,不断找词频最高、且连续的两个token合并,直到达到目标词数。
- BBPE:BBPE核心思想将BPE的从字符级别扩展到子节(Byte)级别。BPE的一个问题是如果遇到了unicode编码,基本字符集可能会很大。BBPE就是以一个字节为一种“字符”,不管实际字符集用了几个字节来表示一个字符。这样的话,基础字符集的大小就锁定在了256(2^8)。采用BBPE的好处是可以跨语言共用词表,显著压缩词表的大小。而坏处就是,对于类似中文这样的语言,一段文字的序列长度会显著增长。因此,BBPE based模型可能比BPE based模型表现的更好。然而,BBPE sequence比起BPE来说略长,这也导致了更长的训练/推理时间。BBPE其实与BPE在实现上并无大的不同,只不过基础词表使用256的字节集。
- WordPiece:WordPiece算法可以看作是BPE的变种。不同的是,WordPiece基于概率生成新的subword而不是下一最高频字节对。WordPiece算法也是每次从词表中选出两个子词合并成新的子词。BPE选择频数最高的相邻子词合并,而WordPiece选择使得语言模型概率最大的相邻子词加入词表。
- Unigram:它和 BPE 以及 WordPiece 从表面上看一个大的不同是,前两者都是初始化一个小词表,然后一个个增加到限定的词汇量,而 Unigram Language Model 却是先初始一个大词表,接着通过语言模型评估不断减少词表,直到限定词汇量。
- SentencePiece:SentencePiece它是谷歌推出的子词开源工具包,它是把一个句子看作一个整体,再拆成片段,而没有保留天然的词语的概念。一般地,它把空格也当作一种特殊字符来处理,再用BPE或者Unigram算法来构造词汇表。SentencePiece除了集成了BPE、ULM子词算法之外,SentencePiece还能支持字符和词级别的分词。
4.具体应用示例
当前大语言模型大部分使用sentencepiece库中的BBPE分词算法来构建词表。
模型 | 训练数据 | 模型参数 | 训练数据范围 | 词表大小 | 分词算法 |
---|---|---|---|---|---|
llama | 1T-1.4T | 7B-65B | 英文等拉丁语 | 32000 | BBPE |
chatglm-6b | 1T | 6B | 中英双语 | 130528 | BBPE |
bloom | 1.6T | 300M-176B | 46种语言 | 250680 | BBPE |
简单介绍一下sentencepiece:
SentencePiece 是一种无监督的文本 tokenizer 和 detokenizer,主要用于基于神经网络的文本生成系统,其中,词汇量在神经网络模型训练之前就已经预先确定了。 SentencePiece 实现了subword单元(例如,字节对编码 (BPE))和 unigram 语言模型),并可以直接从原始句子训练字词模型(subword model)。 这使得我们可以制作一个不依赖于特定语言的预处理和后处理的纯粹的端到端系统。
技术优势:
SentencePiece 技术优势
- 纯数据驱动:SentencePiece 从句子中训练 tokenization 和 detokenization 模型。 并不总是需要Pre-tokenization(Moses tokenizer/MeCab/KyTea) 。
- 独立于语言:SentencePiece 将句子视为 Unicode 字符序列。 没有依赖于语言的逻辑。多子词算法:支持 BPE 和 unigram 语言模型。
- 子词正则化:SentencePiece 实现子词正则化和 BPE-dropout 的子词采样,有助于提高 NMT 模型的鲁棒性和准确性。
- 快速且轻量级:分割速度约为 50k 句子/秒,内存占用约为 6MB。
- Self-contained:只要使用相同的模型文件,就可以获得相同的tokenization/detokenization。
- 直接词汇 ID 生成:SentencePiece 管理词汇到 ID 的映射,可以直接从原始句子生成词汇 ID 序列。
- 基于 NFKC 的 normalization:SentencePiece 执行基于 NFKC 的文本 normalization。