文本分词算法:Byte-Pair Encoding (BPE)、WordPiece 和 SentencePiece
在将自然语言文本输入大语言模型之前必须先将其转换为模型能够计算的数字序列。这一过程被称为分词Tokenization而执行该转换的模块即为分词器Tokenizer。分词器定义了一套规则将原始文本切分为一个个最小的语义单元这些单元叫作词元Token。为了在词汇表大小与语义表达能力之间取得平衡现代大语言模型普遍采用子词分词Subword Tokenization算法。其核心思想是将高频词如 “agent”保留为一个完整的词元而将低频或未登录词如 “Tokenization”拆分成多个有意义的子词片段如 “Token” 和 “ization”。这样做既能控制词汇表规模又赋予模型通过子词组合来理解与生成新词的能力。最终所有词元会被映射为固定的整数 ID形成模型可直接计算的数字序列。本文围绕子词分词技术详细讲解三种主流算法Byte-Pair Encoding (BPE)、WordPiece和SentencePiece (Unigram 语言模型)。1. Byte-Pair Encoding (BPE)原理BPE 最早是一种数据压缩算法后被用于机器翻译等 NLP 任务。它从字符级开始统计所有相邻符号对的出现频率反复将频率最高的那一对合并成一个新符号直到词汇表达到预定大小或没有可合并的对。训练 BPE 前通常需要一个预分词步骤如按空格分词并为每个词加上结尾标记如/w保证合并出的子词能还原词边界。最终词汇表包含单字符、合并得到的子词以及词尾标记。举例假设有词频数据low/w出现 5 次lower/w出现 2 次newest/w出现 6 次widest/w出现 3 次。初始分割为字符序列例如l o w /w。统计所有相邻对(l, o)出现 527 次(o, w)出现 7 次(w, /w)出现 5 次(e, w)出现 2 次…最高频对为(e, s)出现 639 次于是合并成es。继续迭代直到词汇表达到预设大小。编码/分词对于一个新词按照训练时学到的合并顺序merges依次应用合并规则将词拆分为子词序列。Python 实现importrefromcollectionsimportCounter,defaultdictdefget_initial_vocab(word_freqs):将词拆为字符序列末尾加特殊标记/wvocab{}forword,freqinword_freqs.items():chars .join(list(word)) /wvocab[chars]freqreturnvocabdefget_pair_stats(vocab):统计所有相邻符号对的频率pairsCounter()forword,freqinvocab.items():symbolsword.split()foriinrange(len(symbols)-1):pairs[(symbols[i],symbols[i1])]freqreturnpairsdefmerge_vocab(pair,vocab):将指定符号对在词汇表中合并bigram .join(pair)replacement.join(pair)new_vocab{}forword,freqinvocab.items():new_wordword.replace(bigram,replacement)new_vocab[new_word]freqreturnnew_vocabdefbpe_train(word_freqs,num_merges):训练 BPE返回合并列表和最终词汇表vocabget_initial_vocab(word_freqs)merges[]foriinrange(num_merges):pairsget_pair_stats(vocab)ifnotpairs:breakbest_pairmax(pairs,keypairs.get)merges.append(best_pair)vocabmerge_vocab(best_pair,vocab)returnmerges,vocab# ---- 使用演示 ----word_freqs{low:5,lower:2,newest:6,widest:3}merges,final_vocabbpe_train(word_freqs,num_merges10)print(合并顺序:,merges)print(最终词汇表示例:,list(final_vocab.items())[:5])2. WordPiece原理WordPiece 与 BPE 非常相似最大的区别在于合并准则WordPiece 不选频率最高的对而是选择最大化语言模型似然的符号对。实际实现中计算分数score freq ( x , y ) freq ( x ) × freq ( y ) \text{score} \frac{\text{freq}(x,y)}{\text{freq}(x) \times \text{freq}(y)}scorefreq(x)×freq(y)freq(x,y)​其中freq ( x , y ) \text{freq}(x,y)freq(x,y)是相邻对共现次数freq ( x ) \text{freq}(x)freq(x)和freq ( y ) \text{freq}(y)freq(y)分别是两个符号单独出现的次数。这样倾向于合并那些经常一起出现、且单独出现相对较少的组合得到的子词更具语言学意义。与 BPE 的另一区别是WordPiece 在词内部用##前缀标记非起始子词如word与##piece以防止跨词边界的歧义合并。举例词频同 BPE 例子但合并时选择 score 最高的对统计出(e, s)频率高但e和s本身也频繁出现因此 score 可能不如(w, ##i)在wide中等高。最终合并会优先使单个符号之间依赖更强的合并。编码/分词采用贪心最长匹配策略从左到右逐步匹配词汇表中最长的子词。Python 实现defwordpiece_train(word_freqs,num_merges):简化的 WordPiece 训练# 词内符号以 ## 标记非首字符vocab{}forword,freqinword_freqs.items():charsword[0]# 首字符不加 ##forcinword[1:]:chars ##c chars /wvocab[chars]freq merges[]for_inrange(num_merges):pairsCounter()# 统计每个符号的独立频率symbol_freqCounter()forword,freqinvocab.items():symbolsword.split()forsinsymbols:symbol_freq[s]freqforiinrange(len(symbols)-1):pairs[(symbols[i],symbols[i1])]freqifnotpairs:break# 计算 score选最大best_pairmax(pairs,keylambdap:pairs[p]/(symbol_freq[p[0]]*symbol_freq[p[1]]))merges.append(best_pair)bigram .join(best_pair)replacement.join(best_pair)new_vocab{}forword,freqinvocab.items():new_wordword.replace(bigram,replacement)new_vocab[new_word]freq vocabnew_vocabreturnmerges,vocab3. SentencePiece (Unigram 语言模型)原理SentencePiece 是 Google 推出的分词框架它不依赖预分词即不需要事先按空格切分而是把整个输入视为原始字节流直接学习子词。虽然它支持 BPE但其最具代表性的算法是Unigram 语言模型配合子词正则化。核心思想从一个很大的候选词汇表如所有可能的子串出发假设每个子词的出现相互独立句子的概率为各子词概率的乘积P ( s e n t e n c e ) ∏ x ∈ s e g m e n t a t i o n p ( x ) P(sentence) \prod_{x \in segmentation} p(x)P(sentence)∏x∈segmentation​p(x)通过期望最大化EM算法优化训练数据的边缘似然同时逐步剪掉概率较低的候选子词直到词汇表达到指定大小。训练完成后编码可以用维特比算法寻找概率最大的分割也可以根据概率采样多种分割以实现正则化。SentencePiece 把空格编码为_或其它元符号并将所有字符统一处理非常适合多语言或无需分词的场景如中文、日文。举例训练数据low lower newest widest初始候选词汇所有单个字符l, o, w, e, r, n, s, t, d, i, _空格以及高频率的 bigram如lo,ow,er,es, …。给每个候选子词均匀概率然后开始 EM 迭代E 步计算每个句子所有可能分割下各子词的期望出现次数。M 步用期望计数重新估计子词概率。每轮剪掉概率最低的 20% 子词重复直到词汇表大小符合要求。Python 实现importmath,refromcollectionsimportCounter,defaultdictdefinit_vocab(texts,max_len3):从文本中收集所有长度 max_len 的子串作为初始候选词汇vocabCounter()fortextintexts:# 将空格替换为特殊标记使其可分割texttext.replace( ,_)foriinrange(len(text)):forjinrange(1,max_len1):ifijlen(text):vocab[text[i:ij]]1# 只保留出现次数足够多的候选例如至少2次return{w:cforw,cinvocab.items()ifc2}defviterbi_segment(text,vocab_probs):用动态规划找概率最大的分割路径nlen(text)dp[0.0]*(n1)dp[0]1.0back[0]*(n1)foriinrange(n):ifdp[i]0:continueforjinrange(i1,n1):subtext[i:j]ifsubinvocab_probs:probdp[i]*vocab_probs[sub]ifprobdp[j]:dp[j]prob back[j]i# 回溯segments[]idxnwhileidx0:prevback[idx]segments.append(text[prev:idx])idxprevreturnsegments[::-1]deftrain_unigram(texts,vocab_size100,num_iters10):简化的 Unigram 训练Viterbi 近似 EM# 初始词汇表raw_vocabinit_vocab(texts,max_len4)vocablist(raw_vocab.keys())print(初始候选词汇数:,len(vocab))# 均匀概率probs{w:1/len(vocab)forwinvocab}foritinrange(num_iters):# 用维特比硬分割并统计频率countsCounter()total0fortextintexts:texttext.replace( ,_)segviterbi_segment(text,probs)forsubinseg:counts[sub]1total1# 重新估计概率probs{w:counts[w]/totalforwinvocabifcounts[w]0}# 剪枝如果词汇量超过目标去掉概率最低的whilelen(probs)vocab_size:worstmin(probs,keyprobs.get)delprobs[worst]vocablist(probs.keys())print(fIter{it1}, vocab size:{len(vocab)})returnprobs# ---- 使用演示 ----texts[low lower newest widest]probstrain_unigram(texts,vocab_size20,num_iters10)print(最终词汇:,sorted(probs.keys()))三者优缺点对比方法优点缺点BPE简单、高效完全基于频率可解释性强训练速度快编码规则确定。依赖预分词可能合并不合理的子词无法解决多分割歧义对低频对容易过拟合。WordPiece合并准则基于概率最大化子词更具语言学意义结合##前缀边界清晰在 BERT 等模型中效果好。训练开销稍大于 BPE需维护单符号频率依赖预分词贪心分词可能非最优。SentencePiece不依赖预分词将输入视为字节流天然支持所有语言Unigram 提供概率模型和子词正则化增强鲁棒性空格可见标记。训练复杂EM速度慢实现难度高Viterbi 解码开销较大超参数调节需经验。三者都在现代 NLP 中被广泛使用。BPE 适合快速实现与清晰规则WordPiece 在理解型模型如 BERT中平衡了效果与速度而 SentencePieceUnigram提供了最灵活、最一致的多语言处理方案尤其在需要避免预分词偏见的生产系统中优势明显。

