通俗易懂的LLM(下篇)

前言

  书接上文。

一、大模型激活函数

  参考大模型结构细节

1、ReLU

  原始的Transformer采用的是ReLU,后面的T5,OPT采用的激活函数也是ReLU,此时 FFN 可以表示为:
F F N ( x , W 1 , W 2 , b 1 , b 2 ) = R e L U ( x W 1 + b 1 ) W 2 + b 2 FFN(x,W_{1},W_{2},b_{1},b_{2})=ReLU(xW_{1}+b_{1})W_{2}+b_{2} FFN(x,W1,W2,b1,b2)=ReLU(xW1+b1)W2+b2

2、GeLU

  GPT-1、GPT-2、GPT-3、BLOOM采用的激活函数就是GeLU(Gaussian Error Linear Unit)。GeLU的表达式如下:
G e L U ( x ) = x Φ ( x ) GeLU(x)=x\Phi(x) GeLU(x)=xΦ(x)
  其中:
Φ ( x ) = ∫ − ∞ x e − t 2 / 2 2 π d t \Phi(x)=\int_{-\infty}^{x}\frac{e^{-t^{2}/2}}{\sqrt{2\pi}}dt Φ(x)=x2π et2/2dt
  原论文中给出了GeLU的两个近似计算:
x Φ ( x ) ≈ x σ ( 1.702 x ) x\Phi(x)\approx x\sigma(1.702x) xΦ(x)xσ(1.702x)
  其中 σ \sigma σ s i g m o i d sigmoid sigmoid函数。或者:
x Φ ( x ) ≈ 1 2 x [ 1 + t a n h ( 2 π ( x + 0.044715 x 3 ) ) ] x\Phi(x)\approx \frac{1}{2}x[1+tanh(\sqrt\frac{2}{\pi}(x+0.044715x^{3}))] xΦ(x)21x[1+tanh(π2 (x+0.044715x3))]
  此时 FFN 可以表示为:
F F N ( x , W 1 , W 2 , b 1 , b 2 ) = G e L U ( x W 1 + b 1 ) W 2 + b 2 FFN(x,W_{1},W_{2},b_{1},b_{2})=GeLU(xW_{1}+b_{1})W_{2}+b_{2} FFN(x,W1,W2,b1,b2)=GeLU(xW1+b1)W2+b2

3、GLU

  GLU Variants Improve Transformer提出,可以利用门控线形单元:GLU(Gated Linear Units)对激活函数进行改进。首先,GLU的基本形式是:对输入做双线性变换(多了一个矩阵 V),并且其中一个添加 s i g m o i d sigmoid sigmoid变换:
G L U ( x , W , V , b , c ) = σ ( x W + b ) ⊗ ( x V + c ) GLU(x,W,V,b,c)=\sigma(xW+b)\otimes(xV+c) GLU(x,W,V,b,c)=σ(xW+b)(xV+c)
  此时 FFN 可以表示为:
F F N ( x , W 1 , W 2 , V , b 1 , b 2 , c ) = ( σ ( x W 1 + b 1 ) ⊗ ( x V + c ) ) W 2 + b 2 FFN(x,W_{1},W_{2},V,b_{1},b_{2},c)=(\sigma(xW_{1}+b_{1})\otimes(xV+c))W_{2}+b_{2} FFN(x,W1,W2,V,b1,b2,c)=(σ(xW1+b1)(xV+c))W2+b2

4、GeGLU

  将GLU中的 s i g m o i d sigmoid sigmoid换成GeLU激活函数,就得到了GLU的一个变体:GeGLU,GLM-130B采用的激活函数就是GeGLU,具体表达式如下所示:
G e G L U ( x , W , V , b , c ) = G e L U ( x W + b ) ⊗ ( x V + c ) GeGLU(x,W,V,b,c)=GeLU(xW+b)\otimes(xV+c) GeGLU(x,W,V,b,c)=GeLU(xW+b)(xV+c)
  此时 FFN 可以表示为:
F F N ( x , W 1 , W 2 , V , b 1 , b 2 , c ) = ( G e L U ( x W 1 + b 1 ) ⊗ ( x V + c ) ) W 2 + b 2 FFN(x,W_{1},W_{2},V,b_{1},b_{2},c)=(GeLU(xW_{1}+b_{1})\otimes(xV+c))W_{2}+b_{2} FFN(x,W1,W2,V,b1,b2,c)=(GeLU(xW1+b1)(xV+c))W2+b2

5、SwiGLU

  将GLU中的 s i g m o i d sigmoid sigmoid换成另一种激活函数,就得到了GLU的又一个变体:SwiGLU,LLaMA采用的激活函数就是SwiGLU,具体表达式如下所示:
