大模型系列:大模型tokenizer分词编码算法BPE理论简述和实践

前言

token是大模型处理和生成语言文本的基本单位,在之前介绍的Bert和GPT-2中,都是简单地将中文文本切分为单个汉字字符作为token,而目前LLaMAChatGLM等大模型采用的是基于分词工具sentencepiece实现的BBPE(Byte-level BPE)分词编码算法,本节介绍BBPE分词编码作为大模型系列的开篇。


常用分词算法简述

分词编码指的是将自然语言切割为最小的语义单元token,并且将token转化为数值id供给计算机进行模型学习的过程。常用的分词算法根据切分文本的颗粒度大小分为word,char,subword三类,以英文文本I am disappointed in you为例,三种方法切分结果如下

颗粒度切割方式分词结果
word单词级别分词,英文天然可以根据空格分割出单词[I, am, disappointed, in, you]
character字符级别分词,以单个字符作为最小颗粒度[I, , a, m, , d, i, s, …, y, o, u]
subword介于word和character之间,将word拆分为子串[I, am, disappoint, ed, in, you]

word方式的优点是保留住了完整的单词作为有意义的整体,相比于character语义表达更加充分,但是缺点是导致词表变大,因为罗列出单词的所有组合明显比穷举出所有字符更加困难,并且对于极少出现单词组合容易训练不充分,另外的word虽然区分出了单词,但是对于单词之间语义关系无法进一步刻画,比如英文中的cat和cats这种单复数情况。
character方法的优势在于词表小,5000多个中文常用字基本能组合出所有文本序列,但是缺点也很明显,缺乏单词的语义信息,并且分词的结果较长,增加了文本表征的成本。
subword方法平衡以上两种方法, 它可以较好的平衡词表大小和语义表达能力,本篇介绍的Byte-Pair Encoding (BPE) 和Byte-level BPE(BBPE)都属于subword方法。


以中文LLaMA(Atom)为例快速开始BBPE

Atom是基于LLaMA架构在中文文本上进行训练得到的语言模型,它对中文采用BBPE分词,整个词表包含65000个token,在HuggingFace搜索Atom-7B进行模型下载

HuggingFace Atom

Atom的分词器使用的是LlamaTokenizer,使用Python简单调用对文本进行分词如下

>>> from transformers import LlamaTokenizer
>>> tokenizer = LlamaTokenizer.from_pretrained("./Atom-7B")
>>> text = "我很开心我能和我们的团队一起工作"
>>> tokenizer.tokenize(text)
['▁我', '很开心', '我能', '和我们', '的团队', '一起', '工作']
>>> tokenizer.encode(text)
[32337, 43804, 42764, 53769, 49300, 32212, 32001]

从分词结果来看,BBPE类似jieba分词一样将中文字符进行了聚合成为一个一个的子串,而最终也是以子串整体映射到一个数值id,其中句子开头,或者文本中存在空格符,分词算法会将其替换为符号。
在LlamaTokenizer类中调用了sentencepiece来获取模型分词器,后续的分词操作也是基于sentencepiece提供的API方法

import sentencepiece as spm
...
self.sp_model = spm.SentencePieceProcessor(**self.sp_model_kwargs)
self.sp_model.Load(vocab_file)

Atom-7B模型目录下的tokenizer.model为BBPE分词模型,使用sentencepiece载入该分词模型可以实现LlamaTokenizer同样的效果

# pip install sentencepiece
>>> import sentencepiece
>>> tokenizer = sentencepiece.SentencePieceProcessor()
>>> tokenizer.Load("./Atom-7B/tokenizer.model")
>>> tokenizer.encode_as_pieces(text)
['▁我', '很开心', '我能', '和我们', '的团队', '一起', '工作']
>>> tokenizer.encode(text)
[32337, 43804, 42764, 53769, 49300, 32212, 32001]

tokenizer.model分词模型可以通过手动安装谷歌的项目源码,使用命令行导出为tokenizer.vocab词表,从而得到每个token和token id的对应关系,sentencepiece命令工具安装方式如下