相关新闻

面向对象2.1 封装

面向对象2.1 封装

封装是将数据和操作数据的方法捆绑到一个单元中。对外部隐藏对象的内部实现细节,仅通过有限受控的接口与外部进行交互。2.1.1 成员权限public、private、protected// public: 任何地方都可以访问。类的内部、子类、类的外部(通过对象)都可以直…

2026/7/1 2:21:58阅读更多 →
什么是整型提升?为什么要使用整型提升?整型提升是如何进行的?

什么是整型提升?为什么要使用整型提升?整型提升是如何进行的?

.整型提升在c语言中,一些表达式在求值的过程中,操作数可能需要转换为其他类型,这种转换,我们程序员是看不见的,称其为隐式类型转换,而整型提升就是之一1.1什么是整型提升在C语言中计算整数的时候&#xff0…

2026/7/1 2:21:58阅读更多 →
【Springboot毕设全套源码+文档】基于Java+springboot电影院票务预定系统的设计与实现(丰富项目+远程调试+讲解+定制)

【Springboot毕设全套源码+文档】基于Java+springboot电影院票务预定系统的设计与实现(丰富项目+远程调试+讲解+定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/1 2:16:58阅读更多 →
Agentic AI的真正价值:认知复利与工作流进化,而非单纯速度提升

Agentic AI的真正价值:认知复利与工作流进化,而非单纯速度提升

最近和几个做AI应用的朋友聊天,发现一个挺有意思的现象:大家一提到“Agentic AI”(智能体AI),第一反应往往是“它能自动执行任务,肯定更快”。但折腾了几个项目下来,我发现,“快”可…

2026/7/1 3:32:07阅读更多 →
AI智能体团队协作开发:从概念到实战的完整指南

AI智能体团队协作开发:从概念到实战的完整指南

1. 先搞清楚“代码秀”和“AI团队”到底在解决什么问题 看到“代码秀全拆解”和“AI团队已就位”这种标题,第一反应往往是:这又是一个炫技的Demo,还是真的能解决实际开发流程中的痛点?结合“2026峰会现场”这个时间点,…

2026/7/1 3:32:07阅读更多 →
35岁女生适合考什么证书?2026年职场破局与系统提升路径深度解析

35岁女生适合考什么证书?2026年职场破局与系统提升路径深度解析

在职业发展的长河中,“35岁”往往被赋予了太多焦虑的色彩。尤其是对于女性职场人而言,处于这个阶段,常常面临着家庭与工作的平衡、新人辈出的竞争以及行业技术的迅速迭代。但在我多年观察职场发展的经验来看,35岁绝不是职业生涯的…

2026/7/1 3:32:07阅读更多 →
青岛家电企业数字化转型:T+0快速搭建虚拟产线,降低试错成本90%

青岛家电企业数字化转型:T+0快速搭建虚拟产线,降低试错成本90%

一、 青岛“家电之都”的效率焦虑青岛,孕育了海尔、海信、澳柯玛等享誉全球的家电巨头。这些企业在智能制造转型的道路上起步早、成效显著,但其数字化转型始终有一个核心难题:产线规划。当企业需要规划一条新产线,或者对现有产线进…

2026/7/1 3:32:07阅读更多 →
Agentic AI实战:基于LangChain构建具备ReAct推理能力的智能体

Agentic AI实战:基于LangChain构建具备ReAct推理能力的智能体

大家好,我是专注于技术实战与经验分享的博主。今天我们来深入探讨一个正在重塑软件开发与自动化流程的前沿概念——Agentic AI(智能体式人工智能)。很多开发者初次接触时,可能会将其简单理解为“更快的自动化脚本”或“升级版的RP…

2026/7/1 3:32:07阅读更多 →
QMCDecode:Mac用户必备的QQ音乐加密文件格式转换专业解决方案

QMCDecode:Mac用户必备的QQ音乐加密文件格式转换专业解决方案

QMCDecode:Mac用户必备的QQ音乐加密文件格式转换专业解决方案 【免费下载链接】QMCDecode QQ音乐QMC格式转换为普通格式(qmcflac转flac,qmc0,qmc3转mp3, mflac,mflac0等转flac),仅支持macOS,可自动识别到QQ音乐下载目录&#xff0…

2026/7/1 3:27:07阅读更多 →
AI Coding 六个月真实ROI账本:产品经理的血泪教训,研发的冷静忠告

AI Coding 六个月真实ROI账本:产品经理的血泪教训,研发的冷静忠告

6个月前的2025年12月,Boris Cherny 公开宣布自己卸载了 IDE。一时间,Vibe Coding 成了全行业最热的话题。6个月后,当我们回过头来拉一份真实账本,发现事情远没有"一句话生成一个App"那么浪漫。本文从产品经理和研发两个…

2026/6/30 4:03:30阅读更多 →
审计来了,数据权限全开——审计走了,怎么确保权限全部关掉?

审计来了,数据权限全开——审计走了,怎么确保权限全部关掉?

引言:审计结束三个月了,审计员的权限还没关某城商行每年按照监管要求开展至少一次数据安全审计。审计期间,内审部门需要抽样检查各类业务数据——交易流水、客户信息、员工操作日志、权限配置记录。这些数据分布在不同系统中,审计…

2026/6/30 4:36:27阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/1 0:01:44阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/1 0:01:44阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/1 0:01:44阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/1 0:01:44阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/1 0:01:44阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/1 0:01:44阅读更多 →