文章目录
- 背景
- 基于词(Word-based)
- 基于字符(Character-based)
- 子词词元化(Subword tokenization)
背景
tokenization是包括大语言模型在内所有自然语言处理的任务的基础步骤,其目标是将文本数据转化为数值。完成这一步骤的组件称之为tokenizer。该过程可以用以下图表示:
基于词(Word-based)
基于词的方法仅通过一些简单的规则来完成这一步骤。比如,在英文中可以使用空格作为分隔符:
tokenized_text = "This is a test".split()
print(tokenized_text)
输出:
['This', 'is', 'a', 'test']
每个单词对应一个ID,可以设置词表为 N N N,然后取最高频的 N N N个词作为词表(这里未考虑特殊字符),这个方法简单直接,但是有以下问题:
- 相似的词有着截然不同的意思,如:“dog”和“dogs”
- 词表会非常大
- OOV(Out-Of-Vocabulary)情况会很多,而这些词都会统一用一个token表示,如:“<UNK>”,这使得很多词都会使用同一个token表表示,原来的语义会丢失。
基于字符(Character-based)
更加进一步,我们可以将切分的力度更细一点,使用字符来切分文本,这有2个好处:
- 词表很小,单词也就26个字母,常用的汉字也就几千。
- OOV的情况很少,因为切分的力度更小,所以相比基于词的方法,很少会出现OOV。
但同时缺点也显而易见:
- 相对于词而言,每个token能表示的语义信息更少
- 文本转为token之后会很长
为了兼顾两者的优势,现在用的比较多的方法称之为:子词词元化(subword tokenization)。
备注:熟悉的味道,计算机领域经常会出现这种,在两个极端中取一个平衡。
子词词元化(Subword tokenization)
子词词元化的目标有2个:
- 常见词不应该切分为更小的单元
- 罕见词应该被分解为有意义的子词
比如:Let’s do tokenization!
,可以被切分为:
其中,“</w>”表示单词的结尾。
这样子词的表示会有更多的语义信息,同时也可以使在小的词表情况下,尽可能减少<UNK>
token的出现。
子词词元化有很多种方法,比较典型的包括:
- GPT-2中的Byte-level BPE
- BERT中的WordPiece
- T5中的Unigram
每一种方法的具体介绍将在之后的博客中进行分享(很快)。
参考资料:
- Huggingface NLP course
- 大规模语言模型:从理论到实践 – 张奇、桂韬、郑锐、黄萱菁