训练模型时应该考虑哪些因素?
模型有多大?参数占用多少显存?可以安装吗?需要多少算力支持?本文简单介绍一下标准的Transformer模型例程。
首先就每个变量的含义达成一致,以便每个人都理解后面的计算。
L: Transformer 有多少层H?这意味着两件事。第一个含义是hiddensize的维度,第二个含义是嵌入token后的维度。这两个值原本是相等的h:小写的h是多头注意力的数量,即有几个注意力头。 B:batchsizeS:序列长度,如GPT 2K、LLama2 4K。这是V: 词汇表中的单词数。
现在我们来看看需要一一统计哪些模块。
如上图所示,这是标准的Transformer 架构,但正如我所说,除了T5 和一些特定网络之外,没有人使用这种方式,目前的主流是针对CLM 任务和执行CLM 任务的Causal-decoder。由于目前LLM的主流任务主要是生成,所以对这个知识点感兴趣的读者可以先到以下页面:小周的论文2《连草履虫都能理解的老变形金刚的研究》阅读。只需关注(1) (qq.com)
因此,我们主要考虑的是Causal-decoder-only架构。
如上图所示,嵌入后我们需要传递一个注意力层,然后是两个LN 层和一个FFN 层。这是Transformer 的标准CLM 架构。所有LLama系列的贝壳都是这样的,而且它的作用就像一个魅力。事实上,没有太多可以添加的内容,因此我们将要描述的算法可以被认为是通用的。
自注意力层:
该层首先从嵌入层检索数据,这是一个矢量化的令牌。向量化token 的维度是h,所以当我们进入Self-Attend 时,我们得到的形状是[B, S, H]。
让我们看看Self-Attention层做了什么
首先我们需要生成四个权重矩阵,对吗?
现在
,
每个权重矩阵的形状为[H,H]。
前三个权重矩阵分别生成QKV 和输入嵌入向量[B, S, H]。每个矩阵需要计算点积[B, S, H]*[H, H]。 BSH^2 次,总共3BSH^2 次,所有生成的张量形状均为[B, S, H]
接下来我们进入QKV环节,首先将Q*K的转置除以K的维度的平方根,然后进入softmax。
完整的公式
由于K 的维数等于H,因此我们可以写:
这一步的计算复杂度为[B,S,H]*[B,H,S](K矩阵转置)。我们现在考虑多头注意力机制。
h是Long的数量,H'是分配给每个Long的head_dim,看下面的代码就可以理解。
class LongLlamaAttendant(nn.Module): def __init__(self, config: LongLlamaConfig, mem_config:Optional[LongLlamaMemConfig]=None): super().__init__() self.config=config # 隐藏层维度,4096 self.hidden_size=config 。 hide_size #受关注头的数量,32 self.num_heads=config.num_attention_heads #每个受关注头的尺寸,4096 //32=128 self.head_dim=self.hidden_size //self .num_heads #位置length Vector, 2048 self .max_position_embeddings=config.max_position_embeddings #缓存中缓存的支架最大长度,2048 self.max_cache=self.max_position_embeddings if (self.head_dim * self.num_heads) !=self.hidden_size: raise ValueError( f 'hidden_sizemust be pisible by num_heads (got `hidden_size`: {self.hidden_size}' f' and `num_heads`: {self.num_heads}).' ) # 使用self 的线性映射层.q_proj=生成查询、键和值时。 nn.Linear(self.hidden_大小, self.num_heads * self.head_dim,bias=False) self.k_proj=nn.Linear(self.hidden_大小, self.num_heads * self.head_dim,bias=False) self.v_proj=nn.v_proj Linear(self.hidden_size, self.num_heads * self.head_dim,bias=False) self.o_proj=nn.Linear(self.num_heads * self.head_dim, self.hidden_size,bias=False) # 旋转位置编码self.rotary_emb=LongLlamaRotaryEmbedding(self.head_dim, max_position_embeddings=self.max_position_embeddings) # 内存注意力相关参数self.mem_config=mem_config
计算量等于[B,h,S,H']*[B,h,H',S],计算量为BHS^2(H'和h最终组成H。见上面)代码),形状为[ B,h,S,S]
完成此步骤后,我们需要计算上一步的解与V 矩阵的点积结果。
即[B,h,S,S]*[B,h,S,H'],计算量为BhS^2H'或BHS^2,计算出的形状为[B,h,S,H ']
化的最后一步是经过线性层Wo,将多头头寸减少为单头寸。
算力计算为[B,h,S,H']*[H,H]。由于h*H'=H,它简化为[B,S,H]*[H,H]。是BSH^2。形状是[B,S,H](这完成了进来和出去的形状)
当然,由于有残差网络,所以我们需要添加一个输入(X),但是这个添加可以忽略。
我们知道,神经网络的计算就是一次加法和一次乘法(实际加法是n-1,别太造作,按两下就可以了)。
那么,对于每个模型参数,整个self-attention阶段的算力需求为:
2*(3BSH^2+BSH^2+BHS^2+BHS^2)
是:
本节结束
标题:LLM 参数,显存,Tflops? 训练篇(1)
链接:https://www.7kxz.com/news/gl/19350.html
版权:文章转载自网络,如有侵权,请联系删除!