旋转位置编码

1. Transformer为什么需要位置编码

因为 transformer 结构本身是和位置编码无关的: Y = T ( X ) = F ( A ( X ) ) Y=\Tau(X)=F(A(X)) Y=T(X)=F(A(X)),其中 A ( ) A() A() 是 attention 变换,只进行了矩阵变换,跟位置无关, F ( ) F() F() 是前馈网络变换,也跟位置无关。

高阶语义向量不仅仅是由周围 token 的语义向量组合表达而成,还需要加上每个 token 所处的位置。比如我们在句子前面加上
< c l s > <cls> <cls> 来学习整个句子的语义向量,如果没有位置编码的话下面两个句子 < c l s > <cls> <cls> token 得到的语义向量是完全一样的。

像是 RNN 和 CNN 结构天然就有序列的位置信息。

2. 如何加入位置编码

2.1. 直接修改输入

X i → Q i , K i , V i X_i \to Q_i,K_i,V_i XiQi,Ki,Vi 之前直接加入位置的embedding: X i ′ = X i + P i X'_i = X_i+P_i Xi=Xi+Pi。优点是简单,缺点是外推困难,对于超过序列最大长度的位置无法表示。用在BERT和GPT中。

典型的方式比如自定义绝对位置编码:

在这里插入图片描述

2.2. 修改Attention

从直觉上来说语义信息关注的是不同 token 之间的相对位置信息,上面的绝对位置编码不够直接,所以引入相对位置编码。
在这里插入图片描述
通过 attention 过程引入位置信息说白了就是在计算 token 之间的相关性矩阵时通过引入某种带有位置信息的操作使得算出来的相关性矩阵里带有相对位置信息。

下面从数学的角度和工程的角度来讲解,可以认为是先通过数学推出了用什么函数修改 attention,然后从工程的角度证明这个函数是有效的。

2.2.1 从数学的角度推理

假设我们引入函数 f ( ) f() f(),它有两个参数,一个是 token 的 embedding 信息,一个是这个 token 的位置信息。比如 f ( q , m ) f(q, m) f(q,m),其中 q q q 是 某个token 的 embedding, m m m 是它的位置信息,但是此时 f ( q , m ) f(q, m) f(q,m) 里面是绝对位置信息。Attention 的核心运算是内积,所以我们希望的内积的结果带有相对位置信息,因此假设存在恒等关系(其中 q q q k k k 是两个不同位置的 token 的 embedding, m m m n n n 是对应的位置信息):

在这里插入图片描述

这样的话只要能求解出满足上式的函数 f ( ) f() f() 就可以将相对位置信息在 attention 阶段引入了,只要 f ( ) f() f() 确定了, g ( ) g() g() 也就可以确定了。

要求解一个函数,首先我们可以设定一些简单的,符合直觉的初始条件:

在这里插入图片描述

我们先考虑二维情形,然后借助复数来求解。在复数中有 < q , k > = R e [ q k ∗ ] <q,k>=Re[qk^*] <q,k>=Re[qk] R e [ ] Re[] Re[] 代表复数的实部,所以有:

在这里插入图片描述

其中 f ∗ ( k , n ) f^*(k, n) f(k,n) 表示 f ( k , n ) f(k, n) f(k,n) 的共轭。

简单起见,我们假设存在复数 g ( q , k , m − n ) g(q, k, m-n) g(q,k,mn),使得 f ( q , m ) f ∗ ( k , n ) = g ( q , k , m − n ) f(q, m)f^*(k, n) = g(q, k, m-n) f(q,m)f(k,n)=g(q,k,mn),然后设:

在这里插入图片描述

注: R f ( q , m ) R_{f(q, m)} Rf(q,m) 是复数 f ( q , m ) f(q, m) f(q,m) 的模, Θ f ( q , m ) \Theta_{f(q,m)} Θf(q,m) 是是复数 f ( q , m ) f(q, m) f(q,m) 的辐角,在苏剑林老师的博客里因为排版问题可能会造成误识。

带入式 (4) 中得到:

在这里插入图片描述

详细的推导如下:

f ( q , m ) f ∗ ( k , n ) = R f ( q , m ) e i θ f ( q , m ) R f ( k , n ) e − i θ f ( k , n ) = R f ( q , m ) R f ( k , n ) e i ( θ f ( q , m ) − θ f ( k , n ) ) = g ( q , k , m − n ) = R g ( q , k , m − n ) e i θ g ( q , k , m − n ) f(q, m)f^*(k, n)=R_{f(q, m)}e^{i\theta_{f(q,m)}}R_{f(k, n)}e^{-i\theta_{f(k,n)}}=R_{f(q, m)}R_{f(k, n)}e^{i(\theta_{f(q,m)-\theta_{f(k,n)}})}=g(q, k, m-n)=R_{g(q, k, m-n)}e^{i\theta_{g(q,k,m-n)}} f(q,m)f(k,n)=Rf(q,m)eiθf(q,m)Rf(k,n)eiθf(k,n)=Rf(q,m)Rf(k,n)ei(θf(q,m)θf(k,n))=g(q,k,mn)=Rg(q,k,mn)eiθg(q,k,mn)

对于第一个方程,代入 m = n m=n m=n 得到:

在这里插入图片描述

最后一个等号源于初始条件 f ( q , 0 ) = q f(q,0)=q f(q,0)=q f ( k , 0 ) = k f(k,0)=k f(k,0)=k。我们假设 R f ( q , m ) = ∣ ∣ q ∣ ∣ , R f ( k , m ) = ∣ ∣ k ∣ ∣ R_{f(q, m)}=||q||,R_{f(k,m)}=||k|| Rf(q,m)=∣∣q∣∣,Rf(k,m)=∣∣k∣∣,即不依赖于 m m m(因为我们是要构造出符合假设的函数 f ( ) f() f(),所以无论怎么假设都可以,只要最后能构造出来就行,这样的话假设条件越简单越好)。

公式 (6) 中的第二个等式带入 m = n m=n m=n 得到:

在这里插入图片描述

这里的 Θ q , Θ k \Theta_{q},\Theta_{k} Θq,Θk q , k q,k q,k 本身的辐角,最后一个等号同样源于初始条件。根据上式得到 Θ f ( q , m ) − Θ q = Θ f ( k , m ) − Θ k \Theta_{f(q,m)}-\Theta_{q}=\Theta_{f(k,m)}-\Theta_{k} Θf(q,m)Θq=Θf(k,m)Θk,所以 Θ f ( q , m ) − Θ q \Theta_{f(q,m)}-\Theta_{q} Θf(q,m)Θq 应该是一个只与 m m m 相关,跟 q q q 无关的函数,记为 φ ( m ) \varphi(m) φ(m),即 Θ f ( q , m ) = Θ q + φ ( m ) \Theta_{f(q,m)}=\Theta_{q}+\varphi(m) Θf(q,m)=Θq+φ(m)。接着代入 n = m − 1 n=m-1 n=m1,整理得到:
在这里插入图片描述

可以看到等式的自变量为 m m m,而上述等式右边跟自变量 m m m 无关,是一个常数,所以 φ ( m ) \varphi(m) φ(m) 是一个等差数列,我们假设右端为 θ \theta θ,则 φ ( m ) = m θ \varphi(m)=m\theta φ(m)=mθ(这是推导出函数 f ( ) f() f() 的关键一步)

至此,我们已经得到了二维情况下用复数表示的RoPE:

在这里插入图片描述

其中 q = ∣ ∣ q ∣ ∣ e i Θ q q=||q||e^{i\Theta_q} q=∣∣q∣∣eiΘq

注:这里要特别注意 Θ \Theta Θ θ \theta θ 的区别,前者是个函数,后者是个数.

根据复数乘法的几何意义,该变换实际上对应着向量的旋转,所以我们称之为“旋转式位置编码”,它还可以写成矩阵形式:

在这里插入图片描述

由于内积满足线性叠加性,因此任意偶数维的RoPE,我们都可以表示为二维情形的拼接,即:
在这里插入图片描述

也就是给位置为 m m m 的向量 q q q 乘上矩阵 R m R_m Rm、位置为 n n n 的向量 k k k 乘上矩阵 R n R_n Rn,用变换后的 Q , K Q,K Q,K 序列做 Attention,那么Attention 就自动包含相对位置信息了,因为成立恒等式:

在这里插入图片描述
按照 (12) 展开之后用三角函数即可证明。

值得指出的是, R m R_m Rm 是一个正交矩阵,它不会改变向量的模长,因此通常来说它不会改变原模型的稳定性,但是向量的方向会发生变化,这就是旋转位置编码中旋转的由来。

由于 R m R_m Rm 的稀疏性,所以直接用矩阵乘法来实现会很浪费算力,推荐通过下述方式来实现RoPE:
在这里插入图片描述
其中⊗是逐位对应相乘,即Numpy、Tensorflow等计算框架中的∗运算。从这个实现也可以看到,RoPE可以视为是乘性位置编码的变体。

