imtoken钱包20下载|token是什么意思怎么处理

作者: imtoken钱包20下载
2024-03-16 19:01:15

用户身份验证的令牌——Token - 知乎

用户身份验证的令牌——Token - 知乎首发于人工智能大数据学习交流切换模式写文章登录/注册用户身份验证的令牌——Token企通查北京奥德塔数据科技有限公司Token是什么?所谓的Token,其实就是服务端生成的一串加密字符串、以作客户端进行请求的一个“令牌”。当用户第一次使用账号密码成功进行登录后,服务器便生成一个Token及Token失效时间并将此返回给客户端,若成功登陆,以后客户端只需在有效时间内带上这个Token前来请求数据即可,无需再次带上用户名和密码。图:来源于网络拿实际过程举例,当你下载QQ或微信后第一次用账号和密码成功登录后,Token就为我们免去了每次打开应用都要输入账号跟密码的过程。为什么要使用Token?为什么要使用Token?这个问题其实很好回答——因为它能解决问题!当下用户对产品的使用体验要求在逐渐提高,从产品体验方面来讲,Token带来的体验更容易能让用户接受。那么Token都可以解决哪些问题呢?Token具有随机性、不可预测性、时效性、无状态、跨域等特点。 Token完全由应用管理,所以它可以避开同源策略Token可以避免CSRF攻击Token可以是无状态的,可以在多个服务间共享Token是在服务端产生的。如果前端使用用户名/密码向服务端请求认证,服务端认证成功,那么在服务端会返回Token给前端。前端可以在每次请求的时候带上Token证明自己的合法地位。如果这个Token在服务端持久化(比如存入数据库),那它就是一个永久的身份令牌。当然说到这里大家可能会想到,用服务器的session_id存储到cookies中也能做到,为什么非要用Token呢?网上有许多对比Token和session的文章,在此就不再赘述。其实小编觉得,如果是开发web应用的话,用两者都可以,但如果是开发API接口,前后端分离,最好使用Token,因为session+cookies是基于web的,但针对API接口可能会考虑到移动端,app是没有cookies和session的。Token的生命周期1)用户未登录用户执行注册/登录→一旦基础数据校验成功,后端生成Token,并且Token包含此次注册/登录用户的用户名并通过JsonResponse返回给前端→前端拿到返回的Token后,存入浏览器本地存储2)用户每次访问博客页面从本地存储中拿出Token→JS将Token 放入request的Authorization头,发送http请求向后端索要数据→服务器接到前端请求(当前URL加了loging_check,并且请求方法在methods参数中),进行校验→从requestAuthorization头拿出Token→校验→校验不通过,返回前端异常代码/校验通过,正常执行对应的视图函数→前端一旦接到关于Token的异常码,则删除本地存储中的Token,且将用户转至登录界面。如何设置Token的有效期?其实Token作为一个概念模型,开发者完全可以针对自己开发的应用自定义Token,只要能做到不让不法分子钻系统漏洞即可。那么为Token设置有效期还有必要吗?对于这个问题,大家不妨先看两个例子:例1:登录密码登录密码一般要求定期改变密码,以防止泄漏,所以密码是有有效期的。例2:安全证书SSL安全证书都有有效期,目的是为了解决吊销的问题。所以无论是从安全的角度考虑,还是从吊销的角度考虑,Token都需要设有效期。那么,Token的有效期多长合适呢?一般来说,基于系统安全的需要当然需要尽可能的短,但也不能短得离谱:如果在用户正常操作的过程中,Token过期失效要求重新登录,用户体验岂不是很糟糕?为了解决在操作过程不让用户感到Token失效的问题,有一种方案是在服务器端保存Token状态,用户每次操作都会自动刷新(推迟)Token的过期时间。如此操作会存在一个问题,即在前后端分离、单页App等情况下,每秒可能发起多次请求,如果每次都去刷新过期时间会产生非常大的代价,同样地,如果Token的过期时间被持久化到数据库或文件,代价就更大了。所以通常为了提升效率、减少消耗,会把Token的过期时保存在缓存或者内存中。另一种方案是使用RefreshToken,它可以避免频繁的读写操作。这种方案中,服务端无需刷新Token的过期时间,一旦Token过期,就反馈给前端,前端使用RefreshToken申请一个全新Token继续使用。这种方案中,服务端只需要在客户端请求更新Token的时候对RefreshToken的有效性进行一次检查,大大减少了更新有效期的操作,也就避免了频繁读写。当然RefreshToken也是有有效期的,但是这个有效期就可以长一点了。使用 Token 和 Refresh Token 的时序图如下:1)登录 图:来源于网络2)业务请求 图:来源于网络3)Token 过期,刷新 Token 图:来源于网络参考文献:发布于 2021-01-14 10:19tokenWeb 应用HTTP​赞同 91​​7 条评论​分享​喜欢​收藏​申请转载​文章被以下专栏收录人工智能大数据学

什么是token?你是怎么理解token? - 知乎

什么是token?你是怎么理解token? - 知乎切换模式写文章登录/注册什么是token?你是怎么理解token?星光说日常分享丨学习干货丨种草答主1、Token的引入:Token是在客户端频繁向服务端请求数据,服务端频繁的去数据库查询用户名和密码并进行对比,判断用户名和密码正确与否,并作出相应提示,在这样的背景下,Token便应运而生。2、Token的定义:Token是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个Token便将此Token返回给客户端,以后客户端只需带上这个Token前来请求数据即可,无需再次带上用户名和密码。3、使用Token的目的:  Token的目的是为了减轻服务器的压力,减少频繁的查询数据库,使服务器更加健壮。发布于 2021-03-31 23:32客户端token服务端​赞同 34​​2 条评论​分享​喜欢​收藏​申请

你真的懂Token吗? - 知乎

