GPT 内部 — I : 了解文本生成

年轻的陀思妥耶夫斯基被介绍给生成AI,通过Midjourney创建

一、说明

        我经常与不同领域的同事互动,我喜欢向几乎没有数据科学背景的人传达机器学习概念的挑战。在这里,我试图用简单的术语解释 GPT 是如何连接的,只是这次是书面形式。

        在ChatGPT流行的魔术背后,有一个不受欢迎的逻辑。你给 ChatGPT 写一个提示,它会生成文本,无论它是否准确,它都类似于人类的答案。它如何能够理解您的提示并生成连贯且易于理解的答案?请看本文。

二、变压器神经网络

        该架构旨在处理大量非结构化数据,在我们的例子中是文本。当我们说架构时,我们的意思本质上是一系列并行在几层中进行的数学运算。通过这个方程组,引入了一些创新,帮助我们克服了长期存在的文本生成挑战。直到 5 年前,我们一直在努力解决的挑战。

        如果 GPT 已经在这里存在了 5 年(确实 GPT 论文是在 2018 年发表的),那么 GPT 不是旧消息吗?为什么它最近变得非常受欢迎?GPT 1、2、3、3.5 (ChatGPT ) 和 4 有什么区别?

        所有 GPT 版本都构建在相同的架构上。但是,每个后续模型都包含更多参数,并使用更大的文本数据集进行训练。显然,后来的 GPT 版本引入了其他新颖性,尤其是在训练过程中,例如通过人类反馈进行强化学习,我们将在本博客系列的第 3 部分中解释。

2.1 向量、矩阵、张量。

        所有这些花哨的词本质上都是包含数字块的单位。这些数字经过一系列数学运算(主要是乘法和求和),直到我们达到最佳输出值,这是可能结果的概率。

        输出值?从这个意义上说,它是语言模型生成的文本,对吧?是的。那么,输入值是什么?是我的提示吗?是的,但不完全是。那么背后还有什么呢?

        在继续讨论不同的文本解码策略(这将是以下博客文章的主题)之前,消除歧义很有用。让我们回到我们一开始问的基本问题。它如何理解人类语言?

2.2 生成式预训练变压器

        GPT 缩写代表的三个词。我们触摸了上面的转换器部分,它代表了进行大量计算的架构。但是我们到底计算了什么?你甚至从哪里得到数字?它是一个语言模型,您要做的就是输入一些文本。如何计算文本?

数据是不可知的。所有数据都是相同的,无论是文本、声音还是图像形式。

2.3 令牌 

        我们将文本拆分为小块(令牌),并为每个块分配一个唯一的编号(令牌ID)。模特不认识文字、图像或录音。他们学会用大量的数字(参数)来表示它们,这可以作为我们以数字形式说明事物特征的工具。令牌是传达含义的语言单位,令牌 ID 是编码令牌的唯一数字。

        显然,我们如何标记语言可能会有所不同。词汇化可能涉及将文本拆分为句子、单词、单词的一部分(子单词)甚至单个字符。

让我们考虑一个场景,我们的语言语料库中有 50,000 个代币(类似于 GPT-2 有 50,257 个)。标记化后我们如何表示这些单位?

Sentence: "students celebrate the graduation with a big party"
Token labels: ['[CLS]', 'students', 'celebrate', 'the', 'graduation', 'with', 'a', 'big', 'party', '[SEP]']
Token IDs: tensor([[ 101, 2493, 8439, 1996, 7665, 2007, 1037, 2502, 2283,  102]])

        上面是一个被标记成单词的示例句子。令牌化方法在实现上可能有所不同。对于我们现在来说,重要的是要了解我们通过其相应的令牌 ID 获取语言单位(标记)的数字表示。那么,现在我们有了这些令牌 ID,我们是否可以简单地将它们直接输入到进行计算的模型中?

        基数在数学 101 和 2493 中很重要,因为令牌表示对模型很重要。因为请记住,我们所做的主要是大块数字的乘法和求和。因此,将数字乘以 101 或 2493 很重要。那么,我们如何确保用数字 101 表示的代币的重要性不亚于 2493,只是因为我们碰巧任意地标记了它?我们如何在不导致虚构排序的情况下对单词进行编码?

