GPT 大型语言模型可视化教程

网址:

LLM Visualization

简介

欢迎来到 GPT 大型语言模型演练!在这里,我们将探索只有 85,000 个参数的 nano-gpt 模型。

它的目标很简单:取一个由六个字母组成的序列:

C B A B B C
并按字母顺序排列,即 "ABBBCC"。

我们称这些字母为一个标记,模型的不同标记集合构成了它的词汇表:

标记 A B C
索引 0 1 2
在这个表格中,每个标记都有一个数字,即标记索引。现在,我们可以将这一串数字输入模型:

2 1 0 1 1 2


在三维视图中,每个绿色单元格代表一个正在处理的数字,每个蓝色单元格代表一个权重。

-0.7
0.4
0.8
正在处理
-0.7
0.7
-0.1
权重
序列中的每个数字首先会被转化为 48 个元素向量(根据本特定模型选择的大小)。这就是所谓的嵌入。

然后,嵌入将穿过模型,经过一系列称为转换器的层,最后到达底层。

那么输出是什么呢?对序列中下一个标记的预测。因此,在第 6 个条目中,我们得到了下一个标记将是 "A"、"B "或 "C "的概率。

在这种情况下,模型非常确定会是 "A"。现在,我们可以将这一预测反馈到模型的顶层,并重复整个过程。

在深入了解算法的复杂性之前,我们先来回顾一下。

本指南侧重于推理而非训练,因此只是整个机器学习过程的一小部分。在我们的例子中,模型的权重已经预先训练好,我们使用推理过程来生成输出。这可以直接在浏览器中运行。

这里展示的模型是 GPT(生成式预训练转换器)系列的一部分,可以说是 "基于上下文的标记预测器"。OpenAI 在 2018 年引入了这一家族,其著名成员包括 GPT-2、GPT-3 和 GPT-3.5 Turbo,后者是广泛使用的 ChatGPT 的基础。它还可能与 GPT-4 有关,但具体细节仍不得而知。

本指南受到 minGPT GitHub 项目的启发,该项目是 Andrej Karpathy 在 PyTorch 中创建的最小 GPT 实现。他的 YouTube 神经网络系列:从零到英雄》系列和 minGPT 项目是创建本指南的宝贵资源。这里介绍的玩具模型基于 minGPT 项目中的一个模型。

好了,让我们开始吧!

嵌入

我们之前看到过如何使用一个简单的查找表将标记映射为一串整数。这些整数,即标记索引,是我们在模型中第一次也是唯一一次看到的整数。从这里开始,我们将使用浮点数(十进制数)。

让我们来看看第 4 个标记(索引 3)是如何用于生成输入嵌入的第 4 列向量的。

我们使用标记索引(本例中为 B = 1)来选择左边标记嵌入矩阵的第 2 列。请注意,我们在这里使用的是基于 0 的索引,因此第一列的索引为 0。

这样就产生了一个大小为 C = 48 的列向量,我们将其描述为标记嵌入。

由于我们要查看的是位于第 4 个位置(t = 3)的标记 B,因此我们将取位置嵌入矩阵的第 4 列。

这也会产生一个大小为 C = 48 的列向量,我们将其描述为位置嵌入。

请注意,这些位置嵌入和标记嵌入都是在训练过程中学习的(用蓝色表示)。

现在我们有了这两个列向量,只需将它们相加,就能产生另一个大小为 C = 48 的列向量。

现在,我们对输入序列中的所有标记进行同样的处理,生成一组包含标记值及其位置的向量。

请将鼠标悬停在输入嵌入矩阵的各个单元格上,查看计算结果及其来源。

我们可以看到,对输入序列中的所有标记执行这一过程会产生一个大小为 T x C 的矩阵。T 代表时间,也就是说,你可以把序列中稍后的标记看作是时间上稍后的标记。C 代表通道,但也被称为 "特征"、"维度 "或 "嵌入大小"。这个长度 C 是模型的几个 "超参数 "之一,由设计者在模型大小和性能之间权衡选择。

这个矩阵,我们称之为输入嵌入,现在可以通过模型向下传递了。在本指南中,我们将非常熟悉由长度为 C 的 T 列组成的矩阵集合。

层规范 

上一节的输入嵌入矩阵是我们第一个变换器模块的输入。

变换器模块的第一步是对该矩阵进行层归一化处理。这是对矩阵每列的值分别进行归一化的操作。

