赞
踩
自从 Transformer 结构被提出以来,以 BERT 为代表的 Encoder 模型,以 GPT 为代表的 Decoder 模型,以 ViT 为代表的 CV 模型,都烜赫一时。时至今日,几乎所有的 LLM 也都是 Transformer 结构,尽管不时也会有新的结构被提出来,但 Transformer 的江湖地位仍然无可撼动。那么本篇将从 Transformer 结构出发,将主要围绕以下问题展开思考和讨论:
希望通过以上问题的思考和讨论,能够帮助我们更好地使用Transformer、理解Transformer、优化Transformer和改进Transformer。
本篇的主要内容是围绕 Transformer 的结构展开的,因此深入了解 Transformer 结构及其工作原理是非常必要的。实际上,在笔者之前的文章中已经分析过 Transformer 的结构
紫气东来:NLP(五):Transformer及其attention机制17 赞同 · 1 评论文章编辑
及一些针对性的可解释研究方法
紫气东来:可解释人工智能 (三): 基于博弈论的可解释性研究方法18 赞同 · 0 评论文章编辑
为了简明起见,本篇将尽可能不与之前讨论过的内容重复,而将试图从问题的角度出发而进行相关思考与讨论。
简单而言,Transformer 结构及工作原理可以用下图表示,其中图左为 Encoder 结构,图右为 Decoder 结构。
Transformer 结构及工作原理
问题一: Encoder 和 Decoder 结构分别适用于什么场景,为什么生成式模型普遍采用 Decoder-only 结构
当前,Transformer 结构中的 Encoder 和 Decoder 结构构成了 3 种主要的模型范式,如下表所示:
结构 | 特点 | 常见任务 | 典型代表 |
---|---|---|---|
Encoder-only | auto-coding | 序列分类,NER,抽取问答,MLM | BERT, RoBERTa, DeBERTa |
Decoder-only | auto-regressive | 文本生成,CLM | GPT, Llama, PaLM |
Encoder-Decoder | sequence-to-sequence | 翻译,总结,生成问答 | BART, T5, Marian |
如果从直观上来解释,Encoder-only 的注意力是双向的,要确定一个 mask 值,需要同时考虑之前和之后的文本信息,因此在问答和填空类的场景比较有效。而人类的语言生成过程具有天然的马尔科夫性,在生成过程中没有下文信息可以参考,因此刚好契合 Decoder-only 结构的 token by token 的生成方式。
除了上述解释外,还有从低秩角度来解释的,即在双向注意力中由于 softmax 操作会导致低秩问题,而在单向注意力中,attention 矩阵是满秩的下三角矩阵,因此表达能力更强。另外还有从 scaling law 等角度进行解释的,在次不一一展开。
问题二:attention 机制有什么深刻内涵?
让我们重新回顾一下,attention 的计算过程Attention(�,�,�)=softmax(�����)�这个过程可以简单概括为 3 步:
通过这种方式,建立起了序列间的全局的联系。这里还有一些细节需要补充说明:
00:07
问题三:为什么需要多头,是否有深层含义?
看到多头机制,我们可能会比较自然想到 CNN 中的多通道,这样可以实现更好的并行化效果,那么除此之外是否还存在更深层次的原因呢?
根据原文观点,将隐状态向量分成多个头,形成多个子语义空间,可以让模型去关注不同维度语义空间的信息。简单来说就是把 Scaled Dot-Product Attention 过程做 H 次,再把输出合并起来。
多头注意力机制的公式如下:
ℎ����=���������(��,��,��),�=1,...,8
���������(�,�,�)=�������(ℎ���1,...,ℎ����)��
其过程如下所示:
multi-head attention 的工作过程
从更加深刻的角度去认识这个问题,有相当多的研究从秩的角度进行分析,即认为 attention 操作本身就是一个低秩操作,多头机制进一步使低秩问题更加严重,但好处是多头避免了单头的低秩使某些信息丧失,即多头增强了信息关注的多样性。关于这方面的详细推导和证明可参考
等文章,笔者有机会专门出一期进行讨论,在此不予赘述。
问题四:前馈层(feed-forward layers or MLP) 的作用是什么,如何发挥作用的?
全连接网络是最基本的模型,在 Transformer 架构中包括:2 个线性层(升维 and 降维),1 个激活函数,一个残差连接。本节将试图从 memory 的角度理解其作用,即考虑 FFNs 是如何转化和记忆注意力机制中的信息的。
考虑 Memory Network (MN) 的基本原理与过程:
而 Transformer 中的前馈层(不考虑bias)可以简单表示为:
FF(�)=ReLU(�⋅���⋅�����)⋅�这样就完成了前馈层和记忆网络的形式上的统一。当然,这里的论证过程比较粗浅,详细严谨的论证过程可参考:
1.2.1 从 SVM 角度看 Transformer
该部分内容主要参考论文 Transformers as Support Vector Machines,在此仅讨论其核心观点,详细推理证明过程,请参考原文。
该研究证明了 Transformer 架构中自注意力层的优化几何学与硬间隔支持向量机(SVM)问题之间的形式等价性。这种联系是通过自注意力层中输入标记序列X的外积对数线性约束来实现的,旨在将最优输入标记与非最优标记分离,即:落在 SVM 决策边界错误一侧的「坏」token 被 softmax 函数抑制,而「好」token 是那些最终具有非零 softmax 概率的 token。还值得一提的是,这个 SVM 源于 softmax 的指数性质。
Transformer 中的注意力层接受输入 X,并通过计算 �������(�����⊤�⊤) 评估 token 之间的相关性,其中 (��,��) 是可训练的矩阵参数,最终有效捕获远程依赖关系。该研究在此基础上证明了以下几点:
总的来说,这些特性的证明有助于更深入地理解Transformer模型的内部工作机制,特别是在自注意力层如何通过优化过程来选择和组合输入序列中的 token,即可以将多层 transformer 看作分离和选择最佳 token 的 SVM 层次结构。
1.2.2 从 GNN 角度看 Transformer
GNN 和 Transformer 的关联在于二者形式上的相似性,不妨回顾一下GNN的基本原理:
图神经网络(GNN)通过邻域聚合(或消息传递)来构建图数据中节点和边的表示,其中每个节点从其邻域收集特征,以更新其周围局部图结构的表示。GNN 通过对节点自身特征 ℎ�ℓ 的非线性变换,将其添加到每个相邻节点的特征集合 ℎ�ℓ 中,从而在层 ℓ 上更新节点 � 的隐藏特征 ℎ ,即:
ℎ�ℓ+1=�(�ℓℎ�ℓ+∑�∈�(�)(�ℓℎ�ℓ))其中 �ℓ,�ℓ 是 GNN 层的可学习权重矩阵, � 是 ReLU 等非线性因素。在下图左的示例中,有 �()={,,,} 。
GNN and self-attention graph
为了使连接更明确,将一个句子视为一个全连接图,其中每个单词都与其他每个单词连接。现在,我们可以使用 GNN 为图(句子)中的每个节点(单词)构建特征,然后我们可以用它来执行 NLP 任务。概括地说,这就是 Transformers 正在做的事情:它们是具有多头注意力的 GNN,作为邻域聚合函数。标准 GNN 聚合来自本地邻域节点的特征,而 NLP 的 Transformers 将整个句子视为本地邻域,聚合每个邻域的特征每层的单词。
GNN and GAT
如果我们要进行邻域聚合的多个并行头,并用注意力机制(即加权和)代替对邻域的求和,我们就会得到图注意力网络(Graph Attention Network, GAT),如上图左所示。从某种程度上说,GAT 与 attention 已经完成了形式上的统一。还有一点需要注意的是,GNN 的图连接通常不是全连接的,而 Transformer 的关于稀疏性的研究也证明了非全连接同样是有效的。
1.2.3 从 RNN 角度看 Transformer
上一小节构造了 GNN 和 Attention 的形式上的统一,那么能否将 Transformer 推理的 token by token 的过程和 RNN 构造起形式上的统一呢?答案是确定的。
在论文 Transformers are Multi-State RNNs 中,作者提出了一个观点:Transformers(特别是 Decoder)可以被概念化为无限多状态循环神经网络(MSRNNs),其中KV向量对应于一个动态无限增长的多状态。之所以可以这么等价,我们需要回顾一下 RNN 的原理
���+1,ℎ��=�RNN�(���,ℎ�−1�)其中 ℎ�� 表示 � 层 � 时刻的隐藏状态, ��� 则表示对应的输入。
接下来,将 Transformer 的推理过程改造成这种形式,首先我们知道在推理情况下���+1=FF�(Attn�(���,���,���))其中 ��� 来源于 ��� ,考虑到使用 KV cache 的情况,则可以进一步表示为
���+1,(���,���)=�TRANS �(���,(��−1�,��−1�))
如果令 ���=(���,���)=((��−1����),(��−1����)) , 则上式可以进一步简化为
���+1,���=�MSRNN�(���,��−1�)
即和 RNN 构成了形式上的统一。如下图所示,其无限表示即保留所有的 KV cache,而其有限表示则是进行了 KV cache 的稀疏化处理。
此外改论文还提出了:
总结一下本节的核心结论,即:
Transformer 的有效性很大程度上来源于 attention 机制,而 attention 机制的最大特点即在于其 �(�2) 的复杂度与多头机制的并行性。这样在文本生成这类的 token by token 的任务上,由于每步的二次复杂度和 KV cache 的内存限制,在推理过程中表现出较低效率。
很多研究 (如 Linformer) 期望可以降低 attention 的复杂度,这样就可以表现出较好的推理效率,但是这样就一定程度上牺牲了模型精度和效果。
另外基于传统的 RNN 的模型可以达到较好的效果和高效的推理效率,但是由于其没有多头机制,无法实现高效的并行训练,因此无法扩大规模。
也就是说,这些模型架构面前摆着一个“不可能三角”,三个角代表的分别是:并行训练、低成本推理和良好的扩展性能。因此如何平衡这三点,成为优化与改进 Transformer 结构的非常重要的课题。
由于 attention 机制的 �(�2) 复杂度,一个最直观的想法就是尽可能降低其复杂度。该类方法在笔者之前的文章中已有多次讨论,可参考以下文章,在此不予赘述
紫气东来:NLP(二十):漫谈 KV Cache 优化方法,深度理解 StreamingLLM302 赞同 · 12 评论文章编辑
attention 及典型的稀疏化方法
本节将主要介绍另外两种降低 attention 复杂度的方法:Linformer 和 FNet。
2.1.1 Linformer 与 Attention 线性化
Linformer 的核心发现是 Attention 矩阵是低秩,即可以用低秩矩阵来近似,即对于一个N x N
的 Attention 矩阵,可以用一个低秩矩阵(比如N x 128
)就已经足够存储 attention 的大部分信息。
attention 的 SVD 分解的发现
Linformer 对 Self-Attention 的结构进行了一些修改,使复杂度降到线性,修改后的 Self-Attention 结构如下图所示,主要的区别在于增加了两个线性映射层 (用矩阵 E 和 F 表示)。线性映射层 E 和 F 维度是 �×� ,原来计算得到的 ���� 矩阵维度是 �×� ,通过新增的两个线性映射层可以把其转为 �×� 的矩阵,因此得到的 Attention 矩阵 �¯ 维度是 �×� 。
Linformer 的 计算过程
尽管改工作宣传把复杂度降到了 �(�) ,稍加分析便会发现并非如此,把维度从 512 降到 128 是可行的,也并不代表可以从 4096 也降到 128,因此只能说线性降低了复杂度,而不是把复杂度降到了线性。
2.1.2 基于傅里叶变换的 FNet
既然 Attention 的本质是信息的交互,那么除了这种方式之外还有其他方式实现信息交互吗?是的,我们在复分析中常用的傅里叶变换就具有这样的能力。FNet使用了傅里叶变换来实现 token 内部和外部的信息交互。
傅里叶变换的公式如下,从公式中可以看出,傅里叶变换生成的每个元素,都是原始序列中所有token信息的融合,这也是实现信息交互的一种方式。��=∑�=0�−1���−2�����,0≤�≤�−1FNet 每个层都由一个傅里叶混合子层和一个前馈子层组成。研究者将每个 transformer 编码器层的自注意力子层替换为傅里叶变换子层,该子层将 2D 傅里叶变换应用于其 embedding 输入 [���,ℎ�����] - 沿着序列维度 �seq 和隐藏维度 �hidden 进行一维傅里叶变换。
�=ℜ(�seq (�hidden (�)))应用傅里叶变换后, embedding 会被转换到频域。傅里叶变换的每个输出都有每个输入 embedding 的一个分量。这样,所有 embedding 的信息都能得到处理。因此,通过傅里叶变换变相实现了注意力机制。
FNet 结构及 DFT 过程
通过这种方式,算法复杂度被降到了 �(�����) 。还需要说明的是 FNet 中的傅里叶变换层并没有参数需要训练,因此网络中仅有前馈层的参数需要训练 (当然 layer norm 中还有很小部分) 这也大大降低训练成本。从结果来看,FNet 能够 7 倍的速度达到 BERT 92%,也反映了其优化的效果。
当然,对于 Transformer 的结构优化是无止境的,以上仅仅是两个有趣的例子,更多的案例包括但不限于:
既然 Transformer 的一大短板是推理效率较低,那么是否可以通过进一步增加并行程度来实现呢?当然!
2.2.1 Attention 与 FFN 的并行
我们注意到在 Decoder layer 中 attention 模块和 FFN 模块是串行连接的,那么就有了第一种方法。这种方法是在 GPT-J 模型中被首次提出的,即将 attention 模块和 FFN 模块并行连接,如下图右所示,这样很自然可以提高计算效率。但是由于我们在 1.1 节问题四中讨论过 FFN 是对 attention 输出的隐藏表示的记忆,因此这种并行化实际上解耦了这种关系,或许也正是因为这一点,该方案并没有被广泛采用。
GPT-J model architecture VS the standard GPT architecture
在 GPT-J 之后,SIMPLIFYING TRANSFORMER BLOCKS 又进一步简化了这种并行。该方案将 attention 公式简化为SelfAttention��������(�)=softmax(�����)�这样做带来了以下几点变化:
parallel block VS simplified block
同时 MHA 和 MLP 进行并行化计算,如下:
�out =�comb �in +�FFMLP(Norm(�in ))+�SAMHA(Norm(�in ))
其中 α���� 、 β�� 和 β�� 是可训练参数,分别控制输入、MLP 和 MHA 块对输出的贡献。
同时该方案还删除了归一化操作和残差连接,极大程度简化了模型结构。
2.2.2 深入浅出理解 MoE 方案
另一种并行化的方式是只对 FFN 进行拆分并进行并行化,这就是当前炙手可热的 Mixture of Expert (MoE) 方案。MoE 方案的核心在于:稀疏 MoE 层以及门控网络 (router)。
Mixture of Expert (MoE) models
笔者接下来以 DeepSeekMoE 为例做更进一步地说明。DeepSeekMoE 通过两种主要策略来提高专家的专业化程度:
其公式表示如下:
ℎ��=∑�=1��(��,�FFN�(���))+���,��,�={��,�,��,�∈Topk({��,�∣1⩽�⩽��},��),0, otherwise, ��,�=Softmax�(�������),
Illustration of DeepSeekMoE
2. 共享专家隔离(Shared Expert Isolation):
增加该部分后公式表示如下:ℎ��=∑�=1��FFN�(���)+∑�=��+1��(��,�FFN�(���))+���,��,�={��,�,��,�∈Topk({��,�∣��+1⩽�⩽��},��−��),0, otherwise, ��,�=Softmax�(�������)
DeepSeekMoE架构的这两个策略共同工作,以训练一个参数效率高的MoE语言模型,其中每个专家都高度专业化。其实现的核心代码如下:
- class DeepseekMoE(nn.Module):
- """
- A mixed expert module containing shared experts.
- """
- def __init__(self, config):
- super().__init__()
- self.config = config
- self.num_experts_per_tok = config.num_experts_per_tok
- self.experts = nn.ModuleList([DeepseekMLP(config, intermediate_size = config.moe_intermediate_size) for i in range(config.n_routed_experts)])
- self.gate = MoEGate(config)
- if config.n_shared_experts is not None:
- intermediate_size = config.moe_intermediate_size * config.n_shared_experts
- self.shared_experts = DeepseekMLP(config=config, intermediate_size = intermediate_size)
-
- def forward(self, hidden_states):
- identity = hidden_states
- orig_shape = hidden_states.shape
- topk_idx, topk_weight, aux_loss = self.gate(hidden_states)
- hidden_states = hidden_states.view(-1, hidden_states.shape[-1])
- flat_topk_idx = topk_idx.view(-1)
- if self.training:
- hidden_states = hidden_states.repeat_interleave(self.num_experts_per_tok, dim=0)
- y = torch.empty_like(hidden_states)
- for i, expert in enumerate(self.experts):
- y[flat_topk_idx == i] = expert(hidden_states[flat_topk_idx == i])
- y = (y.view(*topk_weight.shape, -1) * topk_weight.unsqueeze(-1)).sum(dim=1)
- y = y.view(*orig_shape)
- y = AddAuxiliaryLoss.apply(y, aux_loss)
- else:
- y = self.moe_infer(hidden_states, flat_topk_idx, topk_weight.view(-1, 1)).view(*orig_shape)
- if self.config.n_shared_experts is not None:
- y = y + self.shared_experts(identity)
- return y

3.1.1 Attention 一定需要么? —— 从 AFT 谈起
Attention Free Transformer (AFT) 是Apple公司提出的一种新型的神经网络模型,它在传统的 Transformer 模型的基础上,通过使用像 Residual Connection 之类的技术来消除注意力机制,从而减少计算量和提升性能。其核心公式为��=��(��)⊙∑�′=1�exp(��′+��,�′)⊙��′∑�′=1�exp(��′+��,�′)
其中 ⊙ 表示逐元素相乘(element-wise product), ��,�′ 为可训练参数,表示位置偏置。
该操作有以下几点值得一提:
3.1.2 从 AFT 到 RWKV
首先解释一下 RWKV 的一些概念:
从宏观来看,RWKV 架构由一系列堆叠的残差块(这个结构显然参考了 Transformer)组成,每个残差块由具有循环结构的时间混合和通道混合子块形成,整体上形成了 RNN 的结构。
在 RWKV 的结构中,其中的递归被表述为当前输入和前一个时间步的输入之间的线性插值(即time-shift mixing或token shift)。这种结构
以上整体展示了 RWKV 的结构,下面进一步细化了关键模块的细节,其中每个时间步的主要元素之间的相互作用都是乘法的。当然这些还不足以是我们理解 RWKV 的设计细节,还需要下文更加细节的讨论。
3.1.3 RWKV的时间混合(time mix)模块与通道混合(channel mix)模块
首先来看时间混合(time mix)模块
时间混合(time mix)模块
假设输入sequence是My name is,目前�=2,则这里��−1是上一个输入token(My),��是这个输入token(name)。�是遗忘因子,越大对上个token(My)就忘的越多,也就是对这个token(name)更专注。用作者的话说,就是递归被表述为当前输入和前一个时间步的输入之间的线性插值,也叫token shift。
�,�,� 本质上都是��,��−1线性组合的变换,注意,这里输入的是前一个token的输入(embedding),不是输出(hidden state)。
���的计算,即 ����, 类似于 Transformers 中 ����(�,�,�) 的角色,而不会产生quadratic成本,因为计算的都是标量。其中 ��,�=−(�−�)� ,其中 �∈(�≥0)�,�是通道数。�为非负数,以确保���,�≤1并且每通道权重随时间向后衰减。
RWKV能减小复杂度的关键是����的 RNN 模式,因此只需要上一时刻的state vector和这一时刻的输入。因此,生成的每一个token只要考虑常数个变量,所以复杂度为�(�)。
直观上,随着时间�的增加,向量��取决于较长的历史,由越来越多的项的总和表示。对于目标位置�,RWKV在[1,�]的位置区间进行加权求和,然后乘以接受度σ(�)。因此,交互作用在给定的时间步长内是乘法的,并在不同的时间步长上求和。
接下来看通道混合(channel mix)模块
该模块类似 Transformer 中的 MLP 结构,只是这里也考虑了前文输入。另外需要注意的是。这里采用平方 ReLU 激活
在循环网络中,使用状态 � 的输出作为状态 �+1 的输入是很常见的。这在语言模型的自回归解码推理中尤其明显,要求每个标记在输入下一步之前进行计算,从而使得RWKV 利用其类似 RNN 的结构,称为时间顺序模式(time-sequence mode)。在这种情况下,可以方便地递归地制定 RWKV 以便在推理过程中进行解码,如附录 B 所示,它利用了每个输出token仅依赖于最新状态的优点,该状态具有恒定的大小,而与序列长度无关。
然后,它充当 RNN 解码器,根据序列长度产生恒定的速度和内存占用,从而能够更有效地处理较长的序列。相比之下,自注意力通常需要 KV 缓存相对于序列长度线性增长,从而导致效率下降,并且随着序列变长而增加内存占用和时间。
RetNet 可以说是我 2023 年看过的最精巧的工作了,每次看都会有新的发现和感悟。下面让我们来尽可能逐步认识其工作的机制。
概括来说,RetNet 综合了 Transformer 和 RNN 的优点,即采用并行训练、循环推理。RetNet 使用 Transformer 的自注意力模块来并行化训练并实现最先进的性能,但它不会遇到推理成本和内存复杂性问题。这是由于在推理阶段,它采用 retention 模块+循环推理范式。RetNet 共有三种计算范式,以适应不同场景:
接下来我们将分别这三种计算范式,以体会其构思的巧妙:
3.2.1 用于训练的并行表示
RetNet 的训练过程采用了 Transformer 的多头并行的方式,以摆脱 RNN 的自回归序列处理的限制。如下图所示,RetNet 放弃了 softmax 操作,转而使用 Hadamard 积,引入了新引入的 D 矩阵,然后是 GroupNorm 操作。那么弄清楚为什么 D 矩阵 + GroupNorm 可以替代 softmax 就成为了问题的关键,可以从两个方面来理解:
由于 RetNet 既在循环范式中运行,也在并行化范式中运行,因此作者首先在循环范式中计算 RetNet 的 retention 块(即单独处理每 n 个输入元素)。然后将他们提出的循环保留块矢量化。因此,初始循环公式如下所示:
��=����=∑�=1�����−���⊤��其中 ��−�=Λ(����)�−�Λ−1 表示位置(pos)矩阵(该表示熟悉 RoPE 的同学应该非常眼熟了)。RetNet 用 pos 矩阵替换了原始 Transformer 的 softmax。把 Λ 吸收进 ��,�� ,则上面的等式可以扩展如下:
��=∑�=1���(����)�−���⊤��=∑�=1�(��(����)�)(��(����)−�)⊤��
将 γ 作为标量值,并对第二项进行共轭表示,上式可以写作 ��=∑�=1���−�(������)(������)†�� ,其中 † 表示共轭转置。由此我们便可以写出并行表示的公式:
�=(���)⊙Θ,�=(���)⊙Θ¯,�=���Θ�=����,���={��−�,�≥�0,�<� Retention (�)=(��⊤⊙�)�
整体来看,与 Transformer 的不同点在于 pos 矩阵 Θ (及其共轭矩阵 Θ¯ )和 D 矩阵。熟悉旋转位置编码都很清楚 Θ 表示空间的位置旋转,D 矩阵充当因果掩码并且指数衰减(可参考 alibi 方案的线性衰减)。可以通过Hadamard 积将位置感知和远程衰减结合起来,如下图所示:
下面通过一个小例子来感受这个过程,假设有 �,�,� 矩阵如下
�=[121323],�=[123456],�=[543210]
首先计算 ��⊤
��⊤=[121323][142536]=[8201640]
然后计算与 D 矩阵之间的 Hadamard 积
��⊤⊙�=[8201640]⊙[100.251]=[80440]
最后乘以 �
(��⊤⊙�)�=[80440][543210]=[4032241005612]
这样我们就完成了并行训练的主要步骤,在后边我们将会发现其与循环表示的神秘而巧妙的等价联结。
3.2.2 用于推理的循环表示
RetNet 的循环范式是通过解构并行计算获得的,如下图右所示,这样递归地进行计算,且计算成本及复杂度非常低。循环表示的公式如下:
��=���−1+��⊤�� Retention (��)=����,�=1,⋯,|�|
可以轻易发现这里的不同之处:第一步是 �⊤� 而不是 ��⊤ ,最后才将更新后的状态向量与 Q 相乘,得到此步骤的最终输出。
那么通过上一小节的例子来计算这一过程,感受其具体过程
首先计算 �⊤�(n=1)该计算实际上是 2 个向量之间的外积
�1⊤�1=[123][543]=[543108615129]
然后获取 S1。由于没有 S0,因此 S1 与上一步相同
�1=��0+�1⊤�1=[543108615129]
最后将 �1 和 �1 相乘以获得最终输出,这里参考论文中的实现
�1⊗�1=[543108615129]⊗[121]=[54320161215129](sum)=[403224]
这个结果竟然跟并行模式的结果完全一样,真的是非常巧妙!让我们接着进行愉快的计算
�2⊤�2=[456][210]=[84010501260]
�2=��1+�2⊤�2=[1.2510.252.521.53.7532.25]+[84010501260]=[9.2550.2512.571.515.7592.25]
�2⊗�2=[9.2550.2512.571.515.7592.25]⊗[323]=[27.75152.252514347.25276.75](sum)=[1005612]
结果仍然可以对应!这说明 RetNet 能够将并行训练计算解构为完全重复的计算,而在token by token 的推理过程中,这种方式非常适合且有效。
最后总结一下,RetNet 能够如此高效,其代价是什么呢?答案可能是牺牲了 attention 的灵活性,即采用确定的方式来计算 attention 以获得与 RNN 的兼容。
由于篇幅所限,且该部分自成体系,因此单独成章,详情参见
紫气东来:NLP(廿五):从控制系统到语言模型 —— Mamba 的前世今生106 赞同 · 0 评论文章编辑
汪国真在他的著名诗篇《旅程》里写道:“从别人那里,我们认识了自己”。今天,我想通过对诸多Transformer 的改进型和非 Transformer 的模型的讨论和分析,试图帮助大家从更多不同的角度,更加深刻认识和理解 Transformer,也希望能够为我们的学习、工作和研究提供些许的启发和思考。
[2] https://medium.com/@amanatulla1606/transformer-architecture-explained-2c49e2257b4c
[3] https://arxiv.org/pdf/2204.05832.pdf
[4] [2005.00743] Synthesizer: Rethinking Self-Attention in Transformer Models (arxiv.org)
[5] 线性Attention的探索:Attention必须有个Softmax吗? - 科学空间|Scientific Spaces (kexue.fm)
[6] https://generativeai.pub/explainable-ai-visualizing-attention-in-transformers-4eb931a2c0f8
[8] Why multi-head self attention works: math, intuitions and 10+1 hidden insights | AI Summer
[9] https://arxiv.org/pdf/2106.09650.pdf
[10] Performer:用随机投影将Attention的复杂度线性化 - 科学空间|Scientific Spaces (kexue.fm)
[11] https://github.com/pjlab-sys4nlp/llama-moe
[13] Transformers are Graph Neural Networks | NTU Graph Deep Learning Lab
[14] 如何理解 Transformers 中 FFNs 的作用? - 知乎 (zhihu.com)
[15] (4 条消息) 有哪些令你印象深刻的魔改transformer? - 知乎 (zhihu.com)
[16] https://medium.com/gopenai/mixture-of-experts-moe-in-ai-models-explained-2163335eaf85
[17] DeepSeekMoE:基于细粒度专家分割、共享专家的新MOE架构模型
[19] 一文通透想颠覆Transformer的Mamba:从SSM、S4到mamba、线性transformer(含RWKV解析)_mamba模型-CSDN博客
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。