如何将文本拆分成一个个的token,简要介绍几种主流的方法。 https://huggingface.co/docs/transformers/tokenizer_summary
对一个预训练模型来说,使用它时,只有用和训练时相同的tokenize方法时,模型的表现才能正常。
问题在于标点符号和单词无法分割,中文里面还没有空格。 可以通过规则,单独考虑标点符号。 但是仍然有问题,就是don’t这个词,显然分成 do 和 n’t会更合理一些。这正是使tokenize变得复杂的地方。就这个问题,也可以通过添加规则来解决。
但总体来说,空格+标点规则+其他规则组成的tokenizer,还是会产生比较大的词表,这会让模型学习更加困难,并增加显存。
英文只有26个字符,直接将句子按照字符token,当然就大大减小了词表的大小。但是模型很难学习到有意义的表示。
它的假设是,大部分词都不需要进一步拆分,少数词需要进一步拆分成字词。比如,annoyingly拆分成annoying和ly会更合理。
这样的好处是减小词表,仍然能学习到有意义的表示,可以tokenize没有见过的词。
首先将文本进行粗粒度tokenize,比如按照空格。然后,每个word进一步拆分成字符。
然后根据出现频率,不断合并相邻的字符。直到词表大小符合要求。
为了减少基础字符,将byte作为基础字符。这样就只有256个基础字符。gpt2就是这个策略。
BERT就是使用的这个算法。
和bpe不同的是,合并相邻字符时,依据的不是共现频率,而是依据最大化语料的语言概率。
E.g. “u”, followed by “g” would have only been merged if the probability of “ug” divided by “u”, “g” would have been greater than for any other symbol pair.
和bpe不一样。该算法是先创建一个巨大的词表,然后想办法慢慢删除。选择删除的symbol的依据时,训练集中语言概率损失最小。
为了解决,非空格分割的文本。sentence piece将文本抽象为输入流。然后使用bpe或者unigram来减少词表。