Transformer 通关秘籍4:一文看懂文本的 tokenization(分词)的过程

前面两节分别通过两个代码示例展示了模型将文本转换为 token 之后是什么样的,希望你可以对此有一个感性的认识。

本节来简要介绍一下将一个连续的文本转换为 token 序列的大致过程,这个过程被称为分词,也叫 tokenization。

在你没了解这方面的知识之前,如果让你实现一个类似的算法,你会如何来实现呢?我想你可能最先想到便是使用空格来进行分词。

Attention:全网最全的 AI 小白到 AI 大神的天梯成长学习路线,几十万原创专栏和硬核视频,点击这里查看:AI小白到AI大神的天梯之路

基于空格的分词

当然,这是一种最简单的分词方法。

它直接使用空格或者一些标点符号来切分文本。常用于处理那些单词之间以空格明显分隔的语言,如英语,这里给出一个基于空格的分词示例:

假设有下面一句话:

arduino 复制代码
"I love learning new things about artificial intelligence and machine learning."

用空格分词后,就可以直接得到如下的 token 。

css 复制代码
['I', 'love', 'learning', 'new', 'things', 'about', 'artificial', 'intelligence', 'and', 'machine', 'learning.']

这个很简单,也非常好理解。

这种分词方法可以用来处理一些简单的文本,但是在大型语言模型中几乎不会用到。因为太简单了,无法处理复杂的语境。

在大语言模型中,一般会使用更先进的分词方法,比如 BPE (Byte Pair Encoding)和 WordPiece 算法,这两个算法在前面两节展示 token 的时候曾经提到过,但未深入展开。

WordPiece/ BPE 的分词逻辑

WordPiece 是由 Google 开发的,后来被用在了 BERT 模型的分词过程中,而 BPE (Byte Pair Encoding,也叫字节对编码)最初是一种用于数据压缩的算法,后来才被应用到自然语言处理领域,GPT 系列的模型使用的便是 BPE 分词方法。

这两种方法对于文本的分词过程大致相同,下面通过一个例子来说明一下。

假设某文本中仅包含以下词汇:bug,debug,debugger。这里为了方便展示,假设以上词汇在文本中仅出现了一次,不考虑出现多次的情况。

首先,分词算法对以上单词进行拆分,拆分为独立的字符形式,如:

● "bug" → ("b", "##u", "##g") ● "debug" → ("d", "##e", "##b", "##u", "##g") ● "debugger" → ("d", "##e", "##b", "##u", "##g", "##g","##e", "##r")

##代表该字符与前面的字符在拆分之前是一个完整的词。

然后,将拆分后的词汇进行汇总,得到拆分后的词汇表为:("b", "##u", "##g", "d", "##e", "##r")

接下来,对上述词汇表中的词进行合并:通过一定的合并算法,将上述已拆分的子词合并。

比如,你可以使用统计的方法,经过统计发现,##u 和 ##g 在原始文本中成对出现的频率很高,那么就优先将 ##u 和 ##g 进行合并。

合并之后,最初的词汇表就变成了("b", "##ug", "d", "##e", "##r")。

在此基础上,还可以进一步合并,比如还可以将 b 与 ##ug进一步合并得到 bug,将d 和 ##e 进一步合并得到 de。

从而最终合并完的词汇表可能为:("bug", "de", "#ger")。

这种分词的方法,可以理解为是一种将文本拆分然后通过一定的算法再进行合并的过程,也就是说拆了又合,但是合并完和拆之前一般是不一样的。

WordPiece 以及 BPE 算法的不同,便是"一定的合并算法"的不同。

WordPiece 需要计算子词与子词之间的相关性分数来进行合并,而 BPE 则是单纯计算子词之间成对出现的频率来进行合并的。

但不管怎么样,两者有类似的地方:都是要先将原始词汇进行拆分,然后再进行合并,得到最终得到的词汇表(这是一个包含所有 token 的表,也可以认为是 token 的集合或者字典)。

这种方法不仅能够处理一些没有见过的词汇(因为已经把它们分解为已知的子词单元),还能优化词表的大小,从而提高语言模型的性能和效率。

需要说明的是,以上仅描述了分词的大致过程,分词并非本专栏的重要内容,在本专栏的知识架构下,你只需要了解一些常见的分词过程即可。

如果对于分词算法的细节感兴趣,可以查看一下这篇文章,写的比较详细:www.zhihu.com/question/64...

我创建了一个《小而精的AI学习圈》知识星球,星球上有几十万字原创高质量的技术专栏分享,同时你也可以在星球向我提问。 点击这里,我们星球见! >>>
点击这里查看所有 AI 技术专栏

相关推荐
Tingjct11 分钟前
【初阶数据结构-二叉树】
c语言·开发语言·数据结构·算法
C雨后彩虹12 分钟前
计算疫情扩散时间
java·数据结构·算法·华为·面试
yyy(十一月限定版)1 小时前
寒假集训4——二分排序
算法
星火开发设计1 小时前
类型别名 typedef:让复杂类型更简洁
开发语言·c++·学习·算法·函数·知识
醉颜凉1 小时前
【LeetCode】打家劫舍III
c语言·算法·leetcode·树 深度优先搜索·动态规划 二叉树
达文汐1 小时前
【困难】力扣算法题解析LeetCode332:重新安排行程
java·数据结构·经验分享·算法·leetcode·力扣
一匹电信狗1 小时前
【LeetCode_21】合并两个有序链表
c语言·开发语言·数据结构·c++·算法·leetcode·stl
User_芊芊君子1 小时前
【LeetCode经典题解】搞定二叉树最近公共祖先:递归法+栈存路径法,附代码实现
算法·leetcode·职场和发展
算法_小学生1 小时前
LeetCode 热题 100(分享最简单易懂的Python代码!)
python·算法·leetcode
执着2591 小时前
力扣hot100 - 234、回文链表
算法·leetcode·链表