- AI 技能
- 人工智能
- 大模型
- 深度学习
【免费下载链接】AI-Research-SKILLs
Comprehensive open-source library of AI research and engineering skills for any AI model. Package the skills and your claude code/codex/gemini agent will be an AI research agent with full horsepower. Maintained by Orchestra Research.
本篇技术指南以 AI-Research-SKILLs 仓库中 SentencePiece 算法参考文档 为主体,系统讲解 SentencePiece 内置的 BPE(Byte-Pair Encoding)与 Unigram 两种无监督分词算法的完整原理、逐步推演示例、Python 实现方式与适用场景,并深入剖析子词正则化(Subword Regularization)与 NBest 编码两种高级采样能力。读完本文,你将掌握两种算法的取舍依据、alpha 采样参数的含义与取值策略,以及如何在多语言模型、CJK 文本与数据增强场景中正确选用 SentencePiece 的分词策略。
SentencePiece 与分词算法在仓库中的定位
在 AI-Research-SKILLs 的 02-tokenization 分类下,SentencePiece 是与 HuggingFace Tokenizers 并列的两大分词技能之一。与后者不同,SentencePiece 是**语言无关(language-independent)**的无监督分词器:它把文本当作原始 Unicode 字节流处理,无需任何语言特定的预分词规则(如空格切分、标点处理),因此特别适合多语言模型与 CJK(中文、日文、韩文)等无天然词边界的语言。其设计要点如下(出自 SKILL.md):
- 空白作为元符号:空格被映射为
▁(U+2581)元符号参与训练,分词结果可无损还原原始文本; - 无需预分词:可直接在原始文本上训练,训练管线内置句子切分;
- 确定性词汇表:同一语料、同一配置下训练结果可复现;
- 轻量部署:模型加载后内存占用约 6MB,处理速度约 5 万句/秒;
- 知名使用者:T5、ALBERT、XLNet(Unigram),mBART(BPE),以及 mT5、XLM-RoBERTa(子词正则化)。
SentencePiece 支持四种模型类型(model_type):unigram(默认)、bpe、char、word。其中 BPE 与 Unigram 是本文的核心主题,二者代表了"自底向上合并"与"自顶向下剪枝"两种截然不同的子词学习哲学。
BPE(Byte-Pair Encoding)算法
BPE 最初是数据压缩领域的算法(1994 年由 Philip Gage 提出),被 Sennrich 等人引入神经机器翻译后成为 GPT、RoBERTa、mBART 等模型的标准分词方案。其核心思想是:从字符集出发,反复合并语料中出现频率最高的相邻 token 对,直到词汇表达到目标大小。
算法步骤
- 用语料中出现的所有字符初始化词汇表;
- 统计所有相邻 token 对的共现频率;
- 合并频率最高的一对,形成新 token 并加入词汇表;
- 用新 token 更新语料表示;
- 重复步骤 2-4,直到词汇表大小达到设定值(
vocab_size)。
逐步推演示例
沿用 algorithms.md 中的示例语料(括号内为该词在语料中的出现次数):
low: 5 lower: 2 newest: 6 widest: 3第 1 次迭代:
- 统计相邻对频率,
'e' + 's'出现 9 次(newest 贡献 6 次、widest 贡献 3 次),为最高频组合; - 合并
'e' + 's'→'es'; - 词汇表变为:
[chars] + ['es']。
第 2 次迭代:
- 统计相邻对频率,
'es' + 't'出现 9 次,为最高频组合; - 合并
'es' + 't'→'est'; - 词汇表变为:
[chars] + ['es', 'est']。
最终分词结果:newest→new|est,widest→wid|est。
可以看到,BPE 的合并完全由原始共现频率驱动:哪个组合在语料中出现得最多,就优先被合并,最终把高频词缀(如est)固化成语料中的稳定子词单元。
实现方式
使用 SentencePiece Python API 训练 BPE 模型只需一个函数调用:
import sentencepiece as spm spm.SentencePieceTrainer.train( input='corpus.txt', model_type='bpe', vocab_size=16000 )对应的命令行形式为spm_train --input=corpus.txt --model_prefix=m --vocab_size=16000 --model_type=bpe。训练完成后会生成m.model(二进制模型)与m.vocab(文本词汇表)两个文件,详见 training.md。
优点与缺点
| 维度 | 评价 |
|---|---|
| 优点 | 算法简单、训练速度快、压缩比好(以较少 token 覆盖文本) |
| 缺点 | 分词结果是确定性的(无法采样);可能对常见词产生意外的切分 |
从实现层面看,BPE 的"快"来自其贪心合并策略:每一轮只需统计相邻对频率,计算开销低;其"确定性"则意味着同一段文本永远得到同一种切分,无法像 Unigram 那样通过采样生成多样化分词。
Unigram 算法
Unigram 语言模型分词法由 Kudo(2018)提出,是 SentencePiece 的默认算法,也是 T5、ALBERT、XLNet 的选择。它与 BPE 方向相反:从一个覆盖所有子串的超大种子词汇表出发,通过期望最大化(EM)估计每个 token 的概率,然后迭代删除对整体似然损失影响最小的 token,直到词汇表收缩到目标大小。
算法步骤
- 用一个足够大的种子词汇表初始化(包含所有可能的子串);
- 基于频率估计每个 token 的出现概率;
- 逐一评估删除每个 token 会带来的损失增量;
- 删除损失影响最小的 10%-20% 的 token;
- 重新估计概率;
- 重复步骤 3-5,直到词汇表达到目标大小。
这一"先超集、后剪枝"的路径,使 Unigram 的词汇表天然保留了语言学上更有区分度的子词(如词缀、词干),并携带每个 token 的概率信息,这是它支持采样与子词正则化的根本原因。
概率化分词:选择似然最大的切分
Unigram 的核心假设是每个 token 独立出现,因此一段文本的整体概率 = 各 token 概率的乘积。给定如下词汇表概率分布(节选):
P('low') = 0.02 P('est') = 0.03 P('l') = 0.01 P('o') = 0.015 ...对"lowest"进行分词时存在多种候选切分:
方案 1: ['low', 'est'] P = 0.02 × 0.03 = 0.0006 ← 概率最高 方案 2: ['l', 'o', 'w', 'est'] P = 0.01 × 0.015 × 0.01 × 0.03 = 0.000000045最终选择整体概率最高的方案 1。需要指出的是,朴素枚举所有切分方式的复杂度是 O(2ⁿ)(指数级),SentencePiece 实际使用Viterbi 动态规划在 O(n² × vocab_size) 内高效求解最优路径——这一细节可对照 HuggingFace Tokenizers 的 Unigram 文档 中给出的 Viterbi 伪代码加深理解。
实现方式
spm.SentencePieceTrainer.train( input='corpus.txt', model_type='unigram', vocab_size=8000 )优点与缺点
| 维度 | 评价 |
|---|---|
| 优点 | 概率化模型(可采样);对形态丰富的语言(含黏着语、屈折语)效果更好;原生支持子词正则化 |
| 缺点 | 训练更慢(EM 迭代)、算法更复杂 |
Unigram 的"慢"是相对 BPE 而言的:EM 估计与多轮剪枝都需要多次扫描语料。作为参考,仓库 SKILL.md 给出的经验训练耗时为 100MB 语料下 BPE 约 1-2 分钟、Unigram 约 3-4 分钟;1GB 语料下 BPE 约 10-15 分钟、Unigram 约 30-40 分钟。
BPE 与 Unigram 对比
原文档给出的对比表是算法选型的核心依据,完整继承如下:
| 特征 | BPE | Unigram |
|---|---|---|
| 训练速度 | 快 | 慢 |
| 分词方式 | 确定性 | 概率化 |
| 采样 | 不支持 | 支持 |
| 典型词表大小 | 16k-32k | 8k-32k |
| 代表使用者 | mBART | T5、ALBERT、XLNet |
结合两种算法的机制可以进一步解读这张表:
- 确定性 vs 概率化:BPE 的合并序列一旦学成即固定,分词结果唯一;Unigram 基于概率分布,天然存在多个合法切分,可通过采样获取多样性;
- 词表大小的灵活性:Unigram 在更小词表(8k)下仍能保持良好覆盖——HuggingFace 侧的对比测试显示 Unigram(8k 词表)在英文上的 unknown rate 可低至 0.3%,优于同场景下的 BPE 与 WordPiece;
- 选型直觉:追求训练速度、单语/英文场景选 BPE;多语言、CJK、需要数据增强选 Unigram。
若将视野扩展到仓库 02-tokenization 目录下的另一技能,WordPiece(BERT 系)采用score = freq(pair) / (freq(first) × freq(second))的互信息式评分,与 BPE 的纯频率合并形成对比,三者共同构成了主流子词分词算法谱系,详见 HuggingFace Tokenizers 算法文档。
子词正则化(Subword Regularization)
子词正则化是 Unigram 概率模型带来的独特能力:训练模型时不再固定使用最优切分,而是按概率分布采样多种合法分词结果,让模型学会在不同切分下保持语义鲁棒。
开启采样
sp = spm.SentencePieceProcessor(model_file='m.model') # 采样不同的分词结果 for _ in range(5): pieces = sp.encode('tokenization', out_type=str, enable_sampling=True, alpha=0.1) print(pieces) # 输出(每次运行结果不同): # ['▁token', 'ization'] # ['▁tok', 'en', 'ization'] # ['▁token', 'iz', 'ation'] # ['▁to', 'ken', 'ization'] # ['▁token', 'ization']可见同一文本在采样模式下会得到▁token|ization、▁tok|en|ization、▁token|iz|ation等不同切分,其中▁表示空格元符号。注意采样通常要求模型为 Unigram 类型——BPE 的确定性合并序列本身不携带可采样的概率分布。
alpha 参数详解
alpha是控制正则化强度的核心参数(原文档给出如下取值指导):
| alpha | 效果 |
|---|---|
| 0.0 | 完全确定性(不采样,等同最优分词) |
| 0.1 | 轻微变化(默认推荐值) |
| 0.5 | 高度变化 |
| 1.0 | 最大变化(接近均匀随机采样) |
alpha可理解为对 token 概率分布的"平滑温度":alpha 越大,低概率切分被采到的机会越大,分词多样性越高;alpha=0 时退化为确定性最优分词。实操中建议训练阶段使用 alpha=0.1 左右引入轻度噪声,推理阶段设为 0(确定性模式)保证结果一致。
收益
- 鲁棒性:模型在训练中见到多种合法切分,推理时对任意单一切分的依赖降低;
- 数据增强:同一句文本每轮训练可产生不同 token 序列,等效扩充训练数据多样性;
- 更好的泛化:降低模型对特定分词模式的过拟合,对形态丰富语言尤其有效。
训练循环中的应用
# 带正则化的训练循环 for batch in dataloader: # 每轮采样不同的分词结果 tokens = sp.encode(batch['text'], enable_sampling=True, alpha=0.1) # 训练模型...这一模式正是 mT5、XLM-RoBERTa 等大规模多语言预训练模型的标准做法:通过子词正则化提升跨语言与低资源语言的鲁棒性。
NBest 编码:获取带分数的多候选切分
除随机采样外,Unigram 还提供nbest_encode接口,一次性返回 Top-N 个候选分词及其对数概率分数,用于需要显式评估多种切分的场景:
sp = spm.SentencePieceProcessor(model_file='m.model') # 获取 top-5 分词候选 nbest = sp.nbest_encode('tokenization', nbest_size=5, out_type=str) for pieces, score in nbest: print(f"{pieces} (log prob: {score:.4f})") # 输出: # ['▁token', 'ization'] (log prob: -2.34) # ['▁tok', 'en', 'ization'] (log prob: -2.41) # ['▁token', 'iz', 'ation'] (log prob: -2.57)分数为对数概率(负值,越大越优),与子词正则化的采样机制共享同一套概率模型。典型应用场景:
- 集成分词(Ensemble tokenization):对多个候选分词的表示取平均,提升下游模型稳定性;
- 不确定性估计:观察候选分数方差,衡量分词层面的不确定性;
- 调试分析:直观了解分词器对某词的行为偏好,辅助诊断分词质量问题。
与训练配置协同的最佳实践
原文档的 Best Practices 可与 training.md 中的训练参数相互印证,形成一套完整的工程选型清单:
- 多语言选 Unigram——对多种语言与无词边界语言(CJK)更友好;
- 追求速度选 BPE——训练与推理都更快,适合英文单语模型;
- 开启子词正则化——训练时
enable_sampling=True提升模型鲁棒性; - alpha=0.1 作为轻度变化默认值——多样性/稳定性平衡点;
- 推理用确定性模式——
enable_sampling=False(或 alpha=0)保证结果可复现。
此外,训练阶段还需配套设置以下关键参数(详见 training.md):
- character_coverage 字符覆盖率:英文等语言用 0.9995,CJK 需设为 1.0 以确保覆盖全部汉字;
- vocab_size 词表大小:英文单语 16k-32k,多语言 32k-250k,CJK 32k-100k;
- user_defined_symbols / control_symbols:为特殊 token(如
[SEP]、[MASK]、<extra_id_N>)预留永不拆分的位置; - byte_fallback:开启后未知字符回退到字节级表示,增强对 emoji、罕见字符的鲁棒性;
- normalization_rule_name:默认
nmt_nfkc(NFKC 规范化 + 空白处理),代码等大小写敏感任务可用identity保留原始输入。
小结
SentencePiece 的 BPE 与 Unigram 代表了子词分词的两种经典范式:BPE 以频率驱动的贪心合并换取速度与简洁,Unigram 以概率模型换取采样能力与多语言鲁棒性。二者加上子词正则化与 NBest 编码,构成了从"确定性最优分词"到"多样性采样增强"的完整工具箱。工程选型时可遵循"多语言/鲁棒性优先用 Unigram + 子词正则化,速度/单语优先用 BPE"的原则,并结合字符覆盖率、词表大小等训练参数协同调优。本文所依托的完整参考材料位于仓库 02-tokenization/sentencepiece 目录,其中 SKILL.md 提供技能总览,training.md 提供全量训练参数说明,algorithms.md 即本文的主体来源;如需横向对比 WordPiece 等第三类算法,可参阅 HuggingFace Tokenizers 算法文档。
- AI 技能
- 人工智能
- 大模型
- 深度学习
【免费下载链接】AI-Research-SKILLs
Comprehensive open-source library of AI research and engineering skills for any AI model. Package the skills and your claude code/codex/gemini agent will be an AI research agent with full horsepower. Maintained by Orchestra Research.
相关推荐
Transformers 分词算法深入解析:BPE、WordPiece、Unigram 与 SentencePiece 原理与实战
Transformers 分词算法深入解析:BPE、WordPiece、Unigram 与 SentencePiece 原理与实战 本文依据仓库中的 分词器概述
人工智能深度学习机器学习预训练微调NLP计算机视觉语音多模态Transformers 分词算法详解:BPE、WordPiece、Unigram 与 SentencePiece 的原理与源码实现
Transformers 分词算法详解:BPE、WordPiece、Unigram 与 SentencePiece 的原理与源码实现 本文以 HuggingFa
人工智能深度学习机器学习预训练微调NLP计算机视觉语音多模态SentencePiece 子词分词完全指南:语言无关的 BPE / Unigram 分词器实战
SentencePiece 子词分词完全指南:语言无关的 BPE / Unigram 分词器实战 SentencePiece 是 Google 开源的 语言无关
AI 技能人工智能大模型深度学习
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考