2.4 单热编码。 

        令牌的稀疏映射。独热编码是我们将每个令牌投影为二进制向量的技术。这意味着向量中只有一个元素是 1(“热”),其余元素是 0(“冷”)。

作者图片:独热编码向量示例

        令牌用一个向量表示,该向量在我们的语料库中具有总令牌的长度。简单来说,如果我们的语言中有 50k 个令牌,则每个标记都由一个向量 50k 表示,其中只有一个元素为 1,其余元素为 0。由于此投影中的每个向量仅包含一个非零元素,因此将其命名为稀疏表示。但是,您可能认为这种方法效率非常低。是的,我们设法删除了令牌 ID 之间的人工基数,但我们无法推断有关单词语义的任何信息。我们无法通过使用稀疏向量来理解“派对”一词是指庆祝活动还是政治组织。此外,用大小为 50k 的向量表示每个代币将意味着总共 50k 个长度为 50k 的向量。这在所需的内存和计算方面效率非常低。幸运的是,我们有更好的解决方案。

2.5 嵌入。

        令牌的密集表示形式。标记化单元通过嵌入层,其中每个标记都转换为固定大小的连续向量表示。例如,在 GPT 3 的情况下,中的每个标记都由 768 个数字的向量表示。这些数字是随机分配的,然后在看到大量数据(训练)后被模型学习。

Token Label: “party”
Token : 2283
Embedding Vector Length: 768
Embedding Tensor Shape: ([1, 10, 768])Embedding vector:tensor([ 2.9950e-01, -2.3271e-01,  3.1800e-01, -1.2017e-01, -3.0701e-01,-6.1967e-01,  2.7525e-01,  3.4051e-01, -8.3757e-01, -1.2975e-02,-2.0752e-01, -2.5624e-01,  3.5545e-01,  2.1002e-01,  2.7588e-02,-1.2303e-01,  5.9052e-01, -1.1794e-01,  4.2682e-02,  7.9062e-01,2.2610e-01,  9.2405e-02, -3.2584e-01,  7.4268e-01,  4.1670e-01,-7.9906e-02,  3.6215e-01,  4.6919e-01,  7.8014e-02, -6.4713e-01,4.9873e-02, -8.9567e-02, -7.7649e-02,  3.1117e-01, -6.7861e-02,-9.7275e-01,  9.4126e-02,  4.4848e-01,  1.5413e-01,  3.5430e-01,3.6865e-02, -7.5635e-01,  5.5526e-01,  1.8341e-02,  1.3527e-01,-6.6653e-01,  9.7280e-01, -6.6816e-02,  1.0383e-01,  3.9125e-02,-2.2133e-01,  1.5785e-01, -1.8400e-01,  3.4476e-01,  1.6725e-01,-2.6855e-01, -6.8380e-01, -1.8720e-01, -3.5997e-01, -1.5782e-01,3.5001e-01,  2.4083e-01, -4.4515e-01, -7.2435e-01, -2.5413e-01,2.3536e-01,  2.8430e-01,  5.7878e-01, -7.4840e-01,  1.5779e-01,-1.7003e-01,  3.9774e-01, -1.5828e-01, -5.0969e-01, -4.7879e-01,-1.6672e-01,  7.3282e-01, -1.2093e-01,  6.9689e-02, -3.1715e-01,-7.4038e-02,  2.9851e-01,  5.7611e-01,  1.0658e+00, -1.9357e-01,1.3133e-01,  1.0120e-01, -5.2478e-01,  1.5248e-01,  6.2976e-01,-4.5310e-01,  2.9950e-01, -5.6907e-02, -2.2957e-01, -1.7587e-02,-1.9266e-01,  2.8820e-02,  3.9966e-03,  2.0535e-01,  3.6137e-01,1.7169e-01,  1.0535e-01,  1.4280e-01,  8.4879e-01, -9.0673e-01,… … …                           ])

        上面是单词“party”的嵌入向量示例。

        现在我们有 50,000x786 大小的矢量,相比之下,50,000x50,000 个独热编码的效率要高得多。

        嵌入向量将是模型的输入。由于密集的数字表示,我们将能够捕获单词的语义,相似的标记的嵌入向量将彼此更接近。

        如何在上下文中衡量两个语言单元的相似性?有几个函数可以测量相同大小的两个向量之间的相似性。让我们用一个例子来解释它。

        考虑一个简单的例子,我们有标记“猫”、“狗”、“汽车”和“香蕉”的嵌入向量。为了简化起见,我们使用嵌入大小 4。这意味着将有四个学习的数字来表示每个令牌。

