想象你是一个中央厨房的总厨,面前堆着从不同产地运来的整颗蔬菜、整块肉,还有各种方言口音的“边角料”。传统做法是先让工人按标准菜谱把食材切成“词”——白菜叶、白菜梗、猪肉、牛肉——切好后再入锅。可问题来了:如果食材从未见过(比如一种叫“yyds“的野生菌),工人就不知道该把它归到哪一格,只能整个扔掉,或者硬塞进”未知垃圾箱“。SentencePiece 就像一个”无监督切菜机器人“:它不需要任何人工预分词,直接观察大量原始食材的纹理和共现规律,自己学会一套把食材切成”合适大小的块“的刀法。它切的块可能不是传统意义上的”词“,而是更灵活的”子词块“,比如把”机器学习“切成”机器”+“学习”,把“yyds“切成”y”+"yds"。这些小块的组合,恰好能让下游的翻译、搜索、对话系统都吃得舒服。 这篇文章就带你看懂这个“切菜机器人”怎么安装、怎么设定参数(冷藏格多少、宽容度多高),以及它和 BPE、WordPiece 这两套“其他厨房流派”的刀法有什么区别,帮你在 NLP 项目里选到最顺手的那把刀。

岗位关联

掌握 SentencePiece,你就不再被“没有分词器”卡住:多语言、低资源、网络新词场景下都能快速构建高质量预处理流水线,这是 NLP 从业者必备的“做饭基本功”。

目录
  1. 可视化演示
  2. 认识SentencePiece
  3. 安装与快速上手
  4. 核心参数调优
  5. 子词算法原理
  6. 多语言实战
  7. 对比与选型
  8. AI 应用场景
  9. Python 演示
  10. 常见误区
  11. 面试题

可视化演示

动态演示SentencePiece无的核心机制,通过基础/核心/应用/扩展四种模式展示关键概念与交互流程。

本节配有交互动效(进入视口后自动加载,约 3KB)。

SentencePiece无:Sent SentencePiece核心 分词器的训练流程与机制 核心机制可视化 SentencePiece无整体架构与关键组件

认识SentencePiece

中央厨房里最让总厨头疼的,不是炒菜,而是“备菜”。不同菜系对食材的定义完全不一样:中文习惯把“白菜”看作一个词,日文却经常把“白”和“菜”分开处理。如果让每个菜系都提前送一份“切菜清单”(预分词),那新来的食材、方言食材就永远进不了厨房。SentencePiece 这位“无监督切菜机器人”的做法是:我不管你们人类怎么定义词,我只观察食材在真实菜谱里一起出现的规律,自己决定哪里该下刀。它训练时只需要一个要求——给我大量原始文本,不要给我切好的词。

科学家把这种“不依赖人工分词规则,直接从字符序列学习出子词单元”的方法,叫作无监督分词。SentencePiece 是其中最著名的一个实现,它同时支持多种“刀法”(算法),但核心思想一致:把所有可能的切分方式看成一个概率空间,选最合理的那组子词。它尤其擅长处理没有标准分词器的语言,比如越南语、缅甸语,或者中英混合的社交网络文本。

在动手用它之前,先记住它的最大卖点:一步到位。输入原始文本,输出训练好的子词模型,中间不需要任何语言专家帮你先分词。这就像厨房里多了一个能自己研发刀法的机器人,而不是只会照着菜谱切菜的学徒。

$\displaystyle \text{raw text} = c_1 c_2 c_3 \dots c_n$

$\displaystyle \mathcal{V} = \{t_1, t_2, \dots, t_m\}$

$\displaystyle \text{text} \rightarrow \mathcal{V}$

一句话总结:机器人不是按菜谱切菜,而是自己发明了一套菜谱。这套菜谱的好处是,任何新食材都能找到接近的切法,而不是直接被扔进垃圾桶。

