BPE (Byte Pair Encoding)
3 秒看懂
BPE 是一种”先拆字、再合并”的分词算法:从最小单元(字符或字节)出发,反复将语料中出现频率最高的相邻符号对合并为新符号,直到词表达到预设大小。它是 GPT 系列、LLaMA 系列等主流大语言模型的底层分词方案——你输入的每个 token,都是 BPE(或其变体)切出来的。
3 分钟产业解释
为什么分词器(Tokenizer)是大模型的”入口基础设施”?
大语言模型不能直接吃文本字符串,必须先把文本切成离散的 token 序列再送入模型。分词器的质量直接影响:
- 压缩率 / 序列长度:同样的文本,切出的 token 越少,推理时 KV Cache 越小、吞吐越高、上下文窗口能塞进更多内容。
- OOV(未登录词)鲁棒性:老式按词分词(word-level)遇到新词就爆;BPE 能把未知词拆成已知子词,永不 OOV。
- 多语言公平性:对英语以外的语言(中文、日语、阿拉伯语等),分词粒度差异极大。同样的语义,中文可能比英文多消耗 1.5–3 倍 token——这直接决定中文 API 的真实成本。
- 训练-推理一致性:分词器在预训练前确定后通常不再更换。它是模型”认识世界的第一道门”。
BPE 及其变体(Byte-level BPE、WordPiece、Unigram) 几乎垄断了当前主流 LLM 的分词方案。OpenAI 的 tiktoken、Google 的 SentencePiece、HuggingFace tokenizers 是三大主流实现库。
15 分钟专家深入
BPE 的核心算法流程
- 初始化:将训练语料中所有词拆成最小粒度单元——
- 经典 BPE(Sennrich 2016):以 Unicode 字符为底,词尾加特殊符号
</w>以区分词内与跨词边界。 - Byte-level BPE(Radford 2019 / GPT-2):以 256 个字节为底,任何 Unicode 文本均可无损编码为字节序列,彻底消除 UNK。
- 经典 BPE(Sennrich 2016):以 Unicode 字符为底,词尾加特殊符号
- 统计:遍历语料,统计所有相邻符号对(bigram)的出现频率。
- 合并:选频率最高的一对
(a, b)→ 合并为新符号ab,写入合并规则表(merge table)。 - 重复:回到步骤 2,直到词表大小达到预设上限(如 32K / 50K / 100K)。
推理时:加载合并规则表,对新文本按规则逐步合并,得到 token 序列。这是确定性的、可逆的(BPE 解码 = 拼接 token 字符串)。
Byte-level BPE 的关键突破
GPT-2 论文(Radford et al., 2019)引入的 byte-level BPE 解决了一个根本问题:Unicode 字符集(14 万+)太大,字符级底座词表过大且对罕见字符不友好。改用 256 个字节作底,任何语言、任何符号都可以表示,base vocabulary 仅 256 个 token,极其紧凑。
这带来的好处:
- 零 UNK:理论上不可能出现无法编码的输入。
- 语言无关:同一套分词器天然覆盖所有语言(虽然压缩效率有差异)。
- 实现简洁:tiktoken 等库的核心就是字节级 BPE。
技术原理(深入机制)
1. 算法伪代码
Input: 语料库 corpus, 最大词表大小 V_max
Output: 合并规则表 merges[], 词表 vocab[]
# 初始化
vocab ← {所有基础单元} # 字符级: Unicode字符集; 字节级: 0x00~0xFF
for each word in corpus:
word ← 拆为字符/字节序列 + 词尾标记
# 迭代合并
while |vocab| < V_max:
pairs ← 统计语料中所有相邻符号对频率
(a, b) ← argmax(pairs) # 选最高频对
merges.append((a, b)) # 记录合并规则
vocab.add(concat(a, b)) # 新符号入词表
corpus ← 将所有 (a, b) 替换为 concat(a, b)
return merges, vocab
2. 编码(推理)流程
Input: 待编码文本 text
Output: token_id 序列
tokens ← 将 text 拆为基础单元序列
for (a, b) in merges: # 按训练时的合并顺序
while (a, b) in tokens:
tokens ← 替换 (a, b) → concat(a, b)
return tokens 的 id 序列
关键点:合并是有优先级的——先学到的合并规则先应用。这就是为什么 merge table 的顺序至关重要。
3. 与其他分词方案的技术对比
| 维度 | BPE | WordPiece | Unigram LM |
|---|---|---|---|
| 合并依据 | 纯频率(count) | 似然增益(likelihood gain) | 基于概率模型剪枝 |
| 构建方向 | 自底向上(合并) | 自底向上(合并) | 自顶向下(从大词表裁剪) |
| 代表模型 | GPT-2/3/4, LLaMA, Mistral | BERT, DistilBERT | T5(SentencePiece Unigram模式) |
| 实现库 | tiktoken (OpenAI), HuggingFace tokenizers | HuggingFace tokenizers | SentencePiece (Google) |
| 底层单元 | 字节 or 字符 | 字符 (以 ## 标记续接) | 字符 or 字节 |
| 确定性 | 确定 | 确定 | 采样可选(训练时可随机) |
| 核心优势 | 实现简单、零 UNK | 似然驱动、理论上更优 | 可给出 token 概率、支持正则化 |
WordPiece 与 BPE 的核心差异:BPE 选”频率最高的对”合并;WordPiece 选”合并后使语言模型似然提升最大的对”。WordPiece 的合并更”有意义”但计算开销更大。实际效果差距有限。
技术演进史
| 时间 | 事件 | 意义 |
|---|---|---|
| 1994 | Philip Gage 提出 BPE | 原始目标是数据压缩算法(C Users Journal) |
| 2016 | Sennrich, Haddow, Birch 发表论文 “Neural Machine Translation of Rare Words with Subword Units” | 将 BPE 引入 NMT 分词,解决稀有词问题;提出字符级 BPE + </w> 方案 |
| 2018 | Google 发布 SentencePiece 库(Kudo & Richardson) | 实现 BPE + Unigram 两种算法,语言无关(raw text in),成为事实标准工具 |
| 2019 | OpenAI GPT-2 发布(Radford et al.) | 引入 byte-level BPE,以 256 字节为底座,彻底消除 UNK;词表约 50,257 |
| 2020 | GPT-3 延续 GPT-2 分词器 | 确认 byte-level BPE 作为 GPT 系列标准 |
| 2023 | OpenAI 开源 tiktoken 库;GPT-3.5/4 切换至 cl100k_base | 更高效的 BPE 实现(Rust 核心),词表扩大到 ~100K,压缩率提升 |
| 2023 | Meta LLaMA/LLaMA 2 使用 SentencePiece BPE | 词表 32,000;证明 BPE 在开源模型中的可行性 |
| 2024 | GPT-4o 引入 o200k_base | 词表扩展到 ~200K,多语言压缩率显著改善 |
技术路线对比
主流 LLM 分词器参数表
| 模型 | 分词算法 | 底层单元 | 词表大小 | 实现库 | 来源 |
|---|---|---|---|---|---|
| GPT-2 | Byte-level BPE | 256 字节 | ~50,257 | 自研 | [OpenAI GPT-2 论文] |
| GPT-3.5 / GPT-4 | Byte-level BPE | 256 字节 | ~100,256 | tiktoken (cl100k_base) | [tiktoken 官方] |
| GPT-4o | Byte-level BPE | 256 字节 | ~200,019 | tiktoken (o200k_base) | [tiktoken 官方] |
| LLaMA / LLaMA 2 | BPE | 字节(byte fallback) | 32,000 | SentencePiece | [Meta LLaMA 论文] |
| Mistral / Mixtral | BPE | 字节(byte fallback) | 32,000 | SentencePiece | [Mistral 官方] |
| BERT | WordPiece | 字符 | ~30,522 | HuggingFace tokenizers | [Google BERT 论文] |
| T5 | Unigram | 字符 | 32,000 | SentencePiece | [Google T5 论文] |
| Qwen (通义千问) | Byte-level BPE | 字节 | ~151,936 | 自研 (tiktoken-based) | [阿里 Qwen 技术报告] |
| DeepSeek | Byte-level BPE | 字节 | ~100,015 | tiktoken 变体 | [DeepSeek 技术报告] |
注:词表大小数据来自各模型公开技术报告或开源代码,部分为近似值。
上下游
上游:数据与算力
- 训练语料:分词器的合并规则完全由语料决定。语料的语言构成、领域分布、文本清洗方式直接影响 token 粒度。通常在预训练语料的一个子集上训练分词器。
- 计算:BPE 训练本身并不需要 GPU——纯 CPU 即可完成(本质是频率统计+排序),训练时间从几分钟到几小时不等,取决于语料规模。
下游:模型与应用
- 模型输入层:Embedding 矩阵的行数 = 词表大小。词表越大,Embedding 参数越多(~词表 × hidden_dim)。
- 推理成本:token 数 × 每 token 的计算量 = 总推理成本。更好的压缩率 = 更少的 token = 更低的推理成本。
- 上下文窗口:4K / 8K / 128K / 1M 上下文窗口的”K”指的就是 token 数。分词器的压缩率决定了能塞进多少实际文本。
- 多语言公平性:不同语言的 token 效率差异巨大。对于同一条语义,中文通常消耗的 token 数约为英文的 1.5–3 倍(估算,具体取决于模型的分词器),日语、韩语等也类似。
产业链定位
语料数据 ──→ 分词器训练(CPU)──→ 合并规则表 + 词表
│
▼
模型预训练(GPU 集群)
│
▼
推理服务 ──→ token 计费(API)
关键指标
| 指标 | 定义 | 说明 |
|---|---|---|
| 词表大小 (Vocab Size) | 分词器输出的不重复 token 总数 | 直接影响 Embedding 参数量和 softmax 计算量 |
| 压缩率 (Fertility) | 平均每个原始字符被切成多少个 token | 越低越好;中文大约 1 字 ≈ 1–3 token(因模型而异) |
| 字符/token 比 | 压缩率的倒数 | 越高越好,表示每个 token 编码的原始信息越多 |
| OOV 率 | 无法编码的输入比例 | Byte-level BPE 理论上为 0 |
| 编码速度 | 每秒编码的字符/token 数 | tiktoken(Rust)显著快于纯 Python 实现 |
| 跨语言公平性 | 同语义在不同语言间的 token 数比值 | 理想状态为 1:1,实际差距可达 1:3+ |
供需与市场数据
分词器的”隐性成本”
分词器看似”无成本”(训练只需 CPU、几分钟),但其影响渗透到整个推理链路:
- API 定价基础:OpenAI、Anthropic、Google 等 API 均按输入+输出 token 数计费。分词器决定了一美元能买多少语义。
- 上下文窗口利用率:128K 上下文的模型,如果分词器对目标语言压缩率差,实际能塞进的有效内容大打折扣。
- KV Cache 显存:token 数量直接决定 KV Cache 大小,这在长上下文推理中是显存瓶颈。
量化估算
- GPT-2 分词器(50K 词表)处理英文约 1 token ≈ 4 字符 ≈ 0.75 单词。
- 中文约 1 汉字 ≈ 1–2 token(GPT-2 分词器),GPT-4 的 cl100k_base 可压缩到约 1 汉字 ≈ 0.6–1.2 token(估算,取决于具体文本)。
- o200k_base 进一步提升多语言压缩率,具体数据 [未充分披露]。
代表公司与资本映射
| 公司 / 机构 | 角色 | 关键动作 |
|---|---|---|
| OpenAI | BPE 最大的工业推动者 | GPT-2 引入 byte-level BPE;开源 tiktoken;持续扩展词表 |
| SentencePiece 开发者 | SentencePiece 支持 BPE + Unigram,被开源社区广泛采用 | |
| HuggingFace | 开源 tokenization 工具链 | tokenizers 库(Rust 实现),支持 BPE/WordPiece/Unigram |
| Meta | 开源 LLM 分词器标准制定者 | LLaMA 系列使用 SentencePiece BPE,32K 词表成为开源模型标配 |
| 阿里 (通义千问) | 多语言优化 | Qwen 扩展词表到 ~152K,改善中文压缩率 |
| DeepSeek | 中文优化 | 词表 ~100K,中文压缩率显著优于早期 GPT 分词器 |
投资逻辑
1. 分词器是”隐性护城河”
分词器训练成本极低(<1000 美元的 CPU 算力),但它在以下层面构建壁垒:
- 兼容性锁定:模型一旦训练完成,分词器不可更换(否则 Embedding 层、所有权重全部作废)。换模型 = 换分词器 = 重做下游所有适配。
- 多语言体验差异化:对中文用户,分词器效率直接决定使用成本。Qwen、DeepSeek 的大词表分词器在中文场景有实质优势。
2. 关注词表扩展趋势
从 GPT-2 的 50K → GPT-4 的 100K → GPT-4o 的 200K,词表在快速扩展。驱动力:
- 多语言覆盖需求
- 更高压缩率 → 更低推理成本
- Embedding 层参数占比随词表增大而增加,但在大模型中占比很小(<1% 总参数)
3. 非投资标的,但影响投资判断
分词器不是独立产品/公司,但它是评估 LLM 竞争力的隐藏维度:
- 同等模型能力下,分词效率更高的模型推理成本更低。
- 中文场景评估必须考虑分词器效率,不能只看 benchmark 分数。
常见误读纠偏
❌ 误读 1:“BPE 是一种压缩算法,用于减少模型存储”
纠偏:BPE 起源于数据压缩,但在 LLM 场景中它不是压缩模型权重的——它是将文本离散化为 token 序列的算法。它压缩的是”文本到 token 的映射”(即用更少的 token 表示同样的文本),而非模型参数。模型权重压缩是量化(INT8/INT4)、蒸馏等技术的事。
❌ 误读 2:“BPE 分词器越大越好,词表越大模型越强”
纠偏:词表大小需要权衡。更大的词表意味着:
- ✅ 更好的压缩率(更短的序列)
- ❌ 更大的 Embedding 参数(词表 × hidden_dim)
- ❌ 训练时每个 token 被见到的次数更少(语料中低频 token 学不充分)
- ❌ 输出层 softmax 计算量增大(需遍历整个词表)
LLaMA 选择 32K、Qwen 选择 152K,各有取舍,没有绝对最优。对英文为主的场景,32K 够用;对多语言场景,更大词表通常更优。
❌ 误读 3:“Byte-level BPE 可以完美处理所有语言”
纠偏:虽然 Byte-level BPE 保证零 UNK(任何输入都能编码),但不同语言的压缩效率差异巨大。英文每 token 编码约 4 字符,中文可能每 token 只编码 1–3 字节(即 1–1.5 个汉字)。这意味着同样的 128K 上下文窗口,中文能放的有效内容显著少于英文。这是当前大模型的结构性不公平,o200k_base 等新词表正在改善但尚未完全解决。
❌ 误读 4:“GPT-4 和 GPT-2 用同一个分词器”
纠偏:GPT-2 使用约 50K 词表的 r50k_base / p50k_base;GPT-3.5/4 使用约 100K 词表的 cl100k_base;GPT-4o 使用约 200K 词表的 o200k_base。它们都是 byte-level BPE,但合并规则表完全不同,因此同一个句子在不同模型中会切成不同的 token 序列。这意味不同模型之间的 token 数对比不是线性的。
学习路径
入门(30 分钟)
- 动手实验:打开 tiktokenizer.vercel.app,输入中英文文本,观察不同模型的分词结果差异。
- 概念理解:阅读 HuggingFace NLP Course 的 Tokenizer 章节(免费在线)。
进阶(2–3 小时)
- 经典论文:Sennrich et al. (2016), “Neural Machine Translation of Rare Words with Subword Units”——BPE 引入 NLP 的奠基论文,6 页,可读性极强。
- GPT-2 论文:Radford et al. (2019), “Language Models are Unsupervised Multitask Learners”——Byte-level BPE 的引入。
- 实现阅读:阅读 HuggingFace
tokenizers库的 BPE trainer 源码(Rust,但逻辑清晰)。
深度(1 天)
- SentencePiece 论文:Kudo & Richardson (2018), “SentencePiece: A simple and language independent subword tokenizer and detokenizer for Neural Text Processing”。
- 对比实验:用同一语料分别训练 BPE、WordPiece、Unigram 分词器,对比压缩率和 token 分布。
- 中文分词分析:对比 GPT-4(cl100k_base)与 Qwen 在中文语料上的 token 效率,量化差距。
一句话总结
BPE 是大语言模型的”第一道翻译”——它决定了模型以什么粒度”阅读”人类语言,直接影响推理成本、上下文利用率和多语言公平性。
延伸阅读与来源
| 来源 | 内容 | 类型 |
|---|---|---|
| Gage, P. (1994). “A New Algorithm for Data Compression.” C Users Journal. | BPE 原始论文 | 学术论文 |
| Sennrich et al. (2016). Neural Machine Translation of Rare Words with Subword Units. ACL. | BPE 引入 NLP | 学术论文 |
| Radford et al. (2019). Language Models are Unsupervised Multitask Learners. OpenAI. | GPT-2 / Byte-level BPE | 技术报告 |
| Kudo, T. & Richardson, J. (2018). SentencePiece. EMNLP. | SentencePiece 框架 | 学术论文 |
| tiktoken GitHub | OpenAI 分词器实现 | 开源代码 |
| HuggingFace tokenizers | Rust 实现的分词器库 | 开源代码 |
| tiktokenizer.vercel.app | 可视化分词实验 | 在线工具 |
⚠️ 免责声明:本页中涉及的具体词表大小、压缩率数据等,凡标注 [估算] 或 [未充分披露] 的,均为基于公开信息的推测,非精确规格。各模型实际分词器参数请以其官方技术报告或开源代码为准。