首页IT科技meta分析模板(Meta最新模型LLaMA细节与代码详解)

meta分析模板(Meta最新模型LLaMA细节与代码详解)

时间2025-08-05 10:20:49分类IT科技浏览4135
导读:0. 简介 今天介绍的内容是Facebook Meta AI最新提出的语言模型LLaMA,该模型声称以更小的体积,在多数任务上超越了GPT-3的性能。...

0. 简介

今天介绍的内容是Facebook Meta AI最新提出的语言模型LLaMA             ,该模型声称以更小的体积                   ,在多数任务上超越了GPT-3的性能             。

模型相关项目已经开源:

https://github.com/facebookresearch/llama

论文地址:https://scontent-tpe1-1.xx.fbcdn.net/v/t39.8562-6/333078981_693988129081760_4712707815225756708_n.pdf?_nc_cat=108&ccb=1-7&_nc_sid=ad8a9d&_nc_ohc=ov6yTHfLfNQAX-guxqd&_nc_ht=scontent-tpe1-1.xx&oh=00_AfDMyTEYewg-cHT9_4_sUaW5h0gqrqwjcNMylD9HtVFCWA&oe=6401C9E2

由于模型较大       ,目前的设备暂时没有办法支持进一步的实验             ,但是其模型代码已经开源                   ,所以可以先通过代码了解一下模型结构上的一些细节       ,今天就针对github上放出的代码      ,了解一下模型的细节                   。

此外                   ,该模型其实就是transformer做了一点细节上的改进             ,真正更有价值的工作应该在数据和训练方面       。通过阅读代码      ,可以对transformer的基础构造进行复习                   ,并且了解大模型如何在多卡上分布推理             。

由于该项目源码几乎没有注释             ,这就肯定会给很多同学阅读时带来困扰,所以本文顺带着就把代码部分详细的介绍一下                   。

1. 项目环境依赖

此项目给出的环境依赖只有4个:

torch fairscale fire sentencepiece

其中torch不比多讲                   ,fairscale是用来做GPU分布的                   ,一般是当使用DDP仍然遇到超显存的问题时使用fairscale       。目前fairscale我还没有试过,在下文的源码介绍中             ,我会用torch中对应的基础网络替代fairscale中的结构层进行介绍      。fire是一个命令行工具                   ,用或者不用他都可以       ,sentencepiece是用于tokenizer的工具包             ,会在tokenizer部分简单介绍                   。

2. 模型细节

由于该模型就是用的transformer的decoder                   ,所以在结构上它与GPT是非常类似的       ,只是有一些细节需要注意一下             。

2.1 RMS Pre-Norm

关于Pre-Norm和Post-Norm是神经网络中老生常谈的话题      ,目前比较普遍的被大家接受的结论是                   ,相同的深度条件下             ,Post-Norm的效果要优于Pre-Norm      ,因为Pre-Norm实际上相当于通过了一个更宽的网络而非更深的网络                   ,所以在同等深度下             ,Pre-Norm的实际效果相当于一个更浅却更宽的网络,详细的推理过程参考:https://spaces.ac.cn/archives/9009      。

然而在LLaMA中却采用了Pre-Norm                   ,或许是因为模型够深(7B                   ,13B,30B             ,65B的模型                   ,transformer layer数量分别为32       ,40             ,60                   ,80)       ,而Pre-Norm的恒等分支更加明显      ,有利于梯度的传播(这部分暂时没有想到很合理的解释                   ,如果有更好的理解             ,欢迎在评论区补充)                   。

RMS Norm(Root Mean Square Layer Normalization)      ,是一般LayerNorm的一种变体                   ,可以在梯度下降时令损失更加平滑             。

与layerNorm相比             ,RMS Norm的主要区别在于去掉了减去均值的部分(re-centering),只保留方差部分(re-scaling)                   ,从归一化的表达式上可以直观地看出:

一般的LN:

a

i

=

a