归一化是深度神经网络训练中的一个重要步骤,它有助于提高模型在训练过程中的稳定性。

我们可以分别看待每一列,所以现在先关注第 4 列(t = 3)。

我们的目标是使该列的平均值等于 0,标准差等于 1。为此,我们要找出该列的这两个量(平均值 (μ) 和标准差 (σ)),然后减去平均值,再除以标准差。

我们在这里使用的符号是 E[x] 表示平均值,Var[x] 表示方差(长度为 C 的列)。方差就是标准差的平方。ε项(ε = 1×10-5)的作用是防止除以零。

我们在聚合层中计算并存储这些值,因为我们要将它们应用于列中的所有值。

最后,在得到归一化值后,我们将列中的每个元素乘以一个学习权重 (γ),然后加上一个偏置 (β),最终得到我们的归一化值。

我们对输入嵌入矩阵的每一列进行这种归一化操作,得到的结果就是归一化后的输入嵌入,并可将其传入自注意层。

Self Attention 

自我关注层或许是变换器和 GPT 的核心。在这一阶段,输入嵌入矩阵中的各列相互 "对话"。到目前为止,在所有其他阶段,各列都是独立存在的。

自我关注层由几个部分组成,我们现在将重点讨论其中的一个部分。

第一步是为归一化输入嵌入矩阵的每 T 列生成三个向量。这些向量就是 Q、K 和 V 向量:

Q:查询向量
K:键向量
V:值向量

要生成这些向量中的一个,我们要执行矩阵-向量乘法,并加上偏置。每个输出单元都是输入向量的线性组合。例如,对于 Q 向量来说,这是用 Q 权重矩阵的一行与输入矩阵的一列之间的点积来完成的。

我们会经常看到的点乘操作非常简单:我们将第一个向量中的每个元素与第二个向量中的相应元素配对,将配对的元素相乘,然后将结果相加。

这是一种确保每个输出元素都能受到输入向量中所有元素影响(这种影响由权重决定)的通用而简单的方法。因此,它经常出现在神经网络中。

我们对 Q、K、V 向量中的每个输出单元重复这一操作:

我们如何处理 Q(查询)、K(键)和 V(值)向量?命名给了我们一个提示:"key "和 "value "让人联想到软件中的字典,"key "映射到 "value"。那么 "查询 "就是我们用来查找值的。

软件类比
查找表:
table = { "key0":"value0", "key1":"value1", ...}
查询过程:
table["key1"] => "value1"

在自我关注的情况下,我们返回的不是单个条目,而是条目的加权组合。为了找到这种加权,我们在 Q 向量和 K 向量之间进行点乘。我们将加权归一化,最后用它与相应的 V 向量相乘,再将它们相加。

自我关注
查找表:
K:
V:
查询过程:
Q:
w0 =
.
w1 =
.
w2 =
.
[w0n, w1n, w2n] = .
正常化
([w0, w1, w2])
结果 = w0n *
 + w1n *
 + w2n *

举个更具体的例子,让我们看看第 6 列(t = 5),我们将从这一列开始查询:

我们查询的 {K, V} 项是过去的 6 列,Q 值是当前时间。

我们首先计算当前列(t = 5)的 Q 向量与之前各列的 K 向量之间的点积。然后将其存储在注意力矩阵的相应行(t = 5)中。

这些点积是衡量两个向量相似度的一种方法。如果两个向量非常相似,点积就会很大。如果两个向量差别很大,点积就会很小或为负。

只针对过去的密钥进行查询的想法使这种因果关系成为自我关注。也就是说,代币无法 "预见未来"。

另一个要素是,在求出点积后,我们要除以 sqrt(A),其中 A 是 Q/K/V 向量的长度。这种缩放是为了防止大值在下一步的归一化(软最大值)中占主导地位。

我们将跳过软最大操作(稍后描述),只需说明每一行的归一化总和为 1 即可。

最后,我们就可以得到我们这一列(t = 5)的输出向量了。我们查看归一化自我关注矩阵的 (t = 5) 行,并对每个元素乘以其他列的相应 V 向量。

然后,我们就可以将这些相加得出输出向量。因此,输出向量将以高分列的 V 向量为主。

现在我们知道了这个过程,让我们对所有列进行运行。

