大家好啊,我是电棍。距离上次更新已经过去近两个月。我一直想记录跨年前后发生的事,但任务繁重,这些事情并不十分有趣,故迟迟没有记录。
今天来点大家想看的东西。
我得了一种怪病:看到文档就想睡觉。
因此,我会尽力让我写的东西比文档更有趣。
分词器在做什么?怎么做?
分词器的作用是把一段话分成一系列词语,然后将词语变为编号。
把词语变成编号很好理解。但是怎么把一段话分成词语呢?
流派一:基于单词的分词器 Word-based Toknization
这是最符合直觉的方法:按照现有的单词进行编号。
来看英语的例子:
来看汉语的例子:
我们只需要参考辞书进行分词,给词语进行编号即可。
然而这种做法有严重的问题。其一,很多英语单词是由多个词复合而成的。如果以单词为粒度进行分词,词表会膨胀得极其严重。于是一种新的流派也即Subword_based Toknization产生了。这并非我们讨论的重点,故不赘述。
其二,词汇表的空间有限,不可能收纳所有单词。我们在与LLM交流时也免不了会拼错单词。
中国政法大学的郭继承教授有言:
🤓🤏你想想那是个真理,真理是无相的!所以金刚经的一句话,叫凡有所相,皆是虚妄,见所相非相。那是个真理!你不能迷信在这方面。
😠🤚它是个真理!所以,道可道非常道,名可名非常名。
🫳🤓👆但是说那有人说我非得说!你非得说我可以告诉你,老子也没说明白。他是不是语言可以描述的!
🤓👐后来西方的语言哲学家维特根斯坦,把这个事说了一句名言。
😙🤌维特根斯坦说,这个世界上有语言能说的,要说清楚;这个世界上也有超出语言说不明白的,维特根斯坦直接用了俩字:闭嘴。
😫那没法说嘛!

省流:
闭嘴。
让我们看这样的情况:
遇到词汇表中没有的单词,分词器直接甩了俩字:闭嘴!这是不可被接受的。
流派二:基于字节的分词器 Byte-based Tokenization
顾名思义,我们将一句话编码成一串字节,一个字节就是一个词。
来看英语的例子:
来看汉语的例子:
这种方法确确实实解决了词表不能涵盖所有单词的问题。但是它带了了新的问题。不难发现,按照Word-based Tokenization的方案,"Cock loves pussy“只被拆成了三个词;而在Byte-based Tokenization中,它被拆成了14个词。一个汉语字符会占用三个字节;因此,之前只需要三3个词表示的“我鍾意釣蟹“在这里被拆成了15个词。
熟悉Transformer的朋友们应该知道,Transformer的计算复杂度和KV Cache规模随着输入量的增长是平方级增长的。这样的代价是我们无法接受的。
你别说,还真有人做了。
流派三:基于字符的分词器 Character-based Tokenization
依然顾名思义,我们以Unicode字符为粒度进行分词。
来看英语的例子:
来看汉语的例子:
相信聪明的小朋友已经发现了问题:
其一,Unicode字符有约150000个,词表爆炸的问题依然没有得到解决;
其二,大量Unicode字符其实并不常用。