S w i G L U ( x , W , V , b , c ) = S w i s h β ( x W + b ) ⊗ ( x V + c ) SwiGLU(x,W,V,b,c)=Swish_{\beta}(xW+b)\otimes(xV+c) SwiGLU(x,W,V,b,c)=Swishβ(xW+b)(xV+c)
  此时 FFN 可以表示为:
F F N ( x , W 1 , W 2 , V , b 1 , b 2 , c ) = ( S w i s h β ( x W 1 + b 1 ) ⊗ ( x V + c ) ) W 2 + b 2 FFN(x,W_{1},W_{2},V,b_{1},b_{2},c)=(Swish_{\beta}(xW_{1}+b_{1})\otimes(xV+c))W_{2}+b_{2} FFN(x,W1,W2,V,b1,b2,c)=(Swishβ(xW1+b1)(xV+c))W2+b2
  其中, S w i s h β ( x ) = x ⋅ σ ( β x ) Swish_{\beta}(x)=x\cdot\sigma(\beta x) Swishβ(x)=xσ(βx) β \beta β是指定的常数,一般为1。相较于原始的ReLU激活函数,由于涉及到多一维度的线性表示,所以会面临着带来参数量新增和计算量增加。而LLaMA中怎么克服这一点的呢?LLaMA是把SwiGLU中的 W 1 、 W 2 、 V W_{1}、W_{2}、V W1W2V的矩阵维度从 ( d i m , d i m ) (dim, dim) (dimdim)变成 ( d i m , 2 3 d i m ) (dim, \frac{2}{3}dim) (dim,32dim),从而打平参数量和计算量。

二、位置编码

1、旋转位置编码

  旋转位置编码(Rotary Position Embedding,RoPE)来源于苏剑林的Rotary Transformer。传统的位置编码通常是在输入时与token embedding进行加和,在进行后续Attention计算时,公式如下:
