演讲者:核心在于,我们都知道Transformer具备所有重要属性以及有趣的结构,从而支持了这些应用。在Transformers中,我们知道它与多层感知机(MLP)的区别在于存在注意力层。这个注意力层实际上发挥着神奇的作用。对于注意力层,我们知道有查询(query)和键(key),它们进行乘积运算。
接着计算softmax,并使用这些softmax值对前一层的嵌入向量重新加权,这一过程会重复多次。神奇的是,通过预测下一个词元(token),它能给出非常好的结果。因此,本次讲座的大部分时间将致力于探讨如何理解这种应用机制。
我们将主要讨论两篇论文:一篇是2023年欧洲会议接收的“Scan and Snap”;另一篇是我们后续的JoMA论文,已被今年的ICLR接收,旨在深入理解Transformers。
我们从“Scan and Snap”论文开始,该论文主要在一层设置下理解注意力机制。为了获得对多层Transformer的更好理解,我们总是从非常简单的设定开始,以便掌握其数学公式和结构。因此,我们从单层设置入手。
在这种单层设定中,输入输出非常简单。这里的输入基本上是一系列上下文词元x1一直到xt-1。然后有一个被称为查询的最后词元,将其送入进行自注意力计算。
一旦你在多个词元之间基于概率或注意力分数形成了分布,你就使用这些注意力分数作为权重来计算输出特征。该特征经过归一化、解码层和softmax处理,用于预测下一个词元xt+1。这基本上就是一个非常简单的模型结构。
以下是我们试图用来构建端到端数学结构的公式化表达。基于此,你会发现如果将其写下来,会看到很多参数:WQ、WK以及U。这使得情况变得非常复杂。如果将其写下来并尝试计算梯度,过程会显得十分混乱。
因此,我们实际上采用了两个非常重要的技巧。首先,你要确保使用独立变量对问题进行重新参数化。这一点对本论文以及后续更深入理解多层结构的衍生工作都至关重要。
我们实际上是将这些众多变量重新参数化为Y和Z。其中,Y基本上代表顶层的解码器权重;而Z则是自注意力矩阵中成对的logits(对数几率)。
突然之间,动态过程变得更容易分析,我们实际上可以得出一些结论。这基本上就是主要的第一步:我们可以做到这一点,并实际使用它来写出Y和Z的动态方程。我稍后会涵盖这部分内容,因为这个方程式看起来非常复杂。
在接下来的几张幻灯片中,在引入JoMA之后,我们将拥有一个更简单的公式化表达。然后将它们结合起来,事情就会变得容易得多。我们首先从结论开始讲起。
我们不打算先深入细节,而是讨论Transformer的哪些特性为我们带来了什么启示。以下是“Scan and Snap”论文的几个主要假设:首先,没有位置编码(positional encoding)。
我们暂时不讨论位置编码,原因有二:首先,处理起来稍微困难一些;其次,我们看到有论文表明,即使没有位置编码,仍然可以获得合理的性能。
第二个假设是序列长度趋于无穷大,即拥有非常长的序列长度。第三个特定于“Scan and Snap”论文的假设是:解码器Y的学习率大于自注意力层Z的线性学习率。
最后,还有一些关于数据分布的技术性假设。我们假设有从1到K的一系列序列类别。对于不同的序列类别,存在两种不同类型的词元:一种是“独特词元”,它只出现在一个类别中而不出现于其他类别。
另一种是“通用词元”,它们会出现在多个序列类别中。因此,你可以用数学形式表达这一假设:对于独特词元,给定序列X下该词元的概率仅在单个序列类别中大于0。但对于通用词元,它们可能出现在多个序列类别中。
基于上述假设,另一个问题是:自注意力层是如何表现的?以下是主要结论以及Transformer动态的整体图景。首先,我们尝试放置这些关键统计数据,称为C帽($\hat{C}$)。
这实际上是共现概率与成对注意力矩阵指数之间的乘积。其中,共现概率来自我们的数据集。因此你有这个$\hat{C}$项存在,你需要分析它的行为表现。
你会发现对于独特词元,由于相应的共现概率仅在单个类别中非零而在其他类别为零,因此这个$\hat{C}$仅在一个类别中是非零的。所以你会看到非常明显的模式差异。但对于通用词元,它们出现在两个序列类别中。
第一个结论是:对于通用词元,你可以分析这种动态过程。结果显示,梯度基本上会将所有通用词元的注意力分数误差拖拽得越来越小。因此Z会变得越来越小,因为Z关于时间的导数小于0(即$\frac{dZ}{dt} < 0$)。
这里的符号表示时间导数。因此,随着时间的推移,Z会变得越来越小。这基本上适用于通用词元,即出现在多个序列类别中的那些词元。
另一方面,你可以证明对于独特词元,它们对应的Z(即注意力logits)会随着时间增长。下图展示了这种增长情况:对于所有这些独特模式或独特词元,它们的注意力分数都会上升。
而且这种注意力的增加也会使最终的$\hat{C}$随之升高。从这两点可以看出,注意力机制就像是一个可学习的TF-IDF(词频-逆文档频率)。
如果人们在Transformer时代之前从事过自然语言处理工作,可能听说过TF-IDF公式化方法。其含义是:你希望找到那些具有高频率但同时具有低文档频率的词或单词。
希望保留那些具有逆文档频率的词汇。第一项指标强调每个类别中非常重要的词,而第二个标准则要求模型过滤掉在多个文档乃至所有文章中过于常见的通用词汇,因为这些词缺乏信息量。在进行决策或文档分类时,这些常见词应当被抑制;相反,如果存在针对特定类别的特有词汇,我们就应予以关注。例如在讨论体育时,“messy”是运动领域的重要标记词,这种关联可用于提升文档分类的准确性。
此外,我们可以量化注意力分数的增长率。Zml作为自注意力矩阵的一个元素且随时间变化,在给定序列类别的条件下条件概率越大,其增长越快。我们可以通过定理来描述这一特性该定理解释了不同标记之间的增长率差异。图示表明,若某独特标记与查询高度共现,其增长远快于仅偶然共现的标记。因此在训练过程中会观察到显著的增长跳跃,这被称为上下文稀疏性:归一化后注意力分数逐渐变稀疏,“赢家通吃”效应使强者愈强。
这种上下文稀疏性依赖于查询,不同查询会呈现截然不同的曲线模式。对于不同的查询标记,具有高共现率的对应标记也会随之变化,从而展现出依赖查询的稀疏性模式。最终我们展示了注意力的两阶段效应:虽然理论上高共现标记会持续增长直至赢家通吃,但实际并非如此。分析显示存在两个阶段:第一阶段为注意力扫描(Attention Scanning),此时发生赢家通吃效应;第二阶段为注意力快照(Attention Snapping)。
在扫描阶段后,一切稍放缓并最终饱和。一旦观察到“强者愈强”效应,注意力模式便会冻结,形成少数派通吃的局面而非完全的赢家通吃。这是Scan and Snap论文展示的整体图景,并通过多项模拟验证了其真实性。理论分析的基本策略是利用无限序列长度的优势将所有项转化为包含概率分布的统计术语,这是第一步。
第二步基于假设:解码器Y的学习率远快于自注意力矩阵Z,因此在分析解码器动态时可将自注意力视为常数。一旦获得描述梯度如何传播至注意力的方程,并将其代回自注意力层进行分析,即可解析单层Transformer的两层结构动态。我们在WikiText2上进行了简单实验,显示在此学习率结构下注意力呈现稀疏模式。
实际训练Transformer时也会观察到类似的学习模式变化,这简要概括了Scan and Snap论文。接下来讨论如何改进该论文并消除其假设限制,如原模型无嵌入向量、无残差连接且解码器需比自注意力学习更快,这在实践中并不存在。此外原分析仅针对单层结构。为此我们引入JoMA工作作为后续研究,旨在更深入理解动态机制。
在JoMA论文中我们发现了MLP下层与自注意力层之间训练动力学的良好特性,并将它们结合为一个称为修改型MLP的层级。该层同时捕捉两层动态且比分别考虑自注意力和MLP更简单,这是JoMA的核心思想。我们拖拽Transformer的一层并添加符号以分析其过程,引入了先前分析中缺失的ResNet连接。
这些残差连接现被加入以展示其作用,同时利用解码器层中的非线性激活函数。在之前的Scan and Snap论文中无非线性成分,仅对Softmax呈线性关系,这是主要区别。我们展示了其中的良好特性并引入了嵌入矩阵U,假设这些嵌入向量相互正交且不随时间变化。尽管该假设受到审稿人质疑,但通过绘制Pythia等模型不同层嵌入向量相似度的图表,我们证明了这在实践中确实成立。
我们还在其他模型上进行了测试,结果看起来也非常符合。基本上,该图表显示横轴代表小批量训练动态(minibatches),纵轴是余弦相似度。余弦相似度的取值范围在0到1之间,其中1表示完美对齐,0表示相互正交。在这里可以看到,随着训练的进行,余弦相似度并没有显著增加,大致保持在0.03左右。这意味着即使对于不同的层,它们之间也几乎是正交的。图中的每条曲线对应不同的层,层的颜色由曲线的颜色表示。
因此,这基本上意味着正交性假设在近似意义上是成立的。然而,我们尚未分析嵌入(embedding)的动态变化,这可能是下一篇论文的研究内容。基于这些假设,我们将看到MLP下层与自注意力层之间存在联合动态。实际上可以从权重下层的幅度计算出自注意力的相关参数。这意味着一旦有了这个方程,就可以忽略自注意力层的具体细节,只需将该方程代入动态模型中即可得到相应的结果。
该方程基本上描述了自注意力和MLP下层的共同作用故事,从而可以利用它来分析Transformer的动态特性。这就是基本思路,这使得分析变得更加简单。此外,这种方法不再需要假设解码器层的训练速度比自注意力层快得多这一前提条件。以下是几张幻灯片,我尝试比较Scan and Snap与JoMA之间的异同。这些是额外添加的幻灯片,旨在回答学生们提出的问题。
这里提出了一种通用的公式化方法,试图将两者结合起来。我们有一个统一的通用框架来整合这两个概念。这里有一些符号表示以及两篇论文中的共同假设。首先,下层权重W和自注意力层权重Z都是可训练参数,可以进行优化。在大部分工作中,我们不单独考虑WK、WQ、WR等特定权重矩阵,而是将整个Z矩阵视为一个可训练的参数。
这与实际发生的情况有所不同。其次,嵌入U在列方向上是固定的正交向量。这也是我们为这两篇论文所做的另一个假设。第三,输入token的1向量实际上是独热列向量(one-hot column vectors),这样我们就可以计算频率。这在第一层中肯定是成立的,因为每个token都由独热表示编码;但如果考虑到多层以及中间的非线性因素,这一点可能并不一定成立。
Scan and Snap与JoMA之间的区别在于它们设定的环境非常不同。例如,在Scan and Snap中,可能包含额外的归一化(如L2),并且假设激活函数是线性的,同时Z的变化速度远快于W。而在JoMA中,我们采用了不同的设定:phi可能是恒等映射,没有归一化;但在非线性方面,既可以使用线性也可以使用非线性激活函数。因此存在许多不同的研究方向。
这里用一张幻灯片展示了第一个定理的推导过程,我不想详细展开,只是将其作为对定理1的一种总结。如果你感兴趣,可以自行查阅。这比论文中给出的证明要简洁得多,我们将在最终版本中进行更新。人们可能会问:在JoMA具有这种联合动态的情况下会发生什么?由于自注意力层中做出了一些假设,我们需要确保这些假设成立。
有了这种联合动态后,我们可以回到Scan and Snap的设定中(即激活函数为线性),看看是否能得出与Scan and Snap相同的预测结果。答案是肯定的,我们确实可以得到非常相似的预测结论。该预测指出注意力机制将变得更加稀疏,这与Scan and Snap的结果一致。具有最高token判别性和共现性的组件(即幅度最大的项)其曲线增长最快,而其他曲线则会趋于饱和。
这实际上与Scan and Snap的结果是一致的。但更有趣的是,如果将JoMA扩展到非线性激活函数(即激活函数是非线性的),之前的Scan and Snap论文就无法给出任何预测结果。而我们实际上可以揭示出对应于非线性激活的更有趣的行为:注意力首先会变得更加稀疏,这正是Scan and Snap所预测的现象;但同时,在后续的迭代中它会重新变得密集。
基本上,这是非线性激活与线性激活之间不同的图景。在线性激活的情况下,注意力只会变得越来越稀疏,直到达到饱和状态;而在非线性情况下,它在后期会重新变得密集。我不打算深入探讨这一部分的细节,因为涉及大量数学推导,但我们首先希望验证这是否与真实实验一致。
实际上,在真实实验中,我们在两个不同的现实世界文本数据集(WikiText2和WikiText103)上训练了多层Transformer模型。你将看到实际曲线与理论预测完全一致。特别是在第一层,如果使用非线性激活训练单层Transformer,你会观察到注意力先下降然后再回升的现象。
这与理论绘制的曲线非常相似。如果在多层中进行训练,你也会看到非常相似的曲线。特别是在顶层,你会观察到一些下降然后回升的现象。这实际上是非常有趣的结果。
我们想要真正理解为什么会出现这种情况,即为什么会观察到这些行为。因为这些行为看起来并不直观,尤其是对于单层网络而言;在单层中,我们通常期望一次性完成所有特征提取。那么为什么需要稍后去捕捉那些不那么显著的特征呢?首先,由于与“扫描-快照”机制相同的原理,特征变得稀疏:那些与查询词共同出现频率高的令牌会被优先捕捉。
随后注意力分数上升,而其他注意力的变化不大甚至下降。这就是为什么你会看到注意力熵降至极低的数值。但过一段时间后,注意力分数会再次上升——即熵值回升。这是因为模型随后开始捕捉那些虽然不如之前显著、但在时间推移下仍具有一定相关性的特征和令牌,从而导致注意力熵略有回升。
这并非在第一步就下降,因为这里的单位是千级小批量(kilo minibatches)。因此数据必须从第一组千级样本开始统计,随后下降,之后又回升。是的。而且我认为具体的数值尺度可能并不重要,因为通过调整学习率可以获得不同的缩放比例。是的,好的?
你也会在其他模型的实际经验中看到类似的行为。我们之所以观察到这种现象,是因为我们在后续提出了一个假设来解释这些特性。基本上,这种特性对于单层模型来说并非必要;在单层中,为什么不一次性学习所有特征呢?但这种机制可能在多层结构中更有用。
之所以在多层中发挥作用,需要考虑分层数据表示。我们希望通过从数据中学习到一个分层的结构。在这种表示中,你只能看到最终的标签(顶层),以及最底层的令牌(底层),但无法直接观察到内部发生了什么。
因此,存在控制数据生成过程的潜在变量,但我们并不知晓其具体形态。我们虽然对数据集内部的运作机制一无所知,但确实希望训练变换模型(Transformer),使其能够自动学习数据集中的潜在表示。
我们假设,在 Transformer 中观察到的注意力分数先降后升的现象,是因为模型实际上正在学习这些潜在表示。首先可以证明一个定理:如果两个令牌在层级结构中非常接近,它们共同出现的概率将非常高,几乎等于 1。
但如果两个令牌 l'和 m 在层级结构中相距甚远,它们的共同出现概率将非常低,接近于 0。这里有一个方程描述了这种行为:它基本上由这两个令牌 l和 m 的最近共同潜在祖先的高度决定。
对于 l 和 m,它们的共同潜在祖先高度 H=1,非常小,因此代入公式后概率近似为 1。如果使用同样的定理分析 l'和 m(它们相距甚远),它们的共同潜在祖先高度几乎等于层级总深度 L,此时概率将接近 0。
首先我们要接受这个假设,即分层生成模型具有这些有趣的特性。请注意,这一属性与 Transformer 本身无关。接下来我们思考 Transformer 应如何学习它:先学习与高频共同出现的令牌,再学习与稀疏共现的令牌。
这种机制对浅层和深层潜在分布都有效。对于深层分布,我们首先同时学习 m 与 l、以及 m'与 l'的关联,因为它们根据之前的层级分析共同出现频率很高。
由于先学习了这两组关系,模型便隐式地构建了一个层级结构,以便在顶层进一步组合。因此,我们基本上避免了直接学习 m 和 l'之间的关系;尽管它们可能有少量共现,但这种关系并不重要,可以通过分层学习间接获得。
这实际上赋予了我们对 Transformer 为何以这种方式学习特征的直觉。另一方面,如果数据由某些浅层潜在分布生成,其中层级结构不明显,只是非常直接的分布。那么 Transformer 的学习过程会怎样呢?
Transformer 首先学习高频出现的令牌 m 和 l,但最终也会学习到 m 与 l'之间的共现关系,因为这两者之间仍存在某种(尽管可能很微弱)的共现。
因此,相同的注意力机制可以同时学习深层和浅层潜在分布,而无需知晓数据的内部结构。这基本上提供了关于 Transformer 为何能在不知晓底层分布的情况下执行如此多有趣任务的见解:它会自动适应数据的结构。
这也就是为什么我们观察到注意力先下降再回升的原因。如果回到图表,你会看到有趣的行为:如果使用相同的数据集训练同一模型(即单层 Transformer 模型),你会发现非常深且有趣的结构,这非常明显。
但如果 Transformer 的层数增加(即更深的网络),在底层中,曲线基本下降后没有回升;但在顶层,仍然存在类似反弹的特性。这种情况也可以用这一理论来解释:因为如果有多层 Transformer,你首先学习高频共现关系。
一旦学会了这一点,就不需要再次学习 l 和 m'之间微弱的共现关系了。因为不需要再显式地学习这两组共现,所以就不会出现反弹特性;这种反弹特性已经被之前的机制解释掉了。
这就是为什么在使用多层 Transformer 学习数据时,你不会在底层看到曲线反弹的原因。
我认为目前这是我脑海中的一种理论,但我们尚未测试其他可能的解释。好的,我明白了。是的,我目前没有发现能对此做出解释的其他论文,确实如此。但我的意思是,看看是否有其他替代性的系列研究会很有趣。是的,目前只有一种解释方式。
观众:有没有办法生成一些合成的分层数据来证明这一点? 演讲者:是的,我们实际上可以在其中一个实验中做到这一点。因为根据这个理论,一个可能的推论是随着时间的推移,你会在Transformer的不同层中学习这些潜在变量,这对我们的分析来说确实是真实的。
如果我们能从合成实验中生成分层数据,你可以使用Transformer来学习它。你实际上会看到潜在层之间几乎100%的相关性,特别是在Transformer的隐藏层与潜在变量之间。我们可以看到论文中的表格。
首先,这里的因果关系并不相关,所以我们不知道因果性是否会在这里起作用,因为这里我们只有相关性。没有因果性。是的。但确实看起来它会先学习强注意力,即强相关性。
这种强相关性可能意味着因果性,因为如果你看到这两个标记经常一起出现,那么它们之间可能存在真实的关联。是的。所以我想我们之前解释过一点。
如果你只用浅层Transformer训练数据,你会看到非常明显的反弹现象。如果使用深层Transformer进行训练,那么底层一旦下降就不会再反弹,因为反弹意味着底层试图学习弱相关的特征。
如果这些特征已经被顶层解释掉了,那么底层就不需要再学习了。这就是为什么它只降不升的原因。
观众:但我的问题是,如果你之后解冻它们,比如说一或三层或其他层数后,你认为底层是否会达到相同水平——它会反弹并保持在那里吗?还是认为它会再次下降?而高层会怎样呢? 演讲者:是的,这是一个非常有趣的实验尝试。
我认为有可能你会看到底层反弹然后再次下降。实际上我在某些配置中看到了这种曲线。是的,这确实很有趣。
还有其他实验表明,通过链接不同的学习率,你会看到非常不同类型的训练曲线。显示出这种反弹特性的训练曲线将具有最高的验证准确率,这可能意味着与其他类型的学习率相比,这是正确学习数据的方式。是的,你可以在论文中查看这些实验。我们尚未展示这一点。
这取决于你如何定义因果性。所以有可能因果性的含义是如果你消除了第一个属性,第二个就不会发生,反之则不然,因为它是非对称的。
如果是这种情况,那么你可能希望设计属性以强制注意力矩阵也具有相同的特性,诸如此类。这是可能的。是的,我认为这是一个非常好的问题。
所以我们实际上尝试了我们的参数化——在实际中使用了真实的参数Y和Z。然后发生的情况是,它仍然可以学习,但性能显然不如原始Transformer好。
所以我们实际上有一个称为YZ Transformer的东西,它是我们之前展示的YZ参数化方法。你可以实际训练三层模型,它是有效的。但当你要训练多层时,它实际上效果没那么好。
这是因为嵌入的力量。在YZ Transformer中,没有独立的嵌入层。所有嵌入都放入了Z矩阵中。这个Z非常巨大,它是词汇表大小乘以词汇表大小的维度。
但这个巨大的矩阵在实际训练过程中可能无法得到很好的训练。在实践中,我们实际上并不真正训练这个巨大的矩阵,而是训练嵌入以及权重来基本上模拟这个巨大的注意力矩阵。从某种意义上说,这要高效得多。
所以这一方面尚未由理论解释清楚,但希望未来我们将能够解释嵌入矩阵的动态情况。所以我们基本上必须将其分解为部分并逐一分析。
是的,我认为这是一个好问题,因为我们在Scan and Snap论文中做出假设的原因是公式有点受限。所以你确实需要分析两种极端情况,要么是一个标记出现在多个类别中,要么一个标记只出现在一个类别中。
但实际上中间有很多情况。所以我们说比如一个标记在很多地方出现,90%在一个类别中,但20%在另一个类别中。那会发生什么?
JoMA的好处在于一旦你有了这种公式,自然就会产生这种属性。这个属性取代了常见标记与独特标记的区别。现在我们有了一个涵盖所有标记的连续谱系。
如果这个量的幅度很高,那么这就是独特标记。如果这个量几乎为零,那就是常见标记。
所以如果你有一个谱系,那么你就不再需要那种假设了。是的,这就是公式的好处所在。
所以你们仍然拥有共现性和判别性。这与Scan and Snap中的情况类似,但现在它变成了一个自然项。而且这个项不需要特别处理。
好的,我们在40分钟内主要涵盖了这两篇系列论文的内容。我想在接下来的20分钟里,我们将讨论更多的实证工作。
所以我将跳过所有的公式细节。希望人们已经足够了解这些内容了。是的,我认为这里有很多问题是非常棒的。通常来说,系列研究很难理解,但讨论未来的工作可能会很有趣。
我的意思是当然这里的未来工作是我们要进行嵌入向量分析。在这两篇论文中,我们基本上假设嵌入是固定的且彼此正交。虽然如果你检查实证结果这是真的,但它们仍然不理想,因为嵌入也应该在学习过程中被学习出来。
但我们尚未对此进行测试,也还没有真正分析过嵌入方面到底发生了什么,这有点可惜。但下一篇论文将尝试解决这个问题。
此外,位置编码也是其中之一。我们还想谈谈潜在概念学习的基本动态。在多层设置中,我们基本上给出了一个关于如何学习的概念框架,但并没有具体的定理告诉你这个潜在向量是如何随时间被学习到的。但这非常棘手,很难处理。
这是一些无关的内容。我想谈谈由 JoMA 预测的一些有趣特性,但我打算跳过这部分。这将告诉你 MLP 层中的一个向量如何编码多种不同的模式,这被称为“模式叠加”。
实际上,许多实证工作都观察到了这一点,并且 Anisotropic 的一篇论文也强调了它。但在 JoMA 中,我们实际上可以分析并证明,如果遵循训练动态从头开始训练,这确实是可能的。但我打算跳过这部分。好的,让我们进入第二部分,即基于注意力特性的应用,主要是注意力的稀疏性。为此,我们有一堆论文试图利用稀疏性来加速推理。
希望从现在开始,我们在讨论实证结果。也希望观众的认知负担大大减轻。关键点非常简单:我们只想保留注意力、MLP 中的高激活 token,并利用它们来加速大模型的推理。从经验上看,你会发现在每个前向路径中有很多头未被激活。
而且你也看到很多 MLP 层的激活也没有被使用。这其实不太好,因为这意味着相应的权重被白白加载了。为了解决这个问题,我们提出了所谓的 Deja Vu 方法。该论文基本上告诉你如何预测在前向推理过程中哪些头不会被激活。
例如,第 43 号头未被激活,它基本上在 token 上给出了均匀分布。而第 42 号和第 44 号头则有非常清晰的模式,它们在分布上有非常明确的焦点。如何预测这一点呢?我们实际上为每一层、每一个头以及每个激活学习了一种非常简单的预测器,用于判断哪些头和 MLP 中间层应该被激活。
我们基本上利用这一点来预测这种上下文稀疏性,并以此加快前向速度。这很简单吧?我们想要预测它的原因是,如果我们知道在 MLP 层中只有第二和第六个激活会被使用,那么我们只需要加载这两个权重的相应行和列。因此这种加载速度更快,因为需要加载的权重数量更少。
我们都知道在 GPU 上,将内存加载到缓存是非常慢的,可能需要几百个 GPU 周期,而实际计算通常只需要几个周期。所以如果你能加载更少的权重,实际上你的前向速度会快得多。你可以这样做,并完成所有的工程工作,这就是最终的性能表现。
因此,我们实际上可以使这种前向速度比不同的基准测试更快。如果你将其与 HuggingFace 和 Fast Transformers 进行比较,它的延迟更低。这基本上是一个想法。它与量化兼容,并且特别适用于较小的批量大小。我们还有一篇名为 H2O 的论文试图利用这种稀疏注意力进行快速推理。
我们都知道,如果计算注意力,实际上是 O(n^2)。基本上对于每个新 token 要计算注意力,你必须遍历所有之前的 token。但问题是,我们真的需要所有的先前 token 吗?答案是否定的。如果我们画出这个分布图,看看有多少 token 具有较高的激活值,又有多少具有较低的激活值。
你会发现首先注意力分数分布与我在之前的幻灯片系列中经常谈论的共现非常相似。这也是两者之间相关性的良好实证依据。此外,我们还发现如果你去掉那些有很多注意力的 token,下游任务的性能会突然大幅下降。因此这些在前向传递中频繁出现且具有大量注意力的 token,我们称之为“重击者”(heavy hitters)。
如果我们使用这些重击者进行推理,它们表现良好;如果去掉它们,性能会非常差。因此自然的算法变成:我们将保留重击者,但去除所有注意力分数非常低的 token。这就是注意力算法,称为 H2O(Heavy-Hitter Oracle)。这基本上是一种局部贪婪算法。
每次你累加先前 token 的分数时,在每个解码步骤中,你基本上会丢弃从所有以前运行中具有最低累积注意力分数的 token。所以你只保留一定预算的 KV 缓存 token,并去除那些低于累积注意力分数阈值的 token。这基本上就是想法,非常简单。而且你实际上会看到非常好的性能表现。
你会发现只保留 20% 的 KV 缓存 token,令人惊讶的是你在多个基准测试中几乎拥有相同的性能。如果你只保留前几个本地 token,性能会大幅下降;但如果只保留重击者 token,它实际上能提供相当的性能表现,直到你丢弃超过 80% 的 KV 缓存。这将节省内存,因为你不需要保留 KV 缓存,同时也使推理快得多。
我们还看到它实际上还有其他好处,比如它会给你更多的创造力,因为它去除了一些可能限制你创造力的 token。一个自然的问题是:这些重击者到底是什么?我们实际上做了一些进一步的分析,这导致了一篇名为《Attention Sinks》的论文。
那篇被称为 StreamingLLM 的论文也被今年的 ICLR 接收了。我们基本上说,这些注意力重击者到底是什么?结果发现许多重击者实际上是 Transformer 中的前几个 token。它们实际上占据了大部分注意力分数,大约占 50%,非常高、非常多。
那么这种情况会发生什么呢?我们基本上提出了这样一个假设:在某些情况下,或者在许多情境中,也许并不需要注意力权重之和为1。但根据Softmax规则,它们必须求和为1,因此模型实际上会通过给初始的几个Token赋予极高的注意力分数来实现这一点。结果发现,这几个初始Token具体是什么并不重要——也就是说,你可以用特殊的“返回”标记替换掉最初的几个Token,模型依然能保持非常相似的能力。然而,如果你完全移除这些初始Token,模型就会突然崩溃。
困惑度通常会飙升到5000左右,这意味着模型输出的基本全是垃圾信息。因此,初始的几个Token至关重要,但重要的是它们的位置而非内容。这一发现非常有趣。后来我们发现,如果只保留初始的几个Token,就可以与模型进行无限对话,而不受上下文窗口的限制。这对于大型模型的实证分布和部署来说非常重要。
这就是StreamingLLM论文的内容。该论文引起了外界极大的关注,人们对此给予了高度评价。这项工作的一些变体已经被部署在硬件设备和库中。这里有一个非常简单的思路:当生成下一个Token时,首先设定一个固定长度的KV缓存预算。如果生成的Token数量超过了这个预算,就会移除中间部分的Token,但保留最近的Token以及初始的Token。同时,在缓存中保持它们的注意力位置,而不是在原窗口中。这基本上赋予了模型无限对话的能力。
使用StreamingLLM时,你可以进行无限对话且所有文本都可读。当然,如果不使用它,要么会因为需要保持极长的KV缓存序列而耗尽内存;如果直接截断所有之前的Token(包括初始的几个),模型就会突然崩溃,在预算窗口外的几个Token被移除后输出垃圾信息。这非常有趣,我们在许多不同场景中早期就进行了测试。我们发现StreamingLLM能提供稳定的困惑度,意味着输出非常有意义,同时节省了内存。
无论上下文窗口如何变化,你随时间保持恒定的内存占用。只需保留预算和初始的几个Token即可。这样你就可以永远与大型模型对话,这就是其有趣的特性。此外,我们还进行了一系列实验,表明它可以将模型扩展到四百万个Token,甚至更多,且保持相同的准确性。我们还与其他基线方法进行了比较。
你还想了解初始几个Token到底发生了什么。如果将这些初始Token视为可学习的参数会怎样?你会发现,这些可学习Token实际上起到了相同的作用,甚至效果稍好一些。我们在开头设置了一个专门的标记称为“Sink Token”,并保留该Token为零嵌入或可学习嵌入,分别对应零同步和可学习同步。一旦Sink Token存在,模型的容量突然变得很低,你可以与模型进行对话而无需担心上下文窗口的长度问题。
我们还看到了来自Meta的并发工作,有趣的是我们不同部门之间没有交流。当我们提交论文时,发现其他团队也有非常相似的想法。他们也在视觉Transformer中发现了类似的结构,称为“Register”,这对应于注意力Sink。当然,这实际上并没有解决长上下文问题,只是丢弃Token并保持准确性。
但如果要进行某种序列任务(如密码检索),如果对应答案的Token被丢弃,模型将无法给出正确答案。它基本上保持困惑度较低,意味着会给出合理的答案,但不一定能检索到被丢弃的信息。这就是其局限性。希望未来我们能解决这个问题。最后,我想介绍另一篇论文,它试图通过微调来解决长上下文窗口问题——抱歉,就是这篇论文。
在此之前有StreamingH2O,意味着将StreamingLLM与H2O方法结合思考。如果考虑StreamingLLM,它实际上是H2O的一个特例,因为StreamingLLM只保留初始的几个Token,而H2O根据注意力分数选择Token。结合两者实际上会带来更好的性能,同时保持无限对话的特性。这是最近的更新,我们将利用这些改进来实现快速推理。
最后有一篇名为《扩展上下文窗口》的论文。这篇论文一直处于arXiv版本,因为发布两天后(准确说是30小时左右),Reddit上的人们提出了更好的解决方案。考虑到竞争太激烈,我们决定不提交论文。这是一篇试图通过预训练来扩展上下文窗口的论文。众所周知,预训练后上下文窗口无法改变(例如LLaMA模型的2K限制)。如果尝试超出此范围,模型会突然输出垃圾信息。
那么如何扩展它呢?我们可以用长文本进行微调,但这需要大量资源和迷你批次。我们发现通过改变LLaMA模型中的单个参数,可以使微调更加高效。这很简单:我们基本上改变了位置嵌入的缩放比例。将其缩回原始大小。例如,如果模型是2K,你想扩展到4K怎么做?你只需对每个位置编码索引除以2。
对于2K窗口,它映射回... 对于4K窗口,它将映射回2K的范围,使得每个位置编码成为前一个版本中位置编码的插值。
利用这一变化来修改Transformer,你只需几百个样本就能训练模型,突然之间效果变得非常好。原因在于我们发现注意力函数实际上表现不佳(ill-behaved),因此如果进行插值,效果会相当不错。但如果是外推,突然之间它会给出极差的分数,完全超出其训练范围。这就是为什么我们应该进行插值而不是外推的原因。
因此,如果我们使用我们的方法,实际上可以训练出能够扩展到长上下文窗口的模型,且微调步骤少于1000步。你可以将其扩展至原始上下文窗口长度的8倍。这比在不改变模型任何结构的情况下进行硬微调要高效得多。例如,在这种情况下,只需200步就足以将窗口从2K扩展到8K、16K或32K。
你只需要200步,但如果只是进行微调,则需要更多步骤。基本上你需要大约1000步,但并不能真正扩展到8K,只能扩展到2K或2.5K。因此,在位置编码中进行插值要高效得多。是的,而且性能并没有大幅下降。在所有基准测试中,它大致保持不变。
正如我所说的,论文发布两天后,你在Reddit上就看到了更好的结果。竞争非常激烈。我们实际上看到许多论文沿着这些方向涌现出来。我希望人们能从这些见解中受益,这基本上就是我讲座的全部内容。谢谢大家的关注。
观众:是的。你所说的语言模型中的插值和外推是什么意思?那意味着什么? 演讲者:是的。意思非常简单。你从例如2K的窗口开始。这意味着对于每个token,你会首先根据位置分配一个索引,即从0到2K减1。然后根据该索引计算位置编码。
为此我们使用RoPE,这是人们在这些模型中普遍使用的技术。要计算它,首先将位置编码减去位置索引。然后使用m减n这个数值,将其代入方程中,即可据此计算注意力机制。基本上这就是如何使用位置进行位置编码的方法。
观众:所以我的第一个问题是关于如何将理论论文的见解与例如大语言模型的缩放定律(scaling law)以及涌现能力联系起来? 演讲者:是的。 观众:因为论文中的理论图景,我的意思是它们并非完全缺席于早期模型中。 演讲者:你的意思是如何在更大的模型中将两者结合?我认为人们已经在使用了。
观众:当我们的理论扩展时,当我们训练大得多的模型时,我们会获得强大得多的涌现能力。 演讲者:我明白了。我认为肯定存在系列研究(series),即这是一个非常深层的堆栈。你有一系列主要是经验性的,并试图描述现象的研究。我会说像缩放定律和涌现行为这样的属于这一类。
那更多是对正在发生的事情的总结。所以这种理论绝对适用于当前模型。例如,根据缩放定律,你可以知道如果将模型扩大10倍会发生什么?你基本上会得到一条曲线。这条曲线会告诉你预测将会发生的情况,对吧?
所以在许多情况下这非常有用,对吗?而对于像这样的理论。基本上对于系列研究,正如我们这里讨论的,更多是从第一性原理出发,对吧?你从公式开始。然后思考通过该公式将实现什么后果?
这可能很难应用于实际应用。但如果我们做得足够好,突然之间我们就了解了整个过程中的所有情况,那么可能会有许多不同的适用场景。这是一段非常艰难的旅程,但也许未来它会带来很强的应用性。
观众:所以你认为从第一性原理到像缩放定律这样的东西,最直接的一步是什么? 演讲者:是的。我认为对于像缩放定律这样的事情,情况会是这样的:在给出所有理论研究以及系列研究之后,你可能能够模拟如果拥有更多数据会发生什么。那么边界会是什么样子的?这将成为你经验上观察到的缩放定律,对吧?
在这种情况下,这可能比目前我们拥有的缩放定律更进一步。这是纯粹经验性的。是的,有可能。我认为物理学家在许多不同场景中已经这样做了。你可以从第一性原理出发得出一些方程,然后说如果拥有10的32次方个原子会发生什么?
然后得出更宏观和经验性的定律,并尝试将其很好地拟合到现实世界的实验中。那可能是一个可能的方向。这个过程确实各不相同。我的意思是,好吧,我会给出个人观点。
我从2017年开始进行一些系列研究。当时那是一个极其痛苦的过程,我不得不说。是的。在这个过程中,你可能会花几个月时间在一个不可能证明的问题上。即使你证明了它,你也看不到任何好处,并意识到你所证明的毫无意义,根本不需要去证明。
所以在开始时这实际上是一个非常痛苦的过程。但后来,经过多年的探索之后,许多人可能达到了这样一个阶段:你对系列研究的粗略图景有了很好的整体见解。然后基于这个粗略的图景,你知道大致应该证明什么定理。
可能有一些定理可以大致写下来,即使它们是错的也没关系。就像写出错误的定理,但它们在大方向上是正确的。然后通过添加约束、条件以及进行一些经验性的论证,你可能会更好地知道它应该是什么样子,直到你确定一个既在逻辑上正确又在经验上有用的论点。
那可能是使理论更加精简的一种方式。是的。例如,在JoMA论文中(注:原文为drama/joint embeddings相关),我的意思是我们在几天内就提出了联合嵌入这一核心思想,对吧?
一旦推导出那个方程,我们就明白了。显然还有下一步工作要做,我们可以在此基础上深入挖掘。所有的工作基本上都对应着这一点。我得说,理论方面并不是我的主要推动力。我们还有很多其他工作要做。但即便如此,你已经能很好地理解如何推导定理,并思考如何在极短时间内找到良好的解决方案。
我认为如果你经历了这个过程,你就会尝试去具备理论分析的能力。同时,你也可以进行实验和实证研究。这确实有些特别:你首先得尝试一些方法,然后发现它们可能不正确。接着你需要转向不同的假设。这基本上是一个在符号结构与现实世界结构之间来回往复的过程:从现实出发提出假设,再到符号层面审视它,思考该怎么做。
如果在符号上采用这些假设能让事情变得更简单,那就值得考虑;反之则需质疑其合理性。然后回到实践层面继续反复推敲,直到收敛到一组既在符号上有趣、又与现实世界相关的假设。随着时间推移,你会越来越擅长这种平衡。显然,“t趋于无穷大”是其中一个被采用的假设。
我们的合作者,即第二作者做了许多细节工作,他首先提出了一个置信界。如果t是有限值,我会说“先放一边”,直接假设t趋于无穷大,因为这样能捕捉到图像的整体感觉。虽然我们不关心太多最大细节,但在这种情况下,这似乎是一个很好的假设。
但我永远不会假设你的特征是固定的。即使这样会让数学变得简单得多,那也不是正确的做法,因为这基本上扼杀了整个物理图景。所以总是需要平衡:尝试好假设的同时,确保它不会破坏你想做的事情。
关于这一点,我可以讲另一个故事:多年来我一直试图在分层模型上做些什么。从我的硕士论文开始——如果你查阅的话,那是关于某些视觉模型的层次化表示。那篇论文没人读过,但这是一个漫长的努力过程。对于CNN(卷积神经网络),是的,我们也尝试过;如果你查阅一些论文就能发现这一点。
我得说,《JoMA》这篇论文是我第一篇进行分层分析并被接受的论文。之前我们尝试做的所有分层分析论文都被拒稿了,因为符号太复杂。所以这非常棘手。对于CNN来说,确实存在分层结构。这也是我的动机之一:我最初是审稿人,做的是视觉工作,而视觉领域的人痴迷于层次化表示。
我认为CNN和Transformer的区别在于:Transformer使用嵌入(embeddings),而嵌入非常强大,甚至可以说强得惊人。你可以这样思考:在高维空间中有一个有趣的特性——你能将2的d次方个向量放入这个空间,并保持它们彼此几乎正交。这是一个很好的特性:你可以在有限、简单的空间中放置指数级数量的对象。
但在CNN中,你本质上是在对概念进行“独热编码”(one-hot representation)。你说某个token代表某物,这实际上是独热表示。但如果你想让它们在数学上正交,就需要2的d次方维度的空间。这其实非常高效。另一件让事情变得高效的原因是,Transformer还能执行大量的推理任务,我相信这肯定与嵌入的表示有关。
也许A可以由多个嵌入向量的和来表示:一个向量代表字母,另一个代表首字母或大小写等属性。这种表示法非常有用,因为它将不同属性解耦了;这些属性可以在Transformer的计算过程中单独计算。这可能就是我们要分析的下一个方向。