SentencePiece:raw text→V={t1,t2,…,tm}\displaystyle \text{SentencePiece}: \text{raw text} \rightarrow \mathcal{V} = \{t_1, t_2, \dots, t_m\}
这个式子表示:把原始文本作为输入,SentencePiece 直接学出一张子词表 $\mathcal{V}$,表中的每个 $t_i$ 就是一个可以反复使用的“食材块”。
  1. 输入原始文本不需要任何人工预分词,把整段字符流直接喂给模型。
  2. 输出词表模型学到的子词集合,每个子词相当于一个标准食材块。
  3. 整体映射从字符流到词表的映射,正是无监督分词要做的事。

安装与快速上手

想把这个切菜机器人请进厨房,第一步很简单。打开终端,敲下 pip install sentencepiece,机器人就进厨房了。接着你需要准备一份“训练菜谱”——大量纯文本语料。注意,这份菜谱不需要任何标注,不需要分词,甚至不需要清洗得像实验室那么干净。机器人会自己从里面总结规律。

训练代码通常只有几行。核心是调用 SentencePieceTrainer.train(),传入语料文件路径、模型前缀和词表大小。训练完成后,你会得到两个文件:.model 文件是机器人的“刀法模型”,.vocab 文件是食材块的清单。之后用 SentencePieceProcessor 加载模型,就能对任意新文本做切分、还原。

举个具体例子:训练时给机器人看“我爱机器学习”这句话,它可能学到“我”“爱”“机器”“学习”这些子词。下次遇到“机器学习很有趣”,它就能自动切成熟悉的子词组合,而不是一脸茫然地把整句扔进未知垃圾箱。编码(encode)是把句子变成子词 ID 序列,解码(decode)是倒回来拼接成文本,整个过程像把食材切块再装盘一样自然。

$\displaystyle \text{encode}(x) = [\text{id}(t_a), \text{id}(t_b), \dots]$

$\displaystyle \text{decode}([\text{id}(t_a), \text{id}(t_b)]) = t_a t_b$

$\displaystyle \text{decode}(\text{encode}(x)) \approx x$

上手之后你会觉得,这比传统分词器友好太多——没有复杂的规则文件,没有“未登录词”的惊慌失措,一切都由数据说了算。

encode(x)=[ id(ta),id(tb),… ],decode([ id(ta),id(tb) ])=tatb\displaystyle \text{encode}(x) = [\, \text{id}(t_{a}), \text{id}(t_{b}), \dots \,], \quad \text{decode}([\, \text{id}(t_{a}), \text{id}(t_{b})\,]) = t_a t_b
编码和解码是一对互逆操作:编码把句子变成子词 ID 列表,解码把 ID 列表还原成句子。这两个操作是之后所有 NLP 任务的入口。
  1. 编码操作把输入句子 $x$ 切分成子词,再查词表得到每个子词的 ID。
  2. 解码操作把子词 ID 列表映射回对应的子词并拼接。
  3. 互逆关系模型训练出的词表是两者共享的“食材仓库”。

核心参数调优

机器人虽然聪明,但总厨得给它设定两件大事:冰箱冷藏格的数量(词表大小 $vocab\_size$)和对边角料的容忍度(字符覆盖率 $character\_coverage$)。冷藏格太少,食材块就得切得很碎,每个格子只能装点“字母”级别的碎末;冷藏格太多,格子倒是多了,但很多格子一年都用不上一次,白白占地方。实际经验是:中英文混合任务常用 8000 到 32000 之间的词表大小,低资源语言可以更小,比如 4000 到 8000。

字符覆盖率这个参数更有意思。如果你把覆盖率设成 1.0,意味着冰箱必须装下训练语料里出现过的每一个字符,包括各种生僻 emoji 和乱码符号。这就像要求厨房把所有奇怪食材都备一份,成本极高且没有必要。通常设为 0.9995 左右,那 0.0005 的稀有字符会被统一映射到一个特殊的 <unk>(未知)标记,相当于把实在用不上的怪食材放到“杂物间”。

除此之外,还要学会设置特殊标记:<pad>(占位符)、<unk>(未知)、<s> 和 </s>(句子开头与结尾)。这些标记像厨房里的“托盘、垃圾袋、开餐铃”,虽然不直接是菜,但整个流程离不开它们。训练语料方面,建议用领域相关的数据,并且尽量让语料有足够的多样性,否则机器人学到的刀法会偏科。