Q K T = x W Q ⋅ W K T x T + x W Q ⋅ W K T p T + p W Q ⋅ W K T x T + p W Q ⋅ W K T p T O = A ⋅ V = A ⋅ ( x W V + p W V ) \begin{aligned} QK^{T}&=xW_{Q}\sdot W_{K}^{T}x^{T}+xW_{Q}\sdot W_{K}^{T}p^{T}+pW_{Q}\sdot W_{K}^{T}x^{T}+pW_{Q}\sdot W_{K}^{T}p^{T}\\ O&=A\sdot V=A\sdot(xW_{V}+pW_{V}) \end{aligned} QKTO=xWQWKTxT+xWQWKTpT+pWQWKTxT+pWQWKTpT=AV=A(xWV+pWV)
其中 A = s o f t m a x ( Q K T d k ) A=softmax(\frac{QK^{T}}{\sqrt{d_{k}}}) A=softmax(dk QKT)是注意力矩阵, x x x是输入的token embedding, p p p是position embedding。
  事实上,位置向量不一定非要加在输入的token embedding上才能起作用,由上式可知,只要在 Q Q Q K K K矩阵上加上位置编码,同样可以作用在注意力矩阵 A A A上,进而作用在 V V V上。旋转位置编码就是采用的这种思想。

  • 旋转位置编码公式:对于 Q Q Q的第 m m m个向量 q q q K K K的第 n n n个向量 k k k,通过以下方法注入位置编码:
    • 二维:假定词嵌入维度是2维。
      f ( q , m ) = ( c o s ( m θ ) − s i n ( m θ ) s i n ( m θ ) c o s ( m θ ) ) ( q 1 q 2 ) f(q,m)= \begin{pmatrix} cos(m\theta) & -sin(m\theta) \\ sin(m\theta) & cos(m\theta) \end{pmatrix} \begin{pmatrix} q_{1} \\ q_{2} \end{pmatrix} f(q,m)=(cos(mθ)sin(mθ)sin(mθ)cos(mθ))(q1q2)
      f ( k , n ) = ( c o s ( n θ ) − s i n ( n θ ) s i n ( n θ ) c o s ( n θ ) ) ( k 1 k 2 ) f(k,n)= \begin{pmatrix} cos(n\theta) & -sin(n\theta) \\ sin(n\theta) & cos(n\theta) \end{pmatrix} \begin{pmatrix} k_{1} \\ k_{2} \end{pmatrix} f(k,n)=(cos(nθ)sin(nθ)sin(nθ)cos(nθ))(k1k2)
      其中, q = ( q 1 q 2 ) q=\begin{pmatrix} q_{1} \\ q_{2} \end{pmatrix} q=(q1q2) Q Q Q的第 m m m个向量, k = ( k 1 k 2 ) k=\begin{pmatrix} k_{1} \\ k_{2} \end{pmatrix} k=(k1k2) K K K的第 n n n个向量, f ( q , m ) f(q,m) f(q,m) f ( k , n ) f(k,n) f(k,n)分别是经过旋转位置编码后的 q q q k k k。可以发现,旋转位置编码其实就是对 q q q k k k分别乘以了一个旋转矩阵(向量乘以旋转矩阵后,模(向量大小)不变,方向改变),这就是为什么叫做旋转式位置编码的原因。此时 Q K T QK^{T} QKT的计算公式为(仅以 q q q k k k相乘为例):
      ( q 1 q 2 ) ( c o s ( ( m − n ) θ ) − s i n ( ( m − n ) θ ) s i n ( ( m − n ) θ ) c o s ( ( m − n ) θ ) ) ( k 1 k 2 ) \begin{pmatrix} q_{1} & q_{2} \end{pmatrix} \begin{pmatrix} cos((m-n)\theta) & -sin((m-n)\theta) \\ sin((m-n)\theta) & cos((m-n)\theta) \end{pmatrix} \begin{pmatrix} k_{1} \\ k_{2} \end{pmatrix} (q1q2)(cos((mn)θ)sin((mn)θ)sin((mn)θ)cos((mn)θ))(k1k2)
    • 多维:上面的计算是假定词嵌入维度是2维,而对于 d ≥ 2 d\ge2 d2的通用情况,则是将 q q q向量中的元素按照两两一组分组,每组应用同样的旋转操作,具体计算公式如下:
      f ( q , m ) = ( c o s ( m θ 0 ) − s i n ( m θ 0 ) 0 0 ⋯ 0 0 s i n ( m θ 0 ) c o s ( m θ 0 ) 0 0 ⋯ 0 0 0 0 c o s ( m θ 1 ) − s i n ( m θ 1 ) ⋯ 0 0 0 0 s i n ( m θ 1 ) c o s ( m θ 1 ) ⋯ 0 0 ⋮ ⋮ ⋮ ⋮ ⋱ ⋮ ⋮ 0 0 0 0 ⋯ c o s ( m θ d / 2 − 1 ) − s i n ( m θ d / 2 − 1 ) 0 0 0 0 ⋯ s i n ( m θ d / 2 − 1 ) c o s ( m θ d / 2 − 1 ) ) ( q 0 q 1 q 2 q 3 ⋮ q d − 2 q d − 1 ) f(q,m)= \begin{pmatrix} cos(m\theta_{0}) & -sin(m\theta_{0}) & 0 & 0 & \cdots & 0 & 0 \\ sin(m\theta_{0}) & cos(m\theta_{0}) & 0 & 0 & \cdots & 0 & 0 \\ 0 & 0 & cos(m\theta_{1}) & -sin(m\theta_{1}) & \cdots & 0 & 0 \\ 0 & 0 & sin(m\theta_{1}) & cos(m\theta_{1}) & \cdots & 0 & 0 \\ \vdots & \vdots & \vdots & \vdots & \ddots & \vdots & \vdots \\ 0 & 0 & 0 & 0 & \cdots & cos(m\theta_{d/2-1}) & -sin(m\theta_{d/2-1}) \\ 0 & 0 & 0 & 0 & \cdots & sin(m\theta_{d/2-1}) & cos(m\theta_{d/2-1}) \\ \end{pmatrix} \begin{pmatrix} q_{0} \\ q_{1}\\ q_{2}\\ q_{3}\\ \vdots\\ q_{d-2}\\ q_{d-1} \end{pmatrix} f(q,m)= cos(mθ0)sin(mθ0)0000sin(mθ0)cos(mθ0)000000cos(mθ1)sin(mθ1)0000sin(mθ1)cos(mθ1)000000cos(mθd/21)sin(mθd/21)0000sin(mθd/21)cos(mθd/21) q0q1q2q3qd2qd1
      其中, θ j = 1000 0 − 2 j / d \theta_{j}=10000^{-2j/d} θj=100002j/d j ∈ { 0 , 1 , … , d / 2 − 1 } j\in \{0,1,\dots,d/2-1\} j{0,1,,d/21} k k k的计算类似,这里不予展示。
    • 高效计算:由于上述旋转矩阵的稀疏性,所以直接用矩阵乘法来实现会很浪费算力,推荐通过下述方式来实现RoPE:
      f ( q , m ) = ( q 0 q 1 q 2 q 3 ⋮ q d − 2 q d − 1 ) ⊗ ( c o s ( m θ 0 ) c o s ( m θ 0 ) c o s ( m θ 1 ) c o s ( m θ 1 ) ⋮ c o s ( m θ d / 2 − 1 ) c o s ( m θ d / 2 − 1 ) ) + ( − q 1 q 0 − q 3 q 2 ⋮ − q d − 1 q d − 2 ) ⊗ ( s i n ( m θ 0 ) s i n ( m θ 0 ) s i n ( m θ 1 ) s i n ( m θ 1 ) ⋮ s i n ( m θ d / 2 − 1 ) s i n ( m θ d / 2 − 1 ) ) f(q,m)= \begin{pmatrix} q_{0} \\ q_{1}\\ q_{2}\\ q_{3}\\ \vdots\\ q_{d-2}\\ q_{d-1} \end{pmatrix}\otimes \begin{pmatrix} cos(m\theta_{0}) \\ cos(m\theta_{0}) \\ cos(m\theta_{1}) \\ cos(m\theta_{1}) \\ \vdots \\ cos(m\theta_{d/2-1}) \\ cos(m\theta_{d/2-1}) \\ \end{pmatrix}+ \begin{pmatrix} -q_{1} \\ q_{0}\\ -q_{3}\\ q_{2}\\ \vdots\\ -q_{d-1}\\ q_{d-2} \end{pmatrix}\otimes \begin{pmatrix} sin(m\theta_{0}) \\ sin(m\theta_{0}) \\ sin(m\theta_{1}) \\ sin(m\theta_{1}) \\ \vdots \\ sin(m\theta_{d/2-1}) \\ sin(m\theta_{d/2-1}) \\ \end{pmatrix} f(q,m)= q0q1q2q3qd2qd1 cos(mθ0)cos(mθ0)cos(mθ1)cos(mθ1)cos(mθd/21)cos(mθd/21) + q1q0q3q2qd1qd2 sin(mθ0)sin(mθ0)sin(mθ1)sin(mθ1)sin(mθd/21)sin(mθd/21)
    • 直观展示:论文中有个很直观的图片展示了旋转变换的过程。
      在这里插入图片描述
    • 远程衰减:RoPE形式上和传统transformer的三角式位置编码有点相似,只不过三角式位置编码是加性的,而RoPE可以视为乘性的。在 θ i \theta_{i} θi的选择上,RoPE 同样沿用了三角式位置编码的方案,即 θ j = 1000 0 − 2 j / d \theta_{j}=10000^{-2j/d} θj=100002j/d j ∈ { 0 , 1 , … , d / 2 − 1 } j\in\{0,1,\dots,d/2-1\} j{0,1,,d/21},它可以带来一定的远程衰减性。如下图所示:
      在这里插入图片描述
      从图中我们可以看到随着相对距离的变大,内积结果有衰减趋势的出现。因此,选择 θ j = 1000 0 − 2 j / d \theta_{j}=10000^{-2j/d} θj=100002j/d,确实能带来一定的远程衰减性。论文中还试过以 θ j = 1000 0 − 2 j / d \theta_{j}=10000^{-2j/d} θj=100002j/d为初始化,将 θ j \theta_{j} θj视为可训练参数,然后训练一段时间后发现 θ j \theta_{j} θj并没有显著更新,因此干脆就直接固定 θ j = 1000 0 − 2 j / d \theta_{j}=10000^{-2j/d} θj=100002j/d了。
    • RoPE实践:后续看看LLaMA、ChatGLM的源码。
      • ChatGLM2:每个 q q q k k k向量只有前一半的位置添加了旋转位置编码;
      • LLaMA:实现了苏剑林版本的旋转位置编码。
    • 优缺点
      • 优点:RoPE是通过绝对位置编码实现相对位置编码,优点是这种方法不仅可以处理位置信息,还可以处理距离信息,因为旋转操作可以很好地反映出元素之间的相对位置关系;
      • 缺点:缺点是它需要更多的计算资源,因为旋转操作比简单的向量加法更复杂。
    • 参考资料十分钟读懂旋转编码(RoPE)一文看懂LLaMA中的旋转式位置编码

