【大模型LLM面试合集】大语言模型架构_Transformer架构细节

Transformer架构细节

在这里插入图片描述

在这里插入图片描述

1.Transformer各个模块的作用

(1)Encoder模块

  • 经典的Transformer架构中的Encoder模块包含6个Encoder Block.
  • 每个Encoder Block包含两个⼦模块, 分别是多头⾃注意⼒层, 和前馈全连接层.
    • 多头⾃注意⼒层采⽤的是⼀种Scaled Dot-Product Attention的计算⽅式, 实验结果表 明, Multi-head可以在更细致的层⾯上提取不同head的特征, ⽐单⼀head提取特征的 效果更佳.
    • 前馈全连接层是由两个全连接层组成, 线性变换中间增添⼀个Relu激活函数, 具体的 维度采⽤4倍关系, 即多头⾃注意⼒的d_model=512, 则层内的变换维度d_ff=2048.

(2)Decoder模块

  • 经典的Transformer架构中的Decoder模块包含6个Decoder Block.
  • 每个Decoder Block包含3个⼦模块, 分别是多头⾃注意⼒层, Encoder-Decoder Attention 层, 和前馈全连接层.
    • 多头⾃注意⼒层采⽤和Encoder模块⼀样的Scaled Dot-Product Attention的计算⽅ 式, 最⼤的 区别在于需要添加look-ahead-mask, 即遮掩"未来的信息".
    • Encoder-Decoder Attention层和上⼀层多头⾃注意⼒层最主要的区别在于Q != K = V, 矩阵Q来源于上⼀层Decoder Block的输出, 同时K, V来源于Encoder端的输出.
    • 前馈全连接层和Encoder中完全⼀样.

(3)Add & Norm模块

  • Add & Norm模块接在每⼀个Encoder Block和Decoder Block中的每⼀个⼦层的后⾯.
  • 对于每⼀个Encoder Block, ⾥⾯的两个⼦层后⾯都有Add & Norm.
  • 对于每⼀个Decoder Block, ⾥⾯的三个⼦层后⾯都有Add & Norm.
  • Add表示残差连接, 作⽤是为了将信息⽆损耗的传递的更深, 来增强模型的拟合能⼒.
  • Norm表示LayerNorm, 层级别的数值标准化操作, 作⽤是防⽌参数过⼤过⼩导致的学习过程异常 , 模型收敛特别慢的问题.

(4)位置编码器Positional Encoding

  • Transformer中采⽤三⻆函数来计算位置编码.
  • 因为三⻆函数是周期性函数, 不受序列⻓度的限制, ⽽且这种计算⽅式可以对序列中不同位置的编码的重要程度同等看待

2.Decoder端训练和预测的输入

  1. 在Transformer结构中的Decoder模块的输⼊, 区分于不同的Block, 最底层的Block输⼊有其特殊的地⽅。第⼆层到第六层的输⼊⼀致, 都是上⼀层的输出和Encoder的输出。
  2. 最底层的Block在训练阶段, 每⼀个time step的输⼊是上⼀个time step的输⼊加上真实标 签序列向后移⼀位. 具体来看, 就是每⼀个time step的输⼊序列会越来越⻓, 不断的将之前的 输⼊融合进来.
    假设现在的真实标签序列等于"How are you?", 
    当time step=1时, 输⼊张量为⼀个特殊的token, ⽐如"SOS"; 
    当time step=2时, 输⼊张量为"SOS How"; 
    当time step=3时, 输⼊张量为"SOS How are";
    以此类推...
    
  3. 最底层的Block在训练阶段, 真实的代码实现中, 采⽤的是MASK机制来模拟输⼊序列不断添 加的过程.
  4. 最底层的Block在预测阶段, 每⼀个time step的输⼊是从time step=0开始, ⼀直到上⼀个 time step的预测值的累积拼接张量. 具体来看, 也是随着每⼀个time step的输⼊序列会越来越长. 相⽐于训练阶段最⼤的不同是这⾥不断拼接进来的token是每⼀个time step的预测值, ⽽不是训练阶段每⼀个time step取得的groud truth值
    当time step=1时, 输⼊的input_tensor="SOS", 预测出来的输出值是output_tensor="What";
    当time step=2时, 输⼊的input_tensor="SOS What", 预测出来的输出值是output_tensor="is";
    当time step=3时, 输⼊的input_tensor="SOS What is", 预测出来的输出值是output_tensor="the";
    当time step=4时, 输⼊的input_tensor="SOS What is the", 预测出来的输出值是output_tensor="matter";
    当time step=5时, 输⼊的input_tensor="SOS What is the matter", 预测出来的输出值是output_tensor="?";
    当time step=6时, 输⼊的input_tensor="SOS What is the matter ?", 预测出来的输出值是output_tensor="EOS", 代表句⼦的结束符, 说明解码结束, 预测结束.