$\displaystyle \text{covered\_chars} = \sum_{t \in \mathcal{V}} \text{count}(t)$

$\displaystyle \text{total\_chars}$

$\displaystyle \text{coverage} = \frac{\text{covered\_chars}}{\text{total\_chars}}$

调参的智慧在于平衡:让机器人在“记忆一切”和“灵活应变”之间找到那个甜点。宁可让它把极少数生僻字放进杂物间,也不要把整个厨房塞满一辈子用不到一次的存货。

coverage=词表能覆盖的训练字符数训练语料总字符数\displaystyle \text{coverage} = \frac{\text{词表能覆盖的训练字符数}}{\text{训练语料总字符数}}
覆盖率衡量的是:词表这把“刀”能处理多少比例的原始字符。一般来说,覆盖率越接近 1,稀有字符处理越完整,但模型体积和过拟合风险也越大。
  1. 分子含义训练语料中能被词表内子词完全覆盖的字符数量。
  2. 分母含义训练语料的总字符数,包括空格和标点。
  3. 计算覆盖率两者相除得到 0 到 1 之间的小数。

子词算法原理

同一个切菜机器人,其实可以换不同的“刀法”。SentencePiece 最常用的刀法是 Unigram 语言模型,它像一位品酒师:对每一种切分方式都打个分,然后选总得分最高的那套切法。具体来说,它先给每个候选子词一个出现概率,再假设句子在某个切分下的概率等于所有子词概率的乘积。由于一个句子往往有多种切法,Unigram 会把所有可能切法的概率加起来,得到句子的总概率,然后通过最大似然估计不断调整每个子词的概率。训练完成后,概率低的子词会被逐步淘汰,最终剩下精炼的词表。

另一种常见刀法是 BPE(字节对编码)。它不看概率,只看“哪些字符对总是黏在一起”。比如英文里 e 和 r 经常连着出现,er 就被合并成一个块;再继续合并 er 和 s,得到 ers。合并操作反复进行,直到词表达到目标大小。BPE 的哲学是“高频搭档就该被固定下来”。

还有 WordPiece,它和 BPE 类似,但不是单纯看频次,而是看两个符号组合后带来的信息增益有多大,也就是“这对搭档是不是比各自单干更好”。三者同属子词切分,但评估标准不同:一个看概率,一个看频率,一个看互信息。

$\displaystyle p(t) \in (0, 1), \quad \sum_{t \in \mathcal{V}} p(t) = 1$

$\displaystyle p(s) = \prod_{t \in s} p(t)$

$\displaystyle P(x) = \sum_{s \in S(x)} p(s)$

理解了这三种刀法,你就明白了为什么 SentencePiece 如此强大:它把“选刀法”和“训练刀法”解耦。你可以用同一套代码,在 Unigram、BPE、WordPiece 之间一键切换,像厨房里换一把刀柄一样方便。

P(x)=∑s∈S(x)∏t∈sp(t)\displaystyle P(x) = \sum_{s \in S(x)} \prod_{t \in s} p(t)
这是 Unigram 模型的核心公式:句子 $x$ 的概率等于所有可能切分方式 $S(x)$ 的概率之和,而每种切分方式的概率等于其中每个子词 $t$ 的概率乘积。
  1. 子词概率每个子词 $t$ 在词表中都有一个概率 $p(t)$,初始随机,训练中不断调整。
  2. 单种切分的概率一种切分方式 $s$ 的概率,是切分出的所有子词概率的乘积。
  3. 所有切分求和把句子所有可能的切分方式概率加总,得到句子概率。

多语言实战

现实世界里,总厨常常要同时处理多个菜系的食材:一段客服对话里可能混着中文、英文、颜文字和网络新词。传统分词器遇到这种“大杂烩”往往崩溃,但 SentencePiece 天生适合多语言,因为它根本不关心“词”是什么,只关心字符块怎么切最合理。很多低资源语言(比如国内少数民族语言、东南亚小语种)没有公开的分词工具,SentencePiece 却可以直接从原始语料中学习,堪称低资源场景的救命稻草。