三、Decoder-only模型

1、生成任务

  • 有条件文本生成:进行文本生成任务时,给定前置的生成条件,例如输入是:给定文本内容:春天真美好,进行故事续写;
  • 无条件文本生成:进行文本生成任务时,不给定前置的生成条件,例如输入是:写一篇作文。

2、推理流程

  • Casual LM
    • 原始输入构成:对于类GPT模型,无论是有条件文本生成任务,还是无条件文本生成任务,都是将原始输入整体喂入模型;
    • 新输入构成:一个一个的生成token,生成的token会拼接在原始输入后面,构成新的输入喂入模型,继续生成新的token;
    • Attention计算:输入之间满足Mask Attention机制(后面的token可以看见前面的token,前面的token无法看到后面的token);
    • token生成:新token的生成机制,是将输出层的最后一列logits拿去做全词表分类;而最终选取哪个词进行输出,有多种方式,参考下面的解码生成方式
  • Prefix LM
    • 原始输入构成:对于类GLM模型,无论是有条件文本生成任务,还是无条件文本生成任务,都是将原始输入整体喂入模型;
    • 新输入构成:一个一个的生成token,生成的token会拼接在原始输入后面,构成新的输入喂入模型,继续生成新的token;
    • Attention计算:输入之间满足Prefix Attention机制(原始输入token之间可以互相看见,新拼接的token只能看见前面的token,看不到后面的token);
    • token生成:新token的生成机制,是将输出层的最后一列logits拿去做全词表分类;最终选取哪个词进行输出,有多种方式,参考下面的解码生成方式

