结构解读
这里用来配合理解的图片除了llama2结构图其他均来自datawhale。
llama2与qwen2的结构对比如图,这里主要从注意力层结构进行分析。这里的GQA为分组自注意力将query进行了分组,仅在组内共享同一个key和value,虽然qwen2的图中没有明写,它的key和value也是组内共享的。这样做的好处就是kv cache占用的显存就变小
forward过程
inputs_embeds = self.embed_tokens(input_ids) # embed positions hidden_states = inputs_embeds
将输入的id值转化成向量,然后就是经过若干次decode层再用模型的norm层进行归一化获得最终结果
解码层
这里设计到了MLP,注意力机制和标准化,这里先讲讲MLP的机制和作用
MLP结构如下
简单来说就是将激活的线性层输出和未激活的相乘,再经过一个线性层获得下一个hidden_state,中间的两个线性层参数设置完全一致。mlp(多层感知机)的作用就是特征转换和映射。
norm层
此为标准化公式,w_i与x分别是每个hs最后一个维度的值和当前hs最后一个维度的值,非常基础标准化方法。
forward
- 首先复制一份
hidden_states
为residual
,然后将hidden_states
送入Norm
,再送入attn
模块。 - 得到
attn
的输出后,再复制一份residual
,再将hidden_states
送入Norm
,mlp
,再与residual
进行相加。最后输出的就是这个hidden_state
这里的residual为残差,这里的作用查了一下可能是避免梯度消失,并加速收敛
attention层
这里简要描述一下各个层的作用
rotary_pos_emb
含义是对每一个token的每一个dim赋予不同的位置信息,主要是为每个维度同时添加相对位置以及绝对位置信息,因为同一个字位置不同意义也有可能不一样。
这里其实就是llama中的rope操作。rope操作本质是矩阵旋转,要详细实现代码有点多,这里就简要总结一下
常规rope操作:
- 先定义并生成旋转角度,然后将上述生成角度与每一个位置乘积,区分一个seq中各个词
- emb将二者cat(连接)起来,得到dim维度,每dim/2一循环
- 应用旋转:在取出位置编码信息
cos
与sin
的时候,就是将seq
的部分切出来,原先设置的1024是最大pos
编码,每次用的时候只取当下seq_len
的即可,1024代表位置特征,可以自行设置
repeat_kv
就是llama2中的rqa,对key和value的扩展,保证扩展至与query相同大小,对query无操作。
dot attn
注意力点积,transformer的灵魂(之一),用于计算注意力权重。公式为
q*kT/hd_d^0.5
attention_mask
实现掩盖读取功能,为了保证从左往右读取,每一步只有自己和已经读取过有值,其余都是0。
总结
学习的时候由于基础不稳,基本只是看了一遍流程,了解其中每层的一些作用,具体的算法和数据结构没有细看,不过也算了解了一些大模型的基础结构知识。