# download sentencepiece项目源码
$ unzip sentencepiece.zip
$ cd sentencepiece
$ mkdir build
$ cd build
$ cmake ..
$ make -j $(nproc)
$ make install
$ ldconfig -v

安装完成在环境变量下出现命令spm_export_vocab,指定分词模型地址和输出词表文本地址即可完成词表导出

$ which spm_export_vocab
/usr/local/bin/spm_export_vocab$ spm_export_vocab \
--model=./Atom-7B/tokenizer.model \
--output=./Atom-7B/tokenizer.vocab

完成后生成tokenizer.vocab词表文件,打开词表搜索下’很开心’这个子串处在43805行,和编码结果43804一致(索引从0开始)

$ less -N tokenizer.vocab
...
43804 骑行    0
43805 很开心  0
43806 在里面  0
...

对于不在tokenizer.vocab中的生僻中文字符,BBPE会将他进行UTF-8编码用字节表示,使用字节去映射词表的token id,而不是使用UNK位置填充,这也是BBPE中Byte-level的体现

# 以生僻字’龘‘为例,对’龘‘进行UTF-8编码为字节表示
>>> "龘".encode("utf-8")
b'\xe9\xbe\x98'>>> tokenizer.encode_as_pieces("龘")
['▁', '<0xE9>', '<0xBE>', '<0x98>']
>>> tokenizer.tokenize("龘")
[29871, 236, 193, 155]

Byte-Pair Encoding (BPE) 原理简述

BBPE是基于BPE在字节颗粒度上的拓展,两者在分词算法上没有本质区别,本节先介绍BPE分词算法。
BPE的核心思想是事先给定一个最大分词数量,针对语料文本中的每个字符token,逐步合并出现频率最高的连续的两个字符组合,形成一个新词token,直到达到目标分词数量。BPE的计算流程图如下

BPE计算流程图

  • step 1:设定最大分词词典数量vocab size,初始化一个词典
  • step 2:将语料中所有文本切成单个字符形式加入词典,并且将,,,空格符等特殊字符也加入词典
  • step 3:对已经切为字符的语料,全局统计一轮连续两个字符出现组合的频率
  • step 4:取最大频率的组合,将这两个字符合并为一个整体,将这个整体添加到词典,并且在语料中将这两个字符也同步全部替换为这个新的整体,当作一个词
  • step 5:重复step 3和step 4直到达到vocab size或者无法再合并为止
  • step 6:将最终的词典生成分词编码模型文件,比如tokenizer.model,后续的任务都以这个分词词典来切词和编码

以一个只有2行的小文本“我很开心我能和我们的团队一起工作。我很欣赏我团队”为例,来说明BPE的计算流程,事先设定vocab size为23。两句话一共包含16个字符,但是还需要加上,,以及句子开头▁四种特殊符号,将它们全部添加到词表已经有20个token,下一步对单个token进行聚合,统计出有三个组合的频率最高,分别为’▁我’,‘我很’,'团队’各出现了2次,继续添加到词表,最终刚好形成23个词,BPE算法停止

语料我很开心我能和我们的团队一起工作。我很欣赏我团队
单字符作, 们, 一, 工, 能, 队, 欣, 的, 和, 我, 心, 起, 开, 赏, 团, 很
特殊字符, , , ▁
组合字符▁我, 我很, 团队

Byte-level BPE(BBPE)原理简述

BBPE将BPE的聚合下推到字节级别的,先通过UTF-8的编码方式将任意字符转化为长度1到4个字节,1个字节有256种表示,以字节为颗粒度进行聚合,其他流程和BPE是一样的。
在BBPE训练之前,256个字节表示作为token会全部加入词典,观察Atom的tokenizer.vocab,前三个位置分别为未登录词UNK,句子开头符,句子结束符,从第四个位置开始插入了256个字节集

1 <unk>   0
2 <s>     0
3 </s>    0
4 <0x00>  0
5 <0x01>  0
...
258 <0xFE>  0
259 <0xFF>  0
...

