公司动态

大模型知识(二)transformer小知识

📅 2026/7/15 19:07:08
大模型知识(二)transformer小知识
两种常见的预训练任务因果语言建模来源于NNLM遮盖语言建模来源于CBOW预训练没有先验知识需要海量训练数据时间和经济成本都很高。因此使用标注好的任务语料对模型进行二次训练迁移学习这个过程称为微调。微调充分利用了预训练的知识需要的数据量很少。1. 总体结构编解码结构编码将输入序列变成等长的连续表示自回归解码将连续表示变成一个输出序列编解码都使用堆叠的自注意力机制和逐点全连接层2. 编码层6层相同的层每一层有两个子层第一个子层是多头自注意力层第二个子层是逐点全连接前馈层。两个子层都包括一个残差连接和层归一化即每个子层的输出是layernorm(xsublayer(x))3. 解码层6层相同的层每一层有三个子层第一个子层是掩码多头注意力层指的是因果掩码预测不能依赖未来信息第二个子层是多头自注意力层其中query来自第一个子层key value来自于编码器第三个子层是逐点全连接前馈层。三个子层都包括一个残差连接和层归一化即每个子层的输出是layernorm(xsublayer(x))。4. 注意力机制将一个query和一组key-value对映射为一个output其中querykeysvaluesoutput都是向量。output等于value的加权和每个value的权重由query和相应的key计算得来query通过和key内积并softmax的方式得到query和各个value的相似度然后加权求和得到一个dv维的向量K 是为了被检索而存在的特征V 是为了被阅读而存在的内容。必须用 Q 去匹配 K才能决定去读取哪个 V。5. 缩放点积注意力query和key的维度是dkvalue的维度是dv。将一组queries组合成一个矩阵Q同理得到K, V为什么除以根号dk因为q k 都是dk维度防止注意力分数值过大落入softmax的饱和区导致梯度消失注意mask的位置在scale和softmax之间6. 多头注意力b batch_sizen sequence_lengthd hidden_sizeh num_headsk head_dim输入张量x为batch_size*sequence_length*hidden_size1线性投影x*[hidden_size*hidden_size] 得到 Q K VK和V的sequence_length要相等形状为batch_size*sequence_length*hidden_size2分头hidden_sizenum_heads*head_dim对Q K V进行reshape和transpose操作将注意力头的数量提前成为批处理维度的一部分形状为batch_size*num_heads*sequence_length*head_dim3计算注意力得分并加attention mask关键只有在 输入 softmax 之前 把无效位置设为 -inf才能让它们的权重变成 0。如果在 softmax 之后再 mask就无法保证概率和为 1且无法真正“忽略”这些位置。Q*K.Tbatch_size*num_heads*sequence_length*sequence_length4加权求和weight*Vbatch_size*num_heads*sequence_length*head_dim5合并头并最终投影output: batch_size*sequence_length*num_heads*head_dim--batch_size*sequence_length*hidden_sizefinal_output: batch_size*sequence_length*hidden_size多头注意力有三种应用1kv来自编码器q来自解码器 2自注意力中qkv来自同一个地方 3自回归解码中加入掩码机制另外attention mask可以遮盖padding等防止模型关注import torch import torch.nn as nn import torch.nn.functional as F import math class mha(nn.Module): def __init__(self,config): super().__init__() self.emb_dimconfig.hidden_size self.num_attention_headsconfig.num_attention_heads self.head_dimself.emb_dim//self.num_attention_heads self.q_projnn.Linear(self.emb_dim,self.emb_dim) self.k_projnn.Linear(self.emb_dim,self.emb_dim) self.v_projnn.Linear(self.emb_dim,self.emb_dim) self.o_projnn.Linear(self.emb_dim,self.emb_dim) def forward(self,x,attn_maskNone): qself.q_proj(x) kself.k_proj(x) vself.v_proj(x) batch_size,seq_len,_q.size() qq.view(batch_size,seq_len,self.num_attention_heads,self.head_dim).transpose(1,2) kk.view(batch_size,seq_len,self.num_attention_heads,self.head_dim).transpose(1,2) vv.view(batch_size,seq_len,self.num_attention_heads,self.head_dim).transpose(1,2) # batch_size,self.num_attention_heads,seq_len,self.head_dim attn_scoretorch.matmul(q,k.transpose(-1,-2)) # batch_size,self.num_attention_heads,seq_len,seq_len dkk.size(-1) attn_scoreattn_score/math.sqrt(dk) if attn_mask is not None: attn_scoreattn_score.masked_fill(attn_mask0,-float(inf)) weightsF.softmax(attn_score,dim-1) outputtorch.matmul(weights,v) # batch_size,self.num_attention_heads,seq_len,self.head_dim outputoutput.transpose(1,2).contiguous().view(batch_size,seq_len,self.emb_dim) outputself.o_proj(output) return output7. 逐点前馈网络编码器和解码器都包括一个逐点前馈网络包括一个线性层一个RELU激活函数一个线性层8. 嵌入层和softmax编码器和解码器的嵌入层都是将token映射为dmodel维向量在解码器最后对每个位置的输出向量维度dmodel​施加一个线性变换全连接层将其映射到词汇表大小∣V∣的 logits 空间再通过Softmax得到下一个 token 的概率分布P(wt​∣wt​)Softmax(Wout​⋅ht​)transformer在三处共享权重矩阵输入嵌入层输出嵌入层预softmax线性变换层显著提升性能并减少参数量在 Transformer 模型中“在嵌入层将权重乘以根号dmodel​​”是一个关键的缩放技巧其主要目的是平衡词嵌入token embeddings与位置编码positional encodings的尺度scale从而确保模型训练的稳定性。PyTorch 的 embedding 初始化使其向量长度与维度无关恒定小值而 PE 长度随 dmodel​​增长。通过 ×dmodel​​将 embedding 的尺度提升到与 PE 匹配确保两者在相加时贡献均衡。层后归一化原使用方式层后归一化归一化层在跳跃连接外在跳跃连接后层前归一化归一化层在跳跃连接内在内部最前面9. 位置编码内部式子相同,只是sin和cos的区别d代表位置编码向量的总维度数对于同一个词的不同维度,2i代表偶数维,2i1代表奇数维由于有足够的数据,足够深的网络,所以模型可以训练整合位置和词向量的信息由于词向量维度够高,所以碰撞发生的可能性很低10 teacher forcing在训练解码器时使用真实的目标序列前一个词作为输入而不是模型预测的词加速训练稳定收敛支持并行计算通过掩码防止信息泄露11 编码器模型Auto-Encoding适合理解整个句子语义的任务包括分类NER抽取式问答等包括BERT DistilBERT更小的模型 RoBERTa更大数据量更长时间 ModernBERT2万亿个次元12 解码器模型Auto-Regressive适合文本生成任务13 编码器-解码器模型适合给定输入生成新文本的任务包括摘要翻译生成式问答等T5将所有的NLU NLG任务转换成seq2seq形式解决BART 同时结合了BERT和GPT的预训练过程M2M-100语言对之间可能存在共享知识来处理小众语言之间的翻译BIGBIRD通过线性扩展的稀疏注意力形式扩展可处理的文本长度14 两阶段推理过程预填充分词词元嵌入转换初始处理解码注意力计算回顾所有先前的词元以理解上下文概率计算词元选择持续性检查需要考虑的关键指标1 首次响应时间TTFT 2 输出每词元的时间 TPOT 3 吞吐量 同时处理的请求数量 4 显存使用情况15 一些新型模型结构MambaRWKVRetNetHyena16 MoE结构将特定FFN替换成MoE使得模型可以在推理过程中仅激活部分参数从而在不显著提升计算成本的同时实现对模型参数的扩展。每个MoE包含K个专家每个专家是一个FFN对于输入模型首先通过一个路由网络来计算各专家的权重然后选择概率最高的k个激活最后通过softmax计算出k个专家权重没选中的权重置为017 手撕GQAimport math import torch import torch.nn as nn class GQA(nn.Module): def __init__(self,hidden_dim128,head_size8,key_head_size4,dropout_rate0.1): super().__init__() self.hidden_dimhidden_dim self.head_sizehead_size self.key_head_sizekey_head_size # key_head_size1时就是MQA self.head_dimself.hidden_dim//self.head_size self.q_projnn.Linear(hidden_dim,hidden_dim) self.k_projnn.Linear(hidden_dim,self.key_head_size*self.head_dim) self.v_projnn.Linear(hidden_dim,self.key_head_size*self.head_dim) #这边注意 self.dropoutnn.Dropout(dropout_rate) self.output_projnn.Linear(hidden_dim,hidden_dim) def forward(self,X,attention_maskNone): b,s,_X.shape Qself.q_proj(X) Kself.k_proj(X) Vself.v_proj(X) QQ.view(b,s,self.head_size,self.head_dim).transpose(1,2) KK.view(b,s,self.key_head_size,self.head_dim).transpose(1,2) VV.view(b,s,self.key_head_size,self.head_dim).transpose(1,2) KK.repeat_interleave(repeatsself.head_size//self.key_head_size,dim1) VV.repeat_interleave(repeatsself.head_size//self.key_head_size,dim1) #torch.repeat_interleave(input, repeats, dimNone) 会对张量 input 中的每个元素进行指定次数的重复并将结果拼接成一个新的张量。 #input输入张量 #repeats每个元素的重复次数可以是整数或与 input 维度匹配的张量 #dim指定重复的维度不指定时会先将张量展平 # 把维度转换一下 attention_valueQ K.transpose(-1,-2) attention_weightattention_value/math.sqrt(self.head_dim) if attention_mask is not None: attention_weightattention_weight.masked_fill(attention_mask0,-float(inf)) attention_weighttorch.softmax(attention_weight,-1) attention_weightself.dropout(attention_weight) outputattention_weight V outputoutput.transpose(1,2).contiguous() #contiguous() 方法的作用是确保张量tensor在内存中是连续存储的 #某些操作如 view()只支持连续张量对不连续张量使用会报错 #b,s,head_num,head_dim outputoutput.view(b,s,-1) # 再把维度转换回来 outputself.output_proj(output) return output