这就是自我关注层头部的流程。自我关注的主要目标是,每一列都希望从其他列中找到相关信息并提取其值,并通过将其查询向量与其他列的键进行比较来实现这一目标。但有一个附加限制,即它只能查找过去的信息。

MLP  

在自我注意之后,变压器模块的下半部分是 MLP(多层感知器)。虽然有点拗口,但在这里它是一个有两层的简单神经网络。

与自我注意一样,在向量进入 MLP 之前,我们也要进行层归一化处理。

在 MLP 中,我们将每个 C = 48 长度的列向量(独立)放入其中:

1.1. 添加偏置的线性变换,转换为长度为 4 * C 的向量。

2.一个 GELU 激活函数(按元素计算)

3.带偏置的线性变换,返回长度为 C 的矢量

让我们追踪其中一个向量:

我们首先执行带偏置的矩阵-向量乘法,将向量扩展为长度为 4 * C 的矩阵。这纯粹是为了可视化的目的)。

接下来,我们对向量的每个元素应用 GELU 激活函数。这是任何神经网络的关键部分,我们要在模型中引入一些非线性。使用的特定函数 GELU 看起来很像 ReLU 函数(计算公式为 max(0,x)),但它有一条平滑的曲线,而不是一个尖角。

-1
1
2
3
-3
-2
-1
1
2
3

然后,我们用另一个带偏置的矩阵-向量乘法将向量投影回长度 C。

与自我关注 + 投影部分一样,我们将 MLP 的结果按元素顺序添加到输入中。

现在,我们可以对输入中的所有列重复这一过程。

MLP 就这样完成了。现在我们有了转换器模块的输出,可以将其传递给下一个模块了。

Transformer 

这是一个完整的转换模块!

这些转换构成了任何 GPT 模型的主体,并且会重复多次,一个转换的输出会馈入下一个变压器块,继续剩余通路。

与深度学习中常见的情况一样,我们很难说清楚这些层中的每一层都在做什么,但我们有一些大致的想法:较早的层往往侧重于学习较低层次的特征和模式,而较晚的层则学习识别和理解较高层次的抽象概念和关系。在自然语言处理中,低层可能学习语法、句法和简单的词汇关联,而高层可能捕捉更复杂的语义关系、话语结构和上下文相关的含义。

Softmax 

如上一节所述,softmax 操作是自我关注的一部分,它也将出现在模型的最后。

它的目的是将一个向量的值归一化,使其总和为 1.0。然而,这并不像除以总和那么简单。相反,每个输入值都要先进行指数化处理。

a = exp(x_1)

这样做的效果是使所有值都为正。有了指数化值的向量后,我们就可以用每个值除以所有值的总和。这将确保所有数值之和为 1.0。由于所有指数化值都是正值,我们知道得出的值将介于 0.0 和 1.0 之间,这就提供了原始值的概率分布。

这就是 softmax 的原理:简单地将数值指数化,然后除以总和。

不过,还有一个小麻烦。如果输入值很大,那么指数化后的值也会很大。我们最终会用一个很大的数除以一个很大的数,这可能会导致浮点运算出现问题。

softmax 运算的一个有用特性是,如果我们在所有输入值上添加一个常数,结果将是相同的。因此,我们可以找到输入向量中的最大值,然后将其从所有值中减去。这样就能确保最大值为 0.0,从而使 softmax 在数值上保持稳定。

让我们结合自我注意层来看看 softmax 操作。每个 softmax 运算的输入向量都是自我注意矩阵的一行(但只到对角线)。

与层归一化一样,我们有一个中间步骤来存储一些聚合值,以保持流程的高效性。

对于每一行,我们都会存储该行的最大值以及移位值和指数值之和。然后,为了生成相应的输出行,我们可以执行一小套操作:减去最大值、指数化和除以总和。

为什么叫 "softmax"?这种操作的 "硬 "版本称为 argmax,它只是找出最大值,将其设为 1.0,并将所有其他值设为 0.0。相比之下,softmax 操作则是其 "柔和 "版本。由于 softmax 涉及指数运算,最大值会被强调并推向 1.0,同时仍保持所有输入值的概率分布。这样就能获得更细致的表示,不仅能捕捉到最有可能的选项,还能捕捉到其他选项的相对可能性。

结果

最后,我们来到模型的末端。最后一个变换器模块的输出经过层归一化处理,然后我们使用线性变换(矩阵乘法),这次没有偏差。