你真的懂Token吗? - 知乎切换模式写文章登录/注册你真的懂Token吗?威客星球重塑用户价值生态,链接人与数据区块链中,有很多关于数字货币的说法,包括「Coin」「Token」「Cash」,是不是傻傻分不清楚?今天威客君就给大家梳理一下关于Token的那些事。什么是Token?Blockchain译为「区块链」,而Token目前最倍接受的翻译就是「通证」,意思是就是「可流通的加密数字权益证明」。事实上,货币即权力,货币即政治,货币权力必须属于国家。所以 Token代什么都容易,就是代货币难,没有国家的授权支持和信用背书,就很难有属于大多数人的共识,所以之前很多人把Token翻译成「代币」只是自欺欺人。事实上Token的本意是“令牌”,是服务端生成的一串字符串,作为客户端进行请求的一个标识。当用户第一次登录后,服务器生成一个token并将此token返回给客户端,以后客户端只需带上这个token前来请求数据即可,无需再次带上用户名和密码。简单Token的组成:Uid(用户唯一的身份标识)+Time(当前时间的时间戳)+Sign(签名,Token的前几位以哈希算法压缩成的一定长度的十六进制加密字符串)。现在我们所说的Token是指基于区块链而生成的Token,之所以被广泛认识,是以太坊及其订立的 ERC20标准。基于这个标准,任何人都可以在以太坊上发行自定义的Token,这个Token可以代表任何权益和价值。敲黑板,划重点:现在用Token来作为代币权益证明进行ICO(之前被广为称道的首次“代币”发行)是一个普遍的做法,但很多以圈钱为目的的项目所进行的ICO其实风险很大。由此我们也认识到,其实现在市面上流行的“加密数字货币”只不过是一种特殊的Token。区块链Token的三个要素a.数字权益证明,也就是说通证必须是以数字形式存在的权益凭证,它必须代表的是一种权利,一种固有和内在的价值b.加密,也就是说通证的真实性、防篡改性、保护隐私等能力,由密码学予以保障c.可流通,也就是说通证必须能够在一个网络中流动,从而随时随地可以验证。其中一部分通证是可以交易、兑换的事实上,通证可以代表一切权益证明,从身份证到学历文凭,从货币到票据,从钥匙、门票到积分、卡券,从股票到债券,人类社会全部权益证明,都可以用通证来代表。Token和Coin的区别Coin,是预埋在系统里面,为系统工作的激励机制。第二,Coin是区块链上面记帐的符号,Coin也成为了一种通用的货币,所有的艾西欧都是以自己发行的Token去换比特币或者去换以太币。Coin没有使用场景,匿名,发行的方法也不同,在某种程度下,也被当做支付工具,比如说日本,认可了比特币。Token是智能合约的产物,有更多的应用场景。实际上目前属于Token的代币远远多于COIN,这要归功于以太坊近些年的成功。但Token的功能往往不只是支付,而是在特定区块链生态中发挥奖励、消耗、等各种功能性。Token的真正价值取决于所属区块链项目应用落地之后所产生的价值(说白了,在项目没有落地之前Token是没有价值的。目前就没有几个区块链项目有实际的应用,所以大多数的Token都是没有价值的。或者换个你更容易接受的说法,你目前持有的大部分Token的价值都仅仅是基于他们的潜力!几年后项目落地了价值水涨船高,但更大的概率是彻底归零!目前最有价值的Token,自然是Eth。一个优秀的Token在获得大众的认可后甚至可以担当起Coin的作用。这也就是为什么Eth会成为比特币以外的第二大虚拟货币。Token的分类证券型代币(Security Token)证券型代币是指符合联邦证券法的数字资产。通俗地说,它们是数字资产(代币)与传统金融产品的交汇点——一种改进旧事物的新技术。如果我们把比特币这样的加密货币称之为“可编程货币”,那么证券型代币则可以被称为“可编程所有权”版本的代币,也就是其所有权下的任何资产都可以并将被代币化(包括公开募股和私募股权、债务、不动产等)。实用型代币(Utility Token)也可以称为功能型代币,这种代币为用户提供对产品或服务的访问权。实用型令牌代表的是出于对平台或者底层协议的一种访问或者使用权利而购买(排除套利者),使用的是不受监管的众筹模式。资产型代币(Equity Token)资产型代币是基于以太坊智能合约技术,也被看作是最有前途的应用之一。初创公司可以通过ICO发行自己的代币,也可以视作公司的资产权益,这对于初创企业来说是一件好事,因为这样初创公司进入金融市场的门槛将大大降低。这样一来能使得普通投资者更容易通过购买其代币来参与投资,此外,在区块链的透明机制下,投资者能够在公司运行中发挥出更积极的作用。但由于目前缺乏监管,很少有初创公司试图销售这种股权类的代币,法律对其界定很模糊公司一般不敢乱来。然而,特拉华州最近通过了一项法案,历史性地承认使用区块链作为创建和管理企业记录的一种方式,这就使基于区块链的股票交易有了极大的可能性。因此,资产代币在加密金融行业中扮演核心角色可能只是时间问题。看了这么多,课后问题:FCoin代币是Coin还是Token?编辑于 2018-07-13 13:41区块链(Blockchain)比特币 (Bitcoin)​赞同 2​​1 条评论​分享​喜欢​收藏​申请

解读AI大模型,从了解token开始 - 知乎

解读AI大模型,从了解token开始 - 知乎切换模式写文章登录/注册解读AI大模型,从了解token开始AI小智公众号:AI小智解读AI大模型,从了解token开始上次一文中,我基于结合大量示例及可视化的图形手段给大家科普了AI大模型的相关算法和核心概念。但是收到不少非技术背景的小伙伴反馈,相关的算法内容的解释技术性还是太强,很难完全理解。所以这次,题主从最基础的概念“token”着手,跳过了复杂的算法逻辑,这次一定让你建立起对AI大模型工作原理的清晰认知。什么是token?最小的语义单元你可能会好奇,大规模语言模型是如何工作的呢?它们是如何从数据中学习到语言的呢?它们是如何根据输入来生成合理的文本延续的呢?为了回答这些问题,我们需要从最基础的概念开始讲起:token。在自然语言处理(NLP)中,token是指文本中最小的语义单元。比如,一个句子可以被分割成若干个单词,每个单词就是一个token。例如,“I love you”这个句子可以被分割成三个token:“I”,“love”和“you”。token可以帮助我们把文本分解成更容易处理和分析的部分。但是,并不是所有的语言都可以用空格来划分单词。有些语言,比如中文、日语等,没有明显的单词边界。在这种情况下,我们需要用一些更复杂的方法来进行tokenization(分词)。比如,我们可以用一些规则或者统计模型来判断哪些字或者字组合构成了一个有意义的token。例如,“我爱你”这个句子可以被分割成两个token:“我”和“爱你”。当然,这种方法并不完美,有时候会出现错误或者歧义。除了单词之外,还有一些其他的符号也可以被视为token。比如,标点符号、数字、表情符号等等。这些符号也可以传达一些信息或者情感。例如,“I love you!”和“I love you?”就不同于“I love you”,因为感叹号和问号表达了不同的语气和态度。总之,token就是文本中的最小有意义的单位,它们可以帮助我们把文本分解成更容易处理和分析的部分。不同的语言和场景可能需要不同的tokenization方法。接下来,我们要看看GPT系列采用了什么样的token类型?GPT系列采用了什么样的token类型?GPT系列是一系列基于Transformer的生成式预训练模型,它们可以用来生成各种类型的文本。目前,已经有了GPT-2、GPT-3和GPT-4等不同版本的模型,它们的区别主要在于模型的大小、训练数据的规模和质量、以及生成能力的强度。GPT系列的模型都是基于子词(subword)来进行tokenization的。子词是指比单词更小的语言单位,它们可以根据语料库中的词频和共现频率来自动划分。比如,一个单词“transformer”可以被划分成两个子词“trans”和“former”,或者三个子词“t”,“rans”和“former”,或者四个子词“t”,“r”,“ans”和“former”,等等。不同的划分方法会产生不同数量和长度的子词。一般来说,子词越多越短,就越能覆盖更多的语言现象,但也会增加模型的计算复杂度;子词越少越长,就越能减少模型的计算复杂度,但也会损失一些语言信息。GPT系列采用了一种叫做Byte Pair Encoding(BPE)的子词划分方法。BPE是一种基于数据压缩原理的算法,它可以根据语料库中出现频率最高的字节对(byte pair)来合并字节,从而生成新的字节。比如,如果语料库中出现频率最高的字节对是“th”,那么BPE就会把所有的“ns”替换成一个新的字节“Z”,从而减少字节总数。这个过程可以重复进行,直到达到预设的字节总数或者没有更多的字节对可以合并为止。这样,BPE就可以把原始的字节序列转换成一个由新字节组成的子词序列。例如,“obsessiveness”这个单词可以被BPE转换成以下子词序列:原始字节序列:o b s e s s i v e n e s s第一次合并:o b s e Z i v e n e Z (假设Z代表ss)第二次合并:o b s E i v e n E (假设E代表e Z)最终子词序列:o b s E i v e n E(如果没达到预设的字节要求,可合并只出现一次的子词)当然,这只是一个简单的例子,实际上BPE会根据大规模的语料库来生成更多更复杂的子词。GPT系列使用了不同大小的BPE词典来存储所有可能出现的子词。比如,GPT-3使用了50,257个子词。总之,GPT系列采用了基于BPE算法的子词作为token类型,主要目的是以无损的方式压缩文本的内容,从而以保证语言覆盖度和计算效率之间达到一个平衡。接下来,我们要看看如何用子词来表示和生成文本?如何用子词来表示和生成文本?我们已经知道了GPT系列使用了子词作为token类型,并且通过上文讲述的BPE或其他相关算法我们可以将文本内容转换为由子词组合而成的序列,也就是术语中分词过程。有了子词序列之后,我们就可以用子词来表示和生成文本了吗?答案是否定的。因为语言模型是基于神经网络的,而神经网络只能处理数值数据,而不能处理文本数据。因此,我们还需要做第二件事情:将子词序列转换为数值向量。这里,我们需要介绍两个重要的概念:编码(encoding)和解码(decoding)。编码和解码将子词序列转换为数值向量的过程叫做编码(Encoding),它是语言模型的第二步。编码的目的是将一个个离散且无序的token映射到一个个连续且有序的向量空间中,从而方便语言模型进行计算和学习。比如,我们可以用以下的BPE词典来表示上面的例子:子词数值编码子词数值编码o1i5b2v6s3e7E4n8那么,编码和解码就可以按照以下的规则进行:编码:根据BPE算法,将文本分割成最长的匹配子词,然后根据BPE词典,将每个子词替换成其对应的数值编码,从而得到一个数值向量。比如,“obsessiveness”这个单词可以被编码为[1, 2, 3, 4, 5,6,7,8,4]这个数值向量。解码:根据BPE词典,将每个数值编码替换成其对应的子词,然后根据BPE算法,将相邻的子词合并成最长的匹配单词,从而得到一个文本。比如,[1, 2, 3, 4, 5,6,7,8,4]这个数值向量可以被解码为“obsessiveness”这个单词。通过编码和解码,我们就可以实现文本和子词序列向量之间的互相转换。但是,这还不够。我们还需要让GPT系列能够理解和生成这些子词序列。为了做到这一点,我们还需要进行另外两个步骤:嵌入(embedding)和预测(prediction)。嵌入和预测我们已经知道,子词分词和编解码,可以把文本转换成数字,就像我们用数字来表示电话号码一样。但是,这样的数字只是一种编码方式,它们并不能告诉我们子词之间有什么关系。比如,我们怎么知道“猫”和“狗”是两种动物,而“猫”和“桌子”是不同的东西呢?为了让GPT系列能够理解子词之间的关系,我们需要进行嵌入(embedding)。嵌入就是把每个子词用一个特征向量来表示,这个特征向量可以反映出子词的含义、用法、情感等方面的信息。特征向量的计算算法比较复杂,但计算原理比较容易理解,GPT只需要基于互联网上大量的文本资料,统计出两个词语在相邻/句子/文章中共同出现的概率并通过权重来汇总计算,就能分析出某个词语与另外一个词语的亲密度的数值,并将这个数值作为特征向量来描述这个词语。 比如,“猫”在互联网的资料中与“动物”等词语一同出现的次数多,所以“猫”的特征向量可能包含了它是一种动物、有毛发、喜欢吃鱼、会发出喵喵声等信息。通过嵌入,我们就可以把每个子词看作是高维空间中的一个点,而这些点之间的距离和方向,就可以表示出子词之间的相似度和差异度。比如,“猫”和“狗”的点因为同为宠物,可能会比较接近,相对“狗”而言,“猫”和“牛”的点可能会比较远离。在完成嵌入后,我们就可以进行预测(prediction)。预测就是根据给定的文本,计算出下一个子词出现的概率。比如,如果给定的文本是“我家有一只”,那么下一个子词可能是“猫”或者“狗”,而不太可能是“桌子”或者“电视”。这个概率的计算,就是基于特征向量表进行的。 通过嵌入和预测,我们就可以实现从数字到文本,或者从文本到数字的转换。但是,这还不够。我们还需要让GPT系列能够根据给定的文本来生成新的文本。为了做到这一点,我们还需要进行最后一个步骤:生成(generation)。生成与自回归生成是指根据给定的文本来生成新的文本的过程。生成可以分为两种模式:自回归(autoregressive)和自编码(autoencoding),GPT系列主要采用了自回归模式。那么什么是自回归?简单理解就是想象这么一副画面:一个人在拍连环画,每一页连环画都是前一张连环画的延续。也就是说,人需要看前一张画乃至前多张画才能知道该画什么内容。类似地,自回归模型中的每个时间点都需要前一个时间点的信息才能计算出当前时间点的输出值。就像拍连环画一样,自回归模型中各个时间点之间存在着紧密的联系和依赖关系,这种联系在预测时间序列数据时非常有用。 例如,“I love you”这个句子可以被GPT系列生成为以下的文本:I love you more than anything in the world.I love you and I miss you so much.I love you, but I can't be with you.总之,GPT系列使用了子词、数值向量、实数向量和Transformer模型来表示和生成文本。通过编码、解码、嵌入、预测和生成等步骤,它可以实现从文本到文本的转换。整体过程可以参考GPT官方的示意图,如下: 总结今天,我们学习了GPT系列是如何用子词来表示和生成文本的。我们了解了token相关的概念和文本生成的步骤,通过这些概念和步骤,我们可以理解GPT系列是如何从文本到文本的转换。希望你喜欢今天的AI科普文章,如果你有任何问题或建议,请在评论区留言。谢谢你的阅读和支持! 发布于 2023-11-03 08:31・IP 属地湖北AI技术人工智能​赞同 9​​添加评论​分享​喜欢​收藏​申请

token详解-阿里云开发者社区

token详解-阿里云开发者社区

产品解决方案文档与社区权益中心定价云市场合作伙伴支持与服务了解阿里云联系我们4008013260售前咨询售后服务其他服务我要建议我要投诉备案控制台开发者社区首页探索云世界探索云世界云上快速入门,热门云上应用快速查找了解更多问产品动手实践考认证TIANCHI大赛活动广场活动广场丰富的线上&线下活动,深入探索云世界任务中心做任务,得社区积分和周边高校计划让每位学生受益于普惠算力训练营资深技术专家手把手带教话题畅聊无限,分享你的技术见解开发者评测最真实的开发者用云体验乘风者计划让创作激发创新阿里云MVP遇见技术追梦人直播技术交流,直击现场下载下载海量开发者使用工具、手册,免费下载镜像站极速、全面、稳定、安全的开源镜像技术资料开发手册、白皮书、案例集等实战精华插件为开发者定制的Chrome浏览器插件探索云世界新手上云云上应用构建云上数据管理云上探索人工智能云计算弹性计算无影存储网络倚天云原生容器serverless中间件微服务可观测消息队列数据库关系型数据库NoSQL数据库数据仓库数据管理工具PolarDB开源向量数据库热门Modelscope模型即服务弹性计算云原生数据库物联网云效DevOps龙蜥操作系统平头哥钉钉开放平台大数据大数据计算实时数仓Hologres实时计算FlinkE-MapReduceDataWorksElasticsearch机器学习平台PAI智能搜索推荐人工智能机器学习平台PAI视觉智能开放平台智能语音交互自然语言处理多模态模型pythonsdk通用模型开发与运维云效DevOps钉钉宜搭支持服务镜像站码上公益

开发者社区

安全

文章

正文

token详解

2023-07-28

1777

版权

版权声明:

本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《

阿里云开发者社区用户服务协议》和

《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写

侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

简介:

token详解

王卫

目录

热门文章

最新文章

为什么选择阿里云什么是云计算全球基础设施技术领先稳定可靠安全合规分析师报告产品和定价全部产品免费试用产品动态产品定价价格计算器云上成本管理解决方案技术解决方案文档与社区文档开发者社区天池大赛培训与认证权益中心免费试用高校计划企业扶持计划推荐返现计划支持与服务基础服务企业增值服务迁云服务官网公告健康看板信任中心关注阿里云关注阿里云公众号或下载阿里云APP,关注云资讯,随时随地运维管控云服务联系我们:4008013260法律声明Cookies政策廉正举报安全举报联系我们加入我们阿里巴巴集团淘宝网天猫全球速卖通阿里巴巴国际交易市场1688阿里妈妈飞猪阿里云计算AliOS万网高德UC友盟优酷钉钉支付宝达摩院淘宝海外阿里云盘饿了么© 2009-2024 Aliyun.com 版权所有 增值电信业务经营许可证: 浙B2-20080101 域名注册服务机构许可: 浙D3-20210002 京D3-20220015浙公网安备 33010602009975号浙B2-20080101-4

在机器学习领域“token”到底是什么意思? - 知乎

在机器学习领域“token”到底是什么意思? - 知乎首发于AIGC 相关知识切换模式写文章登录/注册在机器学习领域“token”到底是什么意思?7号床​信息技术行业 CEOToken 词元在机器学习领域、NLP领域、文生图等领域,机器读懂词汇和语句是通过 Token 来进行的。尽管在许多领域中都有“Token”这个字符被使用,在不同领域被翻译成代币、象征、标志、表示、信物、标记等等意思。但是在人工智能 AIGC 领域,通常是指“词元”,它是语言类模型中用数字来表示单词的最小语义单位。在提示词文本发送给神经网络之前,Tokenizer 将组合词、句子、段落、文章这类型的长文本分解为最小单位的 Token 词元,然后再通过 Embedding 的方式把 token 转化为向量表示的数据结构,最后输入给神经网络。比如图中这句话“This is a input text.” 首先被 Tokenizer 转化成最小词元,其中[CLS][SEP]为一句话的起始与结束符号,然后再通过 Embedding 的方式转化为向量。(CLS:classification 告知系统这是句子级别的分类的开始、SEP:separator 告知系统结束本句或分割下一句)一句话“This is a input text.” 首先被 Tokenizer 转化成最小词元,然后再通过 Embedding 的方式转化为向量Token 是最小单位的“词元”,或者说单词的“片段”,就是不可再拆分的最小语义单位,比如 “waterfall”,会被拆成2个 token:water、fall。另外,标点符号也会被分解为 token,因为标点符号也影响了对全文的语义理解。比如“I don‘t know.”可以分解为5个Token,他们是:“ I ”、“don”、“ ‘t” 、“know”、“.”。在 Stable Diffusion 中默认的提示词输入最大量为不超过75个,这里的75指的就是Token 数,而不是75个单词。所以,经常会发生你输入的单词数字没有到达75个时,Token 就已经超过75个了。因为标点符号、复合词等等都会被解读为 Token(当然,现在无需担心在 Stable Diffusion WebUI 的提示词输入框中输入超过75个 Token 的问题,因为它可以通过分段输入的方式来进行了,但是75个 token 这一个概念大家应该明白)。Stable Diffusion WebUI 的提示词输入框初步限定为 75 个 token一大堆提示词,或一句话最终都被拆解为哪些 token 呢?大家可以通过 AUTOMATIC1111 提供的 Stable Diffusion WebUI 扩展插件 tokenizer 来查看,建议安装。(https://github.com/AUTOMATIC1111/stable-diffusion-webui-tokenizer),这个扩展插件可以直接在 Extensions 标签下搜索安装。我将一直本着让非专业人士也能看懂的讲解,尽量以比喻和通俗易懂的图表等方式来描述技术术语的原则。这同样是本着 AI 将人类知识壁垒大幅度降低门槛好让更多的普通人都能够涉足专业领域的宗旨,比如 Stable Diffusion 模型让一个从没有学过 PS 却有着超强艺术细胞和创造力的广场舞大妈都能绘出顶级的 CG 作品,而他们却因为年轻时的某些原因错过了走入专业领域的机会,或许是出身、或许是经济条件、或许是其他的命运所致。查询资料、分析、组织、撰写…工作不易,请多多支持我。转载请注明出处,将万分感谢。编辑于 2023-11-23 11:14・IP 属地北京tokenNLP​赞同 48​​5 条评论​分享​喜欢​收藏​申请转载​文章被以下专栏收录AIGC 相关知识用普通人能看懂的文字来解读AIGC领域的相关技术Stable DiffusionAIGC之Stable Diffus

入门区块链,你不可不知的“Token” - 知乎

入门区块链,你不可不知的“Token” - 知乎切换模式写文章登录/注册入门区块链,你不可不知的“Token”币侠1.什么是Token?Token本是一个计算机安全术语,是计算机身份认证中“令牌” 的意思,随着ICO和区块链的大火,Token也变得广为人知。在数字经济的语境中,Token类似于区块链生态里用于流通的货币,也就是代币。比如,我们平时所说的比特币、以太坊就是Token。虽然被称为代币,也类似于货币,但是从Token这个词的本义以及具体内容来看,其本质上是一段代码,并不是货币。Token由区块链的分布式记账技术确保一段代码的唯一性,在发布此Token的组织的生态圈内部流通,像是一个个令牌或者门禁卡,可以打开或关闭一个个大门(智能合约)。发行Token的这个组织想要建立的生态圈,或者说虚拟王国的内部,有着很多的关卡和大门,这些都需要令牌才能打开或者关闭,但是令牌的数量是一定的。在只有三五个人想要令牌,某组织却发放了几千万甚至几千亿个令牌的时候,每个人都可以轻易获得无数的令牌,令牌当然就不值钱了。因此,8年前,程序员LaszloHanyecz用了1万个比特币只能买到2个披萨。但是,一旦人们觉得这个组织想要建立的虚拟王国大有可为,也想要获得一部分令牌以备将来进入王国之需的时候,而令牌的数量却不会增长,受供求关系的影响,自然而然地,令牌的价值就提高了。由此,比特币从一文不名到最高时价值2万美元。于是,8年后,程序员LaszloHanyecz再买两个披萨就只需要花费0.00649个比特币。像是游戏币可以用来购买各种游戏道具一样,Token也可以用来“支付”其王国内的各种服务,从这种角度来看,将其称为代币更加形象一点。另外值得注意的是,Token有其天然的内在价值,并且可交易,这让Token有了价格。通常情况下,Token一经发行,便严格按照区块链代码执行,不受个人或机构控制的。比特币、以太坊、瑞波币、莱特币、以太坊经典是当前市值排名前五的Token。2.Token的产生比特币是早发行的一种Token,比特币背后的区块链是一个记录了比特币产生和交易的账本,且交易不需要任何人担保即可完成。比特币的成功经验,推动了更多Token的产生。目前,新的Token主要通过以下几种方式生成:1)通过改写现有的比特币代码,可以分叉出新的区块链而产生的Token。著名的莱特币,最开始只是简单地调整了比特币的代码。而其他的Token,例如Zcash、Dash和Monero等,则在隐私保护方面进行了创新。所有的这些Token都发起了自己的区块链,和原有的比特币区块链完全分离。2)通过编写全新的区块链而产生的Token。这当中最成功的例子就是以太坊。以太坊受到比特币的启发,从底层设计了新的区块链并且使区块链变得可编程,给区块链带来了新的功能。伴随着这条区块链的产生Token就是Ether,至今,已经上涨了40倍。3.Token的发行首次币发行(ICO),这也是个不陌生的概念,往往跟IPO联想起来,但事实上,二者并不一样,ICO只是对令牌进行预售,令牌可以在将来的虚拟王国中使用,并不涉及到对未来收益的分配。随着数字货币转账在世界范围内的普及,Token发行已经成为了全球关注的大事。除了中国外,区块链项目还在美国、欧洲、日本等地区得到了广泛的关注。如果有个新开的银行账户在几分钟内接到来自世界各地的几千笔汇款,涉及数百万美元,这个账户很可能就会被冻结,但使用数字货币就不会出现这样的情况。互联网和区块链技术使得Token的发售成了一个全球性的行为。Token一旦发行交易后就有了价格,而价格会随着市场波动,这也是它和股权的一大区别。投资者手里的股权可能要等10年之后才能退出变现,但Token在10分钟内就能变现。当前Token在法律和技术上还面临一些未解决的问题。2017年9月4日,央行联合中央网信办、工业和信息化部、工商总局、银监会、证监会以及保监会发布《关于防范代币发行融资风险的公告》(以下简称《公告》),明确表示,发行代币形式包括首次代币发行(ICO)进行融资的活动本质上是一种未经批准非法公开融资的行为,要立即停止各类代币发行融资活动,对于已完成代币发行融资的组织和个人应当做出清退等安排。4. Token带来的改变Token可以在互联网上向合格的投资人发售,因此创业者不必再像以前一样,跑去VC的办公室或者创业咖啡厅进行融资,而可以直接发行Token在全网公开融资。互联网诞生之初,就秉承着开源的精神,然而这些早期的参与者并没有得到太多实际的利益,反而是Google、阿里、腾讯这样的大公司赚得盆满钵满。Token的出现可以使得项目的早期开发人员得到经济上的回报。不过,从Token的本质上来说,它需要找到的是那些将来会真正使用到产品的用户,但事实上,实际的购买者却大多数并不是将来的用户,而是一群试图通过持有代币找人接盘赚取差价的人。这些人的存在,的确使得项目开发人员更容易地获得了经济上的回报,但也阻碍了Token去寻找真正的用户。当Token在这些炒币者的手中迅速拉高价位时,也预示着一个真实有需要的应用可能变成了击鼓传花的游戏,问题在于,花落谁家?更多区块链干货知识,炒币行情,请关注薇信公众号: 币侠(ID:zongcuang666)领取代币奖励编辑于 2018-03-04 16:04区块链(Blockchain)比特币 (Bitcoin)虚拟货币​赞同 41​​1 条评论​分享​喜欢​收藏​申请

解读AI大模型,从了解token开始 - 知乎

