Transformer - 所有生成模型的基石(PART1 / PART5)
Transformer - 所有生成模型的基石PART1 / PART5从计算机视觉 (CV) 转型为 AI 工程师生成式AI、多模态、大模型方向 -- PART1目录什么是TransformerSelf-Attention机制详解Multi-Head AttentionPositional EncodingEncoder-Decoder架构三种主流架构对比关键理解检验一、什么是Transformer1.1 诞生背景Transformer架构由Google在2017年论文《Attention Is All You Need》中提出彻底改变了NLP领域。在此之前RNN/LSTM是主流但它们有两个致命缺点串行计算慢必须一个词一个词地处理长距离依赖差句子太长时前面的信息会遗忘Transformer的核心创新完全基于Attention机制抛弃RNN实现并行计算。先上模型架构图1.2 核心优势特性RNN/LSTMTransformer并行性❌ 串行✅ 完全并行长距离依赖❌ 梯度消失✅ 直接连接训练速度慢快适合GPU位置信息天然有序需额外编码二、Self-Attention机制详解2.1 通俗理解图书馆找书想象你在一个巨大的图书馆找资料写论文Query (Q) 你的搜索关键词“我想找关于深度学习的书”Key (K) 每本书的书脊标签“这本书是讲机器学习的”Value (V) 书的实际内容书里的知识为什么要乘VQ×K只告诉你哪本书相关相似度分数但你还没看到书的内容乘V相当于翻开书把相关书籍的内容按重要性加权求和这才是你真正需要的知识。2.2 快递分拣系统类比想象一个智能快递分拣中心Query 待分拣包裹的目的地信息“这个包裹要去北京”Key 各个分拣口的标签“这个口处理去华北的包裹”Value 实际的分拣动作“把这个包裹放到传送带A上”计算过程Q × K^T → 计算包裹和每个分拣口的匹配度Softmax → 确定最可能的分拣口概率分布× V → 执行实际的分拣动作2.3 数学公式拆解Attention(Q, K, V) softmax(QK^T / √d_k) V分步理解Step 1: Q × K^T计算相似度Q: [batch_size, seq_len, d_k] K^T: [batch_size, d_k, seq_len] 结果: [batch_size, seq_len, seq_len] ← Attention Score矩阵每个元素表示第i个词对第j个词的关注程度。Step 2: 除以√d_k缩放防止点积结果过大导致Softmax梯度消失d_k是Key的维度通常是64Step 3: Softmax归一化将分数转换为概率分布每行和为1Step 4: × V加权求和用注意力权重对Value进行加权得到每个位置的上下文表示2.4 代码示例importtorchimporttorch.nnasnnimportmathclassSelfAttention(nn.Module):def__init__(self,d_model512):super().__init__()self.d_modeld_model self.d_kd_model//8# 64# 三个线性变换生成Q、K、Vself.W_qnn.Linear(d_model,self.d_k)self.W_knn.Linear(d_model,self.d_k)self.W_vnn.Linear(d_model,self.d_k)defforward(self,x):# x: [batch, seq_len, d_model]Qself.W_q(x)# [batch, seq_len, d_k]Kself.W_k(x)# [batch, seq_len, d_k]Vself.W_v(x)# [batch, seq_len, d_k]# 计算Attention Scorescorestorch.matmul(Q,K.transpose(-2,-1))# [batch, seq_len, seq_len]scoresscores/math.sqrt(self.d_k)# Softmax归一化attn_weightstorch.softmax(scores,dim-1)# 加权求和outputtorch.matmul(attn_weights,V)# [batch, seq_len, d_k]returnoutput,attn_weights三、Multi-Head Attention3.1 通俗理解多人多角度看问题想象一个复杂的商业决策Head 1财务专家关注成本收益Head 2市场专家关注用户需求Head 3技术专家关注可行性每个专家Head都有自己的Q/K/V从不同角度分析同一问题最后汇总意见。3.2 为什么需要Multi-Head单一Attention可能只捕捉到一种关系语法关系主谓宾语义关系同义词指代关系他指的是谁Multi-Head让模型同时学习多种关系类型。3.3 数学表示MultiHead(Q, K, V) Concat(head_1, ..., head_h) W^O where head_i Attention(QW_i^Q, KW_i^K, VW_i^V)维度变化d_model 512h 8 heads每个head的d_k d_v 512/8 643.4 代码示例classMultiHeadAttention(nn.Module):def__init__(self,d_model512,num_heads8):super().__init__()assertd_model%num_heads0self.d_modeld_model self.num_headsnum_heads self.d_kd_model//num_heads# 一个大的线性层包含所有head的变换self.W_qnn.Linear(d_model,d_model)self.W_knn.Linear(d_model,d_model)self.W_vnn.Linear(d_model,d_model)self.W_onn.Linear(d_model,d_model)defforward(self,x):batch_size,seq_len,_x.size()# 生成Q、K、V并分割成多个headQself.W_q(x).view(batch_size,seq_len,self.num_heads,self.d_k).transpose(1,2)Kself.W_k(x).view(batch_size,seq_len,self.num_heads,self.d_k).transpose(1,2)Vself.W_v(x).view(batch_size,seq_len,self.num_heads,self.d_k).transpose(1,2)# 形状: [batch, num_heads, seq_len, d_k]# 计算Attention所有head并行计算scorestorch.matmul(Q,K.transpose(-2,-1))/math.sqrt(self.d_k)attntorch.softmax(scores,dim-1)# 应用Attention到Vcontexttorch.matmul(attn,V)# [batch, num_heads, seq_len, d_k]# 合并所有headcontextcontext.transpose(1,2).contiguous().view(batch_size,seq_len,self.d_model)# 最终线性变换outputself.W_o(context)returnoutput四、Positional Encoding4.1 为什么需要位置编码Self-Attention是位置无关的猫追老鼠和老鼠追猫对Attention来说是一样的模型不知道哪个词在前哪个词在后4.2 正弦位置编码Transformer使用正弦和余弦函数PE(pos, 2i) sin(pos / 10000^(2i/d_model)) PE(pos, 2i1) cos(pos / 10000^(2i/d_model))特点每个位置有唯一的编码可以处理任意长度的序列相对位置可以通过线性变换得到4.3 可视化理解位置0: [sin(0), cos(0), sin(0), cos(0), ...] 位置1: [sin(1/10000^0), cos(1/10000^0), sin(1/10000^(2/512)), ...] 位置2: [...]不同维度的正弦波有不同的频率形成独特的指纹。4.4 代码实现classPositionalEncoding(nn.Module):def__init__(self,d_model512,max_len5000):super().__init__()# 创建位置编码矩阵petorch.zeros(max_len,d_model)positiontorch.arange(0,max_len).unsqueeze(1).float()# 计算div_termdiv_termtorch.exp(torch.arange(0,d_model,2).float()*(-math.log(10000.0)/d_model))# 偶数维度用sin奇数维度用cospe[:,0::2]torch.sin(position*div_term)pe[:,1::2]torch.cos(position*div_term)self.register_buffer(pe,pe.unsqueeze(0))defforward(self,x):# x: [batch, seq_len, d_model]returnxself.pe[:,:x.size(1),:]五、Encoder-Decoder架构5.1 整体结构输入 → [Encoder] × N → 上下文表示 → [Decoder] × N → 输出Encoder理解输入生成上下文表示Decoder基于上下文生成输出5.2 Encoder详解每个Encoder层包含两个子层输入 → Multi-Head Self-Attention → AddNorm ↓ Feed-Forward Network → AddNorm ↓ 输出Add Norm残差连接 Layer NormalizationoutputLayerNorm(xSublayer(x))5.3 Decoder详解每个Decoder层包含三个子层输入 → Masked Multi-Head Self-Attention → AddNorm ↓ Multi-Head Cross-Attention → AddNorm (Q来自Decoder, K/V来自Encoder) ↓ Feed-Forward Network → AddNorm ↓ 输出5.4 Mask机制详解为什么需要MaskDecoder是自回归Auto-regressive的生成第i个词时只能看到已经生成的词不能偷看后面的词。类比写作不能偷看后面想象你在写作文写第3句话时你只能参考第1、2句话不能提前知道第4、5句话是什么否则就是作弊Causal Mask因果掩码词1 词2 词3 词4 词1 [1 0 0 0] ← 词1只能看自己 词2 [1 1 0 0] ← 词2能看词1、词2 词3 [1 1 1 0] ← 词3能看词1、词2、词3 词4 [1 1 1 1] ← 词4能看所有1表示可见0表示不可见实际实现中用-∞代替0Softmax后变为0。5.5 代码示例defcreate_causal_mask(seq_len):创建因果掩码下三角矩阵masktorch.triu(torch.ones(seq_len,seq_len),diagonal1)maskmask.masked_fill(mask1,float(-inf))returnmask# 示例maskcreate_causal_mask(4)print(mask)# tensor([[0., -inf, -inf, -inf],# [0., 0., -inf, -inf],# [0., 0., 0., -inf],# [0., 0., 0., 0.]])六、三种主流架构对比6.1 GPT系列Decoder-only结构只有Decoder使用Causal Mask特点自回归生成适合文本生成只能从左到右看单向注意力代表GPT-1/2/3/4, ChatGPT适用任务文本生成、对话、代码补全6.2 BERTEncoder-only结构只有Encoder使用双向注意力特点双向上下文理解能力强使用[MASK]进行预训练不适合直接生成文本代表BERT, RoBERTa, ALBERT适用任务文本分类、命名实体识别、问答6.3 T5Encoder-Decoder结构完整的Encoder-Decoder特点统一框架所有任务转为text-to-text翻译、摘要等Seq2Seq任务表现好代表T5, BART, mT5适用任务机器翻译、文本摘要、问答6.4 对比总结特性GPT (Decoder-only)BERT (Encoder-only)T5 (Encoder-Decoder)注意力方向单向左→右双向Encoder双向Decoder单向预训练任务语言建模MLM NSPSpan Corruption生成能力强弱强理解能力中等强强典型应用对话、写作分类、NER翻译、摘要七、关键理解检验问题1为什么Transformer比RNN更适合长文本答案长距离依赖RNN需要一步步传递信息长距离时梯度消失Transformer通过Attention直接连接任意两个位置并行计算RNN必须串行处理Transformer可以一次性处理整个序列复杂度对比RNN: O(n) 时间步但每步只能看到前面Transformer: O(1) 时间步O(n²) Attention计算问题2Self-Attention的时间复杂度是多少如何优化答案标准Self-Attention复杂度为O(n² × d)Q×K^T: [n×d] × [d×n] O(n² × d)当序列长度n很大时如4096n²成为瓶颈优化方法Sparse Attention只关注局部或稀疏位置Linear Attention将复杂度降到O(n × d²)Flash Attention通过IO感知优化减少显存访问Sliding Window每个词只关注附近的词问题3为什么BERT不能用于文本生成答案BERT是Encoder-only架构双向注意力每个词都能看到所有其他词没有Causal Mask预训练目标MLMMasked Language Model是预测被遮盖的词不是自回归生成缺乏自回归机制生成需要已知→未知的顺序BERT没有这个机制如果强行用BERT生成会出现生成第i个词时偷看了后面的词生成的文本不连贯附录学习资源推荐论文Attention Is All You Need - Transformer原论文The Illustrated Transformer - 可视化讲解代码实现Hugging Face Transformers - 工业级实现The Annotated Transformer - 带注释的PyTorch实现视频教程Stanford CS224N - Natural Language Processing with Deep Learning李宏毅机器学习课程 - Transformer讲解PART1 Transformer生成式AI 持续更新中PART1 / PART5