Byte-Pair Encoding(BPE,字节对编码)是一种分词(tokenization)方法,最初用于数据压缩,后来被广泛应用到自然语言处理(NLP)中,尤其是在大语言模型的分词器里。它的核心思想是通过统计字符或子词的出现频率,逐步合并最常见的一对(pair),生成一个更紧凑且灵活的词表。简单来说,BPE 从字符开始,慢慢“拼凑”出常见的词或词片段,既能处理已知词,又能适应新词。
BPE 怎么工作?
BPE 的过程可以分成两个阶段:训练词表和分词应用。
1. 训练词表
- 起点:从最基本的字符开始(比如字母、汉字),把每个字符看作一个 token。
- 统计:在一个大规模语料库中,统计所有相邻字符对(pair)的出现频率。
- 合并:找出最常见的字符对,把它们合并成一个新的 token,更新文本。
- 迭代:重复统计和合并,直到达到预设的词表大小(比如 30,000 个 token)。
举个简单例子(英文)
假设语料库是:“low lower lowest”:
- 初始状态(按字符切分,空格用 _表示):- l o w _ l o w e r _ l o w e s t
 
- 统计字符对:- l o(3 次),- o w(3 次),- w _(2 次),- e r(1 次)...
 
- 合并最常见的 l o→lo:- lo w _ lo w e r _ lo w e s t
 
- 再次统计:- lo w(3 次),- w _(2 次),- e r(1 次)...
 
- 合并 lo w→low:- low _ low e r _ low e s t
 
- 继续迭代,直到词表大小够了。
最终词表可能是:[l, o, w, e, r, s, t, _, lo, low, er, est]。
2. 分词应用
训练好词表后,BPE 用这个词表把新文本切成 token:
- 从字符开始,贪婪地匹配词表中最长的子词。
- 如果找不到完整词,就切成更小的子词或字符。
例子(用上面词表)
- 输入:“lower”
- 过程:- 尝试匹配 low→ 成功,得low。
- 剩下 er,匹配er→ 成功。
 
- 尝试匹配 
- 输出:[low, er]
中文的 BPE
中文没有天然的空格,所以 BPE 通常直接从单个汉字开始合并。假设语料库有“今天的天气很好”和“昨天的天气不好”:
- 初始状态:- 今 天 的 天 气 很 好和- 昨 天 的 天 气 不 好
 
- 统计字符对:- 天 的(2 次),- 天 气(2 次),- 的 天(2 次)...
 
- 合并 天 气→天气:- 今 天 的 天气 很 好和- 昨 天 的 天气 不 好
 
- 再合并 的 天气→的天气(假设频率够高)。
最终词表可能是:[今, 天, 的, 气, 很, 好, 昨, 不, 天气, 的天气]。
- 输入:“今天的天气很好。”
- 输出:[今天, 的天气, 很, 好](假设“今天”和“的天气”在词表里)。
BPE 的特点
- 从字符到词的过渡:- 开始是字符级,合并后逐渐变成子词或词,兼顾灵活性和效率。
 
- 处理未知词(OOV):- 如果遇到新词(比如“人工智脑”),可以切成 [人工, 智, 脑],不至于完全无法处理。
 
- 如果遇到新词(比如“人工智脑”),可以切成 
- 词表大小可控:- 通过设置合并次数,可以控制词表大小(比如 10,000 或 50,000)。
 
- 语言无关:- 不依赖特定语言规则,适合多语言模型。
 
BPE 在 NLP 中的应用
- GPT 系列:GPT-2、GPT-3 用 BPE 构建分词器,词表大小通常是 50,000 左右。
- RoBERTa:优化版的 BERT,也用 BPE。
- 多语言模型:如 mBART,BPE 能统一处理多种语言。
例子(GPT 的 BPE)
- 英文:“playing” → [play, ing](如果词表有这两个)。
- 中文:“人工智能” → [人工, 智能]或[人, 工, 智, 能](取决于词表)。
优点和局限
优点:
- 灵活性:能处理新词和多语言。
- 效率:词表比字符级小,比词级紧凑。
- 通用性:不依赖语言特定工具(不像中文的 jieba 需词典)。
局限:
- 语义不完整:有时切分不合理,比如“天气”可能变成 [天, 气]。
- 依赖语料:词表质量取决于训练数据,如果数据偏了,分词效果可能差。
用你的句子举例
“今天的天气很好。”:
- 如果 BPE 词表训练充分,可能切成:[今天, 的, 天气, 很, 好](5 个 token)。
- 如果词表小,可能切成:[今, 天, 的, 天, 气, 很, 好](7 个 token)。
总结
BPE 是一种“自下而上”的分词方法,从字符开始,通过统计合并生成子词,逐步构建词表。它在大模型中很流行,因为它既能压缩词表,又能灵活处理各种语言和未知词。就像搭积木,从小块拼出大块,最终让模型理解“今天的天气很好”这样的句子。
 
                             
        