随着字节的聚合形成原始的字符,进一步可以形成词组,最终输出到tokenizer.model的时候会转化为聚合后的字符。
在模型使用的时候对于输入的字符,如果直接存在则映射为token id,如果不存在则转化为UTF-8编码之后的字节作为单位做映射,例如前文中的’龘‘会被映射为3个token id。
BBPE的优点:可以跨语言共用词表,任意语种都可以被编码到字节进行表示,另外UTF-8编码可以在不同语言之间具有一定互通性,底层字节层面的共享来实可能能够带来知识迁移。针对稀有字符,BBPE不会为其分配专门的token id,而是使用字节级别来编码来解决OOV的问题,一定程度上控制了词表大小和解决了稀疏字符难以训练的问题。
BBPE的缺点:会使得单个中文字符被切割为多个字节表示,导致表征的成本上升,可以通过扩大vocab size来促进字节的聚合,使得更多的字符和词组被挖掘出来作为单独的token id。


使用sentencepiece训练BPE,BBPE

Python安装的包sentencepiece和源码安装的spm_train命令工具都可以完成BPE和BBPE的训练,例如以小部分《狂飙》的剧本作为语料训练分词模型,代码如下

>>> import sentencepiece as spm>>> spm.SentencePieceTrainer.train(input='./data/corpus.txt',model_type="bpe",model_prefix='tokenizer',   vocab_size=3000, character_coverage=1,  max_sentencepiece_length=6, byte_fallback=False
)

SentencePieceTrainer的训练模式支持BPE,unigram等多种模式,当model_type为’bpe’且不开启byte_fallback,该模式为BPE,如果开启byte_fallback代表BBPE模式,byte_fallback代表是否将未知词转化为UTF-8字节表示进行编码,如果不开启则对于OOV的词会直接输出。
训练完成后在目录下会生成tokenizer.model和tokenizer.vocab两个文件,查看BPE的分词词表tokenizer.vocab如下

1 <unk>   0
2 <s>     0
3 </s>    0
4 :-0
5 ▁”      -1
6 安欣    -2
7 ..      -3
8 高启    -4
9 ?”      -5
10 高启强  -6

词表从上到下的顺序也蕴含了词频从高到低的关系。针对未在语料中出现过的字符分别测试下BPE和BBPE的编码结果

>>> # BPE
>>> token_model_1 = sentencepiece.SentencePieceProcessor()
>>> token_model_1.Load("./tokenizer.model")>>> # BBPE
>>> token_model_2 = sentencepiece.SentencePieceProcessor()
>>> token_model_2.Load("./tokenizer2.model")

针对文本中未出现的’凰’字符分词编码结果如下

>>> token_model_1.encode("凰")
[882, 0]>>> token_model_2.encode("凰")
[882, 232, 138, 179]

结论和前文一致,BPE方式对于未登陆词输出的token id为0,而BBPE如果映射不到该词会转化为3个字节表示,输出三个token id,全文完毕。

最后的最后

感谢你们的阅读和喜欢,我收藏了很多技术干货,可以共享给喜欢我文章的朋友们,如果你肯花时间沉下心去学习,它们一定能帮到你。

因为这个行业不同于其他行业,知识体系实在是过于庞大,知识更新也非常快。作为一个普通人,无法全部学完,所以我们在提升技术的时候,首先需要明确一个目标,然后制定好完整的计划,同时找到好的学习方法,这样才能更快的提升自己。

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

一、全套AGI大模型学习路线

AI大模型时代的学习之旅:从基础到前沿,掌握人工智能的核心技能!

img

二、640套AI大模型报告合集

这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。

img

三、AI大模型经典PDF籍

随着人工智能技术的飞速发展,AI大模型已经成为了当今科技领域的一大热点。这些大型预训练模型,如GPT-3、BERT、XLNet等,以其强大的语言理解和生成能力,正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。

img

四、AI大模型商业化落地方案

img

五、面试资料

