目录
1. space、punctuation、rule-based tokenization
2.4 SentencePiece:ALBERT,XLNet,Marian和T5
tokenizing a text是将文本分为words或subwords,然后通过look-up table将其转换为ID。我们将研究Transformers中使用的三种主要分词器类型:字节对编码(BPE),WordPiece和SentencePiece,并显示每种模型使用哪种分词器类型的示例。
1. space、punctuation、rule-based tokenization
space、punctuation、rule-based tokenization: word tokenization, 即splitting sentences into words.
优点:将文本分成较小chunks的最直观的方法;
缺点:使用所有唯一的words和tokens,通常会使vocabulary很大。Such a big vocabulary size forces the model to have an enormous embedding matrix as the input and output layer, which causes both an increased memory and time complexity. In general, transformers models rarely have a vocabulary size greater than 50,000, especially if they are pretrained only on a single language.
例如,Transformer XL使用空格和标点符号化,词汇量为267,735!
2. Subword tokenization
Subword tokenization是word-level 和 character-level tokenization的混合体。
Subword tokenization算法基于以下原则:不应将常用词分解为较小的子词,而应将稀有词分解为有意义的子词,即frequently used words should not be split into smaller subwords, but rare words should be decomposed into meaningful subwords.
from transformers import BertTokenizer
tokenizer = BertTokenizer.from_pretrained("bert-base-uncased")
tokenizer.tokenize("I have a new GPU!")
[“i”, “have”, “a”, “new”, “gp”, “##u”, “!”]
The tokenizer splits “gpu” into known subwords: [“gp” and “##u”].
"##"
:that the rest of the token should be attached to the previous one, without space (for decoding or reversal of the tokenization)
from transformers import XLNetTokenizer
tokenizer = XLNetTokenizer.from_pretrained("xlnet-base-cased")
tokenizer.tokenize("Don't you love Transformers? We sure do.")
[“▁Don”, “’”, “t”, “▁you”, “▁love”, “▁”, “”, “▁”, “Transform”, “ers”, “?”, “▁We”, “▁sure”, “▁do”, “.”]
2.1 Byte-Pair Encoding (BPE)
学习资料:BPE论文
BPE依赖于pre-tokenizer,该pre-tokenizer将训练数据分成单词, Pretokenization可以像空格分词器一样简单。
After pre-tokenization, a set of unique words has been created and the frequency of each word it occurred in the training data has been determined. Next, BPE creates a base vocabulary consisting of all symbols that occur in the set of unique words and learns merge rules to form a new symbol from two symbols of the base vocabulary. It does so until the vocabulary has attained the desired vocabulary size. Note that the desired vocabulary size is a hyperparameter to define before training the tokenizer.
Step1:pre-tokenization:创建一组唯一的单词和在训练数据中出现的每个单词的频率。如:
("hug", 10), ("pug", 5), ("pun", 12), ("bun", 4), ("hugs", 5)
Step2:BPE创建一个base vocabulary(该词汇表由一组出现在唯一词中的所有符号组成);并学习合并规则(从基础词汇表的两个符号中形成一个新符号), 这样做直到词汇表达到所需的词汇量vocabulary size 为止。 注意,vocabulary size 是在训练tokenizer之前定义的超参数。如:
Base vocabulary:
["b", "g", "h", "n", "p", "s", "u"]
Splitting all words into symbols of the base vocabulary:("h" "u" "g", 10), ("p" "u" "g", 5), ("p" "u" "n", 12), ("b" "u" "n", 4), ("h" "u" "g" "s", 5)
然后,BPE计算每个可能的符号对的频率,并选择最频繁出现的符号对。
假设BPE训练将在此处停止,则将学习的合并规则应用于新单词(只要这些新单词不包括基本词汇表中没有的符号)。
the vocabulary size = the base vocabulary size + the number of merges, is a hyperparameter to choose.
For instance GPT has a vocabulary size of 40,478 since they have 478 base characters and chose to stop training after 40,000 merges.
Byte-level BPE
包含所有可能的基本字符的基本词汇表可能非常大,例如 所有unicode字符都被视为基本字符。 为了拥有更好的基础词汇表,GPT-2使用字节作为基础词汇表,这是一个巧妙的技巧,可以强制基础词汇表的大小为256,同时确保词汇表中包含每个基本字符。随着一些额外的rules 来处理标点符号,GPT-2的标记生成器可以记号化每个文本,而不需要<UNK>符号。
GPT-2的词汇量为50257,它对应于256个字节的基本标记,一个特殊的文本结尾标记以及通过50,000次合并学习的符号。
2.2 WordPiece
WordPiece本质还是用的BPE思想,是用于BERT,DistilBERT和Electra的subword分词算法。
与BPE非常相似,WordPiece首先初始化一个词汇表,包含训练数据中存在的每个字符,然后逐步学习给定数量的合并规则。
与BPE相比,WordPiece不会选择最频繁的符号对,而是会选择一种将训练数据添加到词汇表中的可能性最大化的符号对。最大化训练数据的可能性等同于找到符号对,在所有符号对中,第一个符号后紧跟第二个符号的概率最大。例如。仅当“ ug”由“ u”,“ g”分割的概率大于任何其他符号对时,“ u” followed by“ g”才可以合并。直观上,WordPiece与BPE稍有不同,它通过合并两个符号来评估丢失的内容
2.3 Unigram
与BPE或WordPiece相比,Unigram将其基本词汇表初始化为大量符号,并逐步修整每个符号以获得较小的词汇表。基本词汇可以例如对应于所有pre-tokenized的单词和最常见的substrings。
Unigram不能直接用于Transformers中的任何模型,但可以与SentencePiece结合使用。
2.4 SentencePiece
参考:https://github.com/google/sentencepiece
使用SentencePiece的模型示例包括ALBERT,XLNet,Marian和T5。
到目前为止描述的所有tokenization算法都具有相同的问题:假定输入文本使用空格分隔单词。 但是,并非所有语言都使用空格来分隔单词。 一种可能的解决方案是使用特定于语言的pre-tokenizers,例如 XLM使用特定的中文、日文和泰文pre-tokenizer。 为了更广泛地解决此问题:
SentencePiece将输入视为原始输入流,因此在要使用的字符集中包含空格 ;
然后,它使用BPE或unigram算法来构建适当的词汇表。
XLNetTokenizer使用SentencePiece。 使用SentencePiece进行解码非常容易,因为所有tokens都可以串联在一起,并且用空格替换"▁"
。 transformers库中所有使用SentencePiece的模型都将它与unigram结合使用。