2.2.2 从工程的角度

在这里插入图片描述
工程上直接用了数学上推出的结论,也就是说 f ( Q , i ) = Q i R ( i ) f(Q,i)=Q_iR(i) f(Q,i)=QiR(i),可以看到上面的数学推理出的式子是 f ( q , m ) = R ( m ) q m f(q,m)=R(m)q_m f(q,m)=R(m)qm,这是因为数学上一般使用矩阵左乘一个列向量,而代码实现的时候一般是矩阵右乘一个行向量,也正是因为这个原因,所以工程上的旋转矩阵为:

在这里插入图片描述
与数学上有区别。

在这里插入图片描述
如果在投影之前做旋转的话就无法在 attention 的时候加上相对位置信息了。
在这里插入图片描述
在这里插入图片描述
在高维空间做旋转可以拆分为在多个二维子空间上左旋转然后拼接起来。

在这里插入图片描述
这里只是设计了一个基准 θ k = 1000 0 − k / d \theta_k=10000^{-k/d} θk=10000k/d,也可以设为其他。一个复数乘以 i i i 就会在复平面上逆时针旋转90°

在这里插入图片描述

在这里插入图片描述
进入·每一层Transformer的时候都会计算一次相对位置编码,不像在绝对位置编码中只在第一层Transformer中添加位置编码,这样的话随着层数的增加相对位置编码的位置信息是一直都很强的。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

这里解释了上一小节中式子 (14) 是怎么来的。

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

3. 复数相关知识

在这里插入图片描述
在这里插入图片描述

其中 r r r z z z 的模, θ \theta θ z z z 辐角

内积满足线性叠加性:

在这里插入图片描述

在这里插入图片描述

4. 矩阵相关知识

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
正交矩阵:如果: A A T = E AA^T = E AAT=E(E为单位矩阵,AT表示“矩阵A的转置矩阵”。)或 A T A = E A^TA=E ATA=E,则n阶实矩阵A称为正交矩阵。

5. 三角函数

在这里插入图片描述

参考1:Transformer升级之路:2、博采众长的旋转式位置编码

参考2:一文看懂 LLaMA 中的旋转式位置编码

参考3:十分钟读懂旋转编码

参考4:Meta最新模型LLaMA细节与代码详解

参考5:B站视频

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

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

相关文章

激活函数、条件熵和最大熵在机器学习的应用

文章目录 摘要Abstractsigmoid 和 softmaxsigmoid和softmax的关系 条件熵最大熵总结 摘要 本周学习内容探讨了神经网络中激活函数的选择及其对梯度消失问题的影响。通过使用 ReLU 函数替代 Sigmoid 函数来改善梯度消失问题的优化方法&#xff0c;同时分析了 Sigmoid、Softmax …

【AIGC】深入探索『后退一步』提示技巧:激发ChatGPT的智慧潜力

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AIGC | ChatGPT 文章目录 &#x1f4af;前言&#x1f4af;“后退一步”技巧介绍技巧目的 &#x1f4af;“后退一步”原理“后退一步”提示技巧与COT和TOT的对比实验验证 &#x1f4af;如何应用“后退一步”策略强调抽象思考引导提…

uni-app 下拉刷新、 上拉触底(列表信息)、 上滑加载(短视频) 一键搞定