i

μ

σ

g

i

\overline{a}_i = \frac {a_i- \mu} \sigma g_i

ai=σaiμgi 其中                   ,

μ

=

1

n

i

=

1

n

a

i

\mu = \frac 1 n \sum_{i=1}^na_i

μ=n1i=1nai

σ

=

1

n

i

=

1

n

(

a

i

μ

)

2

\sigma= \sqrt {\frac 1 n \sum_{i=1}^n{{(a_i-\mu)}^2}}

σ=n1i=1n(aiμ)2

RMS Norm:

a

i

=

a

i

R

M

S

(

a

)

g

i

\overline{a}_i = \frac {a_i} {RMS(a)} g_i

ai=RMS(a)aigi

其中,

R

M

S

(

a

)

=

1

n

i

=

1

n

a

i

2

{RMS(a)}=\sqrt {\frac 1 n \sum_{i=1}^n{{a_i}^2}}

RMS(a)=n1i=1nai2

可以看到             ,二者的区别就在于有没有减去均值。至于RMS Norm为什么有用                   ,需要求梯度进行分析       ,感兴趣的同学可以阅读RMS Norm的论文                   。

2.2 SwiGLU激活函数

LLaMA采用SwiGLU替换了原有的ReLU                   。

采用SwiGLU的FNN             ,在论文中以如下公式进行表述:

F

F

N

s

w

i

G

L

U

(

x

,

W

,

V

,

W

2

)

=

(

S

w

i

s

h

1

(

x

W

)

x

V

)

W

2

FFN_{swiGLU}(x, W, V, W_2) = (Swish_1(xW)\otimes xV)W_2

FFNswiGLU(x,W,V,W2)=(Swish1(xW)xV)W2

其中                   ,

S

w

i

s

h

β

(

x

)

=

x

σ

(

β

x

)

Swish_\beta(x) = x\sigma(\beta x)

Swishβ(x)=xσ(βx), (Ramachandran et al., 2017.)

2.3 RoPE旋转位置编码

RoPE(Rotary Position Embedding)旋转位置编码       ,是苏剑林老师提出的一种旋转位置编码方法      ,其思想是采用绝对位置编码的形式                   ,实现相对位置编码。这一部分比较关键             ,如果不理解的话      ,后边的代码估计就看不懂了             。读懂RoPE涉及一点复变函数的基础知识                   ,不过如果你没有学过的话也没有关系                   。

位置编码对大模型而言尤为重要             ,因为既然是要训练大模型,那么长文本的表征和模型对于长文本的建模能力就显得非常重要       。(但是对于绝对位置编码                   ,我有一个直观地感受                   ,认为其本质上不适用于长文本的场景,因为它会直接导致模型的Embedding层被无限放大             ,并且由于数据分布在seq_len方向上通常是长尾的                   ,这又会必然导致绝对位置编码的矩阵在尾部会越来越稀疏       ,一方面造成资源浪费             ,另一方面这种表示方法直观上就很不利于模型的学习                   ,因为它与我们实际场景是有很大的矛盾的             。而RoPE虽然具有相对位置编码的性质       ,但是从代码部分可以看出      ,在构造的时候                   ,其也是受到了最大长度的限制的                   。关于这一点             ,我无法严谨得说明      ,只是一点个人的想法       。)      。

而RoPE的巧妙之处在于                   ,它既保留了绝对位置编码中的绝对位置信息             ,又保留了在内积运算下,对位置信息的相对性                   。

RoPE主要借助了复数的思想             。为了引入复数                   ,首先假设了在加入位置信息之前                   ,原有的编码向量是二维行向量

q

m

q_m

qm

k

n

k_n

kn
,其中

m

m

m

n

n

n
是绝对位置             ,现在需要构造一个变换                   ,将

m

m

m

n

n

n
引入到

q

m

q_m

qm

k

n

k_n

kn
中       ,即寻找变换:

q

m

~

