大模型 Tokenizer:从字符到 Byte,再到大词表

大模型 Tokenizer:从字符到 Byte,再到大词表

Tokenizer 是大语言模型处理文本的第一步。

简单来说,它负责把一句话转换成模型能够理解的 Token。

例如:

text 复制代码
我喜欢机器学习
↓
[我] [喜欢] [机器] [学习]
↓
[Token ID]

Tokenizer 的核心问题其实很简单:

怎么让文本既能被完整表示,又尽量使用更少的 Token?


一、为什么不能直接按词切?

最简单的方法是按照完整单词切分:

text 复制代码
I love machine learning
↓
[I] [love] [machine] [learning]

这种方法很直观,但有一个明显的问题:新词怎么办?

如果词表里没有某个词,就会出现 OOV(Out-of-Vocabulary,登录外词)。

所以后来出现了 Character-level Tokenizer,把词拆成一个个字符:

text 复制代码
machine
↓
[m] [a] [c] [h] [i] [n] [e]

这样基本不会遇到新词问题,但 Token 数量会明显增加,导致模型处理序列变长。

于是就有了折中方案:Subword Tokenizer

它既不把整个词作为一个 Token,也不把所有东西拆成单个字符,而是学习常见的词片段。


二、BPE 是怎么做的?

BPE(Byte Pair Encoding) 是目前非常经典的一种 Subword 方法。

它的基本思路就是:常见的组合,就把它们合并起来。

例如:

text 复制代码
a + b → ab
ab + c → abc

训练 Tokenizer 时,它会根据训练数据学习这些合并规则。到了真正使用的时候,就按照已经学好的规则进行切分。

除了 BPE,还有 WordPiece 和 Unigram 等方法,它们的训练方式不同,但目的类似:找到一套合适的 Token,让文本表示更加高效。


三、为什么又出现 Byte-level?

Subword 已经解决了很多 OOV 问题,但还有一个问题:Unicode 字符非常多。

如果把大量 Unicode 字符直接作为基础单元,词表会变得很复杂。

UTF-8 提供了一个更简单的办法。

一个 Byte 只有 256 种可能:

0 ∼ 255 0 \sim 255 0∼255

因此,可以先把文本转换成 UTF-8 Byte,再在 Byte 上进行 BPE。

例如:

text 复制代码
中
↓
UTF-8
↓
E4 B8 AD

所以:

Character ≠ Byte ≠ Token \boxed{\text{Character} \neq \text{Byte} \neq \text{Token}} Character=Byte=Token

"中"是一个字符,E4 B8 AD 是它的 UTF-8 编码,而 Token 是 Tokenizer 最终生成的离散单位。


四、什么是 BBPE?

BBPE 就是 Byte-Level BPE。

它的过程可以简单理解为:

text 复制代码
文本
↓
UTF-8 Byte
↓
BPE 合并
↓
Token
↓
Token ID

它最大的优势是:

  • Byte:作为一种通用的基础表示,让各种 UTF-8 文本都有基本的表示路径,解决基础表示问题。
  • BPE:把常见的 Byte 序列组合成更大的 Token,从而减少 Token 数量,提高文本压缩效率。

五、为什么现在词表越来越大?

当 Tokenizer 能够表示各种文本之后,另一个问题就出现了:能不能用更少的 Token 表示相同的内容?

例如,如果一个常见词组总是一起出现,那么把它作为一个 Token,显然比拆成很多 Token 更高效。

因此,现在一些大模型的词表从早期的几十 K,逐渐扩大到 100K 甚至更大。

大词表的好处是:

text 复制代码
词表更大
↓
可以容纳更多常见模式
↓
Token 数量可能减少
↓
文本表示更加紧凑

特别是在中文、多语言、代码和数字等场景中,大词表可能带来更好的 Token 压缩效果。


六、大词表是不是越大越好?

当然不是。

词表越大,也意味着更高的系统成本。

例如 Embedding 参数量大致为:

V × d model V \times d_{\text{model}} V×dmodel

其中 V V V 是词表大小。

所以:

text 复制代码
词表变大
↓
可以容纳更多高频文本模式
↓
在合适的训练条件下,Token 数量可能减少
↓
但 Embedding / LM Head 等成本增加

因此,Tokenizer 实际上一直在做一个平衡:

覆盖能力 + Token 压缩效率 ↔ 词表成本 \boxed{\text{覆盖能力} + \text{Token 压缩效率} \leftrightarrow \text{词表成本}} 覆盖能力+Token 压缩效率↔词表成本


七、总结

从 Word-level 到 Character-level,再到 Subword、Byte-level BPE,Tokenizer 的发展可以简单理解为:

text 复制代码
按词
↓ (解决语义粒度问题)

按字符
↓ (减少 OOV)

Subword
↓ (在词和字符之间寻找平衡)

Byte-level
↓ (提供通用的基础表示)

大词表
↓ (进一步减少 Token 数量)

最终,Tokenizer 要解决的并不是"怎么分词"这么简单,而是一个很实际的工程问题:

如何用尽可能少的 Token,稳定、高效地表示尽可能多的文本,同时控制词表带来的成本。

相关推荐
__Wedream__1 小时前
ICPR 2022 多教师知识蒸馏技术应用于图像超分辨率重建——MTKDSR
图像处理·人工智能·深度学习·超分辨率重建·图像复原和增强
湘美书院--湘美谈教育2 小时前
湘美书院谈探索式教育,中医药AI研究络病理论
大数据·人工智能·深度学习·学习·生活
kaixin_啊啊2 小时前
头歌——人工智能(深度学习初体验)
人工智能·深度学习
硅谷秋水3 小时前
WAM-Nav:用于统一视觉导航的非对称潜世界动作建模
深度学习·机器学习·计算机视觉·语言模型·机器人
卡梅德生物科技小能手3 小时前
卡梅德生物科普 Zika Virus(寨卡病毒)|病毒结构与科研实验体系解析
经验分享·深度学习·生活
别动我齐刘海4 小时前
“三层同步审计”判定掉帧缺失
c语言·c++·人工智能·深度学习·学习·机器学习·机器人
wuyk5554 小时前
第1章:无刷电机核心原理与运行机制
c语言·开发语言·stm32·单片机·嵌入式硬件·机器学习
SomeB1oody4 小时前
【RustyML入门】2.10. 主成分分析
开发语言·后端·机器学习·rust·教程