token-BPE算法概述

现代大语言模型的分词基础

token-BPE算法概述

BPE算法概述

BPE(Byte Pair Encoding) 是一种数据压缩算法,后来被OpenAI等团队引入自然语言处理领域,用于构建子词(subword)词汇表。它是现代大语言模型(如GPT系列)分词器的核心基础。

核心思想

BPE的核心思想是:通过迭代合并频率最高的字符对,逐步构建出更长的子词单元

核心优势:在字符级(粒度太细,序列过长)和词级(无法处理未登录词)之间找到平衡,有效处理:

  • 罕见词/未登录词(OOV)
  • 形态变化丰富的语言
  • 拼写错误和变体

算法步骤详解

第一步:初始化

将训练语料中的每个单词拆分为字符序列,并在末尾添加特殊的词尾标记 </w>

原始语料:
"low" × 5次, "lower" × 2次, "newest" × 6次, "widest" × 3次

初始化后:
l o w </w> : 5
l o w e r </w> : 2
n e w e s t </w> : 6
w i d e s t </w> : 3

第二步:统计频率

统计所有相邻字符对的出现频率。

字符对频率:
(l, o): 7 (5+2)
(o, w): 7 (5+2)
(w, </w>): 5
(w, e): 2
(e, r): 2

第三步:合并最高频字符对

将频率最高的字符对合并为一个新符号,加入词汇表。

第1轮合并:(e, s) 出现 9 次 → 合并为 "es"
第2轮合并:(es, t) 出现 9 次 → 合并为 "est"
第3轮合并:(l, o) 出现 7 次 → 合并为 "lo"
第4轮合并:(lo, w) 出现 7 次 → 合并为 "low"

第四步:迭代直至满足停止条件

重复合并过程,直到:

  • 达到预定的词汇表大小(如32,000、50,000)
  • 或没有可合并的字符对

编码(分词)过程

训练完成后,对新文本进行分词时采用贪心最长匹配策略:

输入:"lowest"
尝试匹配词汇表中最长的子词:
1. 尝试 "lowest" → 不在词表
2. 尝试 "lowe" → 不在词表
3. 尝试 "low" → ✅ 在词表
4. 剩余 "est" → ✅ 在词表

最终分词结果:["low", "est"]

BPE的变体与演进

算法 特点 代表应用
原始BPE 贪心合并,基于频率 GPT-2, RoBERTa
WordPiece 基于似然增益而非频率 BERT, DistilBERT
Unigram 概率模型,从大到小剪枝 T5, AlBERT
SentencePiece 语言无关,直接处理原始文本 XLNet, Marian NMT

实际应用示例

以GPT-2的分词器为例:

import tiktoken

# GPT-2使用的BPE分词器
enc = tiktoken.get_encoding("gpt2")

text = "Tokenization is the process of breaking down text."
tokens = enc.encode(text)

print(f"文本: {text}")
print(f"Token数量: {len(tokens)}")
print(f"字符数量: {len(text)}")
print(f"压缩比: {len(text)/len(tokens):.2f}")

BPE的优缺点

✅ 优点 ❌ 缺点
有效处理未登录词 对多语言支持不够均衡(英语token更短)
词汇表大小可控 无法理解语义,纯统计方法
可复现、确定性强 对空格敏感,"hello"和" hello"是不同token
平衡词级和字符级粒度 处理数字、代码时可能产生碎片化token

总结

BPE算法通过迭代合并高频字符对,构建出高效的子词词汇表,解决了传统词级分词的OOV问题。它是现代大语言模型的基石技术之一,理解BPE有助于深入掌握Tokenizer的工作原理,以及为什么LLM在某些文本(如非英语、数字序列)上表现特殊。

← 返回 2. Pre-training