最后的变换将我们的每个列向量从长度 C 变为长度 nvocab。因此,这实际上是为我们每一列词汇中的每个单词生成一个分数。这些分数有一个特殊的名字:logits。

logits "这个名字来源于 "log-odds",即每个标记的几率的对数。之所以使用 "对数",是因为我们接下来应用的 softmax 会进行指数运算,将其转换为 "几率 "或概率。

为了将这些分数转换为漂亮的概率,我们将它们通过软最大运算。现在,对于每一列,我们都有了模型分配给词汇表中每个词的概率。

在这个特定的模型中,它已经有效地学习了如何对三个字母进行排序这一问题的所有答案,因此概率在很大程度上倾向于正确答案。

当我们对模型进行时间步进时,我们会使用上一列的概率来决定下一个要添加到序列中的标记。例如,如果我们已经向模型提供了 6 个标记,我们就会使用第 6 列的输出概率。

这一列的输出是一系列概率,我们实际上必须从中挑选一个作为序列中的下一个。我们通过 "从分布中采样 "来实现这一点。也就是说,我们随机选择一个标记,并根据其概率进行加权。例如,概率为 0.9 的令牌将在 90% 的情况下被选中。

不过,这里还有其他选择,比如总是选择概率最高的代币。

我们还可以使用温度参数来控制分布的 "平滑度"。温度越高,分布越均匀;温度越低,分布越集中在概率最高的标记上。

在应用 softmax 之前,我们先用温度除以 logits(线性变换的输出)。由于 softmax 中的指数化会对较大的数字产生较大影响,因此将所有数字拉近会减少这种影响。

 

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

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

相关文章

Jboss 反序列化 CVE-2017-12149

一、漏洞简介 JBoss是一个管理EJB的容器和服务器,支持EJB 1.1、EJB 2.0和EJB3的规范。在/invoker/readonly路径下,攻击者可以构造序列化代码传入服务器进行反序列化,由于没有对反序列化操作进行任何检测,导致攻击者可以执行任意代码。 而jbo…

TCP(TCP客户端、服务器如何通信)

一、TCP介绍 TCP的特点: 面向连接的协议:TCP是一种可靠的、面向连接的协议,在通信之前需要建立连接,以确保数据的可靠传输。这意味着在传输数据之前,发送方和接收方之间需要建立一条可靠的连接通道。流式协议&#x…

Linux实验 系统管理(三)

实验目的: 了解Linux系统下的进程;掌握一类守护进程——计划任务的管理;掌握进程管理的常用命令;掌握进程的前台与后台管理;了解Linux系统的运行级别;掌握系统服务管理的常用命令。 实验内容: …

040——移植数据库sqlite3到i.mx6ull

目录 一、下载 二、移植数据库 三、测试sqlite3 一、下载 SQLite Download Page 暂时先下载最新版的试试,我们以前其实在ubuntu上直接使用过 嵌入式数据库sqlite3_常见的嵌入式数据库-CSDN博客 当时我把常用的操作和怎么使用记录下来了 现在把他移植到开发板…

下水道井盖多分类检测定位

下水道井盖识别,多分类,使用yolov5训练,采用一部分开源数据集和自建数据集。python pytorch opencv 深度学习#人工智能#深度学习#目标检测

【Python项目】基于大数据的【电影市场预测分析】

技术简介:使用Python技术、B/S架构、MYSQL数据库等实现。 系统简介:系统都需要简单的安全登陆检查,在登陆成功之后要进行在映电影的分析、票房分析、电影数据等功能相关性的数据统计,为了使用方便这些统计型的数据使用图表来进行表…

【基于element ui的color选择器】基于element ui的color选择器

技术版本如下&#xff1a; vue 2.6.14 less 3.13.1 element-ui 2.15.6 less-loader 5.0.0需求&#xff1a; 支持RGB、HEX编码、支持吸管吸取颜色、颜色选择器、颜色模板、透明度、色板、线性渐变颜色 效果图&#xff1a; 1.引入选择器的color-all文件 <template><…

web前端之纯CSS实现简单酷炫的照片墙效果、排除元素的伪类、scale

MENU 效果htmlstylescale:not() 效果 html <div class"container"><div class"box"><img src"../../image/1_.jpg"></div><div class"box"><img src"../../image/2_.jpg"></div>…