import numpy as np
from sklearn.metrics.pairwise import cosine_similarity# Example word embeddings for "cat" , "dog", "car" and "banana"
embedding_cat = np.array([0.5, 0.3, -0.1, 0.9])
embedding_dog = np.array([0.6, 0.4, -0.2, 0.8])
embedding_car = np.array([0.5, 0.3, -0.1, 0.9])
embedding_banana = np.array([0.1, -0.8, 0.2, 0.4])

        使用上面的向量,让我们使用余弦相似度来计算相似度分数。人类逻辑会发现“狗”和“猫”这个词比“香蕉汽车”这两个词彼此更相关。我们可以期望数学来模拟我们的逻辑吗?

# Calculate cosine similarity
similarity = cosine_similarity([embedding_cat], [embedding_dog])[0][0]print(f"Cosine Similarity between 'cat' and 'dog': {similarity:.4f}")# Calculate cosine similarity
similarity_2 = cosine_similarity([embedding_car], [embedding_banana])[0][0]print(f"Cosine Similarity between 'car' and 'banana': {similarity:.4f}")
"Cosine Similarity between 'cat' and 'dog': 0.9832"
"Cosine Similarity between 'car' and 'banana': 0.1511"

        我们可以看到,单词“cat”和“dog”的相似度得分非常高,而单词“car”和“banana”的相似度得分非常低。现在想象一下,对于我们的语言语料库中的每 50000 个标记,嵌入长度为 768 而不是 4 个的向量。这就是我们如何找到彼此相关的单词的方式。

        现在,我们来看看下面两个语义复杂度较高的句子。