3.Self-attention

Transformer中⼀直强调的self-attention是什么? 为什么能 发挥如此⼤的作⽤? 计算的时候如果不使⽤三元组(Q, K, V), ⽽ 仅仅使⽤(Q, V)或者(K, V)或者(V)⾏不⾏?

(1)self-attention的机制和原理

self-attention是⼀种通过⾃身和⾃身进⾏关联的attention机制, 从⽽得到更好的 representation来表达⾃身.

self-attention是attention机制的⼀种特殊情况: 在self-attention中, Q=K=V, 序列中的每个单词(token)都和该序列中的其他所有单词 (token)进⾏attention规则的计算.

attention机制计算的特点在于, 可以直接跨越⼀句话中不同距离的token, 可以远距离的学习到序列的知识依赖和语序结构.

在这里插入图片描述

  • 从上图中可以看到, self-attention可以远距离的捕捉到语义层⾯的特征(it的指代对象是 animal).
  • 应⽤传统的RNN, LSTM, 在获取⻓距离语义特征和结构特征的时候, 需要按照序列顺序依次 计算, 距离越远的联系信息的损耗越⼤, 有效提取和捕获的可能性越⼩.
  • 但是应⽤self-attention时, 计算过程中会直接将句⼦中任意两个token的联系通过⼀个计算 步骤直接联系起来,

(2)关于self-attention为什么要使⽤(Q, K, V)三元组⽽不是其他形式

⾸先⼀条就是从分析的⻆度看, 查询Query是⼀条独⽴的序列信息, 通过关键词Key的提示作⽤, 得到最终语义的真实值Value表达, 数学意义更充分, 完备.

这⾥不使用(K, V)或者(V)没有什么必须的理由, 也没有相关的论⽂来严格阐述⽐较试验的结果差异, 所以可以作为开放性问题未来去探索, 只要明确在经典self-attention实现中⽤的是三元组就好

4.Self-attention归一化和放缩

(1)self-attention中的归⼀化概述

训练上的意义:随着词嵌⼊维度d_k的增⼤, q * k 点积后的结果也会增⼤, 在训练时会将 softmax函数推入梯度⾮常⼩的区域, 可能出现梯度消失的现象, 造成模型收敛困难.

数学上的意义: 假设q和k的统计变量是满⾜标准正态分布的独⽴随机变量, 意味着q和k满⾜均 值为0, ⽅差为1。** 那么q和k的点积结果就是均值为0, ⽅差为** d k d_k dk, 为了抵消这种⽅差被放⼤ d k d_k dk** 倍的影响, 在计算中主动将点积缩放**​ 1 ( d k ) \frac{1}{\sqrt(d_k)} ( dk)1, 这样点积后的结果依然满⾜均值为0, ⽅差为 1。

(2)softmax的梯度变化

这⾥我们分3个步骤来解释softmax的梯度问题:

第⼀步: softmax函数的输⼊分布是如何影响输出的

对于⼀个输⼊向量x, softmax函数将其做了⼀个归⼀化的映射, ⾸先通过⾃然底数e将输⼊元素之间的差距先"拉⼤", 然后再归⼀化为⼀个新的分布。 在这个过程中假设某个输⼊x 中最⼤的元素下标是k, 如果输⼊的数量级变⼤(就是x中的每个分量绝对值都很⼤), 那么在数学上会造成y_k的值⾮常接近1。

具体⽤⼀个例⼦来演示, 假设输⼊的向量 x = [ a , a , 2 a ] x = [a, a, 2a] x=[a,a,2a], 那么随便给⼏个不同数量级的值来看看对y3产⽣的影响

a = 1时,   y3 = 0.5761168847658291
a = 10时,  y3 = 0.9999092083843412
a = 100时, y3 = 1.0

采⽤⼀段实例代码将a在不同取值下, 对应的y3全部画出来, 以曲线的形式展示:

from math import exp
from matplotlib import pyplot as plt
import numpy as np
f = lambda x: exp(x * 2) / (exp(x) + exp(x) + exp(x * 2))
x = np.linspace(0, 100, 100)
y_3 = [f(x_i) for x_i in x]
plt.plot(x, y_3)
plt.show()

在这里插入图片描述

从上图可以很清楚的看到输⼊元素的数量级对softmax最终的分布影响⾮常之⼤。