多语言训练时,一个关键技巧是控制不同语言的语料比例。如果你把 100 份中文语料和 1 份藏语语料混在一起,机器人学到的基本是中文刀法,藏语部分只学会几个高频碎片。建议根据实际业务需求调节比例,必要时对低资源语言做上采样(重复多放几遍),让它在词表里占据合理份额。这就像做自助餐,每道菜都要给足够的品尝机会,总厨才会记得每道菜的特点。

如果业务上线后发现某些新词(比如产品名、人名)总是被切得稀碎,可以用增量训练:加载现有模型,用包含新词的语料再训练几步,让旧刀法逐渐适应当下需求。或者更直接一点,把自定义词汇预先加入词表,相当于在冰箱里专门给“招牌菜”留出固定格子,防止它们被切成莫名其妙的碎片。

$\displaystyle N_i$

$\displaystyle \sum_{j=1}^{K} N_j$

$\displaystyle R_i = \frac{N_i}{\sum_{j=1}^{K} N_j}$

多语言实战的核心心法:不追求每种语言都完美,而是让机器人对每种语言都“够用”。与其让模型把罕见语言切得天花乱坠,不如保证常见语言的切分稳定又高效。

Ri=Ni∑j=1KNj(i=1,2,…,K)\displaystyle R_i = \frac{N_i}{\sum_{j=1}^{K} N_j} \quad (i = 1, 2, \dots, K)
$R_i$ 是第 $i$ 种语言在训练语料中的占比,$N_i$ 是这种语言的样本量,$K$ 是语言总数。比例直接决定了机器人学习每种语言“刀法”的投入度。
  1. 某语言样本量$N_i$ 表示第 $i$ 种语言放入训练的文本量。
  2. 总样本量分母是所有语言样本量之和。
  3. 占比计算第 $i$ 种语言的占比,占比越大,学习权重越高。

对比与选型

当你真正开始选型时,会发现市面上的“分词流派”不止 SentencePiece 一家。最常被拿来比较的是 BPE 和 WordPiece。BPE 是 GPT 系列等模型的最爱,它简单粗暴,按相邻符号的出现频率反复合并,词表利用率高;WordPiece 则是 BERT 系列的标配,它额外引入了一个“配对收益”的概念,更倾向于合并那些能显著降低不确定性的字符对。

SentencePiece 和这两者的根本区别在于:它自带“无监督”属性,不需要你先用空格或其他规则把文本切成词。BPE 和 WordPiece 在原始设计中通常需要预分词,比如英文先把句子按空格分成单词再进一步切分。而 SentencePiece 把空格也当成一种普通字符处理,甚至会把空格转成特殊的 ▁ 记号。这对于中文、日文等没有天然空格的语言特别友好,也是它成为多语言 NLP 首选的原因之一。

那么到底怎么选?我给你一个简单的判断框架:如果你的任务是纯英文、语料干净且已有成熟分词流水线,原生 BPE 完全够用;如果你要做多语言、低资源语言或中英混合,优先选 SentencePiece 的 Unigram 模式;如果你想复现 BERT 类模型,可以参考 WordPiece,但实现上 SentencePiece 也提供了 --model_type=wordpiece 选项,方便你在同一套代码里做对比实验。选型的终点不是“哪个更先进”,而是“哪个和你厨房的食材、菜系、客人口味最匹配”。

$\displaystyle \text{coverage}_{\text{SentencePiece}}$

$\displaystyle \text{coverage}_{\text{BPE\_baseline}}$

$\displaystyle \text{cov\_ratio} > 1 \Rightarrow \text{SentencePiece 更优}$

记住,分词器只是厨房里的第一道工序。真正决定菜品好不好吃的,是后面的大厨——也就是你的模型架构和训练策略。但一把好用的刀,确实能让大厨少生很多气。