"students celebrate the graduation with a big party""deputy leader is highly respected in the party"

        第一句和第二句中的“党”一词传达了不同的含义。大型语言模型如何能够区分作为政治组织的“政党”和作为庆祝社会活动的“政党”之间的区别?

        我们能否通过 token 嵌入来区分同一个 token 的不同含义?事实是,尽管嵌入为我们提供了一系列优势,但它们不足以解决人类语言语义挑战的全部复杂性。

        自我关注。变压器神经网络再次提供了解决方案。我们生成一组新的权重(参数的另一个名称),即查询矩阵、键矩阵和值矩阵。这些权重学习将标记的嵌入向量表示为一组新的嵌入。如何?只需取原始嵌入的加权平均值即可。每个标记“关注”输入句子中的每个其他标记(包括其自身),并计算一组注意力权重,或者换句话说,新的所谓“上下文嵌入”。

        它所做的只是通过分配使用标记嵌入计算的新数字集(注意力权重)来映射输入句子中单词的重要性。

        作者提供的图片:不同上下文中 token 的注意力权重(BertViz 注意力头视图)

        上面的可视化用两句话展示了令牌“方”对其余令牌的“关注”。连接的大胆性表明了代币的重要性或相关性。注意和“出席”是指代一系列新的数字(注意参数)及其大小的术语,我们用它来用数字表示单词的重要性。在第一句中,“聚会”一词最关注“庆祝”一词,而在第二句中,“代表”一词最受关注。这就是模型如何能够通过检查周围的单词来合并上下文。

        正如我们在注意力机制中提到的,我们推导出新的权重矩阵集,即:查询、键和值(简称 q,k,v)。它们是相同大小(通常小于嵌入向量)的级联矩阵,被引入到体系结构中以捕获语言单元的复杂性。学习注意力参数是为了揭开单词,单词对,单词对和单词对对等之间的关系的神秘面纱。下面是查找最相关单词的查询、键和值矩阵的可视化效果。

        图片由作者提供:查询键值矩阵及其最终概率图示(BertViz q,k,v 视图)

        可视化将 q 和 k 向量表示为垂直波段,其中每个波段的粗体反映了其幅度。令牌之间的连接表示由注意力决定的权重,表明“party”的q向量与“is”,“deputy”和“respected”的k向量最显着地对齐。

        为了使注意力机制和q,k和v的概念不那么抽象,想象一下你去参加一个聚会,听到了一首你爱上的惊人歌曲。派对结束后,您渴望找到这首歌并再次收听,但您只记得歌词中的 5 个单词和歌曲旋律的一部分(查询)。要找到这首歌,您决定浏览派对播放列表(键)并收听(相似性功能)派对上播放的列表中的所有歌曲。当您最终认出这首歌时,您会记下歌曲的名称(值)。

        转换器引入的最后一个重要技巧是将位置编码添加到向量嵌入中。仅仅因为我们想捕获单词的位置信息。它增强了我们更准确地预测下一个标记的机会,以达到真实的句子上下文。这是基本信息,因为经常交换单词会完全改变上下文。例如,“蒂姆追了一辈子的云”和“云追了蒂姆一辈子”这句话在本质上是绝对不同的。

        到目前为止,我们在基本级别上探索的所有数学技巧,其目标是在给定输入令牌序列的情况下预测下一个令牌。事实上,GPT 是在一个简单的任务上进行训练的,即文本生成,或者换句话说,下一个令牌预测。问题的核心是,我们衡量代币的概率,给定它之前出现的代币序列。

        您可能想知道模型如何从随机分配的数字中学习最佳数字。这可能是另一篇博客文章的主题,但这实际上是理解的基础。此外,这是一个很好的迹象,表明您已经在质疑基础知识。为了消除不明确性,我们使用了一种优化算法,该算法根据称为损失函数的指标调整参数。此指标是通过将预测值与实际值进行比较来计算的。该模型跟踪指标的机会,并根据损失值的大小调整数字。这个过程一直完成,直到给定我们在称为超参数的算法中设置的规则,损失不能更小。一个示例超参数可以是,我们想要计算损失和调整权重的频率。这是学习背后的基本思想。

        我希望在这篇简短的文章中,我至少能够稍微清除图片。本博客系列的第二部分将重点介绍解码策略,即为什么您的提示很重要。第三部分也是最后一部分将专门讨论 ChatGPT 成功的关键因素,即通过人类反馈进行强化学习。非常感谢您的阅读。直到下次。

三、引用:

A.瓦斯瓦尼,N.沙泽尔,N.帕尔马,J.乌什科雷特,L.琼斯,A.N.戈麦斯,Ł。Kaiser和I. Polosukhin,“注意力是你所需要的一切”,神经信息处理系统进展30(NIPS 2017),2017。

J. Vig,“转换器模型中注意力的多尺度可视化”,计算语言学协会第 57 届年会论文集:系统演示,第 37-42 页,意大利佛罗伦萨,计算语言学协会,2019 年。

L. Tunstall、L. von Werra 和 T. Wolf,“使用变形金刚进行自然语言处理,修订版”,O'Reilly Media, Inc.,2022 年 9781098136796 月发布,ISBN:<>。

1 -懒惰的程序员博客

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

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

相关文章

Windows安装Neo4j

