字节对编码
BPE (Byte Pair Encoding)
BPE(Byte Pair Encoding,字节对编码)是一种数据压缩算法,被广泛用于大语言模型的分词器(Tokenizer),用于将文本切分成高频子词单元。
详细解释
BPE(字节对编码)最初由 Philip Gage 在 1994 年提出,作为一种文本压缩算法。2016 年,Sennrich 等人在论文《Neural Machine Translation of Rare Words with Subword Units》中将其引入 NLP 领域作为分词方法,从此成为几乎所有现代大模型(GPT、LLaMA、Qwen、GLM 等)的默认分词器。
BPE 的核心思想
- 初始化:把语料切成单字符(如英文 a, b, c…;中文每字一 token)。
- 统计频率:统计所有相邻字符对的出现次数。
- 合并最高频对:把出现频率最高的字符对合并成一个新的子词(如 t + h → th)。
- 重复:不断重复步骤 2-3,直到达到预设词表大小(通常 32K-200K)。
- 输出:得到一份「词表 + 合并规则」,可用于编码新文本。
BPE 的优势
- 解决 OOV(Out-of-Vocabulary)问题:任何新词都可以被拆成已学过的子词。
- 词表可控:固定 5 万或 10 万的词表大小就能覆盖多语言。
- 高频词保留整体,低频词自动拆分:既节省 token 数,又避免词表爆炸。
BPE 的变体
| 算法 | 特点 | 代表模型 |
|---|---|---|
| BPE | 基于频率贪心合并 | GPT-2, GPT-3 |
| WordPiece | 基于互信息合并 | BERT |
| Unigram LM | 基于概率剪枝 | LLaMA, Qwen |
| SentencePiece | 语言无关的子词工具 | 通义千问、智谱 GLM |
示例
用 tiktoken 库查看 BPE 切分结果:
import tiktoken
enc = tiktoken.get_encoding("cl100k_base")
print(enc.encode("唯元智创大模型"))
# 输出:[45208, 116, 226033, 99047, 100264]
常见问题
BPE 和 WordPiece 哪个更好?
两者思想接近。WordPiece 选择能让训练数据似然最大的合并对;BPE 直接选频率最高的合并对。实际效果差异不大,主要看实现细节。
中文 BPE 词表多大才够用?
通常 5-10 万词表可以覆盖 99% 的中文场景。唯元智创接入的 Qwen3.7 词表为 152K,兼顾中英双语与代码。