cov_ratio=coverageSentencePiececoverageBPE_baseline\displaystyle \text{cov\_ratio} = \frac{\text{coverage}_{\text{SentencePiece}}}{\text{coverage}_{\text{BPE\_baseline}}}
这个比值帮你量化比较:不同分词器在同一语料上的覆盖率之比。如果 SentencePiece 的覆盖率明显更高,说明它的刀法对这份语料更友好。
  1. 分子SentencePiece 在目标语料上的字符覆盖率。
  2. 分母BPE 基线模型在同一语料上的覆盖率。
  3. 比值意义比值大于 1 说明 SentencePiece 覆盖更好,小于 1 则相反。

AI 应用场景

多语言电商搜索

阶段:文本预处理

解决的问题:传统分词器面对“iPhone 15 手机壳 yyds 特价”这种中英混搭查询,往往把英文单词整个丢掉或切得稀碎,导致搜索结果不准确。SentencePiece 不需要预分词,直接切出"iPhone""15““手机壳””yyds"“特价”等子词,大幅降低未登录词率。

具体案例:某跨境电商平台在东南亚上线后,用户搜索词混有英语、马来语、中文。技术团队用 SentencePiece 统一训练多语料,词表大小设为 16000,上线后搜索无结果率下降了 42%。

低资源语言机器翻译

阶段:数据准备与词表构建

解决的问题:很多低资源语言没有公开分词器,人工标注成本极高。SentencePiece 直接从原始语料学习子词,让翻译模型不必依赖外部分词工具。

具体案例:某公益项目需要做汉语到彝语的翻译,市面上找不到彝语分词器。研究员收集了 200 万条互联网彝语文本,直接用 SentencePiece 训练 8000 词表,完成了翻译系统的预处理环节。

对话系统的快速迭代

阶段:特征编码与词表更新

解决的问题:对话系统每天都会遇到新词如“绝绝子”“栓Q”,固定词表无法覆盖。利用 SentencePiece 的增量训练能力,可以在不重建整个模型的情况下快速吸收新词。

具体案例:某银行客服机器人每周更新一次词表,用最近一周的对话语料做增量训练,新词覆盖率从 76% 提升到 95%,用户情绪识别准确率提高 6 个百分点。

Python 演示

python30 行
import sentencepiece as spm spm.SentencePieceTrainer.train(    input='corpus.txt',    model_prefix='mymodel',    vocab_size=8000,    character_coverage=0.9995,    model_type='unigram',    max_sentence_length=4192,    pad_id=0,    unk_id=1,    bos_id=2,    eos_id=3,) sp = spm.SentencePieceProcessor(model_file='mymodel.model') text = '我爱机器学习,也爱yyds美食'pieces = sp.encode(text, out_type=str)print('子词切分:', pieces) ids = sp.encode(text, out_type=int)print('子词ID:', ids) decoded = sp.decode(ids)print('还原文本:', decoded) for piece in ['yyds', '机器学习', '美食']:    sub = sp.encode(piece, out_type=str)    print(piece, '->', sub)
目的:演示 SentencePiece 从训练到编码、解码的完整流程,帮助你快速搭建自己的无监督分词器。
  1. spm.SentencePieceTrainer.train(...)启动训练,输入原始语料,输出模型文件。
  2. input='corpus.txt'指定训练语料路径,文件里每行一句话即可。
  3. model_prefix='mymodel'模型前缀,训练后生成 mymodel.model 和 mymodel.vocab。
  4. vocab_size=8000词表大小,相当于给冰箱预定的冷藏格数量。
  5. character_coverage=0.9995字符覆盖率,保留极少量稀有字符给 <unk>。
  6. model_type='unigram'选择 Unigram 刀法,也可换成 bpe 或 wordpiece。
  7. sp = spm.SentencePieceProcessor(model_file='mymodel.model')加载训练好的模型。
  8. sp.encode(text, out_type=str)把文本切分成子词字符串列表。
  9. sp.encode(text, out_type=int)把文本编码成子词 ID 列表。
  10. sp.decode(ids)把子词 ID 列表还原成原始文本,验证无损。

常见误区

