深度解析GPT中的Tokenizer

继学习完深度解析大语言模型中的词向量后,让我们继续学习大语言模型中另外几个重要概念:token(词元)、tokenization(词元化)、tokenizer(词元生成器)。

在GPT模型中,tokenization(词元化)指的是将用户输入的文本分割成token(词元)的过程,以让GPT能更好地理解输入文本的词义、句法和语义,以及生成更连贯的输出内容。这是非常重要的预处理操作,对模型的最终效果有重大影响。

tokenizer(词元生成器)是将文本切分成token的工具或组件。它将原始文本转换成模型可处理的数字形式,为GPT的生成与推理提供基础能力。

语言大模型(如GPT-3/4、LLaMA和PaLM)使用token作为基本单位进行工作。它们接受文本作为输入,将其转换为token(整数),然后预测接下来应该出现哪些token。
 

通过操作这些token,可以更好地了解它们在语言模型内部的工作原理。


OpenAI提供了一个tokenizer,用以探索token的工作方式。我自己构建了一个更有意思的工具,是一个Observable notebook(https://observablehq.com/@simonw/gpt-tokenizer)。在这个Observable notebook中,你可以将文本转换为token,将token转换为文本,还可以搜索整个token表。

这个Observable notebook看起来是这样的:

我在这里切分的文本是:

The dog eats the apples

El perro come las manzanas

片仮名

在给定示例中,总共生成了21个整数token。5个对应英文文本,8个对应西班牙文本,6个(每个字符两个)对应三个日文字符。两个换行符也分别被表示为整数token。

Observable notebook使用了GPT-2的tokenizer(基于EJ Fox和Ian Johnson所创建的优秀notebook),主要作为教育工具使用,不过GPT-3及更高版本的最新tokenizer与GPT-2的tokenizer存在些许差异。

1、探索一些有趣的token

通过与tokenizer进行交互可以发现各种有趣的模式。大多数常见的英语单词都分配一个token,如上所示:

  • “The”: 464
  • “ dog”: 3290
  • “ eats”: 25365
  • “ the”: 262
  • “ apples”: 22514

需要注意的是:字母的大小写很重要。以单词“the”为例,大写字母T的“The”对应的token是464,而以小写字母t开头且有一个前导空格的单词“the”对应的token却是262。

许多单词的token里都包含了一个前导空格,这样就不再需要为每个空格字符使用一个额外的token,从而能更有效地对整个句子进行编码,相比英语,在对其他语言进行切分时,效率可能要低点。西班牙语“El perro come las manzanas”这句话的编码如下:

  • “El”: 9527
  • “ per”: 583
  • “ro”: 305
  • “ come”: 1282
  • “ las”: 39990
  • “ man”: 582
  • “zan”: 15201
  • “as”: 292

此处就显示出了对英语的偏向。因为“man”是一个英语单词,所以它的token ID较低,为582。而“zan”不是一个在英语中独立存在的单词,但也是一个常见的字符序列,因此仍然值得拥有自己的token,所以它的token ID为15201。

有些语言甚至会出现单个字符编码为多个token的情况,比如以下这些日语:

  • 片: 31965 229
  • 仮: 20015 106
  • 名: 28938 235

2、故障token

“故障token”(glitch tokens)是一类令人着迷的token子集。其中一个有趣的例子是token 23282,即“davidjl”。可以通过在notebook的搜索框中搜索“david”来找到该token。

Scale AI的prompt工程师Riley Goodside指出了与该token相关的一些奇怪行为。

为什么会发生这种情况?这是一个有趣的谜题。

token 23282可能与Reddit上的用户“davidjl123”有关。该用户是/r/counting子论坛的一位热情用户,他经常在该论坛上发布递增数,并且已经发布了超过163,000次这样的帖子。

据推测,/r/counting子论坛中的数据最终被用于训练GPT-2的tokenizer。由于用户davidjl123在该子论坛中出现了数十万次,所以最终分配到了属于自己的token。

为什么这种情况会导致类似问题呢?到目前为止,我看到最好的解释来自Hacker News上的用户@londons_explore

这些故障token都位于token嵌入空间的中心附近。这意味着,模型在区分这些token和其他位于嵌入空间中心附近的token时存在困难,因此当被要求“重复”这些token时,模型会选择错误的token。

这种情况发生的原因是,这些token在互联网上出现了很多次(例如,davidjl用户在Reddit上有163000个帖子,仅仅是计算递增的数字),但是这些token本身并不难以预测(因此,在训练过程中,梯度变得几乎为零,并且嵌入向量会衰减到零,这是某些优化器在归一化权重时会进行的操作)。

在“SolidGoldMagikarp (plus, prompt generation)”这篇帖子下,LessWrong对这种现象进行了详细说明。

3、用tiktoken进行token计数

OpenAI的模型都有token限制。有时在将文本传递给API之前,需要计算字符串中的token数量,以确保不超过该限制。

其中,一个需要计算token数量的技术是“检索增强生成(Retrieval Augmented Generation)”,通过对文档语料库运行搜索(或嵌入搜索)来回答用户的问题,提取最有可能的内容,并将其作为上下文涵盖在prompt中。

成功实现这种模式的关键是,在token限制内包含尽可能多的相关上下文,因此需要能够计算token数量。

OpenAI提供了一个名为tiktoken(https://github.com/openai/tiktoken)的Python库来实现这一功能。

如果你深入研究这个库,就会发现它目前包括五种不同的切分方案:r50k_base、p50k_base、p50k_edit、cl100k_base和gpt2。

其中,cl100k_base是最相关的,它是GPT-4和当前ChatGPT使用的经济型gpt-3.5-turbo模型的tokenizer。

text-davinci-003 使用的是p50k_base 。在tiktoken/model.py 的MODEL_TO_ENCODING 词典中可以找到模型与tokenizer的完整映射。

以下是如何使用tiktoken 的代码示例:

import tiktoken
encoding = tiktoken.encoding_for_model("gpt-4")
# or "gpt-3.5-turbo" or "text-davinci-003"
tokens = encoding.encode("Here is some text")
token_count = len(tokens)  

现在token将是一个包含四个整数token ID的数组——在该例中是[8586, 374, 1063, 1495]。

使用.decode()方法将一个token ID数组转换回文本:

text = encoding.decode(tokens)
# 'Here is some text' 

第一次调用encoding_for_model()时,编码数据将通过HTTP从 openaipublic.blob.core.windows.net Azure Blob存储桶(storage bucket)获取(代码:https://github.com/openai/tiktoken/blob/0.4.0/tiktoken_ext/openai_public.py)。这些数据会被缓存在临时目录中,但如果机器重新启动,该目录将被清除。你可通过设置 TIKTOKEN_CACHE_DIR环境变量来强制使用更持久的缓存目录。

4、ttok

几周前,我介绍了ttok(https://github.com/simonw/ttok),这是tiktoken的一个命令行封装工具,具有两个关键功能:一是可以计算输入给它的文本中的token数量,二是可以将该文本截断为指定数量的token。

它可以计算输入到其中的文本中的token数:

# Count tokens
echo -n "Count these tokens" | ttok
# Outputs: 3 (the newline is skipped thanks to echo -n)  

# Truncation
curl 'https://simonwillison.net/' | strip-tags -m | ttok -t 6
# Outputs: Simon Willison’s Weblog 

# View integer token IDs
echo "Show these tokens" | ttok --tokens
# Outputs: 7968 1521 11460 198 


使用-m gpt2或类似选项可选择使用适用于不同模型的编码。

5、token生成过程

一旦你理解了token,那么GPT工具生成文本的方式就会变得更加明了。

特别有趣的是,观察到GPT-4将其输出流式化为独立的token(GPT-4的速度略慢于3.5版本,可以更容易观察到其生成过程)。

以下是使用我的llm CLI(https://github.com/simonw/llm)工具从GPT-4生成文本的结果,命令是llm -s 'Five names for a pet pelican' -4:


如你所见,不在词典中的名字(如“Pelly”)占据了多个token,而“Captain Gulliver”作为一个整体输出了token “Captain”。

原文:Understanding GPT tokenizers

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【与C++的邂逅之旅】--- 内联函数 auto关键字 基于范围的for循环 nullptr

关注小庄 顿顿解馋૮(˶ᵔ ᵕ ᵔ˶)ა 博主专栏: 💡 与C的邂逅之旅 💡 数据结构之旅 上篇我们了解了函数重载和引用,我们继续学习有关C的一些小语法— 内联函数,auto关键字,基于范围的for循环以及 nullptr&…

设计模式——建造者模式03

工厂模式注重直接生产一个对象,而建造者模式 注重一个复杂对象是如何组成的(过程),在生产每个组件时,满足单一原则,实现了业务拆分。 设计模式,一定要敲代码理解 组件抽象 public interface …

02---webpack基础用法

01 entry打包的入口文件: 单入口entry是一个字符串:适用于单页面项目module.exports {entry:./src/index.js}多入口entry是一个对象module.exports {entry:{index:./src/index.js,app:./src/app.js}} 02 output打包的出口文件: 单入口配置module.ex…

【opencv】教程代码 —video(3) 视频背景剔除

bg_sub.cpp 这段代码的功能是把视频中的背景和前景分离,提取出前景的运动物体。根据用户选择的不同的模式,可以选择基于MOG2或者基于KNN的方法来进行背景减除。在处理每一帧图像的过程中,首先使用背景减除模型对图像帧进行处理,得…

RabbitMQ3.7.8集群分区(脑裂现象)模拟及恢复处置全场景测试

测试环境准备: MQ服务器集群地址,版本号为3.7.8: 管理控制台地址:http://173.101.4.6:15672/#/queues 集群状态 rabbitmqctl cluster_status 集群操作相关命令: 创建一个RabbitMQ集群涉及到如下步骤: 安装RabbitMQ: 在每台要在集…

JVM专题——类文件加载

本文部分内容节选自Java Guide和《深入理解Java虚拟机》, Java Guide地址: https://javaguide.cn/java/jvm/class-loading-process.html 🚀 基础(上) → 🚀 基础(中) → 🚀基础(下&a…

利用AI结合无极低码(免费版)快速实现接口开发教程,会sql即可,不需要编写编译代码

无极低码无代码写服务+AI实践 本次演示最简单的单表无代码增删改查发布服务功能,更复杂的多表操作,安全验证,多接口调用,自自动生成接口服务,生成二开代码,生成调用接口测试,一键生成管理界面多条件检索、修改、删除、查看、通用公共接口调用、通用无限级字典调用等后续…

【Linux】Ubuntu 文件权限管理

Linux 系统对文件的权限有着严格的控制,用于如果相对某个文件执行某种操作,必须具有对应的权限方可执行成功,这也是Linux有别于Windows的机制,也是基于这个权限机制,Linux可以有效防止病毒自我运行。因为运行的条件是必…

第二十三章 Git

一、Git Git 是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。 Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。 Git 与常用的版本控制工具 CVS, Subversion 等不同,它采用了分布式版…

前端三剑客 —— CSS ( 坐标问题 、定位问题和图片居中 )

前期内容回顾: 1.常见样式 text-shadow x轴 y轴 阴影的模糊程度 阴影的颜色 box-shadow border-radio 实现圆角 margin 内边距 padding 外边距 background 2.特殊样式 媒体查询:media 自定义字体:font-face { font-family:自定义名称&#…

代码随想录算法训练营第四十四天 |卡码网52. 携带研究材料 、518. 零钱兑换 II、377. 组合总和 Ⅳ

代码随想录算法训练营第四十四天 |卡码网52. 携带研究材料 、518. 零钱兑换 II、377. 组合总和 Ⅳ 卡码网52. 携带研究材料题目解法 518. 零钱兑换 II题目解法 377. 组合总和 Ⅳ题目解法 感悟 卡码网52. 携带研究材料 题目 解法 题解链接 1. #include <iostream> #inc…

生成式人工智能与 LangChain(预览)(上)

原文&#xff1a;Generative AI with LangChain 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 一、生成模型是什么&#xff1f; 人工智能&#xff08;AI&#xff09;取得了重大进展&#xff0c;影响着企业、社会和个人。在过去的十年左右&#xff0c;深度学习已经发…

【接口】HTTP(1)|请求|响应

1、概念 Hyper Text Transfer Protocol&#xff08;超文本传输协议&#xff09;用于从万维网&#xff08;就是www&#xff09;服务器传输超文本到本地浏览器的传送协议。 HTTP协议是基于TCP的应用层协议&#xff0c;它不关心数据传输的细节&#xff0c;主要是用来规定客户端和…

单元测试 mockito(二)

1.返回指定值 2.void返回值指定插桩 3.插桩的两种方式 when(obj.someMethod()).thenXxx():其中obj可以是mock对象 doXxx().wien(obj).someMethod():其中obj可以是mock/spy对象 spy对象在没有插桩时是调用真实方法的,写在when中会导致先执行一次原方法,达不到mock的目的&#x…

RobotFramework测试框架(2)-测试用例

创建测试数据 测试数据语法 这里的测试数据就是指的测试用例。 测试文件组织 测试用例的组织层次结构如下&#xff1a; 在测试用例文件&#xff08; test case file &#xff09;中建立测试用例 一个测试文件自动的建成一个包含了这些测试用例的测试集&#xff08; test s…

vulhub中Apache Solr 远程命令执行漏洞复现(CVE-2019-0193)

Apache Solr 是一个开源的搜索服务器。Solr 使用 Java 语言开发&#xff0c;主要基于 HTTP 和 Apache Lucene 实现。此次漏洞出现在Apache Solr的DataImportHandler&#xff0c;该模块是一个可选但常用的模块&#xff0c;用于从数据库和其他源中提取数据。它具有一个功能&#…

【Android Studio】上位机-安卓系统手机-蓝牙调试助手

【Android Studio】上位机-安卓系统手机-蓝牙调试助手 文章目录 前言AS官网一、手机配置二、移植工程三、配置总结 前言 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 AS官网 AS官网 一、手机配置 Android Studio 下真机调试 二、移植工程 Anro…

【Linux】第二个小程序--简易shell

请看上面的shell&#xff0c;其本质就是一个字符串&#xff0c;我们知道bash本质上就是一个进程&#xff0c;只不过命令行就是一个输出的字符串&#xff0c; 我们输入的命令“ls -a -l”实际上是我们在输入行输入的字符串&#xff0c;所以&#xff0c;如果我们想要做一个简易的…

通用开发技能系列:SQL基础学习

云原生学习路线导航页&#xff08;持续更新中&#xff09; 本文是 通用开发技能系列 文章&#xff0c;主要对编程通用技能 SQL基础 进行学习 1.数据库简介 1.1.数据库中的一些名称 DataBase&#xff1a;数据库 程序员只负责怎么维护存取数据&#xff0c;不管数据库是什么 DBA…

c#程序报错引用无效解决办法之一:检查引用的文件路径

直接右键然后打开本地 打开这个.csproj文件&#xff0c;直接对着路径看看里面的路径对不对。 一般是很多人一起开发&#xff0c;然后这个文件路径被推送上来的问题