保姆级教程介绍分词算法BPE

文章目录

  • [1. 为什么需要 BPE?](#1. 为什么需要 BPE?)
    • [方法一:一个字母一个 Token](#方法一:一个字母一个 Token)
    • [方法二:一个单词一个 Token](#方法二:一个单词一个 Token)
  • [2. BPE 就是在两者之间折中](#2. BPE 就是在两者之间折中)
  • [3. 用一个超级简单的例子理解 BPE](#3. 用一个超级简单的例子理解 BPE)
  • [4. 第一次合并](#4. 第一次合并)
  • [5. 再统计一次](#5. 再统计一次)
  • [6. 一直重复](#6. 一直重复)
  • [7. 所以 BPE 的算法其实就这几行](#7. 所以 BPE 的算法其实就这几行)
  • [8. 为什么这样做最后会产生「词根」「后缀」?](#8. 为什么这样做最后会产生「词根」「后缀」?)
  • [9. 再看一个现实一点的例子](#9. 再看一个现实一点的例子)
  • [10. 遇到从没见过的新词怎么办?](#10. 遇到从没见过的新词怎么办?)
  • [11. 那为什么 GPT 经常说「Byte-level BPE」?](#11. 那为什么 GPT 经常说「Byte-level BPE」?)
    • [UTF-8 是什么关系?](#UTF-8 是什么关系?)
  • [12. 中文 BPE 是什么样?](#12. 中文 BPE 是什么样?)
  • [13. 这也解释了一个很有意思的现象](#13. 这也解释了一个很有意思的现象)
  • [14. 这就是为什么代码 Tokenizer 也很有意思](#14. 这就是为什么代码 Tokenizer 也很有意思)
  • [15. BPE 有两个阶段,千万别混](#15. BPE 有两个阶段,千万别混)
  • [16. 用一张脑图记住 BPE](#16. 用一张脑图记住 BPE)
  • [17. 为什么它叫 Byte **Pair** Encoding?](#17. 为什么它叫 Byte Pair Encoding?)
  • [18. 用一句话做学习检验](#18. 用一句话做学习检验)

可以。用费曼学习法讲 BPE,关键不是先背"Byte Pair Encoding",而是先把它理解成一句人话:

BPE 就是在大量文本里,发现哪些相邻的小片段经常一起出现,然后把它们粘成一个更大的 Token。反复粘,直到词表够大。

你可以把它理解成:给常见字符串建立快捷键。


1. 为什么需要 BPE?

假设大模型看到一句:

text 复制代码
I am playing football

模型不能直接处理字符串,它最终要处理的是一串数字,例如:

text 复制代码
[40, 716, 5732, 9012]

所以中间需要一个 Tokenizer(分词器)

text 复制代码
文本
 ↓
Tokenizer
 ↓
Token
 ↓
Token ID
 ↓
神经网络

问题来了:

到底应该怎么切?


方法一:一个字母一个 Token

比如:

text 复制代码
playing

切成:

text 复制代码
p l a y i n g

好处是词表非常小。

26 个字母基本就够用了。

但坏处非常明显:

text 复制代码
internationalization

可能变成二十多个 Token。

模型处理序列的长度直接爆炸。


方法二:一个单词一个 Token

把:

text 复制代码
playing

直接作为一个 Token。

这样非常爽:

text 复制代码
playing → 一个 Token

但是马上又出问题。

英语单词太多:

text 复制代码
play
plays
played
playing
player
players
playground
...

更别说:

text 复制代码
OpenAI
DeepSeek
ChatGPT
wg666
awefwef123

你不可能提前把世界上所有字符串都放进词表。


2. BPE 就是在两者之间折中

BPE 的思想是:

非常常见的字符串 → 合并成一个 Token。

不常见的字符串 → 继续拆成更小的 Token。

例如:

text 复制代码
playing

最终可能切成:

text 复制代码
play
ing

而不是:

text 复制代码
p l a y i n g

也不是一定要求:

text 复制代码
playing

整体成为一个 Token。

这就是 BPE 最核心的思想。


3. 用一个超级简单的例子理解 BPE

假设我们的整个训练语料只有:

text 复制代码
abab
abab
abac

一开始 BPE 什么都不懂。

所以全部拆成最小单位:

text 复制代码
a b a b
a b a b
a b a c

现在开始统计:

哪两个相邻字符一起出现次数最多?


第一次统计

看看:

text 复制代码
a b
b a
a b

abab 出现两次。

然后:

text 复制代码
a b
b a
a c

abac 出现一次。

所以统计结果大概是:

相邻组合 次数
a + b 5
b + a 3
a + c 1

发现:

text 复制代码
a + b

出现最多。

于是 BPE 做第一件事:

ab 合并成一个新 Token:ab


4. 第一次合并

原来:

text 复制代码
a b a b
a b a b
a b a c

现在就变成:

text 复制代码
ab ab
ab ab
ab a c

词表原来有:

text 复制代码
a
b
c

现在增加:

text 复制代码
ab

变成:

text 复制代码
a
b
c
ab

5. 再统计一次

现在整个语料是:

text 复制代码
ab ab
ab ab
ab a c

重新统计相邻 Token

你可能发现:

text 复制代码
ab + ab

出现得最多。

于是:

text 复制代码
ab + ab

合并成:

text 复制代码
abab

现在:

text 复制代码
abab
abab
ab a c

词表又多了:

text 复制代码
abab

6. 一直重复

BPE 就不停重复:

text 复制代码
统计最高频相邻 Token
        ↓
把它们合并
        ↓
加入词表
        ↓
重新统计
        ↓
继续合并

直到:

text 复制代码
词表大小达到设定值

比如我们希望得到 50,000 个 Token,那就不断合并,直到词表差不多达到目标规模。


7. 所以 BPE 的算法其实就这几行

伪代码基本就是:

python 复制代码
初始化:把文本拆成最小单位

while 词表大小 < 目标大小:

    统计所有相邻 token pair

    找到出现次数最多的 pair

    把这个 pair 合并成新 token

    记录这条合并规则

例如最终学习到了:

text 复制代码
a + b    → ab
ab + ab  → abab
i + n    → in
in + g   → ing
p + l    → pl
pl + ay  → play
...

这些东西就是 BPE merge rules


8. 为什么这样做最后会产生「词根」「后缀」?

这就是 BPE 很聪明的地方。

注意:

BPE 完全不懂英语语法

它不知道:

text 复制代码
ing

是进行时后缀。

但是训练语料里有:

text 复制代码
playing
running
walking
working
talking
looking
reading

ing 出现实在太频繁。

于是经过:

text 复制代码
i + n → in
in + g → ing

以后:

text 复制代码
ing

自然就变成一个 Token。

于是:

text 复制代码
playing

有可能变成:

text 复制代码
play + ing
text 复制代码
working

变成:

text 复制代码
work + ing
text 复制代码
walking

变成:

text 复制代码
walk + ing

没有任何语言学家告诉 BPE:"ing 是后缀"。

它纯粹通过:

高频共现

自己"发现"了这个结构。

这点非常重要。


9. 再看一个现实一点的例子

假设语料里面经常出现:

text 复制代码
happy
happier
happiness
unhappy

训练久了以后可能形成这些 Token:

text 复制代码
happy
happi
ness
un
er

于是:

text 复制代码
unhappy

可能:

text 复制代码
un + happy

而:

text 复制代码
happiness

可能:

text 复制代码
happi + ness

但是注意:

BPE 并不保证符合真正的词法学。

它不是:

text 复制代码
词根分析算法

而是:

text 复制代码
字符串统计压缩算法

只不过语言天然存在大量重复结构,所以它最后经常看起来像是在学习词根、前缀和后缀


10. 遇到从没见过的新词怎么办?

这正是 BPE 最大的价值之一。

比如训练的时候从来没有见过:

text 复制代码
superduperAI2026

如果是传统的"一个单词一个词表项",那就是:

text 复制代码
<UNK>

即 unknown。

很尴尬。

但 BPE 可以拆:

text 复制代码
super
duper
AI
202
6

实在不行继续拆:

text 复制代码
sup
er
du
per
A
I
2
0
2
6

因此理论上:

只要最底层单位覆盖全部输入,就可以表示任意字符串。


11. 那为什么 GPT 经常说「Byte-level BPE」?

这里再进一层。

最原始的 BPE 是 Byte Pair Encoding ,其实最早是个数据压缩算法,后来才被拿来做 NLP 分词。

现代 GPT 类模型常见的是:

Byte-level BPE

最底层甚至不是:

text 复制代码
中文字符
英文字母

而是:

text 复制代码
byte(字节)

UTF-8 是什么关系?

比如:

text 复制代码
A

UTF-8:

text 复制代码
41

只有一个 byte。

但中文:

text 复制代码

UTF-8 编码通常需要 3 个 byte

所以 byte-level tokenizer 最底层原则上可以把:

text 复制代码
任何 UTF-8 文本

都表示出来。

包括:

text 复制代码
中文
英文
Emoji
代码
奇怪符号

这解决了 OOV(Out Of Vocabulary,词表外字符)问题。


12. 中文 BPE 是什么样?

假设语料里面疯狂出现:

text 复制代码
人工智能
人工智能
人工智能
人工神经网络
人工智能模型

最开始可能是:

text 复制代码
人 工 智 能

发现:

text 复制代码
人 + 工

特别常见。

合成:

text 复制代码
人工

然后:

text 复制代码
智 + 能

特别常见:

text 复制代码
智能

然后:

text 复制代码
人工 + 智能

又非常常见。

可能进一步得到:

text 复制代码
人工智能

于是最终:

text 复制代码
我正在研究人工智能

可能被切成类似:

text 复制代码
我
正在
研究
人工智能

注意还是那句话:

不是人为规定"人工智能是一个词"。

而是因为这个字符串在训练数据里足够常见。


13. 这也解释了一个很有意思的现象

为什么有些词只占 1 Token

text 复制代码
the
function
import

而一些奇怪词可能占很多 Token:

text 复制代码
xqwejasd123

因为前者在训练数据中出现过无数次。

BPE 会觉得:

"天天见,直接给你办个 VIP,整个字符串一个编号。"

而后者:

"你谁啊?没怎么见过。拆开处理。"

所以可以粗略理解为:

出现得越频繁 → 越倾向形成大 Token。

越罕见 → 越容易被拆碎。


14. 这就是为什么代码 Tokenizer 也很有意思

例如训练数据里面大量存在 Java:

java 复制代码
public static void main

那么 tokenizer 很可能学会很多类似:

text 复制代码
public
static
void
main

甚至:

text 复制代码
public static

是否成为一个 Token,要看具体 tokenizer 和语料统计。

而一个极其罕见的变量名:

java 复制代码
wgHuangJiaSuperServiceImpl666

很可能被切成:

text 复制代码
wg
Huang
Jia
Super
Service
Impl
666

甚至切得更碎。

这也是为什么:

Token 数量 ≠ 字符数量 ≠ 单词数量。


15. BPE 有两个阶段,千万别混

这是理解 tokenizer 很关键的一点。

阶段一:训练 Tokenizer

拿大量训练文本:

text 复制代码
海量语料
 ↓
统计 pair
 ↓
不断 merge
 ↓
得到词表 + merge rules

最后保存:

text 复制代码
Vocabulary
Merge Rules

例如:

text 复制代码
i + n → in
in + g → ing
p + l → pl
...

这个阶段通常只做一次。


阶段二:真正给模型分词

以后用户输入:

text 复制代码
playing

不是重新统计全互联网。

而是拿已经训练好的:

text 复制代码
merge rules

执行。

例如初始:

text 复制代码
p l a y i n g

根据已经学好的合并优先级,逐步:

text 复制代码
p l → pl
pl a → pla
pla y → play
i n → in
in g → ing

最后:

text 复制代码
play | ing

然后查词表:

text 复制代码
play → 1382
ing  → 287

于是模型真正收到:

text 复制代码
[1382, 287]

16. 用一张脑图记住 BPE

以后你只需要在脑子里记这个:

text 复制代码
                  BPE
                   │
        ┌──────────┴─────────┐
        │                    │
     为什么?              怎么做?
        │                    │
  字符太碎               找最高频相邻 pair
  单词词表太大                 ↓
        │                  合并
        └────────┬───────────┘
                 ↓
             高频字符串
                 ↓
             一个 Token
                 ↓
          低频字符串继续拆

最终实现:

text 复制代码
字符级                    单词级
  │                         │
太碎                       词表爆炸
  │                         │
  └──────── BPE ────────────┘
              ↑
            折中

17. 为什么它叫 Byte Pair Encoding?

关键就在 Pair

BPE 每一步只看:

两个相邻单位

例如:

text 复制代码
i n g

不能第一步直接说:

text 复制代码
ing

是最高频三元组,然后一次合并。

而是:

text 复制代码
i + n → in

再:

text 复制代码
in + g → ing

所以"大 Token"是由小 Token 一层层长出来的

例如:

text 复制代码
t + i → ti
ti + on → tion
a + tion → ation
iz + ation → ization

最终甚至能形成很长的 Token。


18. 用一句话做学习检验

现在假设一个完全不懂 NLP 的朋友问你:

什么是 BPE?

如果你能回答:

BPE 就是先把文本拆得很细,然后统计哪些相邻片段最经常一起出现,把最高频的两个合成一个新 Token,再重复这个过程。这样常见字符串会变成一个 Token,罕见字符串仍然可以拆成多个小 Token,既不会让序列太长,也不用维护包含所有单词的巨大词表。

那么 BPE 的核心你已经掌握了。


最后给你一个面试级定义

如果面试官问:

"介绍一下 BPE 分词算法。"

可以回答成:

BPE 是一种基于频率的子词分词算法。它首先将语料拆分成字符或字节等基本单元,然后统计所有相邻 Token Pair 的出现频率,每轮选择最高频 Pair 合并成新的 Token,并将该合并操作加入 merge rules,重复直到达到预设词表大小。推理时按照训练阶段学习到的 merge rules 对输入文本进行合并,从而将文本编码为 Token 序列。它在字符级和词级分词之间取得折中,高频字符串可以使用较少 Token 表示,同时低频词和未登录词仍然可以由更小的子词或字节组合表示。

如果你后面准备学大模型,这里下一步最值得一起搞懂的是 BPE、WordPiece、Unigram/SentencePiece 到底有什么区别。这三个搞明白以后,LLM 的 tokenizer 基本就打通了。

相关推荐
工业设备方案笔记1 小时前
RK3588工业视觉检测方案详解:AI如何赋能智能制造?
arm开发·人工智能·计算机视觉·目标跟踪·视觉检测·边缘计算·制造
FlyWIHTSKY1 小时前
在智能体系统中,什么是多模态,举例详细说明
人工智能·python·langchain
fivebliss1 小时前
AI模型最新方向梳理
人工智能
阿图灵1 小时前
Agentic AI 架构入门(十二·完结):ADLC、AgentOps 与企业级平台蓝图
人工智能·架构·ai agent·智能体·agentops·agentic ai·adlc
达达尼昂1 小时前
Flutter AI Harness 如何让 Agent 参与软件开发全流程
android·人工智能·后端
Tongzhi20261 小时前
通芝科技无感考勤一体机:软硬一体,开箱即用
数据结构·数据库·科技·算法·均值算法·数据库开发
人工智能研究所1 小时前
GitHub 10k+ Star:用自然语言描述系统,AI 帮你生成可交互架构图
人工智能·github·交互·自然语言·系统架构图·archify
王六米。1 小时前
武汉自动意志科技有限公司:人工智能应用软件开发:OpenClaw 企业部署怎样配置权限、日志和回滚
人工智能·科技·企业ai落地·ai智能体开发·openclaw部署·武汉自动意志科技·智钳claw
yangmu32031 小时前
脑机接口:当意识越过肉身的边界
人工智能·科技