下面是对 BPE(Byte Pair Encoding)分词算法的深入介绍,涵盖其背景、原理、实现细节、数学机制、优缺点以及在自然语言处理中的实际应用。
一、背景与动机
在自然语言处理中,模型输入通常需要被转换为数值序列,而这首先需要将文本拆分为可处理的最小单元。传统的分词策略有三类:
词级分词(Word-level Tokenization):容易出现 OOV(Out-of-Vocabulary)问题;
字符级分词(Character-level Tokenization):过于细碎,序列长度太长;
子词级分词(Subword-level Tokenization):在这两者之间取得平衡,BPE 就属于这一类。
BPE 分词的核心思想是:通过数据驱动的方法找出最常见的字符组合,以此构建词汇表,使模型既能处理高频词,又能组合出低频词或新词。
二、BPE 的起源
最早的 BPE 是一种用于数据压缩的算法,由 Philip Gage 在 1994 年提出。它的原始用途是用频繁的字节对替换为一个新符号,从而减少文件大小。
2016 年,Sennrich 等人将其引入自然语言处理,用于构建子词单元,从而提升神经机器翻译的效果(论文标题为 "Neural Machine Translation of Rare Words with Subword Units")。
三、BPE 分词算法的核心思想
BPE 是一个基于统计的、贪心的合并策略,其核心思想是:
不断合并训练语料中出现频率最高的符号对(symbol pair)为新符号,直到达到预定词表大小或合并次数。
这些“符号”最初是字符,随着合并的进行,可能变成字符组合。
四、BPE 的详细算法流程
输入:
语料(文本数据)
目标词汇表大小(或最大合并次数)
步骤:
第一步:初始化
将所有词语按字符划分,每个词结尾添加一个特殊终止符,如 </w>
,以区分词边界。例如:
"low" → l o w </w>
"lower" → l o w e r </w>
"newest" → n e w e s t </w>
每个词都被拆成字符序列,并统计出现频率。
第二步:统计字符对频率
遍历整个词表,统计每个相邻字符(或子词)对出现的总次数。
例如:
"l o w </w>":字符对 ("l", "o")、("o", "w")、("w", "</w>")
将这些字符对及其频率记录下来。
第三步:合并频率最高的字符对
找出出现频率最高的字符对(如 "o w"),并将其视为一个新子词 "ow"。
例如:
"l o w </w>" → "l ow </w>"
"l o w e r </w>" → "l ow e r </w>"
更新词表,替换所有出现该字符对的地方。
第四步:重复步骤 2~3
继续统计新的子词对频率,并合并频率最高的一对,直到达到指定的合并次数或词表大小为止。
第五步:构建最终词表
在所有合并步骤中出现过的子词都可以构成词表(vocabulary),用于编码文本。
举个简化例子:
给定词频如下:
low: 5
lowest: 2
newest: 6
newer: 3
初始化分词(添加 </w>
):
l o w </w> ×5
l o w e s t </w>×2
n e w e s t </w>×6
n e w e r </w> ×3
第一轮统计所有字符对频率,如 ("e", "s") 出现频率最高 → 合并为 "es"
继续合并 → ("es", "t") → "est" → ("n", "e") → "ne"……
直到构建出子词如:
"low", "new", "est", "er", "ne", "er", "lowest", "newest"
这样,无论是高频词(如 newest)还是低频词(如 newer),都能被拆解成已知子词。
五、BPE 分词的编码与解码
编码:
编码时,BPE 会根据训练生成的子词词表,用最长匹配的策略将输入词切分为子词组合。
比如输入词 newer
:
子词词表有:
new
、er
输出:
new er
若词表没有 newer
但有 n
、e
、w
、er
,则输出:n e w er
解码:
将子词逐个拼接回原始词,如果有 </w>
终止符,就表示到一个词的结尾。
六、BPE 的优点与缺点
优点:
处理 OOV(未登录词)能力强:所有词都可以拆成子词,模型不会因不认识词而出错。
词表大小可控:相比整词级分词,词表更小,占用内存更少。
训练速度快,易于实现。
子词建模兼顾精细性与语义性,保留了一定的语言结构信息。
缺点:
合并操作是贪心策略,非全局最优。
同一个词可能被拆分成不同子词序列,影响一致性(尤其在跨语料中)。
不会考虑上下文:合并是基于频率的,无法根据语境灵活调整。
七、BPE 与其他分词算法对比
方法 | OOV处理 | 词表大小 | 序列长度 | 是否上下文相关 |
---|---|---|---|---|
Word-level | 差 | 大 | 短 | 否 |
Char-level | 好 | 小 | 长 | 否 |
BPE | 好 | 中 | 中 | 否 |
Unigram LM | 更灵活 | 中 | 中 | 否 |
SentencePiece | 更健壮 | 中 | 中 | 否 |
八、在实际系统中的应用
1. HuggingFace Transformers
HuggingFace 的 tokenizers
库中提供了 ByteLevelBPETokenizer
,被 GPT-2 和 RoBERTa 等模型使用。
2. SentencePiece + BPE 模式
Google 的 BERT 和 T5 使用 SentencePiece,它支持 BPE 和 Unigram 模型。
3. GPT 系列
OpenAI GPT 系列(包括 GPT-2、GPT-3)使用了一种改进版的 BPE,称为 Byte-Level BPE,对输入进行字节级别处理,能处理任意 UTF-8 字符。
九、小结
BPE 是一种高效的分词算法,介于词级和字符级之间。通过频率驱动的合并策略,构建出对语言有表达能力的子词单元,有效减少词表大小,提升模型泛化能力。如今,它已成为现代 NLP 模型(如 Transformer 系列)的基础技术之一。