我们学习AI大模型必然是想找到高薪的工作,下面这些面试题都是总结当前最新、最热、最高频的面试题,并且每道题都有详细的答案,面试前刷完这套面试题资料,小小offer,不在话下。
在这里插入图片描述

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/341394.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL——索引下推

1、使用前后对比 index Condition Pushdown(ICP)是MySQL5.6中新特性&#xff0c;是一种在存储引擎层使用索引过滤数据的优化方式。 如果没有ICP&#xff0c;存储引擎会遍历索引以定位基表中的行&#xff0c;并将它们返回给MySQL服务器&#xff0c;由MySQL服务器评估WHERE后面…

QT案例 记录解决在管理员权限下QFrame控件获取拖拽到控件上的文件路径

参考知乎问答 Qt管理员权限如何支持拖放操作&#xff1f; 的回答和代码示例。 解决在管理员权限运行下&#xff0c;通过窗体的QFrame子控件获取到拖拽的内容。 目录标题 导读解决方案详解示例详细 【管理员权限】在QFrame控件中获取拖拽内容 【管理员权限】继承 IDropTarget 类…

深度学习笔记:2.Jupyter Notebook

Jupyter Notebook 常用操作快捷键魔法指令_jupyter notebook快捷键调用函数-CSDN博客https://blog.csdn.net/qq_26917905/article/details/137211336?ops_request_misc%257B%2522request%255Fid%2522%253A%2522171748112816800182160793%2522%252C%2522scm%2522%253A%25222014…

CS4344国产替代音频DAC数模转换芯片DP7344采样率192kHz

目录 DAC应用简介DP7344简介结构框图DP7344主要特性微信号&#xff1a;dnsj5343参考原理图 应用领域 DAC应用简介 DAC&#xff08;中文&#xff1a;数字模拟转换器&#xff09;是一种将数字信号转换为模拟信号&#xff08;以电流、电压或电荷的形式&#xff09;的设备。电脑对…

废品回收小程序怎么做?有哪些核心功能?

废品回收行业正逐步走向高质量发展的道路。在国家政策的推动下&#xff0c;再生资源市场需求旺盛&#xff0c;行业内部竞争格局逐渐明朗。 随着互联网技术的发展&#xff0c;"互联网回收"成为废品回收行业的一个新趋势。通过微信小程序这种线上平台&#xff0c;用户…

甲方的苛刻,是成就优质作品的必要条件,辩证看待。

取其上、得其中&#xff0c;取其中&#xff0c;得其下&#xff0c;取其下、则无所的。在进行B端界面的设计的时候&#xff0c;设计师除了自我加压外&#xff0c;还少不了客户的严格要求&#xff0c;贝格前端工场为大家辩证分析一下。 一、严格产出高品质作品 甲方提出苛刻的要…

自然语言处理(NLP)—— C-value方法

自然语言处理&#xff08;NLP&#xff09;和文本挖掘是计算机科学与语言学的交叉领域&#xff0c;旨在通过计算机程序来理解、解析和生成人类语言&#xff0c;以及从大量文本数据中提取有用的信息和知识。这些技术在现代数据驱动的世界中扮演着关键角色&#xff0c;帮助我们从海…

数据结构:单调栈

数据结构&#xff1a;单调栈 题目描述参考代码 题目描述 输入样例 5 3 4 2 7 5输出样例 -1 3 -1 2 2参考代码 #include <iostream>using namespace std;const int N 100010;int stk[N], top; int n, x;int main() {cin >> n;while (n--){cin >> x;while …

Redis 异常三连环

本文针对一种特殊情况下的Reids连环异常&#xff0c;分别是下面三种异常&#xff1a; NullPointerException: Cannot read the array length because “arg” is nullJedisDataException: ERR Protocol error: invalid bulk lengthJedisConnectionException: Unexpected end o…

c++ - list常用接口模拟实现

文章目录 一、模拟list类的框架二、函数接口实现1、迭代器接口2、常用删除、插入接口3、常用其他的一些函数接口4、默认成员函数 一、模拟list类的框架 1、使用带哨兵的双向链表实现。 2、链表结点&#xff1a; // List的结点类 template<class T> struct ListNode {Li…