误区我以为 SentencePiece 和 BPE 一样,必须先按空格把句子切成单词,才能训练子词模型。于是每次都先跑一遍 jieba 分词再喂给它。

正解SentencePiece 最大的特点就是“无监督”,它把空格也当成普通字符,自动学习出合适的切分位置。你给它原始文本就好,任何预分词反而是画蛇添足。它内部会把空格转成 ▁ 记号,方便在需要时还原回空格。

为何常见:很多人先学了 BPE,知道 BPE 通常依赖预分词,于是把这条经验错误地迁移到了 SentencePiece 上。

误区我觉得词表越大,模型能记住的词越多,效果一定越好。于是直接把 vocab_size 设成 128000,结果模型文件大了一倍,下游任务反而变差了。

正解词表过大会让很多子词出现次数很少,导致概率估计不准确,还会增加 embedding 维度和内存占用。词表过小又会让切分过碎,丢失语义。最佳值取决于语料规模和任务类型,一般从 8000 到 32000 这个区间开始网格搜索。

为何常见:“更多参数 = 更强能力”的直觉在深度学习里经常成立,但在词表这种离散符号层面,稀疏性会带来严重的数据稀疏问题。

误区我以为只有 coverage=1.0 才不会漏掉任何字符,否则模型就“不完整”。于是每次都强行设 1.0,导致模型里塞满了生僻字。

正解1.0 意味着词表必须覆盖训练集中所有字符,包括只出现一次的乱码和 emoji。这不仅让词表膨胀,还会降低泛化能力。通常 0.9995 就足够了,剩余极少量字符由 <unk> 兜底。

为何常见:对“未知标记”有天然恐惧,觉得出现 <unk> 就是模型失败。实际上合理的 <unk> 是系统设计的一部分,它在帮你过滤噪声。

误区我觉得这三种模式都是换汤不换药,训练出来效果差不多,随便选一个就行。

正解它们的优化目标完全不同:Unigram 通过最大似然估计逐步剪枝低概率子词;BPE 按相邻字符对的出现频率反复合并;WordPiece 则看配对带来的信息增益。在中文、日文等多语言场景下,Unigram 通常更灵活;在英文上,BPE 更经典稳定。它们不是名字差异,而是刀法差异。

为何常见:对外部使用者来说,调用接口几乎一样,容易让人忽略底层机制的不同。

误区我以为训练好词表后,遇到新词只能等很久后重新训练整个模型,不敢轻易上新产品名。总是用 `<unk>` 硬扛,效果很差。

正解SentencePiece 支持在已有模型基础上继续训练,比如用少量包含新词的语料做增量训练,也可以手动往词表里添加自定义词汇。当然,增量训练会影响原有分布,需要控制学习率和训练步数,但绝不是“不能加新词”。

为何常见:很多人没注意到 SentencePiece 官方提供了 SentencePieceTrainer 的复用能力,把它当成一次性工具。

面试题

Q1. SentencePiece 最核心的“无监督”指的是什么?

单选题 · easy

  • A.不需要标注数据来训练子词模型← 正确答案
  • B.不需要 GPU 也能训练
  • C.不需要设置词表大小
  • D.不需要任何训练语料

答案:A。无监督指不需要人工分词标注,直接把原始文本喂给它学习子词。B 是设备条件,C 和 D 都与无监督无关,词表大小和语料都是必须提供的。

Q2. 训练 SentencePiece 模型时,控制“生僻字符容忍度”的参数是?

单选题 · easy

  • A.vocab_size
  • B.character_coverage← 正确答案
  • C.model_type
  • D.max_sentence_length

答案:B。character_coverage 决定词表覆盖多少训练字符,0.9995 表示允许 0.05% 的稀有字符被映射到 <unk>。vocab_size 控制词表规模,model_type 选刀法,max_sentence_length 控制句子最大长度。

Q3. 关于 BPE 和 WordPiece 的区别,下列说法正确的是?

单选题 · mid

  • A.两者完全相同,没有区别
  • B.BPE 按相邻符号出现频率合并,WordPiece 看配对信息增益← 正确答案
  • C.WordPiece 不需要词表
  • D.BPE 只能用于英文