=

f

(

q

,

m

)

,

k

n

~

=

f

(

k

,

n

)

\tilde {q_m} = f(q, m), \tilde{k_n} = f(k, n)

qm~=f(q,m),kn~=f(k,n)

考虑到Attention的核心计算是内积:

A

t

t

e

n

t

i

o

n

(

Q

,

K

,

V

)

=

s

o

f

t

m

a

x

(

Q

K

T

d

k

)

V

Attention(Q, K,V) = softmax(\frac {QK^T} {\sqrt{d_k}})V

Attention(Q,K,V)=softmax(dkQKT)V

所以             ,寻求的这个

f

(

)

f(*)

f()变换                   ,应该具有特性:

f

(

q

,

m

)

,

f

(

k

,

n

)

=

g

(

q

,

k

,

m

n

)

\langle f(q, m), f(k, n) \rangle = g(q, k, m-n)

f(q,m),f(k,n)⟩=g(q,k,mn)

这里直接说结论       ,寻求的变换就是

q

m

e

i

m

θ

q_me^{im\theta}

qmeimθ      ,也就是给

q

m

q_m

qm
乘以

e

i

m

θ

e^{im\theta}

eimθ
                   ,相应地             ,

k

n

k_n

kn
乘以

e

i

n

θ

e^{in\theta}

einθ
      。

具体的求解过程      ,请参考苏剑林老师的博客                   。

做了这样一个变换之后                   ,根据复数的特性             ,有:

q

m

,

k

n

=

R

e

[

q

m

k

n

]

\langle q_m, k_n \rangle = Re[q_mk^*_n]

qm,kn=Re[qmkn]

也就是,如果把二维向量看做复数                   ,那么它们的内积                   ,等于一个复数乘以另一个复数的共轭,得到的结果再取实部             。

带入上面的变换             ,也就有:

q

m

e

i

m

θ

,

k

n

e

i

n

θ

=

R

e

[

(

q

m

e

i

m

θ

)

(

k

n

e

i

n

θ

)

]

=

R

e

[

q

m

k

n

e

i

(

m

n

)

θ

]

\langle q_me^{im\theta}, k_ne^{in\theta} \rangle = Re[(q_me^{im\theta}) (k_ne^{in\theta})^*] =Re[q_mk_n^*e^{i(m-n)\theta}]

qmeimθ,kneinθ=Re[(qmeimθ)(kneinθ)]=Re[qmknei(mn)θ]

这样一来                   ,内积的结果就只依赖于

(

m

n

)

(m-n)

(mn)       ,也就是相对位置了。换言之             ,经过这样一番操作                   ,通过给Embedding添加绝对位置信息       ,可以使得两个token的编码      ,经过内积变换(self-attn)之后                   ,得到结果             ,是受它们位置的差值      ,即相对位置影响的                   。

于是对于任意的位置为

m

m

m的二维向量

[

x

,

y

]

[x, y]

[x,y]
                   ,把它看做复数             ,乘以

e

i

m

θ

e^{im\theta}

eimθ
,而根据欧拉公式                   ,有:

e

i

m

θ

=

cos

m

θ

+

i

sin

m

θ

e^{im\theta}=\cos{m\theta}+i\sin{m\theta}

eimθ=cosmθ+isinmθ

于是上述的相乘变换也就变成了:

(

x

+

i

y

)

e

i

m

θ

=

(

x

cos

m

θ

y

sin

m

θ

)

+

i

(

x

sin

m

θ

+

y

cos

m

θ

)

(x+iy)e^{im\theta}=(x\cos{m\theta}-y\sin{m\theta})+i(x\sin{m\theta}+y\cos{m\theta})

(x+iy)eimθ=(xcosmθysinmθ)+i(xsinmθ+ycosmθ)

把上述式子写成矩阵形式:

f

(

(

q

,

%2

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
帝国cms目录结构设计(帝国cms栏目给删了怎么办)