分类 tokenize 下的文章

一、SentencePiece 简介

SentencePiece 在大模型领域主要用于文本的 分词 和 编码。

1、分词

是将文本分割成一个个独立的词语或符号。传统的中文分词方法,例如 BMM 分词、隐马尔可夫(H M M ) 分词,都是基于规则的,需要人工制定分词规则。而 SentencePiece 则是基于 无监督学习 的,它可以自动学习文本的语义和结构,并根据学习结果进行分词。

2、编码

是将分词后的词语或符号转换为数字形式,以便计算机能够处理。SentencePiece 使用了一种称为 字节对编码 的方法,它可以将每个词语或符号编码成一个或多个字节。字节对编码的优点是能够有效地利用空间,并且可以将词语或符号之间的关系编码到编码中。

3、优势:SentencePiece 在大模型领域具有以下优势:

分词效果好,能够准确地识别词语和符号的边界。
编码效率高,能够节省空间。
能够将词语或符号之间的关系编码到编码中,有利于模型学习。
因此,SentencePiece 已经被广泛应用于各大模型,例如 Google 的 BERT、GPT-3,以及阿里巴巴的 M6 等。

简单来说,SentencePiece 就是大模型领域的一个 分词和编码工具。它可以帮助大模型更好地理解和处理文本。

4、自监督训练原理

SentencePiece 的自监督训练模型原理是通过 无监督学习 的方式,学习文本的语义和结构,并根据学习结果进行分词和编码。

具体来说,SentencePiece 的训练过程可以分为以下几个步骤:

数据准备:首先需要准备一个文本语料库,语料库中的文本可以是任何类型,例如新闻文章、书籍、代码等。
模型训练:使用无监督学习算法训练 SentencePiece 模型,模型的输入是文本语料库,输出是分词后的文本。
模型评估:使用评估指标评估模型的性能,例如分词准确率、召回率等。
SentencePiece 使用的无监督学习算法是一种称为 Masked Language Modeling (MLM) 的算法。MLM 的基本思想是:将文本中的部分词语或符号进行遮蔽,然后让模型预测被遮蔽的词语或符号。通过这种方式,模型可以学习文本的语义和结构。

在 SentencePiece 中,MLM 的具体实现如下:

随机选择文本中的部分词语或符号进行遮蔽。
将被遮蔽的词语或符号替换为一个特殊符号,例如 [MASK]。
将处理后的文本输入模型,让模型预测被遮蔽的词语或符号。
通过这种方式,模型可以学习到被遮蔽词语或符号与周围词语或符号之间的关系,从而提高分词和编码的准确性。

SentencePiece 的自监督训练模型具有以下优势:

不需要人工制定分词规则,能够自动学习文本的语义和结构。
分词效果好,能够准确地识别词语和符号的边界。
编码效率高,能够节省空间。
SentencePiece 的自监督训练模型已经被广泛应用于各大模型,例如 Google 的 BERT、GPT-3,以及阿里巴巴的 M6 等。

二、TikToken 简介

Tiktoken 的功能与 SentencePiece 类似,都是用于文本的 分词 和 编码。

Tiktoken 是一个基于 BPE 算法的 快速分词器,它专门针对 GPT-4 和 ChatGPT 等大模型进行了优化。Tiktoken 的主要特点如下:

速度快:Tiktoken 的分词速度比 SentencePiece 快很多,可以满足大模型训练和推理的需求。
效果好:Tiktoken 的分词效果与 SentencePiece 相当,能够准确地识别词语和符号的边界。
易用性:Tiktoken 提供了简单的 API 接口,方便使用。
Tiktoken 与 SentencePiece 的主要区别 如下:

分词算法:Tiktoken 使用 BPE 算法进行分词,而 SentencePiece 使用的是无监督学习算法。
速度:Tiktoken 的分词速度比 SentencePiece 快很多。
模型:Tiktoken 专门针对 GPT-4 和 ChatGPT 等大模型进行了优化,而 SentencePiece 则是通用的。

速度探究
所以大家一定对为什么这么快很好奇,查阅tictoken的源码得知,tictoken对CoreBPE类进行了基于RUST的重写,包括真·多线程,regex,缓存caching,哈希各个方面的优化,具体的下面逐一解释:

3.1 regex优化
正则是耗时的大头,解决办法是用一些不那么花哨的方法,比如用 regex crate可解析的形式的regex要比寻常方法快3倍以上。

一旦明确了使用crate可解析的regex,可以选择用regex crate 或者 fancy_regex crate