结论在输⼊元素的数量级较⼤时, softmax函数⼏乎将全部的概率分布都分配给了最⼤值分量所对应的标签

第⼆步: softmax函数在反向传播的过程中是如何梯度求导的

首先,定义神经网络的输入和输出

设 X = [ x 1 , x 2 , . . . , x n ] , Y = s o f t m a x ( X ) = [ y 1 , y 2 , . . . , y 3 ] 则  y i = e x i ∑ j = 1 n e x j , 显然  ∑ j = 1 n e x j = 1 设X=[x_1,x_2,..., x_n], Y=softmax(X)=[y_1, y_2,..., y_3] \\ 则~y_i=\frac{e^{x_i}}{\sum_{j=1}^{n} e^{x_j}},~显然~ \sum_{j=1}^{n} e^{x_j}=1 X=[x1,x2,...,xn],Y=softmax(X)=[y1,y2,...,y3] yi=j=1nexjexi, 显然 j=1nexj=1

反向传播就是输出端的损失函数对输⼊端求偏导的过程, 这⾥要分两种情况,

**(1)当 ** i = j i=j i=j时:

∂ y i ∂ x j = ∂ y i ∂ x i = ∂ ∂ x i ( e x i ∑ k e x k ) = ( e x i ) ′ ( ∑ k e x k ) − e x i ( ∑ k e x k ) ′ ( ∑ k e x k ) 2 = e x i ⋅ ( ∑ k e x k ) − e x i ⋅ e x i ( ∑ k e x k ) 2 = e x i ⋅ ( ∑ k e x k ) ( ∑ k e x k ) 2 − e x i ⋅ e x i ( ∑ k e x k ) 2 = e x i ∑ k e x k − e x i ∑ k e x k ⋅ e x i ∑ k e x k = y i − y i ⋅ y i = y i ( 1 − y i ) \begin{aligned} \frac{\partial y_{i}}{\partial x_{j}}& =\frac{\partial y_i}{\partial x_i} \\ &=\frac{\partial}{\partial x_i}(\frac{e^{x_i}}{\sum_k e^{x_k}}) \\ &=\frac{(e^{x_i})'(\sum_k e^{x_k})-e^{x_i}(\sum_k e^{x_k})'}{(\sum_k e^{x_k})^2} \\ &=\frac{e^{x_i}\cdot(\sum_ke^{x_k})-e^{x_i}\cdot e^{x_i}}{(\sum_ke^{x_k})^2} \\ &=\frac{e^{x_i}\cdot(\sum_k e^{x_k})}{(\sum_k e^{x_k})^2}-\frac{e^{x_i}\cdot e^{x_i}}{(\sum_k e^{x_k})^2} \\ &=\frac{e^{x_i}}{\sum_k e^{x_k}}-\frac{e^{x_i}}{\sum_k e^{x_k}}\cdot\frac{e^{x_i}}{\sum_k e^{x_k}} \\ &=y_i-y_i\cdot y_i \\ &=y_i(1-y_i) \end{aligned} xjyi=xiyi=xi(kexkexi)=(kexk)2(exi)(kexk)exi(kexk)=(kexk)2exi(kexk)exiexi=(kexk)2exi(kexk)(kexk)2exiexi=kexkexikexkexikexkexi=yiyiyi=yi(1yi)

(2)当$ i ≠ j$时:

∂ y i ∂ x j = ∂ ∂ x j ( e x i ∑ k e x k ) = ( e x i ) ′ ( ∑ k e x k ) − e x i ( ∑ k e x k ) ′ ( ∑ k e x k ) 2 = 0 ⋅ ( ∑ k e x k ) − e x i ⋅ e x j ( ∑ k e x k ) 2 = − e x i ⋅ e x j ( ∑ k e x k ) 2 = − e x i ∑ k e x k ⋅ e x i ∑ k e x k = − y i ⋅ y i \begin{aligned} \frac{\partial y_{i}}{\partial x_{j}} & =\frac{\partial}{\partial x_{j}}\left(\frac{e^{x_{i}}}{\sum_{k} e^{x_{k}}}\right) \\ & =\frac{\left(e^{x_{i}}\right)^{\prime}\left(\sum_{k} e^{x_{k}}\right)-e^{x_{i}}\left(\sum_{k} e^{x_{k}}\right)^{\prime}}{\left(\sum_{k} e^{x_{k}}\right)^{2}} \\ & =\frac{0 \cdot\left(\sum_{k} e^{x_{k}}\right)-e^{x_{i}} \cdot e^{x_{j}}}{\left(\sum_{k} e^{x_{k}}\right)^{2}} \\ & =-\frac{e^{x_{i}} \cdot e^{x_{j}}}{\left(\sum_{k} e^{x_{k}}\right)^{2}} \\ & =-\frac{e^{x_{i}}}{\sum_{k} e^{x_{k}}} \cdot \frac{e^{x_{i}}}{\sum_{k} e^{x_{k}}} \\ & =-y_{i} \cdot y_{i} \end{aligned} xjyi=xj(kexkexi)=(kexk)2(exi)(kexk)exi(kexk)=(kexk)20(kexk)exiexj=(kexk)2exiexj=kexkexikexkexi=yiyi

