整个 NLP 的发展分为 4 个阶段:
- 起源
- 基于规则
- 基于统计
- N-gram
- Bow
- 深度学习和大数据驱动:大语言模型
基本概念
词元,英语里面叫做 Token,这是模型里面一个最基本的概念。
词元不仅是模型的输出单位,也是模型的输入单位。发送给模型的提示词(prompt),首先就会被分解为词元。
在 OpenAI 平台官网,提供了在线查看词元的方式。
每一个词元,都会有一个唯一的 ID,因此,最终输入到大模型的数据,是一个词元 ID 列表。
举个例子:
- 假设用户输入的文本为:“Learn about language model tokenization.”
- 首先进行分词:
[Learn] [about] [language] [model] [token] [ization] [.] - 查词表映射 ID:每个 token 会被查表映射为一个整数 ID,比如:
[1122, 98, 4012, ...] - 最终进入模型:
[1122, 98, 4012, 3305, 2351, 7489, 13]这样的整数列表
分词策略
- 词级分词
- 子词级分词
- 字符级分词
- 字节级分词
1. 词级分词
直接以“完整的词”为单位进行切分。适用于空格分隔语言,例如英语。
特点:
- 粒度较大,语义清晰
- 对英文常见词效果很好
- 缺点是无法处理未登录词
I love natural language processing.["I", "love", "natural", "language", "processing", "."]每个单词对应一个词元。如果输入的词是一些新词、或者自造词,就不认识了。不支持 OOV.
OOV 英语全称 Out Of Vocabulary(词汇表),OOV 表示超出了词汇表,从而无法处理这个词。
2. 子词级分词
将词分成更小的子词单元,如词干、前缀、后缀,适合处理未知词。
lovelylove、ly特点:
- 兼顾词级和字符级优点
- 支持 OOV
能够处理一些新词以及自造词。
3. 字符级分词
将每个字符作为一个词元,不依赖词典。
Hello["H", "e", "l", "l", "o"]特点:
- 适合拼写敏感任务(如语言模型、自动补全)
- 能处理所有字符,OOV 问题消失(不存在造不出来的词)
- 缺点是序列长度变长,难以建模高级语义结构
4. 字节级分词
将输入文本首先按UTF-8 字节切分,再对这些字节组成的序列进行建模或进一步压缩。换句话说,它的基本单位是字节而不是字符或词,因此具有语言无关性。
Hello 😊[72, 101, 108, 108, 111, 32, 240, 159, 152, 138]- 前面 6 个是 ASCII 字符(H e l l o 空格)
- 后面 4 个是 emoji 表情的 UTF-8 编码
优势:
- 语言无关,对多语言友好
- 处理 OOV 能力比较强
- 压缩空间效率高:根据训练数据频率自动构建最佳子词组合,减少 token 总数
目前 GPT-2 / GPT-3 / GPT-4 均采用的是字节级分词。
不同版本的大模型,分词的结果会有不同,例如在 GPT2 中,Python 代码 elif 会被分为两个词[el、if],但是到了 GPT4 就已经有自己的词元了,会分为 [elif],这一点源于模型对代码的关注度的提升。
另外,不同的语言模型,分词的效果也会不同,这里举个例子:
ChatGPT真厉害!GPT2/GPT4
['Chat', 'G', 'PT', '真', '厉', '害', '!']BERT
['[UNK]', '真', '厉', '害', '!']Phi-3
['▁Chat', 'G', 'PT', '真', '厉', '害', '!']具体如下表:
| 模型 | 分词方法 | 分词器工具 | 是否字节级 | 是否子词级 | OOV问题 |
|---|---|---|---|---|---|
| GPT-2 | Byte-level BPE | tiktoken | 是 | 是 | 无 |
| GPT-4 | Byte-level BPE(改进) | tiktoken | 是 | 是 | 无 |
| BERT | WordPiece | bert-tokenizer | 否 | 是 | 有 [UNK] |
| Phi-3 | SentencePiece (Unigram+BPE) | sentencepiece | 可选 | 是 | 无 |
-EOF-