解读AI大模型,从了解token开始 - 知乎切换模式写文章登录/注册解读AI大模型,从了解token开始AI小智公众号:AI小智解读AI大模型,从了解token开始上次一文中,我基于结合大量示例及可视化的图形手段给大家科普了AI大模型的相关算法和核心概念。但是收到不少非技术背景的小伙伴反馈,相关的算法内容的解释技术性还是太强,很难完全理解。所以这次,题主从最基础的概念“token”着手,跳过了复杂的算法逻辑,这次一定让你建立起对AI大模型工作原理的清晰认知。什么是token?最小的语义单元你可能会好奇,大规模语言模型是如何工作的呢?它们是如何从数据中学习到语言的呢?它们是如何根据输入来生成合理的文本延续的呢?为了回答这些问题,我们需要从最基础的概念开始讲起:token。在自然语言处理(NLP)中,token是指文本中最小的语义单元。比如,一个句子可以被分割成若干个单词,每个单词就是一个token。例如,“I love you”这个句子可以被分割成三个token:“I”,“love”和“you”。token可以帮助我们把文本分解成更容易处理和分析的部分。但是,并不是所有的语言都可以用空格来划分单词。有些语言,比如中文、日语等,没有明显的单词边界。在这种情况下,我们需要用一些更复杂的方法来进行tokenization(分词)。比如,我们可以用一些规则或者统计模型来判断哪些字或者字组合构成了一个有意义的token。例如,“我爱你”这个句子可以被分割成两个token:“我”和“爱你”。当然,这种方法并不完美,有时候会出现错误或者歧义。除了单词之外,还有一些其他的符号也可以被视为token。比如,标点符号、数字、表情符号等等。这些符号也可以传达一些信息或者情感。例如,“I love you!”和“I love you?”就不同于“I love you”,因为感叹号和问号表达了不同的语气和态度。总之,token就是文本中的最小有意义的单位,它们可以帮助我们把文本分解成更容易处理和分析的部分。不同的语言和场景可能需要不同的tokenization方法。接下来,我们要看看GPT系列采用了什么样的token类型?GPT系列采用了什么样的token类型?GPT系列是一系列基于Transformer的生成式预训练模型,它们可以用来生成各种类型的文本。目前,已经有了GPT-2、GPT-3和GPT-4等不同版本的模型,它们的区别主要在于模型的大小、训练数据的规模和质量、以及生成能力的强度。GPT系列的模型都是基于子词(subword)来进行tokenization的。子词是指比单词更小的语言单位,它们可以根据语料库中的词频和共现频率来自动划分。比如,一个单词“transformer”可以被划分成两个子词“trans”和“former”,或者三个子词“t”,“rans”和“former”,或者四个子词“t”,“r”,“ans”和“former”,等等。不同的划分方法会产生不同数量和长度的子词。一般来说,子词越多越短,就越能覆盖更多的语言现象,但也会增加模型的计算复杂度;子词越少越长,就越能减少模型的计算复杂度,但也会损失一些语言信息。GPT系列采用了一种叫做Byte Pair Encoding(BPE)的子词划分方法。BPE是一种基于数据压缩原理的算法,它可以根据语料库中出现频率最高的字节对(byte pair)来合并字节,从而生成新的字节。比如,如果语料库中出现频率最高的字节对是“th”,那么BPE就会把所有的“ns”替换成一个新的字节“Z”,从而减少字节总数。这个过程可以重复进行,直到达到预设的字节总数或者没有更多的字节对可以合并为止。这样,BPE就可以把原始的字节序列转换成一个由新字节组成的子词序列。例如,“obsessiveness”这个单词可以被BPE转换成以下子词序列:原始字节序列:o b s e s s i v e n e s s第一次合并:o b s e Z i v e n e Z (假设Z代表ss)第二次合并:o b s E i v e n E (假设E代表e Z)最终子词序列:o b s E i v e n E(如果没达到预设的字节要求,可合并只出现一次的子词)当然,这只是一个简单的例子,实际上BPE会根据大规模的语料库来生成更多更复杂的子词。GPT系列使用了不同大小的BPE词典来存储所有可能出现的子词。比如,GPT-3使用了50,257个子词。总之,GPT系列采用了基于BPE算法的子词作为token类型,主要目的是以无损的方式压缩文本的内容,从而以保证语言覆盖度和计算效率之间达到一个平衡。接下来,我们要看看如何用子词来表示和生成文本?如何用子词来表示和生成文本?我们已经知道了GPT系列使用了子词作为token类型,并且通过上文讲述的BPE或其他相关算法我们可以将文本内容转换为由子词组合而成的序列,也就是术语中分词过程。有了子词序列之后,我们就可以用子词来表示和生成文本了吗?答案是否定的。因为语言模型是基于神经网络的,而神经网络只能处理数值数据,而不能处理文本数据。因此,我们还需要做第二件事情:将子词序列转换为数值向量。这里,我们需要介绍两个重要的概念:编码(encoding)和解码(decoding)。编码和解码将子词序列转换为数值向量的过程叫做编码(Encoding),它是语言模型的第二步。编码的目的是将一个个离散且无序的token映射到一个个连续且有序的向量空间中,从而方便语言模型进行计算和学习。比如,我们可以用以下的BPE词典来表示上面的例子:子词数值编码子词数值编码o1i5b2v6s3e7E4n8那么,编码和解码就可以按照以下的规则进行:编码:根据BPE算法,将文本分割成最长的匹配子词,然后根据BPE词典,将每个子词替换成其对应的数值编码,从而得到一个数值向量。比如,“obsessiveness”这个单词可以被编码为[1, 2, 3, 4, 5,6,7,8,4]这个数值向量。解码:根据BPE词典,将每个数值编码替换成其对应的子词,然后根据BPE算法,将相邻的子词合并成最长的匹配单词,从而得到一个文本。比如,[1, 2, 3, 4, 5,6,7,8,4]这个数值向量可以被解码为“obsessiveness”这个单词。通过编码和解码,我们就可以实现文本和子词序列向量之间的互相转换。但是,这还不够。我们还需要让GPT系列能够理解和生成这些子词序列。为了做到这一点,我们还需要进行另外两个步骤:嵌入(embedding)和预测(prediction)。嵌入和预测我们已经知道,子词分词和编解码,可以把文本转换成数字,就像我们用数字来表示电话号码一样。但是,这样的数字只是一种编码方式,它们并不能告诉我们子词之间有什么关系。比如,我们怎么知道“猫”和“狗”是两种动物,而“猫”和“桌子”是不同的东西呢?为了让GPT系列能够理解子词之间的关系,我们需要进行嵌入(embedding)。嵌入就是把每个子词用一个特征向量来表示,这个特征向量可以反映出子词的含义、用法、情感等方面的信息。特征向量的计算算法比较复杂,但计算原理比较容易理解,GPT只需要基于互联网上大量的文本资料,统计出两个词语在相邻/句子/文章中共同出现的概率并通过权重来汇总计算,就能分析出某个词语与另外一个词语的亲密度的数值,并将这个数值作为特征向量来描述这个词语。 比如,“猫”在互联网的资料中与“动物”等词语一同出现的次数多,所以“猫”的特征向量可能包含了它是一种动物、有毛发、喜欢吃鱼、会发出喵喵声等信息。通过嵌入,我们就可以把每个子词看作是高维空间中的一个点,而这些点之间的距离和方向,就可以表示出子词之间的相似度和差异度。比如,“猫”和“狗”的点因为同为宠物,可能会比较接近,相对“狗”而言,“猫”和“牛”的点可能会比较远离。在完成嵌入后,我们就可以进行预测(prediction)。预测就是根据给定的文本,计算出下一个子词出现的概率。比如,如果给定的文本是“我家有一只”,那么下一个子词可能是“猫”或者“狗”,而不太可能是“桌子”或者“电视”。这个概率的计算,就是基于特征向量表进行的。 通过嵌入和预测,我们就可以实现从数字到文本,或者从文本到数字的转换。但是,这还不够。我们还需要让GPT系列能够根据给定的文本来生成新的文本。为了做到这一点,我们还需要进行最后一个步骤:生成(generation)。生成与自回归生成是指根据给定的文本来生成新的文本的过程。生成可以分为两种模式:自回归(autoregressive)和自编码(autoencoding),GPT系列主要采用了自回归模式。那么什么是自回归?简单理解就是想象这么一副画面:一个人在拍连环画,每一页连环画都是前一张连环画的延续。也就是说,人需要看前一张画乃至前多张画才能知道该画什么内容。类似地,自回归模型中的每个时间点都需要前一个时间点的信息才能计算出当前时间点的输出值。就像拍连环画一样,自回归模型中各个时间点之间存在着紧密的联系和依赖关系,这种联系在预测时间序列数据时非常有用。 例如,“I love you”这个句子可以被GPT系列生成为以下的文本:I love you more than anything in the world.I love you and I miss you so much.I love you, but I can't be with you.总之,GPT系列使用了子词、数值向量、实数向量和Transformer模型来表示和生成文本。通过编码、解码、嵌入、预测和生成等步骤,它可以实现从文本到文本的转换。整体过程可以参考GPT官方的示意图,如下: 总结今天,我们学习了GPT系列是如何用子词来表示和生成文本的。我们了解了token相关的概念和文本生成的步骤,通过这些概念和步骤,我们可以理解GPT系列是如何从文本到文本的转换。希望你喜欢今天的AI科普文章,如果你有任何问题或建议,请在评论区留言。谢谢你的阅读和支持! 发布于 2023-11-03 08:31・IP 属地湖北AI技术人工智能​赞同 9​​添加评论​分享​喜欢​收藏​申请

什么是Token?ChatGPT 中 Token 的概念解读:理解模型输入的基本单位 - 知乎

什么是Token?ChatGPT 中 Token 的概念解读:理解模型输入的基本单位 - 知乎切换模式写文章登录/注册什么是Token?ChatGPT 中 Token 的概念解读:理解模型输入的基本单位一笑​​辽宁科技大学 控制科学与工程博士在读在自然语言处理领域中,机器学习模型通常以 token 作为其输入单位。对于 ChatGPT 这样的大型语言模型,了解 token 的概念是理解模型工作原理的关键。一、Token是文本中的最小单位Token 可以被理解为文本中的最小单位。在英文中,一个 token 可以是一个单词,也可以是一个标点符号。在中文中,通常以字或词作为 token。ChatGPT 将输入文本拆分成一个个 token,使模型能够对其进行处理和理解。二、词汇表映射方式对于模型而言,token 是一种数字化的表示形式。每个 token 都与一个唯一的数字 ID 相关联,模型通过这些 ID 来区分不同的 token。在训练过程中,模型学习了将文本映射到这些数字 ID 的方法,以便能够对新的文本进行编码和解码。下面是具体过程(不感兴趣可跳过)这个过程可以通过一种称为词汇表(vocabulary)的映射方式实现。词汇表是一个由模型事先建立的映射表,将每个可能的 token 映射到一个唯一的数字 ID。例如,对于英文单词,一个词汇表可能包含诸如 "hello"、"world"、"chat" 等单词,并为每个单词分配一个唯一的数字 ID。当输入文本被拆分成 token 之后,模型会查找每个 token 在词汇表中的对应 ID,并用这些 ID 来表示输入文本。具体来说,拆分文本为 token 的方式可以根据任务和模型的需求而有所不同。一种常见的方式是通过空格或标点符号来分割文本,将每个单词作为一个 token。然而,对于一些语言,如中文,分词是一个更复杂的过程,需要考虑词和字符之间的关系。一旦输入文本被转换为数字 ID 的序列,模型就可以将其作为输入进行处理。这些数字 ID 可以被表示为向量形式,例如使用独热编码(one-hot encoding)或者更常见的词嵌入(word embedding)表示方法。词嵌入将每个 token 表示为一个连续的向量,其中每个维度代表了某种语义特征。在处理 token 时,模型可以通过逐个 token 的方式进行操作,或者通过考虑 token 之间的关系来获取更多的上下文信息。这取决于具体的模型架构和任务要求。总结而言,ChatGPT 将输入文本拆分为 token,并使用词汇表将每个 token 映射为数字 ID。这种表示形式使得模型能够对文本进行处理和理解,并能够通过学习 token 之间的关系来获取更多的语义信息。三、为什么Token有长度限制模型的输入有一个固定的最大长度限制。当输入文本超过这个限制时,必须进行截断或者其他处理方式来适应模型的要求。这就意味着长文本可能会被分割成多个部分,每个部分成为一个 token 序列。模型有长度限制是由于计算资源和内存限制的存在。大型语言模型如 ChatGPT 包含了数亿甚至数十亿个参数,需要大量的计算资源和内存来运行。为了实现高效的训练和推理,模型的输入必须受到限制。限制输入长度有以下几个原因:计算资源:处理长序列需要更多的计算资源和内存。随着输入长度的增加,模型的计算量也随之增加。为了保证模型能够在合理的时间内完成计算,设置一个最大长度限制是必要的。内存限制:模型的内存资源是有限的。将长序列完整地加载到内存中可能会超出可用的内存容量。通过限制输入长度,可以确保模型能够适应内存的限制并有效地进行计算。训练效果:长序列通常会引入更多的噪声和冗余信息,同时增加模型的复杂度。这可能导致训练过程变得更加困难和低效。通过限制输入长度,可以使训练更加集中和高效,有助于提高模型的性能。四、特殊token在处理 token 时,一些特殊的 token 也起着重要的作用。例如,起始 token(start token)和结束 token(end token)用于指示对话或文本的开头和结尾。模型可以通过这些特殊的 token 来生成连贯的输出。此外,还有一些特殊的 token,如填充 token(padding token)和掩码 token(mask token),用于扩展输入序列的长度或在序列中标记不需要进行处理的部分。总结总结起来,token 是机器学习模型在自然语言处理任务中的输入单位。ChatGPT 将文本拆分成 token 序列,并通过数字 ID 来表示每个 token。理解 token 的概念可以帮助我们更好地了解模型如何处理和理解文本输入。希望这篇博客能帮助你更好地理解 ChatGPT 中的 token 概念!如有需要,可以进一步展开讨论和探索这个话题,留言即可。发布于 2023-05-17 17:24・IP 属地日本tokenOpenAIChatGPT​赞同 87​​2 条评论​分享​喜欢​收藏​申请

NLP领域中的token和tokenization到底指的是什么? - 知乎

NLP领域中的token和tokenization到底指的是什么? - 知乎首页知乎知学堂发现等你来答​切换模式登录/注册机器学习自然语言处理语言学NLP领域中的token和tokenization到底指的是什么?这是一个非常简单的基本概念问题,但作为小白,真的不太清晰显示全部 ​关注者268被浏览714,897关注问题​写回答​邀请回答​好问题 22​添加评论​分享​27 个回答默认排序Glan格蓝​武汉大学 工学硕士​ 关注前面都讲了是指什么,我来浅答一下目前大模型时代分词是怎么做的☺️,主要内容为WordPiece,Byte-Pair Encoding (BPE),Byte-level BPE(BBPE)分词方法的原理以及其代码实现,全篇阅读可能需要45分钟,建议收藏~Tokenization(分词) 在自然语言处理(NLP)的任务中是最基本的一步,把文本内容处理为最小基本单元即token(标记,令牌,词元,没有准确的翻译)用于后续的处理,如何把文本处理成token呢?有一系列的方法,基本思想是构建一个词表通过词表一一映射进行分词,但如何构建合适的词表呢?以下以分词粒度为角度进行介绍:1.word(词)粒度在英文语系中,word(词)级别分词实现很简单,因为有天然的分隔符。在中文里面word(词)粒度,需要一些分词工具比如jieba,以下是中文和英文的例子:中文句子:我喜欢看电影和读书。

分词结果:我 | 喜欢 | 看 | 电影 | 和 | 读书。

英文句子:I enjoy watching movies and reading books.

分词结果:I | enjoy | watching | movies | and | reading | books.word(词)粒度的优点有:语义明确:以词为单位进行分词可以更好地保留每个词的语义,使得文本在后续处理中能够更准确地表达含义。上下文理解:以词为粒度进行分词有助于保留词语之间的关联性和上下文信息,从而在语义分析和理解时能够更好地捕捉句子的意图。缺点:长尾效应和稀有词问题: 词表可能变得巨大,包含很多不常见的词汇,增加存储和训练成本,稀有词的训练数据有限,难以获得准确的表示。OOV(Out-of-Vocabulary): 词粒度分词模型只能使用词表中的词来进行处理,无法处理词表之外的词汇,这就是所谓的OOV问题。形态关系和词缀关系: 无法捕捉同一词的不同形态,也无法有效学习词缀在不同词汇之间的共通性,限制了模型的语言理解能力,比如love和loves在word(词)粒度的词表中将会是两个词。2.char(字符)粒度以字符为单位进行分词,即将文本拆分成一个个单独的字符作为最小基本单元,这种字符粒度的分词方法适用于多种语言,无论是英文、中文还是其他不同语言,都能够一致地使用字符粒度进行处理,因为英文就26个字母以及其他的一些符号,中文常见字就6000个左右。中文句子:我喜欢看电影和读书。

