2. Tokenization
介绍 Transformer 输入表示的分词方法(Tokenization)及子词编码算法(BPE、WordPiece、Unigram)
什么是 Tokenization
Transformer 模型接收的输入是向量序列,而原始的自然语言文本是离散的词/子词/字符
因此,需要完成两个核心步骤,来将文本转换为模型可处理的输入表示:
分词 / 编码(Tokenization)
向量化表示(Token Embedding) + 位置信息(Positional Encoding)
Transformer 模型不直接处理单词的字符串,而是先将文本转换为token 序列:
方法原理优缺点Word-level
每个单词一个 token
简单,但词表太大(长尾问题),难处理未登录词(OOV)
Character-level
每个字符一个 token
词表小,能处理任意词,但序列太长,训练慢,且表示能力有限
Subword-level(推荐)
Byte Pair Encoding (BPE) / WordPiece / SentencePiece
平衡词表大小和 OOV,常用词保持原状,生僻词拆分为子词以共享 token 并压缩空间
例如,对于句子:
transformers are amazingWord-level: [
transformers,are,amazing]Character-level: [
t,r,a,n,s,f,o, ...]Subword-level (BPE): [
transform,##ers,are,amaz,##ing]
BPE
BPE(Byte Pair Encoding)是一种基于数据压缩的分词方法,其核心思想是不断合并出现频率最高的子词对,直到词表达到预定大小为止
具体流程如下:
字符拆分:将每个单词拆分为字符序列,例如
"hello"→["h","e","l","l","o"]统计频率:统计相邻字符或字符组合的出现频率,选择频率最高的序列进行合并
迭代合并:重复第二步,直到达到预定词表大小或无法再合并
每次合并后,词表可能有三种变化:
+1:加入新子词,原两个子词均保留(非连续出现)+0:加入新子词,原子词中一个保留,一个被消解(连续出现)-1:加入新子词,原两个子词同时被消解(连续出现)
示例,对于初始单词列表:
拆分为字符序列:
统计相邻字符序列频率,并合并最高频的
"es":重复迭代,直到达到词表大小或无法再合并
在使用已有的子词词表对新单词进行编码时,从最长 token 开始匹配:
Python 实现示例:
WordPiece
WordPiece 是一种子词(subword)级分词算法,其目标为:
在保持词表规模适中的前提下,提高语言模型对序列的概率
通过合并 “概率关联强” 的子词,使模型在训练时更容易预测序列
WordPiece 的核心思想是最大化序列的似然概率,假设序列 $S$ 被切分为 $[t_1, t_2, \dots, t_n]$,则序列概率为:
logP(S)=i=1∑nlogP(ti)在构建词表时,WordPiece 每次选择合并两个子词 $A$ 和 $B$,使合并后的子词 $AB$ 最大化语言模型的序列概率,即最大化互信息:
score(A,B)=P(A)P(B)P(AB)直观理解:如果
e和d在语料中经常连续出现(如ed表示过去时后缀),合并它们可以增加整个语料的序列概率,从而更符合语言模型的统计规律。与 BPE 算法相比,不同之处在于:
特性BPEWordPiece合并策略
合并频率最高的相邻子词
合并最大化序列概率 / 互信息的相邻子词
目标
压缩词表,减少 token 数
提高语言模型序列概率,更符合语料统计
示例
词表已有
appl+e,则apple优先拆成appl + e根据概率,可能拆成
app + le,更符合训练语料分布可以理解为,BPE 更机械、纯粹按频率,而 WordPiece 更 “聪明”,考虑语言模型预测的概率,也更适合训练语言模型,因为它直接优化了模型的目标函数(序列似然)
Unigram
基本思想
与 BPE 或 WordPiece 的“自底向上合并子词”不同,Unigram使用的是自顶向下的剪枝式(pruning)子词学习
它从一个规模较大的初始候选词表 $V_0$ 出发,再逐步移除贡献最小的子词,直到达到目标词表大小
初始词表通常由预分词器切分结果以及语料中的高频子串构成,每个子词都带有一个重要性评分,用于衡量它对覆盖语料的重要程度
每轮迭代删除评分最低的约 10%~20% ,同时确保语料中的单词仍能由剩余子词组合而成
Unigram 的优化目标是最大化训练语料的似然概率
设训练语料为词序列 $(x_1, x_2, \dots, x_N)$,每个词 $x_i$ 的所有可能 tokenization 方案集合为 $S(x_i)$,每种方案概率 $p(x)$
其损失为:
Loss=−i=1∑Nlogx∈S(xi)∑p(x)含义如下:
对每个词 $x_i$,考虑其所有可行 tokenization 方式的概率总和
Loss 越小,说明当前子词集合更能稳定、有效地覆盖语料
删除某个子词会减少部分词的 tokenization 选项,使得括号内求和变小,从而增大 Loss
因此每次优先删除对 Loss 增加最小的子词,即 “最小影响剪枝”
例如,对于语料:
apple, app, ple, banana, ban, ana):初始词表:
apple, app, ple, banana, ban, ana, a, p, l, e, b, n(极大)概率估计:
apple出现频繁,p单字符几乎不单独使用 ⇒p重要性低删除低影响子词:首先移除
p、l等低频或替代性强的碎片反复迭代:继续删除对子词覆盖影响最小的项
最终词表:保留高频、易组合、能覆盖大部分词的子词集合
SentencePiece
基本思想
SentencePiece不是具体的分词算法,而是一个通用 Tokenizer 框架,内部可使用多种算法,包括 BPE、Unigram、word-level、character-level 或混合策略
它的主要设计目标是提供一个无需预分词、无需依赖空格的统一 Tokenizer 管线
传统 tokenizer(如 WordPiece)通常依赖空格与标点进行切词,存在以下限制:
不适用于没有显式分隔符的语言(中文、日文、泰文)
空格本身无法作为 token,被直接丢失
遇到未登录词(OOV)时表现不稳定
而 SentencePiece 将输入文本视为纯字节序列(raw text),空格也作为普通字符处理。为了保留词边界信息,引入特殊符号
▁(U+2581),表示 “词前空格”。例如:Helloworld在内部会被表示为:
▁Hello▁world这种设计让 tokenizer 能直接在原始语料上训练,无需任何人工断词或预清洗步骤:
输入:未分词、未清洗的原始文本
输出:训练好的 tokenizer 模型(
model.model)与词表(model.vocab)
SentencePiece 提供完整的 tokenizer 工具链,包括:
SPM Trainer(训练器)
编码 / 解码接口
词表与概率管理
Subword Regularization(子词采样与模糊分词)
数据增强式随机分词策略
与仅提供算法的 BPE / WordPiece 不同,SentencePiece 是一个可直接部署和复用的工具框架,训练后通常生成两个文件:
文件说明model.model二进制模型,包含算法类型、参数与概率分布
model.vocab词表,每行包含一个 token 及其 log-prob
模型内部存储结构包括:
前缀树(trie)加速匹配
分词算法实现(BPE / Unigram)
子词概率(Unigram 模式)
token 排序与 fallback 规则
模型加载一次即可复用,适合推理与批量处理场景
Token Embedding
对原始文本进行分词后,得到 token 序列:
经过 Token Embedding,每个 token 被映射为一个向量,维度为
d_model(如 512 或 768)本质上就是 Word2Vec / GloVe 中的embedding lookup table
E∈RV×dmodel$V$ = 词表大小
$d_{model}$ = 词向量维度
代码实现
在实际应用中,通常使用 Hugging Face 的
transformers库中的AutoTokenizer来快速调用不同模型的 Tokenizer它默认封装了多种分词算法的底层实现,并提供了统一的 API 来处理 Padding、Truncation 以及特殊 Token
常见的特殊 Token:
Token说明示例(对应模型)示例值[CLS]序列开始标记
BERT
101[SEP]序列分隔符 / 结束标记
BERT
102[PAD]填充标记,当序列长度小于上下文最大长度时使用
BERT
0[UNK]未登录词标记
BERT
100[MASK]掩码标记,用于掩盖部分输入词以进行预测
BERT
103<end_of_text>文本结束标记
GPT 系列
50256`<
fim_prefix
>`
文本开始标记
`<
fim_middle
>`
文本中间标记
`<
fim_suffix
>`
文本结束标记
`<
fim_pad
>`
填充标记
##子词前缀,表示该子词非词首
BERT
##ization如何处理空格:
不同 tokenizer 对空格的处理方式不同
BERT 的 WordPiece tokenizer 会将空格视为分隔符,不作为 token
SentencePiece 则使用特殊符号
▁来表示词前空格在使用 tokenizer 时,需注意输入文本的格式,确保空格被正确处理
如何处理未登录词(OOV):
Subword-level tokenizer(如 BPE、WordPiece、Unigram)通过将未登录词拆分为已知子词来缓解 OOV 问题
例如,
tokenization可能被拆分为token+##ization
更多关于
tokenizers库的详细方法对比(如encode_plus,batch_encode_plus)与参数说明,可参考:3. tokenizers 库相关参数.md
Last updated
Was this helpful?