图数据库概述 图数据库是基于图论实现的一种NoSQL数据库&#xff0c;其数据存储结构和数据查询方式都是以图论&#xff08;它以图为研究对象图论中的图是由若干给定的点及连接两点的线所构成的图形&#xff09;为基础的&#xff0c; 图数据库主要用于存储更多的连接数据。 Neo…

Java集合(Collection、Iterator、Map、Collections)概述——Java第十三讲

前言 本讲我们将继续来讲解Java的其他重要知识点——Java集合。Java集合框架是Java编程语言中一个重要的部分,它提供了一套预定义的类和接口,供程序员使用数据结构来存储和操作一组对象。Java集合框架主要包括两种类型:一种是集合(Collection),存储一个元素列表,…

C++【C++学习笔记_Wang】

时间进度C是什么&#xff1f;多态什么是多态&#xff1f;生活中的多态C中的多态 赋值兼容赋值兼容规则实现安全转换 时间进度 Day101 ok Day804 ok Day805 ok C是什么&#xff1f; C大部分包含C语言。 C完全兼容C语言。 C在C语言的基础上添加&#xff1a;封装、继承、多态…

Could not find artifact com.mysql:mysql-connector-j:pom:unknown

在 <dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope> </dependency> 添加版本号 这里用的是8.0.33版本&#xff0c;输入5.0的版本依然会报错 我自身用的是5.0…

kubernetes(K8S)笔记

文章目录 大佬博客简介K8SDocker VS DockerDockerK8S简介K8S配合docker相比较单纯使用docker 大佬博客 Kubernetes&#xff08;通常缩写为K8s&#xff09;是一个用于自动化容器化应用程序部署、管理和扩展的开源容器编排平台。它的构造非常复杂&#xff0c;由多个核心组件和附加…

领域驱动设计:事件风暴构建领域模型

文章目录 事件风暴需要准备些什么&#xff1f;如何用事件风暴构建领域模型&#xff1f; 事件风暴是一项团队活动&#xff0c;领域专家与项目团队通过头脑风暴的形式&#xff0c;罗列出领域中所有的领域事件&#xff0c;整合之后形成最终的领域事件集合&#xff0c;然后对每一个…

【PowerQuery】Excel 一分钟以内刷新PowerQuery数据

当需要进行刷新的周期如果小于一分钟,采用数据自动刷新就无法实现自动刷新的目标。那就没有办法了吗?当然不是,这里就是使用VBA来实现自动刷新。这里实现VBA刷新的第一步就是将当前的Excel 保存为带有宏的Excel 文件,如果不带宏则无法运行带有宏代码的Excel文件,保存过程如…

数据结构与算法(一)数组的相关概念和底层java实现

一、前言 从今天开始&#xff0c;笔者也开始从0学习数据结构和算法&#xff0c;但是因为这次学习比较捉急&#xff0c;所以记录的内容并不会过于详细&#xff0c;会从基础和底层代码实现以及力扣相关题目去写相关的文章&#xff0c;对于详细的概念并不会过多讲解 二、数组基础…

分析udev自动创建设备结点的过程

当系统内核发现系统中添加了某个新的设备时&#xff0c;在内核空间中会对该驱动进行注册&#xff0c;并获取该驱动设备的信息&#xff0c;然后创建一个设备类&#xff08;向上提交目录信息&#xff09;&#xff0c;并申请struct class对象并且初始化&#xff0c;然后创建一个设…

SpringCloud:Feign实现微服务之间相互请求

文章目录 &#x1f389;欢迎来到Java学习路线专栏~SpringCloud&#xff1a;Feign实现微服务之间相互请求 ☆* o(≧▽≦)o *☆嗨~我是IT陈寒&#x1f379;✨博客主页&#xff1a;IT陈寒的博客&#x1f388;该系列文章专栏&#xff1a;Java学习路线&#x1f4dc;其他专栏&#xf…

2023大数据面试总结