分词结果:我 | 喜 | 欢 | 看 | 电 | 影 | 和 | 读 | 书 | 。

英文句子:I enjoy watching movies and reading books.

分词结果:I | | e | n | j | o | y | | w | a | t | c | h | i | n | g | | m | o | v | i | e | s | | a | n | d | | r | e | a | d | i | n | g | | b | o | o | k | s | .char(字符)粒度的优点有:统一处理方式:字符粒度分词方法适用于不同语言,无需针对每种语言设计不同的分词规则或工具,具有通用性。解决OOV问题:由于字符粒度分词可以处理任何字符,无需维护词表,因此可以很好地处理一些新创词汇、专有名词等问题。缺点:语义信息不明确:字符粒度分词无法直接表达词的语义,可能导致在一些语义分析任务中效果较差。处理效率低:由于文本被拆分为字符,处理的粒度较小,增加后续处理的计算成本和时间。3.subword(子词)粒度在很多情况下,既不希望将文本切分成单独的词(太大),也不想将其切分成单个字符(太小),而是希望得到介于词和字符之间的子词单元。这就引入了 subword(子词)粒度的分词方法。在BERT时代,WordPiece 分词方法被广泛应用[1],比如 BERT、DistilBERT等。WordPiece 分词方法是 subword(子词)粒度的一种方法。3.1 WordPieceWordPiece核心思想是将单词拆分成多个前缀符号(比如BERT中的##)最小单元,再通过子词合并规则将最小单元进行合并为子词级别。例如对于单词"word",拆分如下:w ##o ##r ##d然后通过合并规则进行合并,从而循环迭代构建出一个词表,以下是核心步骤:计算初始词表:通过训练语料获得或者最初的英文中26个字母加上各种符号以及常见中文字符,这些作为初始词表。计算合并分数:对训练语料拆分的多个子词单元通过合拼规则计算合并分数。合并分数最高的子词对:选择分数最高的子词对,将它们合并成一个新的子词单元,并更新词表。重复合并步骤:不断重复步骤 2 和步骤 3,直到达到预定的词表大小、合并次数,或者直到不再有有意义的合并(即,进一步合并不会显著提高词表的效益)。分词:使用最终得到的词汇表对文本进行分词。简单举例[1]:我们有以下的训练语料中的样例,括号中第2位为在训练语料中出现的频率:("hug", 10), ("pug", 5), ("pun", 12), ("bun", 4), ("hugs", 5)我们对其进行拆分为带前缀的形式:("h" "##u" "##g", 10), ("p" "##u" "##g", 5), ("p" "##u" "##n", 12), ("b" "##u" "##n", 4), ("h" "##u" "##g" "##s", 5)所以这些样例的初始词表将会是:["b", "h", "p", "##g", "##n", "##s", "##u"]接下来重要的一步进行计算合并分数,也称作互信息(信息论中衡量两个变量之间的关联程度[2]),简单来说就是以下公式来计算score=(freq_of_pair)/(freq_of_first_element×freq_of_second_element)

分数 = 合并pair候选的频率 / (第一个元素的频率 × 第二个元素的频率)对于上述样例中这个pair("##u", "##g")出现的频率是最高的20次,但是"##u"出现的频率是36次, "##g"出现的频率是20次,所以这个pair("##u", "##g")的分数是(20)/(36*20) = 1/36,同理计算这个pair("##g", "##s")的分数为(5)/(20*5) = 1/20,所以最先合并的pair是("##g", "##s")→("##gs")。此时词表和拆分后的的频率将变成以下:Vocabulary: ["b", "h", "p", "##g", "##n", "##s", "##u", "##gs"]

Corpus: ("h" "##u" "##g", 10), ("p" "##u" "##g", 5), ("p" "##u" "##n", 12), ("b" "##u" "##n", 4), ("h" "##u" "##gs", 5)重复上述的操作,直到达到你想要的词表的大小Vocabulary: ["b", "h", "p", "##g", "##n", "##s", "##u", "##gs", "hu", "hug"]

Corpus: ("hug", 10), ("p" "##u" "##g", 5), ("p" "##u" "##n", 12), ("b" "##u" "##n", 4), ("hu" "##gs", 5)代码实现:用一些包含中英文的文本作为训练语料,因为英文有天然的分隔符,所以在这个例子中,中文已经进行了分词:sentences = [

"我",

"喜欢",

"吃",

"苹果",

"他",

"不",

"喜欢",

"吃",

"苹果派",

"I like to eat apples",

"She has a cute cat",

"you are very cute",

"give you a hug",

]统计每个词出现的频率并初始化初始词表:from collections import defaultdict

# 构建频率统计

def build_stats(sentences):

stats = defaultdict(int)

for sentence in sentences:

symbols = sentence.split()

for symbol in symbols:

stats[symbol] += 1

return stats

stats = build_stats(sentences)

print("stats:", stats)

alphabet = []

for word in stats.keys():

if word[0] not in alphabet:

alphabet.append(word[0])

for letter in word[1:]:

if f"##{letter}" not in alphabet:

alphabet.append(f"##{letter}")

alphabet.sort()

# 初始词表

vocab = alphabet.copy()

print("alphabet:", alphabet)

# 结果

stats: defaultdict(, {'我': 1, '喜欢': 2, '吃': 2, '苹果': 1, '他': 1, '不': 1, '苹果派': 1, 'I': 1, 'like': 1, 'to': 1, 'eat': 1, 'apples': 1, 'She': 1, 'has': 1, 'a': 2, 'cute': 2, 'cat': 1, 'you': 2, 'are': 1, 'very': 1, 'give': 1, 'hug': 1})

# 初始词表

alphabet: ['##a', '##e', '##g', '##h', '##i', '##k', '##l', '##o', '##p', '##r', '##s', '##t', '##u', '##v', '##y', '##果', '##欢', '##派', 'I', 'S', 'a', 'c', 'e', 'g', 'h', 'l', 't', 'v', 'y', '不', '他', '吃', '喜', '我', '苹']根据初始词表拆分每个词:splits = {

word: [c if i == 0 else f"##{c}" for i, c in enumerate(word)]

for word in stats.keys()

}

print("splits:", splits)

# 结果

splits: {'我': ['我'], '喜欢': ['喜', '##欢'], '吃': ['吃'], '苹果': ['苹', '##果'], '他': ['他'], '不': ['不'], '苹果派': ['苹', '##果', '##派'], 'I': ['I'], 'like': ['l', '##i', '##k', '##e'], 'to': ['t', '##o'], 'eat': ['e', '##a', '##t'], 'apples': ['a', '##p', '##p', '##l', '##e', '##s'], 'She': ['S', '##h', '##e'], 'has': ['h', '##a', '##s'], 'a': ['a'], 'cute': ['c', '##u', '##t', '##e'], 'cat': ['c', '##a', '##t'], 'you': ['y', '##o', '##u'], 'are': ['a', '##r', '##e'], 'very': ['v', '##e', '##r', '##y'], 'give': ['g', '##i', '##v', '##e'], 'hug': ['h', '##u', '##g']}根据上述提到的计算互信息的分数公式进行计算:def compute_pair_scores(splits):

letter_freqs = defaultdict(int)

pair_freqs = defaultdict(int)

for word, freq in stats.items():

split = splits[word]

if len(split) == 1:

letter_freqs[split[0]] += freq

continue

for i in range(len(split) - 1):

pair = (split[i], split[i + 1])

letter_freqs[split[i]] += freq

pair_freqs[pair] += freq

letter_freqs[split[-1]] += freq

scores = {

pair: freq / (letter_freqs[pair[0]] * letter_freqs[pair[1]])

for pair, freq in pair_freqs.items()

}

return scores

pair_scores = compute_pair_scores(splits)

for i, key in enumerate(pair_scores.keys()):

print(f"{key}: {pair_scores[key]}")

if i >= 5:

break一些结果:('喜', '##欢'): 0.5

('苹', '##果'): 0.5

('##果', '##派'): 0.5

('l', '##i'): 0.5

('##i', '##k'): 0.5

('##k', '##e'): 0.125我们需要的是将分数最高的进行合并然后开始循环迭代,看一看分数最高的pair(子词对):best_pair = ""

max_score = None

for pair, score in pair_scores.items():

if max_score is None or max_score < score:

best_pair = pair

max_score = score

print(best_pair, max_score)

# 结果

('S', '##h') 1.0结果为('S', '##h') 1.0,所以最先合成的就是('S', '##h')→'##Sh',合并的函数如下:def merge_pair(a, b, splits):

for word in stats:

split = splits[word]

if len(split) == 1:

continue

i = 0

while i < len(split) - 1:

if split[i] == a and split[i + 1] == b:

merge = a + b[2:] if b.startswith("##") else a + b

split = split[:i] + [merge] + split[i + 2 :]

else:

i += 1

splits[word] = split

return splits最后就是一直进行循环迭代,直到vocab达到了我们想要的数量vocab_size = 50

while len(vocab) < vocab_size:

scores = compute_pair_scores(splits)

best_pair, max_score = "", None

for pair, score in scores.items():

if max_score is None or max_score < score:

best_pair = pair

max_score = score

splits = merge_pair(*best_pair, splits)

new_token = (

best_pair[0] + best_pair[1][2:]

if best_pair[1].startswith("##")

else best_pair[0] + best_pair[1]

)

vocab.append(new_token)

print("vocab:", vocab)

# 结果

vocab: ['##a', '##e', '##g', '##h', '##i', '##k', '##l', '##o', '##p', '##r', '##s', '##t', '##u', '##v', '##y', '##果', '##欢', '##派', 'I', 'S', 'a', 'c', 'e', 'g', 'h', 'l', 't', 'v', 'y', '不', '他', '吃', '喜', '我', '苹', 'Sh', '喜欢', '苹果', '苹果派', 'li', 'lik', 'gi', 'giv', '##pl', '##ppl', '##ry', 'to', 'yo', 'ea', 'eat']上述就是WordPiece分词方法的代码实现,一般来说最后会在词表中加上一些特殊词汇,以及英文中26个字母加上各种符号以及常见中文字符,不过如果训练语料比较大以及词表比较大那这些应该也是已经包括了,只需要添加特殊词汇:all_vocab = vocab + ["[PAD]", "[UNK]", "[CLS]", "[SEP]", "[MASK]"] + other_alphabet在大语言模型时代,最常用的分词方法是Byte-Pair Encoding (BPE)和Byte-level BPE(BBPE),Byte-Pair Encoding (BPE)最初是一种文本压缩算法在15年被引入到NLP用于分词[3],在训练 GPT 时被 OpenAI 用于tokenization,后续好多模型GPT,RoBERTa等都采用了这种分词方法。Byte-level BPE(BBPE)是于19年在BPE的基础上提出以Byte-level(字节)为粒度的分词方法[4],目前 GPT2,BLOOM,Llama,Falcon等采用的是该分词方法。3.2 Byte-Pair Encoding (BPE)Byte-Pair Encoding (BPE)核心思想是逐步合并出现频率最高的子词对而不是像Wordpiece计算合并分数,从而构建出一个词汇表,以下是核心步骤:计算初始词表:通过训练语料获得或者最初的英文中26个字母加上各种符号以及常见中文字符,这些作为初始词表。构建频率统计:统计所有子词单元对(两个连续的子词)在文本中的出现频率。合并频率最高的子词对:选择出现频率最高的子词对,将它们合并成一个新的子词单元,并更新词汇表。重复合并步骤:不断重复步骤 2 和步骤 3,直到达到预定的词汇表大小、合并次数,或者直到不再有有意义的合并(即,进一步合并不会显著提高词汇表的效益)。分词:使用最终得到的词汇表对文本进行分词。简单的代码实现[5]:用一些包含中英文的文本作为训练语料和上面相同,因为英文有天然的分隔符,所以在这个例子中,中文已经进行了分词:sentences = [

"我",

"喜欢",

"吃",

"苹果",

"他",

"不",

"喜欢",

"吃",

"苹果派",

"I like to eat apples",

"She has a cute cat",

"you are very cute",

"give you a hug",

]统计每个词出现的频率并初始化初始词表:# 构建频率统计

def build_stats(sentences):

stats = defaultdict(int)

for sentence in sentences:

symbols = sentence.split()

for symbol in symbols:

stats[symbol] += 1

return stats

stats = build_stats(sentences)

print("stats:", stats)

alphabet = []

for word in stats.keys():

for letter in word:

if letter not in alphabet:

alphabet.append(letter)

alphabet.sort()

# 初始词表

vocab = alphabet.copy()

print("alphabet:", alphabet)

# 结果

stats: defaultdict(, {'我': 1, '喜欢': 2, '吃': 2, '苹果': 1, '他': 1, '不': 1, '苹果派': 1, 'I': 1, 'like': 1, 'to': 1, 'eat': 1, 'apples': 1, 'She': 1, 'has': 1, 'a': 2, 'cute': 2, 'cat': 1, 'you': 2, 'are': 1, 'very': 1, 'give': 1, 'hug': 1})

# 初始词表

alphabet: ['I', 'S', 'a', 'c', 'e', 'g', 'h', 'i', 'k', 'l', 'o', 'p', 'r', 's', 't', 'u', 'v', 'y', '不', '他', '吃', '喜', '我', '果', '欢', '派', '苹']根据初始词表拆分每个词,计算左右pair(子词对)出现的频率splits = {word: [c for c in word] for word in stats.keys()}

print("splits:", splits)

def compute_pair_freqs(splits):

pair_freqs = defaultdict(int)

for word, freq in stats.items():

split = splits[word]

if len(split) == 1:

continue

for i in range(len(split) - 1):

pair = (split[i], split[i + 1])

pair_freqs[pair] += freq

return pair_freqs

pair_freqs = compute_pair_freqs(splits)

for i, key in enumerate(pair_freqs.keys()):

print(f"{key}: {pair_freqs[key]}")

if i >= 5:

break

# 结果

splits: {'我': ['我'], '喜欢': ['喜', '欢'], '吃': ['吃'], '苹果': ['苹', '果'], '他': ['他'], '不': ['不'], '苹果派': ['苹', '果', '派'], 'I': ['I'], 'like': ['l', 'i', 'k', 'e'], 'to': ['t', 'o'], 'eat': ['e', 'a', 't'], 'apples': ['a', 'p', 'p', 'l', 'e', 's'], 'She': ['S', 'h', 'e'], 'has': ['h', 'a', 's'], 'a': ['a'], 'cute': ['c', 'u', 't', 'e'], 'cat': ['c', 'a', 't'], 'you': ['y', 'o', 'u'], 'are': ['a', 'r', 'e'], 'very': ['v', 'e', 'r', 'y'], 'give': ['g', 'i', 'v', 'e'], 'hug': ['h', 'u', 'g']}

('喜', '欢'): 2

('苹', '果'): 2

('果', '派'): 1

('l', 'i'): 1

('i', 'k'): 1

('k', 'e'): 1然后开始循环迭代找到出现频率最高的pair(子词对):best_pair = ""

max_freq = None

for pair, freq in pair_freqs.items():

if max_freq is None or max_freq < freq:

best_pair = pair

max_freq = freq

print(best_pair, max_freq)结果为【('喜', '欢') 2】,所以最先合成的就是('喜', '欢')→'喜欢',然后合并的函数如下:def merge_pair(a, b, splits):

for word in stats:

split = splits[word]

if len(split) == 1:

continue

i = 0

while i < len(split) - 1:

if split[i] == a and split[i + 1] == b:

split = split[:i] + [a + b] + split[i + 2 :]

else:

i += 1

splits[word] = split

return splits最后就是一直进行循环直到vocab达到了我们想要的数量:# 假设我们想要的词典为50

merges = {}

vocab_size = 50

while len(vocab) < vocab_size:

pair_freqs = compute_pair_freqs(splits)

best_pair = ""

max_freq = None

for pair, freq in pair_freqs.items():

if max_freq is None or max_freq < freq:

best_pair = pair

max_freq = freq

splits = merge_pair(*best_pair, splits)

merges[best_pair] = best_pair[0] + best_pair[1]

vocab.append(best_pair[0] + best_pair[1])

print("merges:", merges)

print("vocab:", vocab)

# 结果

merges: {('喜', '欢'): '喜欢', ('苹', '果'): '苹果', ('a', 't'): 'at', ('c', 'u'): 'cu', ('cu', 't'): 'cut', ('cut', 'e'): 'cute', ('y', 'o'): 'yo', ('yo', 'u'): 'you', ('v', 'e'): 've', ('苹果', '派'): '苹果派', ('l', 'i'): 'li', ('li', 'k'): 'lik', ('lik', 'e'): 'like', ('t', 'o'): 'to', ('e', 'at'): 'eat', ('a', 'p'): 'ap', ('ap', 'p'): 'app', ('app', 'l'): 'appl', ('appl', 'e'): 'apple', ('apple', 's'): 'apples', ('S', 'h'): 'Sh', ('Sh', 'e'): 'She', ('h', 'a'): 'ha'}

vocab: ['I', 'S', 'a', 'c', 'e', 'g', 'h', 'i', 'k', 'l', 'o', 'p', 'r', 's', 't', 'u', 'v', 'y', '不', '他', '吃', '喜', '我', '果', '欢', '派', '苹', '喜欢', '苹果', 'at', 'cu', 'cut', 'cute', 'yo', 'you', 've', '苹果派', 'li', 'lik', 'like', 'to', 'eat', 'ap', 'app', 'appl', 'apple', 'apples', 'Sh', 'She', 'ha']再加上一些特殊词汇和其他词汇:all_vocab = vocab + ["[PAD]", "[UNK]", "[BOS]", "[EOS]"] + other_alphabet上述就是BPE的代码实现,BPE理论上还是会出现OOV的,当词汇表的大小受限时,一些较少频繁出现的子词和没有在训练过程中见过的子词,就会无法进入词汇表出现OOV,而Byte-level BPE(BBPE)理论上是不会出现这个情况的。3.3 Byte-level BPE(BBPE)基础知识:Unicode: Unicode 是一种字符集,旨在涵盖地球上几乎所有的书写系统和字符。它为每个字符分配了一个唯一的代码点(code point)用于标识字符。Unicode 不关注字符在计算机内部的具体表示方式,而只是提供了一种字符到代码点的映射。Unicode 的出现解决了字符集的碎片化问题,使得不同的语言和字符能够在一个共同的标准下共存。然而,Unicode 并没有规定如何在计算机内存中存储和传输这些字符。UTF-8: UTF-8(Unicode Transformation Format-8)是一种变长的字符编码方案,它将 Unicode 中的代码点转换为字节序列。UTF-8 的一个重要特点是它是向后兼容 ASCII 的,这意味着标准的 ASCII 字符在 UTF-8 中使用相同的字节表示,从而确保现有的 ASCII 文本可以无缝地与 UTF-8 共存。在 UTF-8 编码中,字符的表示长度可以是1到4个字节,不同范围的 Unicode 代码点使用不同长度的字节序列表示,这样可以高效地表示整个 Unicode 字符集。UTF-8 的编码规则是:单字节字符(ASCII 范围内的字符)使用一个字节表示,保持与 ASCII 编码的兼容性。带有更高代码点的字符使用多个字节表示。UTF-8 使用特定的字节序列来指示一个字符所需的字节数,以及字符的实际数据。例如,英文字母 "A" 的 Unicode 代码点是U+0041,在 UTF-8 中表示为 0x41(与 ASCII 编码相同);而中文汉字 "你" 的 Unicode 代码点是U+4F60,在 UTF-8 中表示为0xE4 0xBD 0xA0三个字节的序列。所以简单的来说:Unicode 是字符集,为每个字符分配唯一的代码点。UTF-8 是一种基于 Unicode 的字符编码方式,用于在计算机中存储和传输字符。Byte(字节):计算机存储和数据处理时,字节是最小的单位。一个字节包含8个(Bit)二进制位,每个位可以是0或1,每位的不同排列和组合可以表示不同的数据,所以一个字节能表示的范围是256个。言归正传:Byte-level BPE(BBPE)和Byte-Pair Encoding (BPE)区别就是BPE是最小词汇是字符级别,而BBPE是字节级别的,通过UTF-8的编码方式这一个字节的256的范围,理论上可以表示这个世界上的所有字符。所以实现的步骤和BPE就是实现的粒度不一样,其他的都是一样的。初始词表:构建初始词表,包含一个字节的所有表示(256)。构建频率统计:统计所有子词单元对(两个连续的子词)在文本中的出现频率。合并频率最高的子词对:选择出现频率最高的子词对,将它们合并成一个新的子词单元,并更新词汇表。重复合并步骤:不断重复步骤 2 和步骤 3,直到达到预定的词汇表大小、合并次数,或者直到不再有有意义的合并(即,进一步合并不会显著提高词汇表的效益)。分词:使用最终得到的词汇表对文本进行分词。简单代码实现,不做赘述,读者朋友们可以自己实现一下from collections import defaultdict

sentences = [

"我",

"喜欢",

"吃",

"苹果",

"他",

"不",

"喜欢",

"吃",

"苹果派",

"I like to eat apples",

"She has a cute cat",

"you are very cute",

"give you a hug",

]

# 构建初始词汇表,包含一个字节的256个表示

initial_vocab = [bytes([byte]) for byte in range(256)]

vocab = initial_vocab.copy()

print("initial_vocab:", initial_vocab)

# 构建频率统计

def build_stats(sentences):

stats = defaultdict(int)

for sentence in sentences:

symbols = sentence.split()

for symbol in symbols:

stats[symbol.encode("utf-8")] += 1

return stats

stats = build_stats(sentences)

splits = {word: [byte for byte in word] for word in stats.keys()}

def compute_pair_freqs(splits):

pair_freqs = defaultdict(int)

for word, freq in stats.items():

split = splits[word]

if len(split) == 1:

continue

for i in range(len(split) - 1):

pair = (split[i], split[i + 1])

pair_freqs[pair] += freq

return pair_freqs

pair_freqs = compute_pair_freqs(splits)

def merge_pair(pair, splits):

merged_byte = bytes(pair)

for word in stats:

split = splits[word]

if len(split) == 1:

continue

i = 0

while i < len(split) - 1:

if split[i:i+2] == pair: # 检查分割中是否有这对字节

split = split[:i] + [merged_byte] + split[i + 2 :]

else:

i += 1

splits[word] = split

return splits

vocab_size = 50

while len(vocab) < vocab_size:

pair_freqs = compute_pair_freqs(splits)

best_pair = ()

max_freq = None

for pair, freq in pair_freqs.items():

if max_freq is None or max_freq < freq:

best_pair = pair

max_freq = freq

splits = merge_pair(best_pair, splits)

merged_byte = bytes(best_pair)

print("vocab:", vocab)着重解释一下为什么Byte-level BPE(BBPE)不会出现OOV问题,初始的词表里有256个表示如下:[b'\x00', b'\x01', b'\x02', b'\x03', b'\x04', b'\x05', b'\x06', b'\x07', b'\x08', b'\t', b'\n', b'\x0b', b'\x0c', b'\r', b'\x0e', b'\x0f', b'\x10', b'\x11', b'\x12', b'\x13', b'\x14', b'\x15', b'\x16', b'\x17', b'\x18', b'\x19', b'\x1a', b'\x1b', b'\x1c', b'\x1d', b'\x1e', b'\x1f', b' ', b'!', b'"', b'#', b'$', b'%', b'&', b"'", b'(', b')', b'*', b'+', b',', b'-', b'.', b'/', b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', b':', b';', b'<', b'=', b'>', b'?', b'@', b'A', b'B', b'C', b'D', b'E', b'F', b'G', b'H', b'I', b'J', b'K', b'L', b'M', b'N', b'O', b'P', b'Q', b'R', b'S', b'T', b'U', b'V', b'W', b'X', b'Y', b'Z', b'[', b'\\', b']', b'^', b'_', b'`', b'a', b'b', b'c', b'd', b'e', b'f', b'g', b'h', b'i', b'j', b'k', b'l', b'm', b'n', b'o', b'p', b'q', b'r', b's', b't', b'u', b'v', b'w', b'x', b'y', b'z', b'{', b'|', b'}', b'~', b'\x7f', b'\x80', b'\x81', b'\x82', b'\x83', b'\x84', b'\x85', b'\x86', b'\x87', b'\x88', b'\x89', b'\x8a', b'\x8b', b'\x8c', b'\x8d', b'\x8e', b'\x8f', b'\x90', b'\x91', b'\x92', b'\x93', b'\x94', b'\x95', b'\x96', b'\x97', b'\x98', b'\x99', b'\x9a', b'\x9b', b'\x9c', b'\x9d', b'\x9e', b'\x9f', b'\xa0', b'\xa1', b'\xa2', b'\xa3', b'\xa4', b'\xa5', b'\xa6', b'\xa7', b'\xa8', b'\xa9', b'\xaa', b'\xab', b'\xac', b'\xad', b'\xae', b'\xaf', b'\xb0', b'\xb1', b'\xb2', b'\xb3', b'\xb4', b'\xb5', b'\xb6', b'\xb7', b'\xb8', b'\xb9', b'\xba', b'\xbb', b'\xbc', b'\xbd', b'\xbe', b'\xbf', b'\xc0', b'\xc1', b'\xc2', b'\xc3', b'\xc4', b'\xc5', b'\xc6', b'\xc7', b'\xc8', b'\xc9', b'\xca', b'\xcb', b'\xcc', b'\xcd', b'\xce', b'\xcf', b'\xd0', b'\xd1', b'\xd2', b'\xd3', b'\xd4', b'\xd5', b'\xd6', b'\xd7', b'\xd8', b'\xd9', b'\xda', b'\xdb', b'\xdc', b'\xdd', b'\xde', b'\xdf', b'\xe0', b'\xe1', b'\xe2', b'\xe3', b'\xe4', b'\xe5', b'\xe6', b'\xe7', b'\xe8', b'\xe9', b'\xea', b'\xeb', b'\xec', b'\xed', b'\xee', b'\xef', b'\xf0', b'\xf1', b'\xf2', b'\xf3', b'\xf4', b'\xf5', b'\xf6', b'\xf7', b'\xf8', b'\xf9', b'\xfa', b'\xfb', b'\xfc', b'\xfd', b'\xfe', b'\xff']通过上述的方式其实是在一直根据训练语料循环迭代合成子词或者词,最后形成词表,比如“苹果”通过UTF-8进行编码后为“\xe8\x8b\xb9\xe6\x9e\x9c”,如果词表里面有,那“苹果”就通过词表映射成了1个表示,准确来说是1个token;如果词表里没有,那就用256中的“\xe8+\x8b+\xb9+\xe6+\x9e+\x9c”来表示“苹果”这个词,那就是6个token。在先前的各种分词方法中,如果词典里没有”苹果“这个词,也没有”苹“,”果“这样的子词的话,那就变成了[UNK]。所以在现在的大模型中,以Byte-level BPE(BBPE)这种方式进行分词是不会出现OOV,但词表中如果没有word级别的词的话,一些中英文就会分词分的很细碎,比如Llama在中文上就会把一些词分成多个token其实就是UTF-8后的中文编码,对编码效率以及语义会有影响,于是出现了一些扩充Llama中文词表的工作。上述分词算法在工程上实现一般使用sentencpiece工具包[6],谷歌在这个包中实现了上述的一系列算法,扩充Llama中文词表的工作也都是在此上面实现的。后续我也会写一篇文章进行详细的讲解。欢迎关注~其他文章:参考^ab[1] https://huggingface.co/learn/nlp-course/chapter6/6?fw=pt^[3] https://zh.wikipedia.org/zh-hans/%E4%BA%92%E4%BF%A1%E6%81%AF^[3] https://arxiv.org/abs/1508.07909^[4] https://arxiv.org/abs/1909.03341^[5] https://huggingface.co/learn/nlp-course/chapter6/5?fw=pt^[6] https://github.com/google/sentencepiece编辑于 2023-09-02 18:19​赞同 309​​8 条评论​分享​收藏​喜欢收起​OpenLLMAI​浙江大学 工学硕士​ 关注简而言之:token可以理解为最小语义单元,翻译的话个人喜欢叫词元(当然翻译成令牌、词都行),可以是word/char/subword。tokenization是指分词,目的是将输入文本分成一个个词元,保证各个词元拥有相对完整和独立的语义,以供后续任务(比如学习embedding或者作为高级模型的输入)使用。原文:0.序章笔者在上一篇文章中对最近折腾大模型的过程进行了反思,痛定思痛,决定除了工作部分以外不再浪费太多时间去跑更大规模的模型,同时决心开一些新坑来倒逼输入并与大家交流讨论,暂时的想法是在OpenLLM下面做两个系列:LLM基础组件和LLM炼丹术。注:从4.11开始,不知不觉居然写到OpenLLM 008了,这十几天累成狗了,最快乐的时候居然是忙里偷闲写这些东西的时候,amazing!LLM基础组件tokenization&tokenizers:分词算法与分词器位置编码attention机制基础架构与attention mask归一化激活函数行为思路分词算法与分词器作为LLM(大语言模型)的基础组件,作用相当于文本与模型的桥梁。因此作为LLM基础组件系列的开篇,本文将对主流的分词算法和分词器进行全面的梳理和介绍。updates2023/04/30,资料阅读+整理,完成大纲;2023/05/01,主流subword算法伪代码;bert分词代码解读;2023/05/02,+byte-level BPE、优缺点、示例、总结等,主体内容基本算是写完了;剩余的代码实现示例和具体模型的分词器示例后续有空再补(看优先级和精力);2023/05/03,XX;1.分词算法tokenization算法大致经历了从word/char到subword的进化,这一章首先介绍不同的分词粒度,然后对主流的三大subword分词算法进行介绍,配合代码和实例,希望可以对subword算法有一个比较全面的梳理。0.文本应该分成什么粒度?分词的目的是将输入文本分成一个个词元,保证各个词元拥有相对完整和独立的语义,以供后续任务(比如学习embedding或者作为高级模型的输入)使用。首先,最自然的粒度当然是词粒度。词,作为语言最自然的基本单元,在英文等语言中有着天然的空格分隔,但是对于中文等语言可能需要额外的分词算法来进行处理(比如中文的jieba分词)。不过,我们总归是有办法获得各种各样的词的,这并不是一个致命的问题。真正影响词粒度分词算法应用问题主要有:1)词粒度的词表由于长尾效应可能会非常大,包含很多的稀有词,存储和训练的成本都很高,并且稀有词往往很难学好;2)OOV问题,对于词表之外的词无能为力;3)无法处理单词的形态关系和词缀关系:同一个词的不同形态,语义相近,完全当做不同的单词不仅增加了训练成本,而且无法很好的捕捉这些单词之间的关系;同时,也无法学习词缀在不同单词之间的泛化。那么,一个很自然的想法就是使用字符粒度的词表,这样OOV问题迎刃而解了,但是字符粒度太细了,会造成新的问题:1)无法承载丰富的语义;2)序列长度增长,带来计算成本的增长。所以,如何结合word和char粒度各自的优势呢?subword分词应运而生,顾名思义,粒度介于char和Word之间,基本思想为常用词应该保持原状,生僻词应该拆分成子词以共享token压缩空间,所以可以较好的平衡词表大小与语义表达能力,比如OOV问题可以通过subword的组合来解决。目前有三种主流的Subword分词算法,分别是Byte Pair Encoding (BPE), WordPiece和Unigram Language Model。总结一下,文本的分词粒度:word:优点:词的边界和含义得到保留;缺点:1)词表大,稀有词学不好;2)OOV;3)无法处理单词形态关系和词缀关系;char:优点:词表极小,比如26个英文字母几乎可以组合出所有词,5000多个中文常用字基本也能组合出足够的词汇;缺点:1)无法承载丰富的语义;2)序列长度大幅增长;subword:可以较好的平衡词表大小与语义表达能力;1.BPEBPE最早其实是一种数据压缩算法,基本思想是将经常一起出现的数据对替换为不在数据串中的其他字符,后续可以通过一个merge表来恢复原始数据。在2015年,由论文[1508.07909] Neural Machine Translation of Rare Words with Subword Units引入NLP领域。核心思想:从一个基础小词表开始,通过不断合并最高频的连续token对来产生新的token。具体做法:输入:训练语料;词表大小V1.准备基础词表:比如英文中26个字母加上各种符号;2.基于基础词表将语料拆分为最小单元;3.在语料上统计单词内相邻单元对的频率,选择频率最高的单元对进行合并;4.重复第3步直到达到预先设定的subword词表大小或下一个最高频率为1;输出:BPE算法得到的subword词表下面是一个BPE的训练示例:优势与劣势:优势:可以有效地平衡词汇表大小和编码步数(编码句子所需的token数量,与词表大小和粒度有关)。劣势:基于贪婪和确定的符号替换,不能提供带概率的多个分词结果(这是相对于ULM而言的);decode的时候面临歧义问题。BPE的劣势:代码实现:refs:[1508.07909] Neural Machine Translation of Rare Words with Subword Units理解NLP最重要的编码方式 — Byte Pair Encoding (BPE),这一篇就够了 - 硅谷谷主的文章 - 知乎https://zhuanlan.zhihu.com/p/424631681 2.Byte-level BPE2019年12月:《Neural Machine Translation with Byte-Level Subwords》,论文提出了一种新的subword算法,称之为BBPE,即Byte-level BPE。核心思想:将BPE的思想从字符级别扩展到子节级别。具体做法:摘要:几乎所有现有的机器翻译模型都建立在基于字符的词汇表之上:characters, subwords or words(只是字符的粒度不同)。 然而,来自噪声文本或字符丰富的语言(如日语和中文)的稀有字符可能会不必要地占用词汇槽并限制其紧凑性。 在字节级别表示文本并使用 256 字节集作为词汇表是解决此问题的潜在方法。 然而,高昂的计算成本阻碍了它在实践中的广泛部署或使用。 在本文中,我们研究了字节级子词,具体为字节级 BPE (BBPE),它比字符词汇表更紧凑,没有词汇表外的标记,但比仅使用纯字节更有效。 我们声称上下文化 BBPE 嵌入是必要的,这可以通过卷积层或循环层来实现。 我们的实验表明,BBPE 具有与 BPE 相当的性能,而其大小仅为 BPE 的 1/8。 在多语言设置中,BBPE 最大限度地共享多种语言的词汇并实现更好的翻译质量。 此外,我们表明 BBPE 可以在具有非重叠字符集的语言之间实现可迁移的模型。我们考虑文本的UTF8编码,它将每个Unicode字符编码成1到4个字节。这允许我们将句子建模为字节序列,而不是字符序列。虽然有覆盖150多种语言的138K Unicode字符,但我们可以将任何语言的句子表示为UTF-8字节序列(只需要256个可能的字节中的248个)。文本的字节序列表示通常比字符序列表示长得多(高达4倍),这使得按原样使用字节(只使用256的子节集)在计算上要求很高。作为另一种选择,我们考虑将字节序列分割成可变长度的n-gram(字节级“subwords”)。具体地说,我们学习关于字节级表示的BPE词汇,该表示用字节n-gram扩展了UTF-8字节集,称之为BBPE。图一展示了BBPE与BPE的对比。不同的词表对序列长度的影响:词表粒度由细到粗,分词序列的对比:我们可以验证一下上图中的部分编码,可以看到是一致的:https://www.browserling.com/tools/utf8-encode优势与劣势:优势:1)效果与BPE相当,但词表大为减小;2)可以在多语言之间通过字节级别的子词实现更好的共享;3)即使字符集不重叠,也可以通过子节层面的共享来实现良好的迁移。劣势:1)编码序列时,长度可能会略长于BPE,计算成本更高;2)由byte解码时可能会遇到歧义,需要通过上下文信息和动态规划来进行解码。refs:Neural Machine Translation with Byte-Level Subwordshttps://arxiv.org/abs/1909.03341 浅谈Byte-Level BPE - CaesarEX的文章 - 知乎https://zhuanlan.zhihu.com/p/146114164 tokenizers小结 - 马东什么的文章 - 知乎https://zhuanlan.zhihu.com/p/360290118 3.WordPieceWordPiece出自《JAPANESE AND KOREAN VOICE SEARCH》,并用于解决日语和韩语的语音问题。核心思想:与BPE类似,也是从一个基础小词表出发,通过不断合并来产生最终的词表。主要的差别在于,BPE按频率来选择合并的token对,而wordpiece按token间的互信息来进行合并。注:互信息,在分词领域有时也被称为凝固度、内聚度,可以反映一个词内部的两个部分结合的紧密程度。具体做法:除了合并对象的选择以外,基本同BPE;输入:训练语料;词表大小V1.准备基础词表:比如英文中26个字母加上各种符号;2.基于基础词表将语料拆分为最小单元;3.基于第2步数据训练语言模型,可以是unigram语言模型,通过极大似然进行估计即可;4.从所有可能得token对中选择,选择合并后可以最大程度地增加训练数据概率的token对进行合并,具体的score=(freq_of_pair)/(freq_of_first_element×freq_of_second_element),当然你也可以取个log,就变成了互信息,选择最高的单元对进行合并;5.重复第4步直到达到预先设定的subword词表大小或概率增量低于某一阈值;输出:wordpiece算法得到的subword词表优势与劣势:优势:可以较好的平衡词表大小和OOV问题;劣势:可能会产生一些不太合理的子词或者说错误的切分;对拼写错误非常敏感;对前缀的支持不够好;复合词错误的切分:前缀的错误处理:一种解决方案是:将复合词拆开;将前缀也拆开;代码实现:refs:japanese and korean voice searchhttps://static.googleusercontent.com/media/research.google.com/zh-CN//pubs/archive/37842.pdf4.ULMULM出自《 Subword Regularization: Improving Neural Network Translation Models with Multiple Subword Candidates 》。核心思想:初始化一个大词表,然后通过unigram 语言模型计算删除不同subword造成的损失来代表subword的重要性,保留loss较大或者说重要性较高的subword。具体做法:输入:训练语料;词表大小V1.准备基础词表:初始化一个很大的词表,比如所有字符+高频ngram,也可以通过BPE算法初始化;2.针对当前词表,用EM算法估计每个子词在语料上的概率;3.计算删除每个subword后对总loss的影响,作为该subword的loss;4.将子词按照loss大小进行排序,保留前x%的子词;注意,单字符不能被丢弃,以免OOV;5.重复步骤2到4,直到词表大小减少到设定值;输出:ULM算法得到的subword词表可见,ULM会倾向于保留那些以较高频率出现在很多句子的分词结果中的子词,因为这些子词如果被删除,其损失会很大。优势与劣势:优势:1)使用的训练算法可以利用所有可能的分词结果,这是通过data sampling算法实现的;2)提出一种基于语言模型的分词算法,这种语言模型可以给多种分词结果赋予概率,从而可以学到其中的噪声;3)使用时也可以给出带概率的多个分词结果。劣势:1)效果与初始词表息息相关,初始的大词表要足够好,比如可以通过BPE来初始化;2)略显复杂。代码实现:refs:Subword Regularization: Improving Neural Network Translation Models with Multiple Subword Candidates https://arxiv.org/abs/1804.10959 NLP三大Subword模型详解:BPE、WordPiece、ULM - 阿北的文章 - 知乎https://zhuanlan.zhihu.com/p/1916484215.SentencePieceSentencePiece,有些文章将其看作一种分词方法,有的地方将其视为一个分词工具包。个人更倾向于后者,但是将其看作一种分词算法也未尝不可(因为不仅是分词算法的集成,还做了很多优化)。官方介绍:SentencePiece is an unsupervised text tokenizer and detokenizer mainly for Neural Network-based text generation systems where the vocabulary size is predetermined prior to the neural model training. SentencePiece implements subword units (e.g., byte-pair-encoding (BPE) [Sennrich et al.]) and unigram language model [Kudo.]) with the extension of direct training from raw sentences. SentencePiece allows us to make a purely end-to-end system that does not depend on language-specific pre/postprocessing.https://github.com/google/sentencepiece 主要特性多分词粒度:支持BPE、ULM子词算法,也支持char, word分词;多语言:以unicode方式编码字符,将所有的输入(英文、中文等不同语言)都转化为unicode字符,解决了多语言编码方式不同的问题;编解码的可逆性:之前几种分词算法对空格的处理略显粗暴,有时是无法还原的。Sentencepiece显式地将空白作为基本标记来处理,用一个元符号 “▁”( U+2581 )转义空白,这样就可以实现简单且可逆的编解码;无须Pre-tokenization:Sentencepiece可以直接从raw text/setences进行训练,无须Pre-tokenization;Fast and lightweight;编解码的可逆性:Decode(Encode(Normalized(text)))= Normalized(text)一个中文转Unicode的示例:https://tool.chinaz.com/tools/unicode.aspx refs:https://github.com/google/sentencepiecesentencepiece原理与实践https://www.zhihu.com/tardis/zm/art/159200073?source_id=1003 6.主流subword算法的对比wordpiece和BPE的对比wordpiece和BPE的对比:都是走的合并的思路,将语料拆分成最小单元(英文中26个字母加上各种符号,这些作为初始词表)然后进行合并,词表从小到大;核心区别就在于wordpiece是按token间的互信息来进行合并而BPE是按照token一同出现的频率来合并的。wordpiece和ULM的对比:wordpiece和ULM的对比:都使用语言模型来挑选子词;区别在于前者词表由小到大,而后者词表由大到小,先初始化一个大词表,根据评估准则不断丢弃词表,直到满足限定条件。ULM算法考虑了句子的不同分词可能,因而能够输出带概率的多个分词结果。三种subword分词算法的关系7.tokenizers库优先级靠后2.分词器1.BERT的分词器BERT的分词器由两个部分组成:BasicTokenizer:转成 unicode:Python3,输入为str时,可以省略这一步_clean_text:去除各种奇怪字符_tokenize_chinese_chars:中文按字拆开whitespace_tokenize:空格分词_run_strip_accents:去掉变音符号_run_split_on_punc:标点分词再次空格分词:whitespace_tokenize(" ".join(split_tokens)),先用空格join再按空白分词,可以去掉连续空格WordpieceTokenizer:贪心最大匹配:用双指针实现;核心代码:tokenize(self, text):2.T5的分词器3.GPT的分词器4.LLaMA的分词器5.GLM的分词器总结下面对主流模型使用的分词器进行总结(待完善):参考资料深入理解NLP Subword算法:BPE、WordPiece、ULM - Luke的文章 - 知乎https://zhuanlan.zhihu.com/p/86965595NLP三大Subword模型详解:BPE、WordPiece、ULM - 阿北的文章 - 知乎https://zhuanlan.zhihu.com/p/191648421NLP中的subword算法及实现 - 微胖界李现的文章 - 知乎https://zhuanlan.zhihu.com/p/112444056NLP BERT GPT等模型中 tokenizer 类别说明详解https://cloud.tencent.com/developer/article/1865689BERT 客制化分词器和 WWM 的实现 - 满甲的文章 - 知乎https://zhuanlan.zhihu.com/p/268515387bert第三篇:tokenizerhttps://blog.csdn.net/iterate7/article/details/108959082BERT 是如何分词的https://blog.csdn.net/u010099080/article/details/102587954同:BERT 是如何分词的 - Alan Lee的文章 - 知乎https://zhuanlan.zhihu.com/p/132361501Bert系列伴生的新分词器https://dxzmpk.github.io/2020/04/29/Bert%E7%B3%BB%E5%88%97%E4%BC%B4%E7%94%9F%E7%9A%84%E6%96%B0%E5%88%86%E8%AF%8D%E5%99%A8/Tokenizers: How machines readhttps://blog.floydhub.com/tokenization-nlp/【HugBert11】聚沙成塔:关于tokenization(词元化)的解疑释惑 - 套牌神仙的文章 - 知乎https://zhuanlan.zhihu.com/p/371300063japanese and korean voice searchhttps://static.googleusercontent.com/media/research.google.com/zh-CN//pubs/archive/37842.pdf[1508.07909] Neural Machine Translation of Rare Words with Subword Units 3-3 Transformers Tokenizer API 的使用https://www.zhihu.com/tardis/zm/art/390821442?source_id=1003关于transformers库中不同模型的Tokenizer - 莫冉的文章 - 知乎https://zhuanlan.zhihu.com/p/121787628NLP领域中的token和tokenization到底指的是什么? - 知乎https://www.zhihu.com/question/64984731NLP中的Tokenization - 薛定谔没养猫的文章 - 知乎https://zhuanlan.zhihu.com/p/444774532大模型中的分词器tokenizer:BPE、WordPiece、Unigram LM、SentencePiece - 眼睛里进砖头了的文章 - 知乎https://zhuanlan.zhihu.com/p/620508648浅谈Byte-Level BPE - CaesarEX的文章 - 知乎https://zhuanlan.zhihu.com/p/146114164 理解NLP最重要的编码方式 — Byte Pair Encoding (BPE),这一篇就够了 - 硅谷谷主的文章 - 知乎https://zhuanlan.zhihu.com/p/424631681 Neural Machine Translation with Byte-Level Subwordshttps://arxiv.org/abs/1909.03341 tokenizers小结 - 马东什么的文章 - 知乎https://zhuanlan.zhihu.com/p/360290118 互信息https://zh.wikipedia.org/wiki/%E4%BA%92%E4%BF%A1%E6%81%AFPython unicodedata.normalize 将Unicode文本标准化https://blog.csdn.net/weixin_43866211/article/details/98384017Weaknesses of WordPiece Tokenizationhttps://medium.com/@rickbattle/weaknesses-of-wordpiece-tokenization-eb20e37fec99 Subwordhttps://paddlepedia.readthedocs.io/en/latest/tutorials/pretrain_model/subword.html sentencepiece原理与实践https://www.zhihu.com/tardis/zm/art/159200073?source_id=1003 抱抱脸:https://huggingface.co/docs/transformers/tokenizer_summaryhttps://huggingface.co/learn/nlp-course/zh-CN/chapter2/4?fw=tfhttps://huggingface.co/learn/nlp-course/chapter6/7?fw=pthttps://huggingface.co/learn/nlp-course/chapter6/5?fw=pt编辑于 2023-05-03 00:20​赞同 153​​7 条评论​分享​收藏​喜欢

ChatGPT如何计算token数? - 知乎

ChatGPT如何计算token数? - 知乎首页知乎知学堂发现等你来答​切换模式登录/注册互联网人工智能OpenAIAI技术ChatGPTChatGPT如何计算token数?【渐构】万字科普GPT4为何会颠覆现有工作流;为何你要关注微软Copilot、文心一言等大模型_哔哩哔哩_bilibili 根据这个视频的说法,cha…显示全部 ​关注者235被浏览763,276关注问题​写回答​邀请回答​好问题 13​1 条评论​分享​36 个回答默认排序卡卡罗特​​南京大学 计算数学硕士​ 关注终于有人意识到这个问题了。首先 OpenAI token 的计算包含两部分。输入给 GPT 模型的 token 数和 GPT 模型生成文本的 token 数。例如,你提问耗费了 100 token,GPT 根据你的输入,生成文本(也就是回答)了 200 token,那么一共消费的 token 数就是 300 。那么 token 和字符是如何映射的呢,是什么关系呢?这里就直接应用我已经上线的新书 《ChatGPT实用指南》中的内容。在上一小节,我们其实刻意回避了一个问题。GPT 的输入和输出都是到中文字的粒度吗?注意,GPT 不仅仅能处理中文,它还能处理几乎世界上所有流行的自然语言。所以这告诉我们 GPT 实际的输入和输出并不是像 1.2.2 中那个图的样子。因此,我们需要引入 token 的概念。token 是自然语言处理的最细粒度。简单点说就是,GPT 的输入是一个个的 token,输出也是一个个的 token。GPT 不是适用于某一门语言的大型语言模型,它适用于几乎所有流行的自然语言。所以 GPT 的 token 需要 兼容 几乎人类的所有自然语言,那意味着 GPT 有一个非常全的 token 词汇表,它能表达出所有人类的自然语言。如何实现这个目的呢?答案是通过 unicode 编码。Unicode(统一码、万国码、单一码)是一种在计算机上使用的字符编码。Unicode 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。例如中文中的 你 字对应如下 unicode 编码:\u4F60\u 表示后面是一个 unicode 编码,它用 16 进制数表示。4F60 转换成 10 进制对应 20320 ,20320 表示在 unicode 编码中,第 20320 个编码对应的是字是 你 。最后将 20320 转换为 2 进制,得到如下结果:0100 1111 0110 0000如果我们直接将 unicode 的编码作为 GPT 中 token 的词表,会存在一些问题。 一方面直接使用 unicode 作为词汇表太大了,另一方面 unicode 自身的粒度有时候太细了,例如 unicode 中的英文编码是以字母粒度进行的。于是我们会将 unicode 的 2 进制结果以 8 个二进制位为单位进行拆分。例如将 你 拆分成:0100 1111和 0110 00008 个二进制位只有 256 种可能,换句话说,只需要 256 个 token 的词汇表就能表示所有 unicode。然而这种方法的词汇表又太小了,编码方法太粗糙了。实际上 GPT 是使用一种称为 BPE (Byte Pair Encoding)的算法,在上面的基础上进一步生成更大的词汇表。它的基本思想如下,将上述的基础 token (256种可能)做组合,然后统计文本数据中这些组合出现的频率,将频率最大的那些保留下来,形成新的 token 词汇表。因此,通过此方法得到的 token 和文字的映射不一定是一对一的关系。例如在英文中, red 会被视为一个 token,这个 token 在词汇表中的编号是 13 。注意,这里 red 前有一个空格,在这里「文字」和 token 是多对一[⑥]。再例如 enlighten 会被视为三个 token,对应的编号分别是 1268,2971,268,在这里「文字」和 token 是一对多[⑥]。在这里我们不对 BPE 算法做进一步的展开。如果读者想查询 OpenAI 的字符和 token 的映射关系,可以使用该[网站](https://platform.openai.com/tokenizer)查询。实际上,OpenAI 不仅对自然语言做了 token 的映射,对编程语言中的代码也做了 token 的映射。有意思的是,unicode 不仅有自然语言,实际上也包含 emoji 等自然语言之外的符号。这也是为什么 ChatGPT 能理解和回复 emoji 的原因。综上所述, GPT 实际是将我们输入的文字转换成 token,然后通过 GPT 模型预测 token,再将 token 转换成文字,最后再输出给我们。通过 token 的学习,我相信读者能感觉到 ChatGPT 理解文本的方式和人类并不相同,它在以自己的方式理解这个世界。⑥ 在这里,文字是指英文单词,英文中的空格,英文中的标点符号等。ChatGPT 实用指南已上线,开源免费,欢迎阅读,转载和点赞。编辑于 2023-04-10 15:59​赞同 451​​37 条评论​分享​收藏​喜欢收起​知乎用户题主有两个问题:汉字是怎么编码的?编码和模型是否相关?虽然 GPT-3.5 的代码和模型权重并未开源,但是 tokenizer 部分是开源到 openai/tiktoken 的,这是一个 BPE(Byte-Pair Encoding tokenization)方法的 tokenizer。关于第一个问题,ChatGPT 是一个多语言模型,因此编码的问题不局限于汉字。tiktoken 的词表绝大多数是英文子词,并包含少量 unicode token 和表示字节的 token,以 UTF-8 的形式表示多语言。关于第二个问题,不同的 OpenAI 模型采用了不同的编码方式。GPT-4、GPT-3.5-turbo 等模型采用的是 cl100k_base,词表 100k 大小。text-davinci 系列采用的是 p50k_base,词表大小 50k。还有一些其他模型采用了 r50k_base。更早的 GPT-2 有单独的编码方式,也开源在 HuggingFace。题主所给的 tokenizer 网站 OpenAI Platform 的 demo 适用于 GPT-3 和 Codex,应该是 p50k/r50k 中的一种编码方式,和 ChatGPT (GPT-3.5)采用的 cl100k_base 已经不是同一种编码方式了。发布于 2023-07-08 21:43​赞同 28​​2 条评论​分享​收藏​喜欢

在机器学习领域“token”到底是什么意思? - 知乎

在机器学习领域“token”到底是什么意思? - 知乎首发于AIGC 相关知识切换模式写文章登录/注册在机器学习领域“token”到底是什么意思?7号床​信息技术行业 CEOToken 词元在机器学习领域、NLP领域、文生图等领域,机器读懂词汇和语句是通过 Token 来进行的。尽管在许多领域中都有“Token”这个字符被使用,在不同领域被翻译成代币、象征、标志、表示、信物、标记等等意思。但是在人工智能 AIGC 领域,通常是指“词元”,它是语言类模型中用数字来表示单词的最小语义单位。在提示词文本发送给神经网络之前,Tokenizer 将组合词、句子、段落、文章这类型的长文本分解为最小单位的 Token 词元,然后再通过 Embedding 的方式把 token 转化为向量表示的数据结构,最后输入给神经网络。比如图中这句话“This is a input text.” 首先被 Tokenizer 转化成最小词元,其中[CLS][SEP]为一句话的起始与结束符号,然后再通过 Embedding 的方式转化为向量。(CLS:classification 告知系统这是句子级别的分类的开始、SEP:separator 告知系统结束本句或分割下一句)一句话“This is a input text.” 首先被 Tokenizer 转化成最小词元,然后再通过 Embedding 的方式转化为向量Token 是最小单位的“词元”,或者说单词的“片段”,就是不可再拆分的最小语义单位,比如 “waterfall”,会被拆成2个 token:water、fall。另外,标点符号也会被分解为 token,因为标点符号也影响了对全文的语义理解。比如“I don‘t know.”可以分解为5个Token,他们是:“ I ”、“don”、“ ‘t” 、“know”、“.”。在 Stable Diffusion 中默认的提示词输入最大量为不超过75个,这里的75指的就是Token 数,而不是75个单词。所以,经常会发生你输入的单词数字没有到达75个时,Token 就已经超过75个了。因为标点符号、复合词等等都会被解读为 Token(当然,现在无需担心在 Stable Diffusion WebUI 的提示词输入框中输入超过75个 Token 的问题,因为它可以通过分段输入的方式来进行了,但是75个 token 这一个概念大家应该明白)。Stable Diffusion WebUI 的提示词输入框初步限定为 75 个 token一大堆提示词,或一句话最终都被拆解为哪些 token 呢?大家可以通过 AUTOMATIC1111 提供的 Stable Diffusion WebUI 扩展插件 tokenizer 来查看,建议安装。(https://github.com/AUTOMATIC1111/stable-diffusion-webui-tokenizer),这个扩展插件可以直接在 Extensions 标签下搜索安装。我将一直本着让非专业人士也能看懂的讲解,尽量以比喻和通俗易懂的图表等方式来描述技术术语的原则。这同样是本着 AI 将人类知识壁垒大幅度降低门槛好让更多的普通人都能够涉足专业领域的宗旨,比如 Stable Diffusion 模型让一个从没有学过 PS 却有着超强艺术细胞和创造力的广场舞大妈都能绘出顶级的 CG 作品,而他们却因为年轻时的某些原因错过了走入专业领域的机会,或许是出身、或许是经济条件、或许是其他的命运所致。查询资料、分析、组织、撰写…工作不易,请多多支持我。转载请注明出处,将万分感谢。编辑于 2023-11-23 11:14・IP 属地北京tokenNLP​赞同 48​​5 条评论​分享​喜欢​收藏​申请转载​文章被以下专栏收录AIGC 相关知识用普通人能看懂的文字来解读AIGC领域的相关技术Stable DiffusionAIGC之Stable Diffus

自然语言处理的基石:Token, Embedding与Encoding-百度开发者中心

处理的基石:Token, Embedding与Encoding-百度开发者中心文章问答开发者资源云+AI应用平台运营支持开源项目社区登录|注册开发者热搜人工智能云原生AI应用推荐人工智能数据库飞桨PaddlePaddle云计算云原生超级链百度安全物联网大数据开源技术开发者企业服务更多内容自然语言处理的基石:Token, Embedding与Encoding作者:沙与沫2023.12.05 14:59浏览量:28简介:“token“, “embedding“,“encoding“各自的区别分别是什么?“token“, “embedding“,“encoding“各自的区别分别是什么?在自然语言处理和深度学习领域,token、embedding和encoding是常用的术语,它们各自有着不同的含义和作用。本文将详细解释这三个术语的区别。一、TokenToken是自然语言处理中的基本单元之一,通常用于表示文本中的单词、短语或符号等语言单位。Token是文本数据的基本组成单元,通过对文本进行分词、切分等操作,将其分解成一系列的token。例如,在英文文本中,每个单词都可以被视为一个token;在中文文本中,每个词语、短语或句子都可以被视为一个token。Token的主要作用是作为文本数据的基本单元,为后续的数据处理提供基础。通过对文本进行token化,可以将其转化为计算机可处理的形式,便于后续的文本分析、分类、聚类等操作。二、EmbeddingEmbedding是一种将高维稠密向量表示为低维稠密向量的方法,通常用于表示词向量。在自然语言处理中,词向量是一种将词汇表中的单词表示为实数向量的方式,以便于计算机处理。通过将单词表示为向量,计算机可以模拟人类对词汇的理解和推理过程,从而实现对文本的语义分析和推理。Embedding的主要作用是将词汇表中的单词表示为低维的向量,以便于后续的数据分析和处理。通过对词进行embedding,可以捕捉到单词之间的语义相似性和上下文关系,从而在文本分类、情感分析、问答系统等任务中取得更好的效果。三、EncodingEncoding是将输入数据转换为机器学习模型可处理的形式的过程。在自然语言处理中,通常将文本数据转换为向量形式,以便于机器学习模型进行处理。Encoding可以是显式的,即将文本转化为符号向量;也可以是隐式的,即将文本转化为语音、图像等其他形式。Encoding的主要作用是将文本数据转换为机器学习模型可处理的形式,以便于后续的数据分析和处理。通过对文本进行encoding,可以将其转化为计算机可处理的形式,从而实现对文本的分类、聚类、情感分析等操作。总结:Token、Embedding和Encoding是自然语言处理和深度学习领域中常用的术语,它们各自有着不同的含义和作用。Token是文本数据的基本组成单元,用于表示文本中的单词、短语等语言单位;Embedding是一种将高维稠密向量表示为低维稠密向量的方法,通常用于表示词向量;Encoding是将输入数据转换为机器学习模型可处理的形式的过程。理解这三个术语的区别有助于更好地理解自然语言处理和深度学习的相关概念和技术。

相关文章推荐文心一言API接入指南文心一言是百度打造出来的人工智能大语言模型,具备跨模态、跨语言的深度语义理解与生成能力十万个为什么2023.10.20 16:567036181从 MLOps 到 LMOps 的关键技术嬗变本文整理自 QCon 全球软件开发大会 -从 MLOps 到 LMOps 分论坛的同名主题演讲百度智能云开发者中心2023.11.15 18:03244462Sugar BI教你怎么做数据可视化 - 拓扑图,让节点连接信息一目了然Sugar BI教你怎么做数据可视化 - 拓扑图,让节点连接信息一目了然百度智能云开发者中心2023.03.21 10:56125920更轻量的百度百舸,CCE Stack 智算版发布百度百舸·AI 异构计算平台,是百度智能云将百度内部强大的 AI 工程能力面向市场推出的解决方案。百度智能云开发者中心2023.03.02 12:1771100打造合规数据闭环,加速自动驾驶技术研发今天跟大家的演讲主题,主要是想交流如何去构建这样两个自动驾驶的数据闭环链路。

百度智能云开发者中心2023.03.02 15:00195100LMOps 工具链与千帆大模型平台LMOps 相关的概念以及关键技术百度智能云开发者中心2023.11.17 15:49105400发表评论登录后可评论,请前往 登录 或 注册评 论关于作者被阅读数被赞数被收藏数关 注最热文章云数据库与自建数据库有什么不同?Windows幻兽帕鲁服务器一键搭建我的世界(minecraft) Java版一键部署分布式数据库 GaiaDB-X 金融应用实践2023 年中国数据库十大发展总结汇聚、开放、助力共赢负载均衡全国首批获得可信云服务认证对象存储服务:N002002 云数据库服务:N003002AI课程中心百度大脑飞桨paddlepaddleApolloDueros友情链接: 百度智能云AI市场百度安全百度地图开放平台搜索资源平台百度众测百度超级链InfoQ© 2022 Baidu 使用百度前必读 | 京ICP证030

对于token的认证,如何保证token的及时刷新? - 知乎

对于token的认证,如何保证token的及时刷新? - 知乎首页知乎知学堂发现等你来答​切换模式登录/注册Web 开发JSON Web Token(JWT)token对于token的认证,如何保证token的及时刷新?1,在拦截器里对将要过期的token 的进行刷新。(一个页面可能n个请求同时发出,也就是说 refresh_token 要支持多个,这个不算最好的解决…显示全部 ​关注者27被浏览88,595关注问题​写回答​邀请回答​好问题​添加评论​分享​4 个回答默认排序张少林同学​ 关注前言记录一下前后端分离下————token超时刷新策略!需求场景昨天发了一篇记录 前后端分离应用——用户信息传递 中介绍了token认证机制,跟几位群友讨论了下,有些同学有这么一个疑惑:token失效了,应该怎么做?强制定向到登录页?其实理论上如果是活跃用户,token失效后,假如用户正在操作表单,此时突然定向到登录页面,那用户体验太差了。实现目标延长token过期时间活跃用户在token过期时,在用户无感知的情况下动态刷新token,做到一直在线状态不活跃用户在token过期时,直接定向到登录页登录返回字段如何签发token,请看上一篇推文,这里不做过多介绍。先看看登录接口返回的数据如下: 1@Data

2public class LoginVo implements Serializable {

3

4 private static final long serialVersionUID = 6711396581310450023L;

5

6 //...省略部分业务字段

7

8 /**

9 * token令牌 过期时间默认15day

10 */

11 private String jwt;

12

13 /**

14 * 刷新token 过期时间可以设置为jwt的两倍,甚至更长,用于动态刷新token

15 */

16 private String refreshJwt;

17

18 /**

19 * token过期时间戳

20 */

21 private Long tokenPeriodTime;

22

23}

具体返回字段的意义请看注释,这里再简要说明:jwt:用户正常访问接口时提交的token,过期时间设置长一些,15day吧refreshJwt:刷新token 过期时间可以设置为jwt的两倍,甚至更长,用于动态刷新token时候提交后台验证tokenPeriodTime:token过期时间戳,前端每次调用接口前需要主动判断是否已经过期,如果过期则提交refreshJwt访问token刷新的接口进行刷新动态刷新token前端检测到token过期后,携带refreshJwt访问后台刷新token的接口,服务端在拦截器中依然对refreshJwt进行解析鉴权假如refreshJwt也过期了,提示登录过期,强制跳转登录页假如refreshJwt还在有效期,则签发新的token返回,前端使用最新的token进行接口请求总结如果是活跃用户,那么允许他在refreshJwt过期时间与token过期时间的差值这段时间内,不停的动态刷新token,使其做到无感知的状态下一直保持登录状态如果用户不活跃,在refreshJwt过期时间到了,依然没有使用系统,那么将判定为不活跃用户,此时应当重定向到登录页了最后篇幅较短,主要是延续上一篇 前后端分离应用——用户信息传递 遗留问题做一下总结。如果你有更好的做法,欢迎留言告知我,谢谢啦。后续会不定期更新原创文章,欢迎关注公众号 「张少林同学」!编辑于 2019-01-22 12:22​赞同 16​​7 条评论​分享​收藏​喜欢收起​编程乐趣​ 关注这是我之前分享在星球里面的课程,下面整理下,分享下这个无感刷新Token技术方案。我们都知道Token是有设置有效期的,为了安全都不会设置过长的有效期;但设置有效期太短,又会导致经常需要重新登录。这就需要无感刷新Token的方案,来提升用户体验。目前比较常用的方案是:双token机制。1、登录时同时返回:Token、RefreshToken,Token用于请求业务接口,RefreshToken用于刷新Token接口;2、每一次Http请求,客户端都会判断服务器返回状态,如果是401,代表Token过期;3、客户端使用RefreshToken,请求服务器Token刷新接口,并获取新的:Token,RefreshToken;4、如果第3步骤成功返回,更新本地的Token、RefreshToken;如果返回失败,代表RefreshToken也过期了,提示过期并跳转至登录页面。下面我们一起看下实现步骤:1、后台登录接口登录验证,验证用户名和密码,验证通过返回Token。登录接口返回的2个内容:Token和RefreshToken,这两个有效期不一样,比如Token有效期是30分钟,RefreshToken有效期是60分钟。2、后台刷新token接口和登录接口一样,也是返回:Token和RefreshToken。3、前端登录功能在前端登录页面,成功登录后,把Token和RefreshToken存储在本地,可以存储在Cookie或者LocalStorage。4、错误响应拦截器axios响应拦截器添加如下代码:a、判断Http返回状态是否为401。b、判断是否授权信息是否使用refreshToken,调用刷新token接口,同样也会发起Http请求,如果refreshToken也过期了,同样会返回401;所以这边要加判断,避免进入死循环。c、如果refreshToken也过期了,直接跳转至登录页面。d、如果调用刷新token接口成功返回,更新本地存储的Token、RefreshToken;并获取上一次业务请求的内容,并更新验证信息,重新发起上一次业务请求,这样才能实现无感刷新。5、实现效果最终实现效果如下:1、请求用户列表接口,返回401;2、调用token刷新接口;3、重新请求用户列表接口。在这过程中,第一次发起用户搜索请求是失败的,我们马上刷新token,并重新发起第二次用户搜索请求,但对用户来说是透明、毫无察觉的。好了,今天就分享到这了。顺便分享一个资料:最后,如果对你有帮助,欢迎点赞、收藏!- End -发布于 2024-02-02 23:28​赞同 1​​1 条评论​分享​收藏​喜欢收起​​

入门区块链,你不可不知的“Token” - 知乎

入门区块链,你不可不知的“Token” - 知乎切换模式写文章登录/注册入门区块链,你不可不知的“Token”币侠1.什么是Token?Token本是一个计算机安全术语,是计算机身份认证中“令牌” 的意思,随着ICO和区块链的大火,Token也变得广为人知。在数字经济的语境中,Token类似于区块链生态里用于流通的货币,也就是代币。比如,我们平时所说的比特币、以太坊就是Token。虽然被称为代币,也类似于货币,但是从Token这个词的本义以及具体内容来看,其本质上是一段代码,并不是货币。Token由区块链的分布式记账技术确保一段代码的唯一性,在发布此Token的组织的生态圈内部流通,像是一个个令牌或者门禁卡,可以打开或关闭一个个大门(智能合约)。发行Token的这个组织想要建立的生态圈,或者说虚拟王国的内部,有着很多的关卡和大门,这些都需要令牌才能打开或者关闭,但是令牌的数量是一定的。在只有三五个人想要令牌,某组织却发放了几千万甚至几千亿个令牌的时候,每个人都可以轻易获得无数的令牌,令牌当然就不值钱了。因此,8年前,程序员LaszloHanyecz用了1万个比特币只能买到2个披萨。但是,一旦人们觉得这个组织想要建立的虚拟王国大有可为,也想要获得一部分令牌以备将来进入王国之需的时候,而令牌的数量却不会增长,受供求关系的影响,自然而然地,令牌的价值就提高了。由此,比特币从一文不名到最高时价值2万美元。于是,8年后,程序员LaszloHanyecz再买两个披萨就只需要花费0.00649个比特币。像是游戏币可以用来购买各种游戏道具一样,Token也可以用来“支付”其王国内的各种服务,从这种角度来看,将其称为代币更加形象一点。另外值得注意的是,Token有其天然的内在价值,并且可交易,这让Token有了价格。通常情况下,Token一经发行,便严格按照区块链代码执行,不受个人或机构控制的。比特币、以太坊、瑞波币、莱特币、以太坊经典是当前市值排名前五的Token。2.Token的产生比特币是早发行的一种Token,比特币背后的区块链是一个记录了比特币产生和交易的账本,且交易不需要任何人担保即可完成。比特币的成功经验,推动了更多Token的产生。目前,新的Token主要通过以下几种方式生成:1)通过改写现有的比特币代码,可以分叉出新的区块链而产生的Token。著名的莱特币,最开始只是简单地调整了比特币的代码。而其他的Token,例如Zcash、Dash和Monero等,则在隐私保护方面进行了创新。所有的这些Token都发起了自己的区块链,和原有的比特币区块链完全分离。2)通过编写全新的区块链而产生的Token。这当中最成功的例子就是以太坊。以太坊受到比特币的启发,从底层设计了新的区块链并且使区块链变得可编程,给区块链带来了新的功能。伴随着这条区块链的产生Token就是Ether,至今,已经上涨了40倍。3.Token的发行首次币发行(ICO),这也是个不陌生的概念,往往跟IPO联想起来,但事实上,二者并不一样,ICO只是对令牌进行预售,令牌可以在将来的虚拟王国中使用,并不涉及到对未来收益的分配。随着数字货币转账在世界范围内的普及,Token发行已经成为了全球关注的大事。除了中国外,区块链项目还在美国、欧洲、日本等地区得到了广泛的关注。如果有个新开的银行账户在几分钟内接到来自世界各地的几千笔汇款,涉及数百万美元,这个账户很可能就会被冻结,但使用数字货币就不会出现这样的情况。互联网和区块链技术使得Token的发售成了一个全球性的行为。Token一旦发行交易后就有了价格,而价格会随着市场波动,这也是它和股权的一大区别。投资者手里的股权可能要等10年之后才能退出变现,但Token在10分钟内就能变现。当前Token在法律和技术上还面临一些未解决的问题。2017年9月4日,央行联合中央网信办、工业和信息化部、工商总局、银监会、证监会以及保监会发布《关于防范代币发行融资风险的公告》(以下简称《公告》),明确表示,发行代币形式包括首次代币发行(ICO)进行融资的活动本质上是一种未经批准非法公开融资的行为,要立即停止各类代币发行融资活动,对于已完成代币发行融资的组织和个人应当做出清退等安排。4. Token带来的改变Token可以在互联网上向合格的投资人发售,因此创业者不必再像以前一样,跑去VC的办公室或者创业咖啡厅进行融资,而可以直接发行Token在全网公开融资。互联网诞生之初,就秉承着开源的精神,然而这些早期的参与者并没有得到太多实际的利益,反而是Google、阿里、腾讯这样的大公司赚得盆满钵满。Token的出现可以使得项目的早期开发人员得到经济上的回报。不过,从Token的本质上来说,它需要找到的是那些将来会真正使用到产品的用户,但事实上,实际的购买者却大多数并不是将来的用户,而是一群试图通过持有代币找人接盘赚取差价的人。这些人的存在,的确使得项目开发人员更容易地获得了经济上的回报,但也阻碍了Token去寻找真正的用户。当Token在这些炒币者的手中迅速拉高价位时,也预示着一个真实有需要的应用可能变成了击鼓传花的游戏,问题在于,花落谁家?更多区块链干货知识,炒币行情,请关注薇信公众号: 币侠(ID:zongcuang666)领取代币奖励编辑于 2018-03-04 16:04区块链(Blockchain)比特币 (Bitcoin)虚拟货币​赞同 41​​1 条评论​分享​喜欢​收藏​申请

token详解-阿里云开发者社区

token详解-阿里云开发者社区

产品解决方案文档与社区权益中心定价云市场合作伙伴支持与服务了解阿里云联系我们4008013260售前咨询售后服务其他服务我要建议我要投诉备案控制台开发者社区首页探索云世界探索云世界云上快速入门,热门云上应用快速查找了解更多问产品动手实践考认证TIANCHI大赛活动广场活动广场丰富的线上&线下活动,深入探索云世界任务中心做任务,得社区积分和周边高校计划让每位学生受益于普惠算力训练营资深技术专家手把手带教话题畅聊无限,分享你的技术见解开发者评测最真实的开发者用云体验乘风者计划让创作激发创新阿里云MVP遇见技术追梦人直播技术交流,直击现场下载下载海量开发者使用工具、手册,免费下载镜像站极速、全面、稳定、安全的开源镜像技术资料开发手册、白皮书、案例集等实战精华插件为开发者定制的Chrome浏览器插件探索云世界新手上云云上应用构建云上数据管理云上探索人工智能云计算弹性计算无影存储网络倚天云原生容器serverless中间件微服务可观测消息队列数据库关系型数据库NoSQL数据库数据仓库数据管理工具PolarDB开源向量数据库热门Modelscope模型即服务弹性计算云原生数据库物联网云效DevOps龙蜥操作系统平头哥钉钉开放平台大数据大数据计算实时数仓Hologres实时计算FlinkE-MapReduceDataWorksElasticsearch机器学习平台PAI智能搜索推荐人工智能机器学习平台PAI视觉智能开放平台智能语音交互自然语言处理多模态模型pythonsdk通用模型开发与运维云效DevOps钉钉宜搭支持服务镜像站码上公益

开发者社区

安全

文章

正文

token详解

2023-07-28

1777

版权

版权声明:

本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《

阿里云开发者社区用户服务协议》和

《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写

侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

简介:

token详解

王卫

目录

热门文章

最新文章

为什么选择阿里云什么是云计算全球基础设施技术领先稳定可靠安全合规分析师报告产品和定价全部产品免费试用产品动态产品定价价格计算器云上成本管理解决方案技术解决方案文档与社区文档开发者社区天池大赛培训与认证权益中心免费试用高校计划企业扶持计划推荐返现计划支持与服务基础服务企业增值服务迁云服务官网公告健康看板信任中心关注阿里云关注阿里云公众号或下载阿里云APP,关注云资讯,随时随地运维管控云服务联系我们:4008013260法律声明Cookies政策廉正举报安全举报联系我们加入我们阿里巴巴集团淘宝网天猫全球速卖通阿里巴巴国际交易市场1688阿里妈妈飞猪阿里云计算AliOS万网高德UC友盟优酷钉钉支付宝达摩院淘宝海外阿里云盘饿了么© 2009-2024 Aliyun.com 版权所有 增值电信业务经营许可证: 浙B2-20080101 域名注册服务机构许可: 浙D3-20210002 京D3-20220015浙公网安备 33010602009975号浙B2-20080101-4

token系统讲解及过期处理 - byd张小伟 - 博客园

token系统讲解及过期处理 - byd张小伟 - 博客园

会员

周边

新闻

博问

AI培训

云市场

所有博客

当前博客

我的博客

我的园子

账号设置

简洁模式 ...

退出登录

注册

登录

byd张小伟

token系统讲解及过期处理

token系统讲解及过期处理:https://blog.csdn.net/qq_35942348/article/details/125971246

前端token知识梳理:token如何存储?token过期如何处理?如何无感刷新token?:https://blog.csdn.net/weixin_42960907/article/details/125503058?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-125503058-blog-126461222.pc_relevant_default&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-125503058-blog-126461222.pc_relevant_default&utm_relevant_index=1

token系统讲解及过期处理1. token是什么?用来做什么2. token存储在哪?过期了怎么办?3. 请求拦截与响应拦截执行时机(面试重点)4. 解决token过期方案一: `重新登录`5. 方案二:使用 `refresh_token` 方案

这玩意很简单,记录一下吧,给入门的小白用下1. token是什么?用来做什么token通常译为令牌,暗号。举个例子:我是古时候皇城中大内的高手(看门的大爷),进皇宫需要皇帝发的特制令牌,没有指定的令牌是不能进的,我会把你拦住,说不定还会把你胖揍一顿。皇宫在这里就相当于我们项目,为了项目的安全性,设置了这个token,进项目的人都需要有这个玩意,证明你有这个权限。token是怎么生成的? 通过哈希算法(不常用)、uuid(雪花算法,可保持全球唯一性),jwt工具等生成随机字符串(也可能会拼接上用户的一些信息)为什么token要有有效期?而且设置得这么短? 为了提高token的安全性,不能永久有效,降低被别人劫持的风险有时候登录的时候为什么会有多个token?1. 常规 token:使用频繁,有效期比较短2. refresh_token:当token过期的时候,用来得到新的token的,使用不频繁,有效期比较长(一般为一个月)我们怎么知道token过期了? 通过调接口时返回的状态码,如果状态码是401(一般情况下),就说明没有携带token,或者token过期了

2. token存储在哪?过期了怎么办?token由服务端生成,通过接口传给前端。一般在登录接口会给token值。存储看具体的项目场景,一般存储在本地缓存里,有两种方案供君选择:sessionStorage(会话级别,网页一关就歇逼了)localStorage(永久的,需要手动去清除)token过期处理重新登录 => 清空token,跳转登录页refresh_token => 得到一个全新的token3. 请求拦截与响应拦截执行时机(面试重点)这玩意面试问的多,看图很清晰:

请求拦截器执行时机:axios调用之后,浏览器真正发起请求之前响应拦截器执行时机:浏览器接受到响应数据之后,axios拿到数据之前4. 解决token过期方案一: 重新登录知道出现了401的错误: 使用响应拦截器进行页面的跳转此种方案用户体验不是很好(目前大部分企业及项目都这么干)import store from '@/store'

// 响应拦截器request.interceptors.response.use( function (response) { // 响应成功(响应状态码是 2xx)时执行第一个回调函数 console.log('响应成功....') return response }, function (error) { // 网络异常或响应失败(响应状态码是非2开头)时执行第二个回调函数 console.log('响应失败....') // 1. 判断响应的状态码是不是401,如果不是401就不用做任何处理 if (error.response && error.response.status === 401) { // 2. 如果是401,就先清空token, 并跳转到登录页 store.commit('setUser', null) router.push('/login') } return Promise.reject(error) })12345678910111213141516171819205. 方案二:使用 refresh_token 方案判断有没有refresh_token,如果没有跳转登录页如果有refresh_token,调用刷新token的接口,拿到新的token更新vuex和loaclStoreage存储的token为原来调用接口方,重新去调用接口如果利用refresh_token,刷新token的接口失败,则还是跳转到登录页附上了详细的注释,讲道理大佬们应该看得懂import axios from 'axios'import store from '@/store'import router from '@/router'

const baseURL = 'http://xxx.xxx.net/'

const request = axios.create({ baseURL // 接口的基准路径})

// 请求拦截器// Add a request interceptorrequest.interceptors.request.use(function (config) { // 请求发起会经过这里 // config:本次请求的请求配置对象 const { user } = store.state if (user && user.token) { config.headers.Authorization = `Bearer ${user.token}` } // 注意:这里务必要返回 config 配置对象,否则请求就停在这里出不去了 return config}, function (error) { // 如果请求出错了(还没有发出去)会进入这里 return Promise.reject(error)})

request.interceptors.response.use( function (response) { // 响应成功(响应状态码是 2xx)时执行第一个回调函数 return response }, async function (error) { // 网络异常或响应失败(响应状态码是非2开头)时执行第二个回调函数 console.log('响应失败时执行的代码....') if (error.response && error.response.status === 401) { const user = store.state.user if (user && user.refresh_token) { // 1. 判断有没有refresh_token,如果没有跳转登录页 // 2. 如果有refresh_token,调用刷新token的接口,拿到新的token try { var res = await axios({ baseURL: baseURL, method: 'PUT', url: '/xxx/xxx', headers: { Authorization: `Bearer ${user.refresh_token}` } }) } catch { // 5. 如果refresh_token过期,进行清空token并跳转到登录页的处理 store.commit('setUser', null) router.push('/login') }

// 3. 更新vuex和loaclStoreage存储的token store.commit('setUser', { refresh_token: user.refresh_token, token: res.data.data.token }) // 4. 为原来调用接口方,重新去调用接口 console.log(error.config) return request(error.config) } else { // 1. 判断有没有refresh_token,如果没有跳转登录页 store.commit('setUser', null) router.push('/login') } }

// 3. 如果利用refresh_token,刷新token的接口失败,则还是跳转到登录页 // eslint-disable-next-line prefer-promise-reject-errors return Promise.reject(error) })

export default request————————————————版权声明:本文为CSDN博主「欧阳呀」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/qq_35942348/article/details/125971246

posted on

2022-12-02 16:50 

byd张小伟 

阅读(1570) 

评论(0) 

编辑 

收藏 

举报

会员力量,点亮园子希望

刷新页面返回顶部

导航

博客园

首页

联系

订阅

管理

公告

Powered by:

博客园

Copyright © 2024 byd张小伟

Powered by .NET 8.0 on Kubernetes