Docker之路(三)docker安装nginx实现对springboot项目的负载均衡

Docker之路&#xff08;三&#xff09;dockernginxspringboot负载均衡 前言&#xff1a;一、安装docker二、安装nginx三、准备好我们的springboot项目四、将springboot项目分别build成docker镜像五、配置nginx并且启动六、nginx的负载均衡策略七、nginx的常用属性八、总结 前言…

Android WebView上传文件/自定义弹窗技术,附件的解决方案

安卓内核开发 其实是Android的webview默认是不支持<input type"file"/>文件上传的。现在的前端页面需要处理的是&#xff1a; 权限 文件路径AndroidManifest.xml <uses-permission android:name"android.permission.WRITE_EXTERNAL_STORAGE"/&g…

计算机网络ppt和课后题总结(上)

试在下列条件下比较电路交换和分组交换。要传送的报文共 x(bit)。从源点到终点共经过 k 段链路&#xff0c;每段链路的传播时延为 d(s)&#xff0c;数据率为 b(b/s)。在电路交换时电路的建立时间为 s(s)。在分组交换时分组长度为 p(bit)&#xff0c;且各结点的排队等待时间可忽…

数据觉醒时代,以“存力”激活数据资产潜能

近日&#xff0c;质汇“杨数浦”主题研讨会首场活动在杨浦滨江举行&#xff0c;是杨浦区筹推进数字经济与城市数字化发展的一大重要举措&#xff0c;各行业协会、科研院所及企业代表参加活动&#xff0c;共商行业发展新机遇。活动现场&#xff0c;优刻得董事长兼CEO季昕华被授予…

Mysql的两种安装方式

文章目录 第一种安装方式国内镜像库下载解压安装配置环境变量初始化数据库安装mysql登录mysql设置root密码退出登录假如忘记了密码&#xff0c;重置密码的步骤1、步骤一&#xff1a;停止 MySQL 服务2、步骤二&#xff1a;使用安全模式启动 MySQL3、步骤三&#xff1a;重置密码4…

大数据之Schedule调度错误(一)

当我们在利用ooize发起整个任务的调度过程中,如果多个调度任务同时运行并且多个调度任务操作了相同的表,那么就会出现如下的错误关系: Invalid path hdfs://iZh5w01l7f8lnog055cpXXX:8000/user/admin/xxx: No files matching path hdfs://iZh5w01l7f8lnog055cpXXX:8000/user/ad…

线性表、单循环链表学习

背景&#xff1a; 单循环链表是一种链表结构&#xff0c;其中最后一个节点指向第一个节点&#xff0c;从而形成一个环。 实现单循环链表通常涉及节点定义、插入节点、删除节点以及遍历链表等操作。以下是如何在Python中实现单循环链表的示例。 单循环链表的实现 1. 节点类 …

掌握ChatGPT的正确打开方式

引言 随着人工智能技术的飞速发展&#xff0c;自然语言处理&#xff08;NLP&#xff09;领域取得了显著的突破。其中&#xff0c;聊天生成预训练变换器&#xff08;ChatGPT&#xff09;作为一种新型的对话式AI模型&#xff0c;引起了广泛关注。本文将详细介绍ChatGPT的正确使用…

使用html2canvas和jspdf导出pdf包含跨页以及页脚

首先要下载两个文件&#xff0c;一个为html2canvas.min.js&#xff0c;另一个是jspdf.umd.min.js这两个文件分别下载的地址我也附录上&#xff0c;都在官网git&#xff1a; html2canvas.min.js: https://html2canvas.hertzen.com/dist/html2canvas.min.js jspdf.umd.min.js: …

vue-pdf 部分中文显示错误,第二次打开是空白,解决方法

首先鸣谢 1. https://blog.csdn.net/m0_71537867/article/details/131614868?spm1001.2014.3001.5506 2. https://blog.csdn.net/weixin_43763952/article/details/133769647 3. https://github.com/FranckFreiburger/vue-pdf/issues/229 4. https://blog.csdn.net/weixin_449…