【python量化交易】qteasy使用教程06——创建自定义因子选股交易策略

创建自定义因子选股策略 使用qteasy创建自定义因子选股交易策略开始前的准备工作本节的目标Alpha选股策略的选股思想计算选股指标用FactorSorter定义Alpha选股策略交易策略的回测结果用GeneralStg定义一个Alpha选股策略回测结果&#xff1a;本节回顾 使用qteasy创建自定义因子选…

Electron、QT、WPF三强争霸,该支持谁呢?

Electron、QT、WPF都是跨平台的桌面应用开发框架&#xff0c;都是非常流行的&#xff0c;作为开发者该选用哪个呢&#xff1f;本文从多个角度分析一下。 一、定义 Electron、Qt 和 WPF 都是用于创建桌面应用程序的框架或工具&#xff0c;它们各自有着不同的特点和优势。 Elec…

Linux-笔记 开发板Uboot命令使用

将之前自学的知识整理了一下笔记&#xff0c;以便回忆 信息查询命令 1、help/?&#xff1a;查看所支持命令 > ? md md - memory displayUsage: md [.b, .w, .l] address [# of objects]2、bdinfo&#xff1a;查询板子信息 > bdinfo arch_number 0x00000000 boot_p…

匿名管道及其应用

目录 一、什么是匿名管道&#xff1f; 三、创建与使用匿名管道 三、匿名管道的特点 匿名管道的四种情况 匿名管道的五种特性 四、匿名管道的实践应用---进程池 在编程的世界中&#xff0c;匿名管道是一种非常重要的通信机制。今天&#xff0c;让我们一起来深入探讨一下匿…

vivado Virtex-7 配置存储器器件

Virtex-7 配置存储器器件 下表所示闪存器件支持通过 Vivado 软件对 Virtex -7 器件执行擦除、空白检查、编程和验证等配置操作。 本附录中的表格所列赛灵思系列非易失性存储器将不断保持更新 &#xff0c; 并支持通过 Vivado 软件对其中所列非易失性存储器 进行擦除、…

单链表经典算法OJ题---力扣206,876(带图详解

1.链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09;【点击即可跳转】 思路&#xff1a;创建三个指针&#xff0c;看下图 注意&#xff1a;n3如果为空&#xff0c;则不能继续指向下一节点&#xff0c;需要进行判断 代码实现&#xff1a; struct ListNode* reverseLi…

第二课,python基础语法(一),认识字面量和变量、注释

一&#xff0c;字面量 &#xff08;一&#xff09;什么是字面量 被写下来的的固定的值&#xff0c;称之为字面量 &#xff08;二&#xff09;常见的三种字面量类型 &#xff08;三&#xff09;练习一下&#xff0c;使用print去输出三种不同类型的字面量&#xff1a;10&#x…

树莓派安装opencv

安装opencv 上述步骤完成后&#xff0c;输入以下代码(基于python3) sudo apt-get install python3-opencv -y不行的话&#xff0c;试试换源&#xff0c;然后 sudo apt-get update成功&#xff01; 测试opencv是否安装成功 输入 python3 然后再输入 import cv2 没有报错就…

【Java】:向上转型、向下转型和ClassCastException异常

目录 先用一个生动形象的例子来解释向上转型和向下转型 向上转型&#xff08;Upcasting&#xff09; 向下转型&#xff08;Downcasting&#xff09; 向上转型 概念 例子 发生向上转型的情况 1.子类对象赋值给父类引用 2.方法参数传递 3.返回值 向下转型 概念 注意…

扩散模型(Diffusion Model)学习笔记

目录 Diffusion Model 基本原理 预测原理 ddpm 实例 ddmp数字图片生成 有的还没看完 Diffusion Model 基本原理 扩散模型1&#xff1a;基本原理 - 知乎 前向扩散过程可以理解为一个马尔可夫链&#xff0c;即通过逐步对一张真实图片添加高斯噪声直到最终变成纯高斯噪声图片…

labview技术交流-字符串数组连接成字符串

应用场景 我们可能需要将一维的字符串数组转换成一整条字符串&#xff0c;然后方便记录在数据库或表格中的一个单元格中。 代码展示 方案一 我们使用for循环完成这样的功能需求&#xff0c;见下图&#xff1a; 这种方案可能相对基础和普通&#xff0c;但是它更方便和易于扩展…