第一篇链接:LLM 参数,显存,Tflops? 训练篇(1) (qq.com)
第一篇我们讲完了Self-Attention层的算力要求和每一步生成的形状,
上节课我们讲的红框里的内容,我们继续从下往上看, 两个LN层就别看了也没啥特别多的可学习对象(跟MHA和FFN相比),其实还有什么drop out啥的,因为这玩意都没可学习的参数,所以都忽略,所以我们就看FFN层需要消耗多少算力
我们之前讲过FFN是干啥的,需要了解的读者请看这个系列:
小周带你读论文-2之"草履虫都能看懂的Transformer老活儿新整"Attention is all you need(1) (qq.com)
小周带你读论文-2之"草履虫都能看懂的Transformer老活儿新整"Attention is all you need(2) (qq.com)
小周带你读论文-2之"草履虫都能看懂的Transformer老活儿新整"Attention is all you need(3) (qq.com)
小周带你读论文-2之"草履虫都能看懂的Transformer老活儿新整"Attention is all you need(4) (qq.com)
为了后文大家看算式明白,我们先约定一下每个变量代表的意义(和前一篇的命名方式一样)
- L: Transfomer有多少层
- H:代表两个意义,第一个意义是hiddensize的维度,第二个就是token被embedding以后的维度,这两值本来也相等
- h: 小写的h代表多头注意力的数量,即有几个attention 头
- B:batchsize
- S:序列的长度,比如GPT 2K,LLama2 4K,就是这个东西
- V: 词表里词的数量
FFN有两个线性层,第一个线性层是升维,从H升级到4h的维度,第二个线性层就是降回到h维度,我们之前讲Llama的时候讲过,Llama的FFN层是和原本的Transfomer有点不一样的
原始Transfomer层的FFN的代码
class PositionwiseFeedForward(nn.Module):
"Implements FFN equation."
def __init__(self, d_model, d_ff, dropout=0.1):
super(PositionwiseFeedForward, self).__init__()
self.w_1 = nn.Linear(d_model, d_ff)
self.w_2 = nn.Linear(d_ff, d_model)
self.dropout = nn.Dropout(dropout)
def forward(self, x):
return self.w_2(self.dropout(F.relu(self.w_1(x))))
d_ff就是你想要把H hidden_size(从atteion层出来就这样,过layer Normal,无论是前置的还是后置的,也不会改变d_model的形状还是H),也就是 d_model升级到的高维空间,一般是d_model的4倍
Llamade MLP就不一样了
它是由3层来替换原来的2层FFN,因为它用了更复杂的激活函数SwiGlu,所以要增加一个门控层
这块的相关知识在这篇文章里可以阅读 用code去探索理解Llama架构的简单又实用的方法 (qq.com)
我们按标准的Transfomer的代码来,我们定义第一层的权重是W1,第二次权重是W2
MLP模块的计算公式是这样的:
第一层就是first_layer_out=W1*input
第二层就是second_layer_out=F.relu(W2*first_layer_out)+input
input是残差过来的
所以总公式就是:
2_layer_out=F.relu(W2*(W1*input))+input
我们现在逐步推导一下:
1- 第一个线性层的输入的是计算完了attetion以后,经过了LN归一化的[B,S,H]形状的Tensor
2-然后它要跟第一个线性层也就是[H,4H]这层点积,得到了[B,S,4H]的第一层的输出,这部分计算量为2*B*S*H*4H 为8BSH^2
3-[B,S,4H]这个第一层的输出Tensor,和第二层的[4H,H]的Tensor做点积,得到了回来了[B,S,H]形状的Tensor,计算量和刚才一样,也是8BSH^2
所以MLP层也就是FFN层,它的算力消耗是16BSH^2
前一篇我们讲过attention模块,它的算力消耗是
所以两者相加总的算力消耗是,这也就是单一一个Transfomer层消耗的算力之和
那要是有多层,我们就乘以L呗,比如24层,40层,80层
当然我们算完了FFN层,别忘了,我们是一个NLG业务,我们要生成token的,所以要算过个softmax层,求词典里,哪些词的概率更高就是我们要生成的token,所以这块的算力,我们也来求一下
我从FFN层出来的形状是[B,S,H],而进softmax,这边的Tensor长成[H,V]的形状,V就是你词典,也就是tokenizer里面的词数
出来以后的形状就是[B,S,H], 那么相应的算力消耗就是BSHV,因为每个参数要算2次(我不遗余力的在每个地方都提醒,矩阵计算,一次加一次乘)
所以最后的整体Transfomer所有参数的算力消耗(一次前向计算啊,没算反向传播)
推导的清晰不,够细致吧,兄弟们,如果看懂了,请给个三连,谢谢
这个系列还没完事呢,还没算显存呢,还有中间计算结果,还有推理时候的算力计算(和训练这个不一样),还有固定GPU卡推算TFLOPS,训练完成时间的公式,后面全是狠活儿
,敬请期待!