regex crate 和 fancy_regex crate也有相互关系,fancy_regex使用的re.find_it会竞争re的可变缓存空间,造成性能下降,而regex的find_iter有不同的代码路径,不会造成这个问题。为此,通过给绝大部分的regex线程做一个克隆线程来避免。

3.2 threading
rayon并没有比python自带的threads和释放GIL的情况下快,所以直接用python线程计数等来完成threads

这里我多说一下,python自带的GIL是指如果没有额外操作,只是使用了类似:

3.3 caching
tokenizer中使用LRU cache是很有必要的,可以加速查找速度,作者使用了RWLock来保护cache安全,对于RWLock,全称是"reader-writer spin lock",和普通的spinlock不同,它对"read"和"write"的操作进行了区分。如果当前没有writer,那么多个reader可以同时获取这个rwlock。如果当前没有任何的reader,那么一个writer可以获取这个rwlock。

3.4 hash
作者使用了FxHashMap替代传统的HashMap达到了一定的性能提升,简单说明一下,FxHashMap的散列算法质量不高,但速度非常快,特别是对整数键而言,并且发现它的性能优于rustc内的所有其他散列算法。

以上就是tictoken进行的性能优化。

v2-3d4a7ff19c9c874dda20b8ecf8ade385_r.jpeg

一、 背景与基础

在使用GPT BERT模型输入词语常常会先进行tokenize ,tokenize具体目标与粒度是什么呢?tokenize也有许多类别及优缺点,这篇文章总结一下各个方法及实际案例。

tokenize的目标是把输入的文本流,切分成一个个子串,每个子串相对有完整的语义,便于学习embedding表达和后续模型的使用。

二、切分粒度

tokenize有三种粒度:word/subword/char

1.词粒度-word

词粒度的切分就跟人类平时理解文本原理一样,常常用一些工具来完成,例如英文的NLTK、SpaCy,中文的jieba、LTP等。举个栗子:

英文
live in New York ------> live / in / New York /

中文
在纽约生活 -----> 在 / 纽约 / 生活
词粒度的切分能够非常好地保留完整语义信息,但是如果出现拼写错误、英文中的缩写等情况,鲁棒性一般。另一方面,词切分会产生非常巨大的词表,而且这都不能确保不会出现out of vocabulary问题。

2.字粒度-char-字符粒度

字粒度最早应该是2015年Karpathy[1]提出,简单说英文就是以字母为单位(对于大小写不敏感的任务,甚至可以先转小写再切分),中文就是以字为单位,举个栗子,

英文
live in New York -----> l / i / v /e / i / n / N / e / w / Y / o / r /k

中文
在纽约生活 -----> 在 / 纽 / 约 / 生 / 活
可以看出,字粒度的切分很好地解决了词粒度的缺陷,鲁棒性增强、词表大大减小。但另一方面,也会带来一些麻烦:

「毫无意义」:一个字母或一个单字本质上并没有任何语义意义;
「增加输入计算压力」:减小词表的代价就是输入长度大大增加,从而输入计算变得更耗时耗力;
如果词粒度不理想,而且字粒度似乎也有自己的问题,那么还有什么替代方法呢?Here comes subword tokenization。

3.Subword粒度

我们需要的tokenization需要满足:

  • 它能够在不需要无限词汇表的情况下处理缺失的标记,即通过有限的已知单词列表来处理无限的潜在词汇。
  • 此外,我们不希望将所有内容分解为单个字符的额外复杂性,因为字符级别可能会丢失单词级别的一些含义和语义细节。

为此,我们需要考虑如何重新利用『小』单词来创建『大』单词。subword tokenization不转换最常见的单词,而是将稀有单词分解成有意义的子词单元。如果unfriendly被标记为一个稀有词,它将被分解为un-friendly-ly,这些单位都是有意义的单位,un的意思是相反的,friend是一个名词,ly则变成副词。这里的挑战是如何进行细分,我们如何获得un-friend-ly而不是unfr-ien-dly。

NLP最火的网红 Transformer 和 BERT 就是Subword的带盐人,来看个它们做tokenization的栗子,

I have a new GPU ----> [’i’, ’have’, ’a’, ’new’, ’gp’, ’##u’, ’.’]
subword粒度切分算法又有一下几种:

1.BPE
2.WordPiece
3.ULM(unigram LM)

SentencePiece集成了两种subword算法,BPE和UniLM, WordPiece 则是谷歌内部的子词包,没对外公开

参考:
1.https://cloud.tencent.com/developer/article/1865689
2.https://zhuanlan.zhihu.com/p/340473354