文章目录 Flink&#xff08;SQL相关后面专题补充&#xff09;1. 把状态后端从FileSystem改为RocksDB后&#xff0c;Flink任务状态存储会发生哪些变化&#xff1f;2. Flink SQL API State TTL 的过期机制是 onCreateAndUpdate 还是 onReadAndWrite&#xff1f;3. watermark 到底…

使用IntelliJ IDEA本地启动调试Flink流计算工程的2个异常解决

记录&#xff1a;471 场景&#xff1a;使用IntelliJ IDEA本地启动调试Flink流计算时&#xff0c;报错一&#xff1a;加载DataStream报错java.lang.ClassNotFoundException。报错二&#xff1a;No ExecutorFactory found to execute the application。 版本&#xff1a;JDK 1.…

【Java基础篇 | 类和对象】--- 聊聊什么是内部类

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【JavaSE_primary】 本专栏旨在分享学习Java的一点学习心得&#xff0c;欢迎大家在评论区讨论&#x1f48c; 前言 当一个事物的内部&…

Shell编程之定时任务

什么是定时任务 顾名思义&#xff0c;定时任务指的就是在指定/特定的时间进行工作&#xff0c;例如备份/归档数据、清理临时文件等。 在 Linux 中&#xff0c;可以使用 cron 定时器来定期执行任务。cron 是一个在后台运行的守护进程&#xff0c;用于根据指定的时间表自动执行任…

学习笔记|小数点控制原理|数码管动态显示|段码跟位码|STC32G单片机视频开发教程(冲哥)|第十集:数码管动态显示

文章目录 1.数码管动态刷新的原理2.动态刷新原理3.8位数码管同时点亮新建一个数组选择每个位需要显示的内容实战小练&#xff1a;简易10秒免单计数器将刷新动作写成函数 课后练习: 1.数码管动态刷新的原理 上述图片引用自&#xff1a;51单片机初学2-数码管动态扫描 用一排端口来…

UG\NX CAM二次开发 设置2D工序部件边界 UF_CAMBND_append_bnd_from_curve

文章作者:代工 来源网站:NX CAM二次开发专栏 简介: UG\NX CAM二次开发 设置2D工序部件边界 UF_CAMBND_append_bnd_from_curve 效果: 代码: static int init_proc(UF_UI_selection_p_t select, void* user_data) { int errorCode = 0; int num_triples = 1; …

【echarts】legend长度过长,内容过多导致换行怎么办?

通过设置翻页即可解决该问题 关键代码&#xff1a; type: scroll,// pageFormatter: , // 隐藏翻页的数字pageButtonItemGap: 2, // 翻页按钮的两个之间的间距pageIconColor: #6495ed, // 翻页下一页的三角按钮颜色pageIconInactiveColor: #aaa, // 翻页&#xff08;即翻页到…

vue三个点…运算符时报错 Syntax Error: Unexpected token

出现以下问题报错&#xff1a; 解决&#xff1a; 在项目根目录新建一个名为.babelrc的文件 {"presets": ["stage-2"] }

docker 部署 node.js(express) 服务

1、在 express 项目根目录下新增 Dockerfile 文件&#xff0c;内容如下&#xff1a; 创建服务容器的方法&#xff0c;可以根据自己的情况选择&#xff1a; 1、以下示例为宿主机没有安装 node 环境的写法&#xff1b; 2、先在本地构建包含 node 和 express 的基础镜像&#xff0…

视频监控/安防监控/AI视频分析/边缘计算/TSINGSEE青犀AI算法智慧仓储解决方案

随着全球经济与科学技术的双重推动&#xff0c;我国的仓储管理已经进入了高速发展时期&#xff0c;物流仓储也由简单的储藏仓库向智能化仓储转变。TSINGSEE青犀AI智慧仓储解决方案是利用先进的信息技术和物联网技术来提高仓储管理效率、降低成本的一种仓储管理模式。 方案功能 …