profileName: youpingfang postId: 404 postType: post categories:

- 6

文本子词分词算法是大语言模型的一项关键技术,负责将文本转换为模型可处理的 token 序列。那为什么不能直接以”字符”或”单词”作为模型的输入单元?BPE(Byte Pair Encoding)算法解决了什么问题?


我们可以把“字符”、“单词”和“子词(Subword)”看作是文本切分的三种不同粒度。下面我们逐一拆解为什么前两者不行,以及 BPE 算法是如何精妙地解决这一痛点的。

一、 为什么不能直接用“单词(Word-based)”作为输入单元?

在英文等天然有空格分隔的语言中,按词切分(如把 Datawhale Agent learns 切分为 ['Datawhale', 'Agent', 'learns'])最符合人类的直觉,但对计算机来说,它有两个致命灾难

  1. 词表爆炸(Vocabulary Explosion)

    人类语言的词汇量是无限的。如果每个独立的单词都要占用一个词表格子,词表轻松就会突破几百万、甚至上千万(比如各种专业术语、网络热词、人名)。在模型中,词表越大,最后的线性输出层(Softmax)参数量就越恐怖,导致显存爆炸,模型根本存不下。

  2. 未登录词困境(Out-of-Vocabulary, OOV)

    无论你的词表多大,总会有模型在训练时没见过的词。比如训练集里有 learnlearning,但有一天用户输入了 learned 或拼接词 DatawhaleAgent。如果按单词切分,模型只能把它们统一标记为 [UNK](Unknown,未知词),导致模型直接变成“文盲”,完全无法理解这些词的含义

  3. 语义关联割裂

    在纯按词切分的模型眼里,looklookslooking 是三个没有任何关系的孤立符号,模型必须分别去学习它们的含义,这极大地浪费了学习效率。


二、 为什么不能直接用“字符(Character-based)”作为输入单元?

既然按单词切分词表太大,那直接按英文字母 $A, B, C \dots$ 或中文的单个汉字切分,词表不就缩减到几百或几千个了吗?这样确实没有 [UNK] 未知词的问题了,但它带来了另外两个极端问题

  1. 序列长度爆炸

    一个短句 Artificial Intelligence 只有 2 个单词,但如果按字符切分就会变成 23 个字符(包含空格)。这会导致输入的序列变得极长。别忘了 Transformer 的自注意力机制计算复杂度是序列长度的平方级别($O(L^2)$),序列变长 10 倍,计算量和显存开销直接飙升 100 倍!

  2. 缺乏独立语义,学习效率极低

    单个字母(如 a, p, p, l, e 中的 a)没有任何实际意义。模型不得不花费大量的网络容量和计算资源,去学习如何把这些字母组合在一起拼成有意义的词,属于典型的“捡了芝麻丢了西瓜”。


三、 BPE(Byte Pair Encoding)算法解决了什么问题?

为了在“单词”的饱满语义和“字符”的超小词表之间找到折中方案,现代大模型普遍引入了子词分词(Subword Tokenization),而 BPE 就是其中最璀璨的代表。

1. BPE 解决的核心问题

BPE 完美地用“动态合并”的贪心思想,跨越了词表大小与未登录词的鸿沟。它的核心策略是:常用的词保留为完整单词,不常用的词拆分成有意义的“子词(Subword)”片段。

  • 如果 agent 在语料里出现了一万次,BPE 就会把它合成一个完整的 Token:['agent'](保留高频词的完整语义)。

  • 如果 Tokenization 是个低频词,BPE 不会把它当成未知词,而是会把它拆成两个高频的子词:['Token', 'ization']

2. BPE 是如何精妙运作的?

它的训练过程像是一个“滚雪球”的贪心游戏:

  1. 底线初始化:把词表初始化为所有最基础的“字符”(如英文字母和标点),确保绝对不会出现 [UNK](大不了退化为字符切分)。

  2. 疯狂数对对:统计语料库里,哪两个相邻的符号在一起出现的次数最多。

  3. 融合升级:把这个最高频的“符号对”整合成一个新词元,加进词表。

  4. 循环往复:重复这个过程,直到词表大小达到预设的上限(比如 GPT-4 的 100K 左右)。

例如,在遇到从未见过的生僻词 bug 时,分词器发现词表里没有整个 bug,但有高频子词 bug,于是它会将其切分为 ['b', 'ug']。模型可以通过 bug 的向量组合,隐式地推理出 bug 的含义。


💡 总结对比

分词粒度 词表大小 序列长度 遭遇未知词(OOV) 语义保留能力
按单词 (Word) 极庞大(百万级) 经常遇到(灾难) 极好(词元自带完整语义)
按字符 (Char) 极小(几百个) 极长(平方面积计算爆炸) 完全没有 极差(单个字母无语义)
BPE 子词 (Subword) 中等可控(几万到十几万) 适中 完美解决(退化为子词拼接) 极佳(兼顾高频语义与低频泛化)

正是因为 BPE 算法在效率、成本和语义理解之间找到了黄金分割点,它才成为了 GPT 系列等现代大语言模型不可或缺的文本前处理基石。