经过对两种情况分别的求导计算, 可以得出最终的结论如下:

综上所述: ∂ y i ∂ x j = { y i − y i ⋅ y i , i=j 0 − y i ⋅ y i , i ≠ j 所以: ∂ Y ∂ X = d i a g ( Y ) − Y T ⋅ Y (当 Y 的 s h a p e 为 ( 1 , n ) 时) \begin{aligned} & 综上所述:\frac{\partial y_i}{\partial x_j}=\begin{cases}y_i-y_i\cdot y_i,&\text{i=j}\\ \\ 0-y_i\cdot y_i,&\text{i}\neq\text{j}\end{cases} \\ & 所以:\frac{\partial Y}{\partial X}=diag(Y)-Y^T\cdot Y(当Y的shape为(1,n)时) \end{aligned} 综上所述:xjyi= yiyiyi,0yiyi,i=ji=j所以:XY=diag(Y)YTY(当Yshape(1,n)时)

第三步: softmax函数出现梯度消失现象的原因

根据第二步中softmax函数的求导结果, 可以将最终的结果以矩阵形式展开如下:

∂ g ( X ) ∂ X ≈ [ y ^ 1 0 ⋯ 0 0 y ^ 2 ⋯ 0 ⋮ ⋮ ⋱ ⋮ 0 0 ⋯ y ^ d ] − [ y ^ 1 2 y ^ 1 y ^ 2 ⋯ y ^ 1 y ^ d y ^ 2 y ^ 1 y ^ 2 2 ⋯ y ^ 2 y ^ d ⋮ ⋮ ⋱ ⋮ y ^ d y ^ 1 y ^ d y ^ 2 ⋯ y ^ d 2 ] \frac{\partial g(X)}{\partial X} \approx\left[\begin{array}{cccc} \hat{y}_{1} & 0 & \cdots & 0 \\ 0 & \hat{y}_{2} & \cdots & 0 \\ \vdots & \vdots & \ddots & \vdots \\ 0 & 0 & \cdots & \hat{y}_{d} \end{array}\right]-\left[\begin{array}{cccc} \hat{y}_{1}^{2} & \hat{y}_{1} \hat{y}_{2} & \cdots & \hat{y}_{1} \hat{y}_{d} \\ \hat{y}_{2} \hat{y}_{1} & \hat{y}_{2}^{2} & \cdots & \hat{y}_{2} \hat{y}_{d} \\ \vdots & \vdots & \ddots & \vdots \\ \hat{y}_{d} \hat{y}_{1} & \hat{y}_{d} \hat{y}_{2} & \cdots & \hat{y}_{d}^{2} \end{array}\right] Xg(X) y^1000y^2000y^d y^12y^2y^1y^dy^1y^1y^2y^22y^dy^2y^1y^dy^2y^dy^d2

根据第一步中的讨论结果, 当输入x的分量值较大时, softmax函数会将大部分概率分配给最大的元素, 假设最大元素是x1, 那么softmax的输出分布将产生一个接近one-hot的结果张量y_ = [1, 0, 0,…, 0], 此时结果矩阵变为:

∂ g ( X ) ∂ X ≈ [ 1 0 ⋯ 0 0 0 ⋯ 0 ⋮ ⋮ ⋱ ⋮ 0 0 ⋯ 0 ] − [ 1 0 ⋯ 0 0 0 ⋯ 0 ⋮ ⋮ ⋱ ⋮ 0 0 ⋯ 0 ] = 0 \frac{\partial g(X)}{\partial X} \approx\left[\begin{array}{cccc}1 & 0 & \cdots & 0 \\ 0 & 0 & \cdots & 0 \\ & & & \\ \vdots & \vdots & \ddots & \vdots \\ 0 & 0 & \cdots & 0\end{array}\right]-\left[\begin{array}{cccc}1 & 0 & \cdots & 0 \\ 0 & 0 & \cdots & 0 \\ & & & \\ \vdots & \vdots & \ddots & \vdots \\ 0 & 0 & \cdots & 0\end{array}\right]=0 Xg(X) 100000000 100000000 =0

结论:综上可以得出,** 所有的梯度都消失为0(接近于0), 参数几乎无法更新, 模型收敛困难**.

(3)维度与点积大小的关系

针对为什么维度会影响点积的大小, 原始论文中有这样的一点解释如下:

To illustrate why the dot products get large, assume that the components of q and k are independent random variables with mean 0 and variance 1. Then their doct product,q*k = (q1k1+q2k2+......+q(d_k)k(d_k)), has mean 0 and variance d_k.

分两步对其进行一个推导, 首先就是假设向量q和k的各个分量是相互独立的随机变量, X = q i X = q_i X=qi, Y = k i Y = k_i Y=ki, X和Y各自有d_k个分量, 也就是向量的维度等于d_k, 有 E ( X ) = E ( Y ) = 0 E(X) = E(Y) = 0 E(X)=E(Y)=0, 以及 D ( X ) = D ( Y ) = 1 D(X) = D(Y) = 1 D(X)=D(Y)=1.

可以得到 E ( X Y ) = E ( X ) E ( Y ) = 0 ∗ 0 = 0 E(XY) = E(X)E(Y) = 0 * 0 = 0 E(XY)=E(X)E(Y)=00=0

同理, 对于 D ( X Y ) D(XY) D(XY)推导如下:

D ( X Y ) = E ( X 2 ⋅ Y 2 ) − [ E ( X Y ) ] 2 = E ( X 2 ) E ( Y 2 ) − [ E ( X ) E ( Y ) ] 2 = E ( X 2 − 0 2 ) E ( Y 2 − 0 2 ) − [ E ( X ) E ( Y ) ] 2 = E ( X 2 − [ E ( X ) ] 2 ) E ( Y 2 − [ E ( Y ) ] 2 ) − [ E ( X ) E ( Y ) ] 2 = D ( X ) D ( Y ) − [ E ( X ) E ( Y ) ] 2 = 1 × 1 − ( 0 × 0 ) 2 = 1 \begin{aligned} D(XY)& =E(X^2\cdot Y^2)-[E(XY)]^2 \\ &=E(X^2)E(Y^2)-[E(X)E(Y)]^2 \\ &=E(X^2-0^2)E(Y^2-0^2)-[E(X)E(Y)]^2 \\ &=E(X^2-[E(X)]^2)E(Y^2-[E(Y)]^2)-[E(X)E(Y)]^2 \\ &=D(X)D(Y)-[E(X)E(Y)]^2 \\ &=1\times1-\left(0\times0\right)^2 \\ &=1 \end{aligned} D(XY)=E(X2Y2)[E(XY)]2=E(X2)E(Y2)[E(X)E(Y)]2=E(X202)E(Y202)[E(X)E(Y)]2=E(X2[E(X)]2)E(Y2[E(Y)]2)[E(X)E(Y)]2=D(X)D(Y)[E(X)E(Y)]2=1×1(0×0)2=1

根据期望和方差的性质, 对于互相独立的变量满足下式:

E ( ∑ i Z i ) = ∑ i E ( Z i ) , D ( ∑ i Z i ) = ∑ i D ( Z i ) \begin{gathered} E(\sum_{i}Z_{i})=\sum_{i}E(Z_{i}), \\ D(\sum_{i}Z_{i})=\sum_{i}D(Z_{i}) \end{gathered} E(iZi)=iE(Zi),D(iZi)=iD(Zi)

根据上面的公式, 可以很轻松的得出q*k的均值为 E ( q k ) = 0 E(qk) = 0 E(qk)=0, D ( q k ) = d k D(qk) = d_k D(qk)=dk。所以方差越大, 对应的qk的点积就越大, 这样softmax的输出分布就会更偏向最大值所在的分量。一个技巧就是将点积除以 d k \sqrt{d_k} dk 将方差在数学上重新"拉回1", 如下所示

D ( q ⋅ k d k ) = d k ( d k ) 2 = 1 D(\frac{q\cdot k}{\sqrt{d_k}})=\frac{d_k}{(\sqrt{d_k})^2}=1 D(dk qk)=(dk )2dk=1

最终的结论:通过数学上的技巧将方差控制在1, 也就有效的控制了点积结果的发散, 也就控制了对应的梯度消失的问题!

5.Multi-head Attention

(1)采⽤Multi-head Attention的原因

  1. 原始论⽂中提到进⾏Multi-head Attention的原因是将模型分为多个头, 可以形成多个子空间间, 让模型去关注不同方面的信息, 最后再将各个⽅⾯的信息综合起来得到更好的效果.
  2. 多个头进⾏attention计算最后再综合起来, 类似于CNN中采⽤多个卷积核的作⽤, 不同的卷 积核提取不同的特征, 关注不同的部分, 最后再进行融合.
  3. 直观上讲, 多头注意力有助于神经网络捕捉到更丰富的特征信息.
(2)Multi-head Attention的计算⽅式
  1. Multi-head Attention和单⼀head的Attention唯⼀的区别就在于,** 其对特征张量的最后⼀个维度进行了分割, ⼀般是对词嵌入的embedding_dim=512进⾏切割成head=8, **这样每⼀个head的嵌⼊维度就是512/8=64, 后续的Attention计算公式完全⼀致, 只不过是在64这个维度上进⾏⼀系列的矩阵运算⽽已.
  2. 在head=8个头上分别进⾏注意⼒规则的运算后, 简单采用拼接concat的⽅式对结果张量进 ⾏融合就得到了Multi-head Attention的计算结果.

6.Transformer和RNN

(1)Transformer的并行计算

对于Transformer⽐传统序列模型RNN/LSTM具备优势的第⼀⼤原因就是强⼤的并⾏计算能力.

对于RNN来说, 任意时刻t的输⼊是时刻t的输⼊x(t)和上⼀时刻的隐藏层输出h(t-1), 经过运算后得到当前时刻隐藏层的输出h(t), 这个h(t)也即将作为下⼀时刻t+1的输⼊的⼀部分. 这个计算过程是RNN的本质特征, RNN的历史信息是需要通过这个时间步⼀步⼀步向后传递的. 而这就意味着RNN序列后⾯的信息只能等到前⾯的计算结束后, 将历史信息通过hidden state传递给后⾯才能开始计算, 形成链式的序列依赖关系, 无法实现并行.

对于Transformer结构来说, 在self-attention层, ⽆论序列的⻓度是多少, 都可以⼀次性计算所有单词之间的注意⼒关系, 这个attention的计算是同步的, 可以实现并⾏.

(2)Transformer的特征抽取能力

对于Transformer⽐传统序列模型RNN/LSTM具备优势的第⼆⼤原因就是强⼤的特征抽取能力 。

Transformer因为采⽤了Multi-head Attention结构和计算机制, 拥有⽐RNN/LSTM更强⼤的特征抽取能⼒, 这⾥并不仅仅由理论分析得来, 而是⼤量的试验数据和对⽐结果, 清楚的展示了Transformer的特征抽取能⼒远远胜于RNN/LSTM.

注意: 不是越先进的模型就越无敌, 在很多具体的应⽤中RNN/LSTM依然⼤有⽤武之地, 要具体问题具体分析

7.Transformer代替seq2seq?

(1)seq2seq的两大缺陷

  1. seq2seq架构的第⼀⼤缺陷是将Encoder端的所有信息压缩成⼀个固定⻓度的语义向量中, ⽤这个固定的向量来代表编码器端的全部信息. 这样既会造成信息的损耗, 也⽆法让Decoder 端在解码的时候去⽤注意⼒聚焦哪些是更重要的信息.
  2. seq2seq架构的第二大缺陷是无法并行, 本质上和RNN/LSTM无法并行的原因⼀样.

(2)Transformer的改进

Transformer架构同时解决了seq2seq的两⼤缺陷, 既可以并⾏计算, ⼜应⽤Multi-head Attention机制来解决Encoder固定编码的问题, 让Decoder在解码的每⼀步可以通过注意⼒去 关注编码器输出中最重要的那些部分.

8.Transformer并行化

(1)Encoder并行化

在这里插入图片描述

  1. 上图最底层绿⾊的部分, 整个序列所有的token可以并⾏的进⾏Embedding操作, 这⼀层的处理是没有依赖关系的.
  2. 上图第⼆层⼟⻩⾊的部分, 也就是Transformer中最重要的self-attention部分, 这⾥对于任意⼀个单词⽐如x1, 要计算x1对于其他所有token的注意⼒分布, 得到z1. 这个过程是具有依赖性的, 必须等到序列中所有的单词完成Embedding才可以进⾏。因此这⼀步是不能并⾏处理的。 但是从另⼀个⻆度看, 我们真实计算注意⼒分布的时候, 采⽤的都是矩阵运算, 也就是可以⼀次性的计算出所有token的注意⼒张量, 从这个⻆度看也算是实现了并行, 只是矩阵运算的"并行"和词嵌⼊的"并行"概念上不同⽽已.
  3. 上图第三层蓝⾊的部分, 也就是前馈全连接层, 对于不同的向量z之间也是没有依赖关系的, 所以这⼀层是可以实现并行化处理的. 也就是所有的向量z输⼊Feed Forward⽹络的计算可以同步进⾏, 互不⼲扰

(2)Decoder的并行化

在这里插入图片描述

  1. Decoder模块在训练阶段采用了并行化处理。 其中Self-Attention和Encoder-Decoder Attention两个子层的并行化也是在进行矩阵乘法, 和Encoder的理解是一致的. 在进行Embedding和Feed Forward的处理时, 因为各个token之间没有依赖关系, 所以也是可以完全并行化处理的, 这里和Encoder的理解也是一致的.
  2. Decoder模块在预测阶段基本上不认为采用了并行化处理. 因为第一个time step的输入只是一个"SOS", 后续每一个time step的输入也只是依次添加之前所有的预测token.
  3. 注意: 最重要的区别是训练阶段目标文本如果有20个token, 在训练过程中是一次性的输入给Decoder端, 可以做到一些子层的并行化处理. 但是在预测阶段, 如果预测的结果语句总共有20个token, 则需要重复处理20次循环的过程, 每次的输入添加进去一个token, 每次的输入序列比上一次多一个token, 所以不认为是并行处理.

(3)总结

Transformer架构中Encoder模块的并行化机制

  • Encoder模块在训练阶段和测试阶段都可以实现完全相同的并行化.
  • Encoder模块在Embedding层, Feed Forward层, Add & Norm层都是可以并行化的.
  • Encoder模块在self-attention层, 因为各个token之间存在依赖关系, 无法独立计算, 不是真正意义上的并行化.
  • Encoder模块在self-attention层, 因为采用了矩阵运算的实现方式, 可以一次性的完成所有注意力张量的计算, 也是另一种"并行化"的体现.

Transformer架构中Decoder模块的并行化机制

  • Decoder模块在训练阶段可以实现并行化.
  • Decoder模块在训练阶段的Embedding层, Feed Forward层, Add & Norm层都是可以并行化的.
  • Decoder模块在self-attention层, 以及Encoder-Decoder Attention层, 因为各个token之间存在依赖关系, 无法独立计算, 不是真正意义上的并行化.
  • Decoder模块在self-attention层, 以及Encoder-Decoder Attention层, 因为采用了矩阵运算的实现方式, 可以一次性的完成所有注意力张量的计算, 也是另一种"并行化"的体现.
  • Decoder模块在预测计算不能并行化处理.

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

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

相关文章

【华为OD-E卷 - 113 跳格子2 100分(python、java、c++、js、c)】

【华为OD-E卷 - 跳格子2 100分(python、java、c、js、c)】 题目 小明和朋友玩跳格子游戏,有 n 个连续格子组成的圆圈,每个格子有不同的分数,小朋友可以选择以任意格子起跳,但是不能跳连续的格子&#xff…

国防科大:双目标优化防止LLM灾难性遗忘

📖标题:How to Complete Domain Tuning while Keeping General Ability in LLM: Adaptive Layer-wise and Element-wise Regularization 🌐来源:arXiv, 2501.13669 🌟摘要 🔸大型语言模型(LLM…

Verilog基础(一):基础元素

verilog基础 我先说,看了肯定会忘,但是重要的是这个过程,我们知道了概念,知道了以后在哪里查询。语法都是术,通用的概念是术。所以如果你有相关的软件编程经验,那么其实开启这个学习之旅,你会感受到熟悉,也会感受到别致。 入门 - 如何开始 欢迎来到二进制的世界,数字…

多无人机--强化学习

这个是我对于我的大创项目的构思,随着时间逐渐更新 项目概要 我们的项目平台来自挑战杯揭绑挂帅的无人机对抗项目,但是在由于时间原因,并未考虑强化学习,所以现在通过大创项目来弥补遗憾 我们项目分为三部分,分为虚…

Python----Python高级(并发编程:进程Process,多进程,进程间通信,进程同步,进程池)

一、进程Process 拥有自己独立的堆和栈,既不共享堆,也不共享栈,进程由操作系统调度;进程切换需要的资源很最大,效率低。 对于操作系统来说,一个任务就是一个进程(Process)&#xff…

在Mapbox GL JS中“line-pattern”的使用详解

在Mapbox GL JS中,line-pattern 是一种用于在地图上绘制带有图案的线条的样式属性。通过 line-pattern,你可以使用自定义的图像作为线条的图案,而不是使用纯色或渐变。 1. 基本概念 line-pattern: 该属性允许你指定一个图像作为线条的图案。…

C++ Primer 算术运算符

欢迎阅读我的 【CPrimer】专栏 专栏简介:本专栏主要面向C初学者,解释C的一些基本概念和基础语言特性,涉及C标准库的用法,面向对象特性,泛型特性高级用法。通过使用标准库中定义的抽象设施,使你更加适应高级…

【大数据技术】本机PyCharm远程连接虚拟机Python

本机PyCharm远程连接虚拟机Python 注意:本文需要使用PyCharm专业版。 pycharm-professional-2024.1.4VMware Workstation Pro 16CentOS-Stream-10-latest-x86_64-dvd1.iso写在前面 本文主要介绍如何使用本地PyCharm远程连接虚拟机,运行Python脚本,提高编程效率。 注意: …

MyBatis-Plus笔记-快速入门

大家在日常开发中应该能发现,单表的CRUD功能代码重复度很高,也没有什么难度。而这部分代码量往往比较大,开发起来比较费时。 因此,目前企业中都会使用一些组件来简化或省略单表的CRUD开发工作。目前在国内使用较多的一个组件就是…

Maven jar 包下载失败问题处理

Maven jar 包下载失败问题处理 1.配置好国内的Maven源2.重新下载3. 其他问题 1.配置好国内的Maven源 打开⾃⼰的 Idea 检测 Maven 的配置是否正确,正确的配置如下图所示: 检查项⼀共有两个: 确认右边的两个勾已经选中,如果没有请…

2.5学习

misc buuctf-假如给我三天光明 下载附件后得到了一个压缩包和一个图片,压缩包为加密压缩包,需要解出密码,然后注意到这个图片并非简单的一个封面,在下方还有诸多点,有黑有灰。经过搜索,发现这是盲文通过与…

java进阶1——JVM

java进阶——JVM 1、JVM概述 作用 Java 虚拟机就是二进制字节码的运行环境,负责装载字节码到其内部,解释/编译为对 应平台上的机器码指令行,每一条 java 指令,java 虚拟机中都有详细定义,如怎么取操 作数&#xff0c…

搭建集成开发环境PyCharm

1.下载安装Python(建议下载并安装3.9.x) https://www.python.org/downloads/windows/ 要注意勾选“Add Python 3.9 to PATH”复选框,表示将Python的路径增加到环境变量中 2.安装集成开发环境Pycharm http://www.jetbrains.com/pycharm/…

《redis4.0 通信模块源码分析(一)》

【redis导读】redis作为一款高性能的内存数据库,面试服务端开发,redis是绕不开的话题,如果想提升自己的网络编程的水平和技巧,redis这款优秀的开源软件是很值得大家去分析和研究的。 笔者从大学毕业一直有分析redis源码的想法&…

开源安全一站式构建!开启企业开源治理新篇章

在如今信息技术日新月异、飞速发展的数字化时代,开源技术如同一股强劲的东风,为企业创新注入了源源不断的活力,然而,正如一枚硬币有正反两面,开源技术的广泛应用亦伴随着不容忽视的挑战。安全风险如影随形,…

DeePseek结合PS!批量处理图片的方法教程

​ ​ 今天我们来聊聊如何利用deepseek和Photoshop(PS)实现图片的批量处理。 传统上,批量修改图片尺寸、分辨率等任务往往需要编写脚本或手动处理,而现在有了AI的辅助,我们可以轻松生成PS脚本,实现自动化处…

Verilog基础(三):过程

过程(Procedures) - Always块 – 组合逻辑 (Always blocks – Combinational) 由于数字电路是由电线相连的逻辑门组成的,所以任何电路都可以表示为模块和赋值语句的某种组合. 然而,有时这不是描述电路最方便的方法. 两种always block是十分有用的: 组合逻辑: always @(…

2024年12月 Scratch 图形化(一级)真题解析 中国电子学会全国青少年软件编程等级考试

202412 Scratch 图形化(一级)真题解析 中国电子学会全国青少年软件编程等级考试 一、单选题(共25题,共50分) 第 1 题 点击下列哪个按钮,可以将红框处的程序放大?( ) A. B. C. D. 标…

C++【深入 STL--list 之 迭代器与反向迭代器】

接前面的手撕list(上)文章,由于本人对于list的了解再一次加深。本文再次对list进行深入的分析与实现。旨在再一次梳理思路,修炼代码内功。 1、list 基础架构 list底层为双向带头循环链表,问题是如何来搭建这个list类。可以进行下面的考虑&am…

如何打开vscode系统用户全局配置的settings.json

📌 settings.json 的作用 settings.json 是 Visual Studio Code(VS Code) 的用户配置文件,它存储了 编辑器的个性化设置,包括界面布局、代码格式化、扩展插件、快捷键等,是用户全局配置(影响所有…