一、下拉刷新 1. 首先找到pages.json中 给需要进行下拉刷新的页面设置可以下拉刷新 2. 然后在需要实现下拉刷新的script标签内添加 导入onPullDownRefresh import {onPullDownRefresh} from dcloudio/uni-app 下拉刷新触发的事件 onPullDownRefresh(()> {console.log(正…

Springboot与easypoi(2):合并单元格、二级表头、动态导出

一、纵向合并单元格 使用Excel(needMerge true)标记的属性表示此单元格需要合并。ExcelCollection表示一对多的集合&#xff0c;下面是合并单元格案例。 实体类 企业类&#xff1a; package com.ywz.entity;import cn.afterturn.easypoi.excel.annotation.Excel; import cn.…

android——渐变色

1、xml的方式实现渐变色 效果图&#xff1a; xml的代码&#xff1a; <?xml version"1.0" encoding"utf-8"?> <shape xmlns:android"http://schemas.android.com/apk/res/android"xmlns:tools"http://schemas.android.com/tools…

使用python画一颗圣诞树

具体效果&#xff1a; 完整代码&#xff1a; import random def print_christmas_tree(height): # 打印圣诞树的顶部 for i in range(height): # 打印空格&#xff0c;使树居中 for j in range(height - i - 1): print(" ", end"") # 打印星号&…

SAP ABAP开发学习——BAPI

目录 业务对象 概念 ​编辑业务对象浏览 BAPI BAPI的浏览 BAPI的调用 BAPI的确认和返回 BAPI的创建 MM/SD常用BAPI 附加&#xff1a;长文本修改 业务对象 概念 业务对象浏览 进入SWO3查看 双击BUS2012 双击下图上方红色位置可以看到BAPI方法的内容 BAPI BAPI(Busines…

MR30分布式IO:石化行业的智能化革新

在浩瀚的工业领域中&#xff0c;石化行业如同一座巨大的化工厂&#xff0c;将自然界的原始资源转化为人们日常生活中不可或缺的各种产品。然而&#xff0c;随着生产规模的扩大和工艺复杂度的提升&#xff0c;石化行业面临着前所未有的挑战&#xff1a;如何在保证生产效率的同时…

VLAN高级特性:VLAN聚合

一、VLAN聚合的概述 在一般的三层交换机中&#xff0c;通常是采用一个VLAN对应一个VLANIF接口实现广播域之间的互通&#xff0c;这导致了在一些情况下造成了IP地址的浪费。 因为一个VLAN对应的子网中&#xff0c;子网号&#xff0c;子网广播地址、子网网关地址不能用作VLAN内…

【Linux系列】磁盘空间不足

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

进程与线程的初探

什么是进程&#xff1f; 现代的操作系统需要运行各种各样的程序。为了管理这些程序的运行&#xff0c;操作系统提出了进程(process)的抽象&#xff1a;每一个进程对应一个运行中的程序。 进程 进程的状态 为了对进程进行管理&#xff0c;操作系统定义了进程的状态。 新生状态…

DNS服务器部署

一、正反向分析 二、主从服务器配置 前提操作&#xff1a; 虚拟机关闭防火墙 一、正反向分析 1、主配置文件 2、正向分析 3、反向分析 二、主从服务器配置 从服务器主配置 从服务器Type改为slave。 编写正反向分析文件。 测试&#xff1…

Spring DispatcherServlet详解

文章目录 Spring DispatcherServlet详解一、引言二、DispatcherServlet的初始化与工作流程1、DispatcherServlet的初始化1.1、加载配置和建立WebApplicationContext1.2、初始化策略 2、DispatcherServlet的工作流程2.1、请求分发2.2、代码示例 三、总结 Spring DispatcherServl…

计算机性能分析的三个模型

计算机性能分析的三个模型【1】 一、瓶颈分析&#xff08;Bottleneck Analysis&#xff09;二、利特尔法则&#xff08;Littles Law&#xff09;【2】三、M/M/1 QueueReference 一、瓶颈分析&#xff08;Bottleneck Analysis&#xff09; 瓶颈分析可以帮我们更好地定位导致性能…

Golang | Leetcode Golang题解之第520题检测大写字母

题目&#xff1a; 题解&#xff1a; func detectCapitalUse(word string) bool {// 若第 1 个字母为小写&#xff0c;则需额外判断第 2 个字母是否为小写if len(word) > 2 && unicode.IsLower(rune(word[0])) && unicode.IsUpper(rune(word[1])) {return f…

开发一个基于Delphi的题库生成系统

开发一个基于Delphi的题库生成系统 步骤一&#xff1a;需求分析 首先明确系统需要实现的功能&#xff0c;比如&#xff1a; 添加题目编辑题目删除题目题目分类管理随机生成试卷导出试卷为PDF或Word格式 步骤二&#xff1a;设计数据库 使用SQLite或其他轻量级数据库存储题…

红队-shodan搜索引擎篇

如涉及侵权马上删除文章 笔记的只是方便各位师傅学习知识,以下网站只涉及学习内容,其他的都与本人无关,切莫逾越法律红线,否则后果自负 一.shodan原理与功能的介绍 Shodan Search Engine 它是专门搜网络设备的,只要联网的,只要有IP地址的都可以称为网络设备 1.shodan&#x…

机器学习中的数据可视化:常用库、单变量图与多变量图绘制方法

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

Python复习2

一、封装函数 #自己封装len函数 s1 "hello,python" print(f"s1的长度为{len(s1)}")def my_len(data):count0for i in data:count 1print(f"{data}的长度为{count}")my_len(s1) 二、容器的排序&#xff08;排序之后的结果都会变成列表&#xf…