答案:B。BPE 的核心是高频字符对合并,WordPiece 则通过衡量配对前后似然增益来决定是否合并。两者都需要词表,BPE 也可用于多语言,A/C/D 均错误。

Q4. 为什么 SentencePiece 对中文、日文等语言特别友好?

单选题 · mid

  • A.因为它内置了中文分词词典
  • B.因为它不需要预分词,把空格也当作普通字符处理← 正确答案
  • C.因为它只能处理 CJK 字符
  • D.因为它会自动翻译成英文

答案:B。SentencePiece 将空格转成 ▁ 记号,不依赖任何语言预分词规则。中文日文本无空格,传统 BPE 需要先按空格切词的方案在这里失效,而 SentencePiece 直接从字符层面学习。

Q5. Unigram 语言模型计算一个句子的概率时,采用什么策略?

单选题 · mid

  • A.只保留概率最高的一种切分方式
  • B.对所有可能切分方式的概率求和← 正确答案
  • C.随机选一种切分方式
  • D.取所有切分方式概率的最大值作为句子概率

答案:B。Unigram 的关键假设是:句子可以通过多种切分方式产生,因此句子概率是每种切分方式概率的加总,而不是只取最大值或只保留一种。

Q6. 你训练了一个 vocab_size=32000 的 SentencePiece 模型,发现模型文件异常大,但下游任务效果变差。最可能的原因是?

单选题 · hard

  • A.词表太大导致大量低频子词和稀疏 embedding← 正确答案
  • B.character_coverage 设置得太低
  • C.训练语料行数不够多
  • D.model_type 选错了

答案:A。32000 的词表在中小语料上会导致大量子词出现次数极少,embedding 参数稀疏且难以学到有效表示,进而影响下游任务。覆盖率低反而会让文件变小,语料行数影响的是训练充分性而非文件大小。

Q7. 下列哪些场景适合优先选用 SentencePiece?

多选题 · mid

  • A.中英混合的社交媒体文本← 正确答案
  • B.没有现成分词器的低资源语言← 正确答案
  • C.已经按 UTF-8 编码的英文纯文本
  • D.需要无预分词的多语言翻译系统← 正确答案

答案:ABD。SentencePiece 的核心优势是无预分词、多语言友好。中英混合、低资源语言、多语言翻译都是它的主场。纯英文场景用原生 BPE 完全可以,并不是“必须选” SentencePiece 的场景。

Q8. 编码和解码的关系是?

单选题 · easy

  • A.编码是句子到子词 ID,解码是子词 ID 到句子← 正确答案
  • B.编码是子词 ID 到句子,解码是句子到子词 ID
  • C.编码和解码完全无关
  • D.解码比编码多一个参数

答案:A。编码 encode(x) 把文本映射成 ID 列表,解码 decode(ids) 把 ID 列表还原成文本,两者是互逆操作,共享同一套词表。

Q9. 关于增量训练,下列说法正确的有?

多选题 · hard

  • A.加载已有模型继续训练可以吸收新词← 正确答案
  • B.增量训练不会影响原有词表分布
  • C.增量训练需要控制学习率和步数,避免破坏旧特征← 正确答案
  • D.增量训练可以完全替代从头训练

答案:AC。增量训练是在旧模型基础上继续学习,能吸收新词但必然会影响原有概率分布,所以需要控制学习率步长。它适合快速补丁式更新,但不能完全替代从头训练的效果。

Q10. 词表大小设置过小可能导致什么问题?

多选题 · mid

  • A.子词切分过碎,丢失语义信息← 正确答案
  • B.每个子词出现频率过高,区分度下降← 正确答案
  • C.模型文件一定变小
  • D.未登录词数量增加← 正确答案

答案:ABD。词表过小意味着很多词必须被拆成碎片,切分过碎导致语义丢失;碎片化让高频子词大量重复,区分度下降;覆盖不了完整词时未登录词自然增多。词表小模型文件确实可能变小,但这不是“问题”本身,而是伴随现象。