3、解码生成方式

  • Greedy Search:贪婪搜索。
    • 方式:每个时间步都选择概率最大的词;
    • 参数设置do_sample = False, num_beams = 1
    • 缺点
      • 生成文本重复;
      • 不支持生成多条结果。 当num_return_sequences参数设置大于1时,代码会报错,说greedy search不支持这个参数大于1。
  • Beam Search:束搜索,对贪心策略的一种改进,当num_beams = 1时会退化成贪心搜索策略。
    • 方式:每个时间步选择概率最高的num_beams个词;
    • 参数设置do_sample = False, num_beams > 1
    • 缺点:虽然结果比贪心搜索更流畅,但是仍然存在生成重复的问题。
  • Top-K sampling
    • 方式:每个时间步,会保留top-k个token,然后对top-k个token的概率重新归一化,最后在重新归一化后的这k个token中进行采样;
    • 参数do_sample = True, num_beams = 1,设定top_k
    • 缺点:在分布陡峭的时候仍会采样到概率小的token,或者在分布平缓的时候只能采样到部分可用token;
  • Top-P sampling
    • 方式:每个时间步,按照token出现的概率由高到底排序,当概率之和大于top-p的时候,就不取后面的样本了。然后对取到的这些token的概率重新归一化后,进行采样;
    • 参数do_sample = True, num_beams = 1,设定top-p,在0-1之间取值;
    • 备注:top-p采样方法往往与top-k采样方法结合使用,每次选取两者中最小的采样范围进行采样,可以减少预测分布过于平缓时采样到极小概率token的几率。
  • Temperature sampling
    • 方式温度调整严格来说不是一种采样方式,只是一种概率改变方法,需要与其他采样方式相结合才可以发挥作用。具体来说,温度调整通过在 s o f t m a x softmax softmax中添加温度系数 t t t来改变每个token输出的概率:
      s o f t m a x ( x i ) = e x i / t ∑ j = 1 n e x j / t softmax(x_{i})=\frac{e^{x_{i}}/t}{\sum_{j=1}^{n}e^{x_{j}}/t} softmax(xi)=j=1nexj/texi/t
      其中, n n n是词表大小, x j x_{j} xj表示词表中每个token对应的logits值, x i x_{i} xi是当前token的logits值, t t t是温度系数。
    • 参数temperature
    • 备注:由上面公式可知,当 t t t趋近于0时,会增加token之间概率的差值,所有token的概率分布会更陡峭,如下图所示。如果采用top-p采样模式,那么最终输出的token可选范围会缩小(因为只需要更少的token,概率和即可满足条件),模型输出更稳定;当 t t t趋近于无穷大时,会降低大概率token之间概率的差值,所有token的概率分布会更平缓,也就是说,最终输出的token可选范围会增大,模型输出随机性更大。
      在这里插入图片描述

四、三种训练方式

  • Pre-trained(预训练):是利用各种语料训练一个语言模型,这个模型已经拥有足够的基础知识,具备强大的基础能力;
  • Finetune(微调):是在Pre-trained的模型后面加一些简单的类似全连接的神经网络,用业务数据再训练一下,学习业务知识;
  • Post-training(后训练):是预训练的二阶段,预训练是从0到1的训练一个语言模型,Post-training是在预训练后的模型上,再进行一次预训练。

总结

  了解LLM,再看这一篇就够了!!!

  • 2
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值