【Transformer基础面经—算法秋招or实习小白必看真实面试经历】https://www.bilibili.com/video/BV1KFafzgEcP?vd_source7c2b5de7032bf3907543a7675013ce3aTransformer整体架构记住这张图左边编码器encoder输入经过 input embedding 和 positional encoding 加上多头注意力机制层、残差连接层归一化、前馈神经网络、残差连接层归一化右边解码器decoder与 encoder 类似但是加入了掩码功能多头自注意力机制整体架构图解析1输入单词的输入由单词 input embedding 和positional encoding 相加得到。单词输入首先进行一个词向量嵌入在做一个位置编码相加得到输入2单词 Embedding可以采用 Word2VecGlove 等算法预训练得到也可以在 Transformer 中训练得到。词向量的两种训练方式CBOW用上下文词预测中心词Skip-gram用中心词预测上下文词3位置 Embedding使用位置编码 Positional Encoding可以通过数据预训练学习得到类似于训练学习词向量。单词和位置 embedding 的维度是一样的的。计算公式如下公式和字母含义要记住其中pos 是位置索引时间步长i 是维度索引d 是词向量维度。为什么要做 positional encodingtransformer的核心机制是self-attention它是不区分词中字的顺序若不加位置编码那么“我爱你”“你爱我”计算的是两个字之间的attention score。1在位置编码矩阵中维度 2i 存储正弦函数值存储余弦函数值这种交替存储方式使得位置编码可以同时捕捉到不同频率的周期信息2是缩放因子确保不同维度的频率不同使得位置编码可以捕捉多维度的位置信息3正弦和余弦函数具有周期性使得位置编码可以捕捉到单词的相对距离具有相位特性两者是相差90度的互补函数组合在一起可以更全面的描述位置信息。了解哪些位置编码的方式4Encoder Block通过上面的单词 embedding 和位置编码相加得到了词向量矩阵传入encoder中。由两层结构组成①多头自注意力层残差连接、层归一化②前馈神经网络层残差连接、层归一化。5Self-Attention上面我们得到了输入矩阵 X通过与线性变换矩阵 WqWkWv 相乘得到 QKV 矩阵。attention 计算公式如下默写公式1计算矩阵 Q 和 K 每一行向量的内积为了防止内积过大除 dk 的平方根。Q 乘以 K 的转置后得到的矩阵行和列都是 nn 为句子单词数这个矩阵可以表示单词之间的 attention 强度。也就是注意力分数 attention score。2得到QKT后使用softmax计算每一个单词对于其他单词的 attention 系数对矩阵每一行进行 softmax 处理即每一行的和都变为 1。3然后与 V 相乘比如单词 1 的输出 Z1 等于所有单词 i 的值 Vi 根据 attention 系数的比例加在一起得到。5Multi-Head Attention多头自注意力矩阵是由多个 self-attention 组成的每个 self-attention 的输出矩阵Multi-Head Attention 将他们拼接在一起concat然后传入一个 linear 层得到最终的输出矩阵 Z 这个输出矩阵 Z 和输入矩阵 X 的维度是一样的。6Add NormAddX multi-head attentionx是一种残差连接残差连接核心思想跳过连接将输入直接加到输出。为什么要做残差连接①有助于解决深层网络带来的梯度消失问题。因为在反向传播过程中梯度可以通过捷径直接传到浅层无序经过链式法则容易导致梯度消失从而缓解梯度消失或梯度不爆炸的风险。②残差连接还有助于特征重用增强浅层特征在网络较深层的重要性从而提升模型的学习能力和泛化能力。Normlayer normalization层归一化通常用于 RNN 结构会将每一层神经元的输入转化为均值为 0 方差为 1加快收敛。用的是什么归一化层归一化 layer normalization为什么使用层归一化而不使用批次归一化7Feed forward 前馈神经网络两层的全连接层第一层激活函数是 Relu第二层不使用激活函数。max(0,XW1b1)W2 b2这里输出矩阵的维度与输入矩阵一致。8组成 Encoder通过上面的 Multi-Head Attention AddNormFeed Forward AddNorm 就可以构造一个 encoder block多个 encoder block 叠加就可以组成 Encoder。第一个 encoder block 的输入是词向量矩阵后续的 encoder block 的输入是前一个 block 的输出最后一个 block 输出的矩阵就是编码信息矩阵 C这个矩阵后续会用到 decoder 中。9Decoder与 Encoder 相似区别在①两个 multi-head attention 层②第一个用了 masked 操作③第二个的 KV 矩阵使用的是 encoder 的编码信息矩阵进行计算而 Q 使用上一个 decoder block 的输出计算④最后有一个线性层和 softmax 层计算下一个词的概率9.1 第一个 multi-head attention1.decoder block 的第一个多头注意力层采用了 masked 操作是为了防止第 i 个单词知道 i1 个单词之后的信息。2.decoder 可以在训练过程中使用 teacher forcing 并且并行化训练即将正确的单词序列和对应输出传递到 encoder那么在预测第 i 个词的时候就要将 i1 之后的单词掩盖住。3.mask 操作是在 self-attention 和 softmax 之前使用的。第一步是 decoder 的输入矩阵和 mask 矩阵。假设输入矩阵包含五个单词的表示向量那么 mask 矩阵就是一个 5*5 的矩阵。单词 0 只能使用单词 0 的信息而单词 1 可以使用 0 和 1 的信息即每个单词只能使用之前的信息。补充这一步的 mask 叫做 sequence mask - 防止未来信息泄露产生一个上三角矩阵上三角的值全为 1下三角的值全为 0对角线也是 0。第二步通过输入矩阵 X 计算得到 QKV 矩阵计算 Q 和KT的点积。第三步得到 Q 和 KT的点积使用 mask 矩阵遮挡得到 mask 后的QKT。然后进行 softmax 操作计算 attention score每一行的和都为1第四步使用 mask QKT与矩阵 V 相乘得到输出 Z例如单词 1 的输出向量 Z1 是只包含单词 1 的信息的第五步通过以上步骤就可以得到 mask self-attention 的输出矩阵 Zi然后通过 multi-head attention 拼接多个输出 Zi计算得到第一个 multi-head attention层的输出 ZZ与输出 X 的维度一致。9.2 第二个 multi-head attention根据encoder 的编码信息矩阵 C 计算得到 K、V根据上一个 decoder block 的输出 Z 计算 Q这样做的目的是在 decoder 的时候每一个单词都可以利用 encoder 的所有单词信息这些信息无需 maskLinear特征组合线性层接收来自解码器最后一层的输出这个输出是一个高维向量包含了关于输入序列的丰富信息。权重矩阵线性层内部有一组可学习的权重它会乘以输入向量并加上一个偏置项。这就像你在计算每个特征的重要性然后给它们打分。简化输出通过这种方式线性层可以将高维向量压缩成一个较低维度的向量通常与目标词汇表大小相同。这样每个位置上的值就代表了对应词汇的可能性得分。9.3 softmax 预测输出单词decoder block 最后的部分是利用 softmax 预测下一个单词在之前的网络层我们可以得到一个最终的输出 Z因为 mask 的存在使得单词 0 的输出 Z0只包含单词 0 的信息softmax 根据输出矩阵的每一行预测下一个单词。概率转换softmax函数接收线性层输出的原始得分logits并将其转换为概率值。这使得我们可以明确知道每个词汇被选中的可能性。指数化首先Softmax 会对每个得分进行指数化处理确保所有的值都是正数并方法差距较大的得分之间的差异。归一化然后它会将所有指数化的得分相加得到一个总和。最后每个指数化的得分除以这个总和得到的概率值就会落在 0 到 1 之间并且所有概率加起来等于 1。Transformer具体提问1.attention 计算公式为什么要除以根号dkQKT点积随着维度增加会过大即向量元素之间差距变大经过 softmax 处理容易出现某个值接近 1其他接近 0从而导致梯度消失除以根号 dk 是为了让 QK 点积后的结果归一化成均值为 0方差为 1 的向量数据标准化处理避免梯度消失。2.自注意力机制为什么使用 QKV可以只用其中两个吗在自注意计算中每个输入 token x 先经过三个不同的线性变换Qquery表示当前 token 想要“查询什么信息”KKey表示其他 token 具备什么信息VValue表示实际要传递的信息注意力计算流程计算相关性当前 token 和其他 token 的匹配程度Softmax归一化成权重乘 V用权重加权汇聚真正要传递的内容3. Transformer使用的是layer norm还是batch norm使用的是层归一化。不使用 batch norm 原因①在 NLP 任务中输入的文本是变长序列句子长短不一用 batch norm 会使得均值方差波动大拖慢模型收敛速度。②NLP 中常用小 batch但 batch norm 通常在一个 batch 里面计算均值方差对于小 batch 不稳定。③layer norm 对每个 token 单独归一化不会破坏句子位置编码也不受序列长度影响这一点batch norm 做不到。4. Transformer中layernorm是放在残差前还是残差后这两种顺序在训练稳定性和收敛速度上有何不同原始的 transformer 中layernorm 是放在残差后。后续先对输入做 layerNorm再经过子层最后直接残差相加无额外 LN。训练稳定性残差后做 layernorm会导致深层网络训练时出现梯度爆炸/消失导致训练不稳定先 LayerNorm 再做子层残差路径是恒等映射梯度可以直接回传避免深层网络梯度消失。收敛速度残差后做 layernorm 初期收敛很快因为每一层的输出经过 LN 后有标准化的分布有助于梯度平衡先做 layernorm 前期收敛较慢但是随着深层训练模型仍能学到合理的尺度这时候收敛表现更优。5. MHA多头注意力的意义多头可以捕捉输入序列的不同特征不同头可以关注不同模式增强模型的表达能力。(1) 每个头可以学习到不同子空间表示例如语义、语法、位置关系(2) 多头使模型对于噪声和初始化更加鲁棒捕捉更丰富的上下文信息。引申 MQA GQA MLAMQA 是多个Q常见8个对应一个K对应一个VGQA 是两两一组的Q对应一个K对应一个V。MLA 通过低秩KV联合压缩实现高效推理6. 位置编码是什么它的作用有哪些位置编码位置编码是 Transformer 里用来注入序列位置信息的机制。因为 Transformer 只有自注意力自注意力是对所有 token 的加权和它本身不区分顺序。①固定位置编码Sinusoidal Encoding原始 Transformer 用的方式用三角函数生成②可学习的位置嵌入Learnable Positional Embedding直接给每个位置一个可训练向量类似词向量BERT 就用这个方式但只能处理训练时看到的最大长度不能很好泛化到更长序列③相对位置编码Relative Positional Encoding不是告诉绝对位置而是告诉相对距离Transformer-XL、T5、DeBERTa 等都用这个公式里 Attention 直接加上相对位置信息④旋转位置编码RoPE, Rotary Positional EncodingGPT-NeoX、LLaMA 等常用通过对 Q、K 向量进行二维旋转让 dot-product 隐式包含位置信息好处保留相对位置信息对长序列泛化好计算高效7.Transformer中的掩码技术1Padding mask填充掩码为了把所有输入序列对齐到相同长度较短的序列就会在末尾进行填充。具体做法是将padding位置的注意力权重设置为负无穷经过 softmax 过后该位置权重就会变成0从而忽略该位置的影响。2前瞻掩码在 decoder 的第一个多头注意力层中为确保解码时模型不能访问到未来时间步的信息生成一个上三角矩阵上三角的值全部为 1下三角的值全部为 0对角线也是 0.这样避免信息泄露。8.手撕均方根归一化d hidden_dimr 可训练缩放参数不包含偏置b比 layernorm 更轻量import torch import torch.nn as nn class RMSNorm(nn.Module): def __init__(self, hidden_dim, eps1e-8): super().__init__() self.hidden_dim hidden_dim self.eps eps self.weight nn.Parameter(torch.ones(hidden_dim)) # 缩放参数 def forward(self, x): rms torch.sqrt(x.pow(2).mean(-1, keepdim True) self.eps) return (x/rms) * self.weight9.Transformer中的交叉注意力 decoder 和 encoder 是如何交互的在 decoder 的第二个多头注意力层中根据 encoder 输出的编码信息矩阵计算的到 K 和 V根据上一个 decoder block 的输出计算得到 Q这样做的目的是在解码时每一个单词都可以利用到编码的所有单词信息这些信息无需编码。10.Transformer与RNN相比有什么优势解决了哪些问题1解决了长距离依赖问题RNN 通过时间步逐步转递隐藏状态长距离依赖会因为梯度消失或爆炸而难以学习transformer通过自注意力机制self-attention直接建模任意两个位置的关系无论距离多远。2解决了并行问题RNN必须按照时间步顺序计算训练速度慢而transformer的自注意力层和全连接层完全并行计算提高训练效率。3避免信息瓶颈RNN最后一个时间步的隐藏状态需要编码整个序列的信息可能导致信息丢失而transformer通过多头注意力Multi-Head Attention和位置编码positional encoding保留所有位置的交互信息。11.手撕注意力机制# 多头注意力机制 import torch import torch.nn as nn import math class MultiHeadAttention(nn.Module): def __init__(self, hidden_dim, num_heads): super().__init__() self.hidden_dim hidden_dim self,num_heads num_heads self.d_k hidden_dim // num_heads def forward(self, x, maskNone): B, L, H x.shape q self.query(x) k self.key(x) v self.value(x) # reshape多分头 q q.view(B, L, self,num_heads, self.d_k).transpose(1, 2) # (B, h, L, d_k) k k.view(B, L, self,num_heads, self.d_k).transpose(1, 2) v v.view(B, L, self,num_heads, self.d_k).transpose(1, 2) attn_score torch.matmul(q, k.transpose(-2, -1) / math.sqrt(self.d_k) if mask is not None: attn_score attn_score.masked_fill(mask 0, float(-inf)) attn_weight torch.softmax(attn_score, dim -1) output torch.matmul(attn_weight, v) # (B, h, L, d_k) out output.transpose(1, 2).contiguous().view(B, L,H) out self.out(out) # 通过最终线性层 return out# 单头自注意力 import torch import torch.nn as nn import math class SelfAttention(nn.Module): def__init__(self, hidden_dim): super().__init__() self.hidden_dim hidden_dim self.query nn.Linear(hidden_dim, hidden_dim) self.key nn.Linear(hidden_dim, hidden_dim) self.value nn.Linear(hidden_dim, hidden_dim) def forward(self, x, mask None): B, L, H x.shape q self.query(x) k self.key(x) v self.value(x) scale math.sqrt(k.size(-1)) attn_score torch.matmul(q, k.transpose(-2, -1) / scale if mask is not None: attn_score attn_score.mask_fill(mask 0, float(-inf)) attn_weight torch.softmax(attn_score, dim -1) output torch.matmul(attn_weight, v) return output # (batch_size, seq_len, hidden_dim)Bert1.bert的输入组成WordPiece Embedding Positional Embedding Segment Embedding分词将单词划分为子词单元位置特征嵌入段落句子嵌入输入通常是两个句子拼接在一起为输入的每个token加一个段落嵌入区分是句子A还是B2.介绍一下bertBert是基于transformer的encoder部分的预训练模型通过双向的上下文信息来理解句子中的词语。本质就是在海量语料的基础上通过自监督学习为单词找到一个好的特征表示。该模型优点是可以根据具体的任务进行微调或者直接使用预训练的模型作为特征提取器。Transformer是一种序列到序列的模型通过self-attention机制并行处理整个序列这种机制使得模型可以同时考虑序列中所有的元素并学习上下文之间的关系。3.bert的两个任务masked language model next sentence prediction1.MLM通过随机掩盖句子里的token要求模型根据上下文来预测被掩盖的词。具体操作80%用mask来替换token10%用随机token替换10%保持原token不变2.NSP给定两个句子要求模型判断这两个句子是否为连续上下句具体操作语料中50%的句子选择其相应的下一句形成上下文作为正样本其余50%的句子选择非下一句作为负样本4.bert里面的cls标记是什么聚合上下文信息cls标记位置经过自注意力计算后能够融合整个输入序列各个位置的信息整合上下文语义为分类任务做准备cls标记的向量会整合整个句子的文本信息来判断该句话属于哪个分类GPT1.介绍一下GPT基于transformer的decoder部分通过自回归语言模型预训练来学习生成连贯文本的能力2.为什么现在的大模型大多数是decoder only而不是encoder only任务需求导致的。目前大模型主流是自回归生成的任务这就是decoder only在做的事情而encoder only更多的用于文本理解任务无法直接生成序列。训练效率。decoder only单一架构训练和推理更高效而encoder only需要全序列双向注意力成本比前者高。数据利用率高。decoder only通过因果语言建模预测下一个词在海量数据训练下效果十分显著而且可以用0样本或者小样本学习而encoder only通过掩码语言模型如果生成任务和预训练任务不同需要额外的微调手段。
Transformer基础面经
【Transformer基础面经—算法秋招or实习小白必看真实面试经历】https://www.bilibili.com/video/BV1KFafzgEcP?vd_source7c2b5de7032bf3907543a7675013ce3aTransformer整体架构记住这张图左边编码器encoder输入经过 input embedding 和 positional encoding 加上多头注意力机制层、残差连接层归一化、前馈神经网络、残差连接层归一化右边解码器decoder与 encoder 类似但是加入了掩码功能多头自注意力机制整体架构图解析1输入单词的输入由单词 input embedding 和positional encoding 相加得到。单词输入首先进行一个词向量嵌入在做一个位置编码相加得到输入2单词 Embedding可以采用 Word2VecGlove 等算法预训练得到也可以在 Transformer 中训练得到。词向量的两种训练方式CBOW用上下文词预测中心词Skip-gram用中心词预测上下文词3位置 Embedding使用位置编码 Positional Encoding可以通过数据预训练学习得到类似于训练学习词向量。单词和位置 embedding 的维度是一样的的。计算公式如下公式和字母含义要记住其中pos 是位置索引时间步长i 是维度索引d 是词向量维度。为什么要做 positional encodingtransformer的核心机制是self-attention它是不区分词中字的顺序若不加位置编码那么“我爱你”“你爱我”计算的是两个字之间的attention score。1在位置编码矩阵中维度 2i 存储正弦函数值存储余弦函数值这种交替存储方式使得位置编码可以同时捕捉到不同频率的周期信息2是缩放因子确保不同维度的频率不同使得位置编码可以捕捉多维度的位置信息3正弦和余弦函数具有周期性使得位置编码可以捕捉到单词的相对距离具有相位特性两者是相差90度的互补函数组合在一起可以更全面的描述位置信息。了解哪些位置编码的方式4Encoder Block通过上面的单词 embedding 和位置编码相加得到了词向量矩阵传入encoder中。由两层结构组成①多头自注意力层残差连接、层归一化②前馈神经网络层残差连接、层归一化。5Self-Attention上面我们得到了输入矩阵 X通过与线性变换矩阵 WqWkWv 相乘得到 QKV 矩阵。attention 计算公式如下默写公式1计算矩阵 Q 和 K 每一行向量的内积为了防止内积过大除 dk 的平方根。Q 乘以 K 的转置后得到的矩阵行和列都是 nn 为句子单词数这个矩阵可以表示单词之间的 attention 强度。也就是注意力分数 attention score。2得到QKT后使用softmax计算每一个单词对于其他单词的 attention 系数对矩阵每一行进行 softmax 处理即每一行的和都变为 1。3然后与 V 相乘比如单词 1 的输出 Z1 等于所有单词 i 的值 Vi 根据 attention 系数的比例加在一起得到。5Multi-Head Attention多头自注意力矩阵是由多个 self-attention 组成的每个 self-attention 的输出矩阵Multi-Head Attention 将他们拼接在一起concat然后传入一个 linear 层得到最终的输出矩阵 Z 这个输出矩阵 Z 和输入矩阵 X 的维度是一样的。6Add NormAddX multi-head attentionx是一种残差连接残差连接核心思想跳过连接将输入直接加到输出。为什么要做残差连接①有助于解决深层网络带来的梯度消失问题。因为在反向传播过程中梯度可以通过捷径直接传到浅层无序经过链式法则容易导致梯度消失从而缓解梯度消失或梯度不爆炸的风险。②残差连接还有助于特征重用增强浅层特征在网络较深层的重要性从而提升模型的学习能力和泛化能力。Normlayer normalization层归一化通常用于 RNN 结构会将每一层神经元的输入转化为均值为 0 方差为 1加快收敛。用的是什么归一化层归一化 layer normalization为什么使用层归一化而不使用批次归一化7Feed forward 前馈神经网络两层的全连接层第一层激活函数是 Relu第二层不使用激活函数。max(0,XW1b1)W2 b2这里输出矩阵的维度与输入矩阵一致。8组成 Encoder通过上面的 Multi-Head Attention AddNormFeed Forward AddNorm 就可以构造一个 encoder block多个 encoder block 叠加就可以组成 Encoder。第一个 encoder block 的输入是词向量矩阵后续的 encoder block 的输入是前一个 block 的输出最后一个 block 输出的矩阵就是编码信息矩阵 C这个矩阵后续会用到 decoder 中。9Decoder与 Encoder 相似区别在①两个 multi-head attention 层②第一个用了 masked 操作③第二个的 KV 矩阵使用的是 encoder 的编码信息矩阵进行计算而 Q 使用上一个 decoder block 的输出计算④最后有一个线性层和 softmax 层计算下一个词的概率9.1 第一个 multi-head attention1.decoder block 的第一个多头注意力层采用了 masked 操作是为了防止第 i 个单词知道 i1 个单词之后的信息。2.decoder 可以在训练过程中使用 teacher forcing 并且并行化训练即将正确的单词序列和对应输出传递到 encoder那么在预测第 i 个词的时候就要将 i1 之后的单词掩盖住。3.mask 操作是在 self-attention 和 softmax 之前使用的。第一步是 decoder 的输入矩阵和 mask 矩阵。假设输入矩阵包含五个单词的表示向量那么 mask 矩阵就是一个 5*5 的矩阵。单词 0 只能使用单词 0 的信息而单词 1 可以使用 0 和 1 的信息即每个单词只能使用之前的信息。补充这一步的 mask 叫做 sequence mask - 防止未来信息泄露产生一个上三角矩阵上三角的值全为 1下三角的值全为 0对角线也是 0。第二步通过输入矩阵 X 计算得到 QKV 矩阵计算 Q 和KT的点积。第三步得到 Q 和 KT的点积使用 mask 矩阵遮挡得到 mask 后的QKT。然后进行 softmax 操作计算 attention score每一行的和都为1第四步使用 mask QKT与矩阵 V 相乘得到输出 Z例如单词 1 的输出向量 Z1 是只包含单词 1 的信息的第五步通过以上步骤就可以得到 mask self-attention 的输出矩阵 Zi然后通过 multi-head attention 拼接多个输出 Zi计算得到第一个 multi-head attention层的输出 ZZ与输出 X 的维度一致。9.2 第二个 multi-head attention根据encoder 的编码信息矩阵 C 计算得到 K、V根据上一个 decoder block 的输出 Z 计算 Q这样做的目的是在 decoder 的时候每一个单词都可以利用 encoder 的所有单词信息这些信息无需 maskLinear特征组合线性层接收来自解码器最后一层的输出这个输出是一个高维向量包含了关于输入序列的丰富信息。权重矩阵线性层内部有一组可学习的权重它会乘以输入向量并加上一个偏置项。这就像你在计算每个特征的重要性然后给它们打分。简化输出通过这种方式线性层可以将高维向量压缩成一个较低维度的向量通常与目标词汇表大小相同。这样每个位置上的值就代表了对应词汇的可能性得分。9.3 softmax 预测输出单词decoder block 最后的部分是利用 softmax 预测下一个单词在之前的网络层我们可以得到一个最终的输出 Z因为 mask 的存在使得单词 0 的输出 Z0只包含单词 0 的信息softmax 根据输出矩阵的每一行预测下一个单词。概率转换softmax函数接收线性层输出的原始得分logits并将其转换为概率值。这使得我们可以明确知道每个词汇被选中的可能性。指数化首先Softmax 会对每个得分进行指数化处理确保所有的值都是正数并方法差距较大的得分之间的差异。归一化然后它会将所有指数化的得分相加得到一个总和。最后每个指数化的得分除以这个总和得到的概率值就会落在 0 到 1 之间并且所有概率加起来等于 1。Transformer具体提问1.attention 计算公式为什么要除以根号dkQKT点积随着维度增加会过大即向量元素之间差距变大经过 softmax 处理容易出现某个值接近 1其他接近 0从而导致梯度消失除以根号 dk 是为了让 QK 点积后的结果归一化成均值为 0方差为 1 的向量数据标准化处理避免梯度消失。2.自注意力机制为什么使用 QKV可以只用其中两个吗在自注意计算中每个输入 token x 先经过三个不同的线性变换Qquery表示当前 token 想要“查询什么信息”KKey表示其他 token 具备什么信息VValue表示实际要传递的信息注意力计算流程计算相关性当前 token 和其他 token 的匹配程度Softmax归一化成权重乘 V用权重加权汇聚真正要传递的内容3. Transformer使用的是layer norm还是batch norm使用的是层归一化。不使用 batch norm 原因①在 NLP 任务中输入的文本是变长序列句子长短不一用 batch norm 会使得均值方差波动大拖慢模型收敛速度。②NLP 中常用小 batch但 batch norm 通常在一个 batch 里面计算均值方差对于小 batch 不稳定。③layer norm 对每个 token 单独归一化不会破坏句子位置编码也不受序列长度影响这一点batch norm 做不到。4. Transformer中layernorm是放在残差前还是残差后这两种顺序在训练稳定性和收敛速度上有何不同原始的 transformer 中layernorm 是放在残差后。后续先对输入做 layerNorm再经过子层最后直接残差相加无额外 LN。训练稳定性残差后做 layernorm会导致深层网络训练时出现梯度爆炸/消失导致训练不稳定先 LayerNorm 再做子层残差路径是恒等映射梯度可以直接回传避免深层网络梯度消失。收敛速度残差后做 layernorm 初期收敛很快因为每一层的输出经过 LN 后有标准化的分布有助于梯度平衡先做 layernorm 前期收敛较慢但是随着深层训练模型仍能学到合理的尺度这时候收敛表现更优。5. MHA多头注意力的意义多头可以捕捉输入序列的不同特征不同头可以关注不同模式增强模型的表达能力。(1) 每个头可以学习到不同子空间表示例如语义、语法、位置关系(2) 多头使模型对于噪声和初始化更加鲁棒捕捉更丰富的上下文信息。引申 MQA GQA MLAMQA 是多个Q常见8个对应一个K对应一个VGQA 是两两一组的Q对应一个K对应一个V。MLA 通过低秩KV联合压缩实现高效推理6. 位置编码是什么它的作用有哪些位置编码位置编码是 Transformer 里用来注入序列位置信息的机制。因为 Transformer 只有自注意力自注意力是对所有 token 的加权和它本身不区分顺序。①固定位置编码Sinusoidal Encoding原始 Transformer 用的方式用三角函数生成②可学习的位置嵌入Learnable Positional Embedding直接给每个位置一个可训练向量类似词向量BERT 就用这个方式但只能处理训练时看到的最大长度不能很好泛化到更长序列③相对位置编码Relative Positional Encoding不是告诉绝对位置而是告诉相对距离Transformer-XL、T5、DeBERTa 等都用这个公式里 Attention 直接加上相对位置信息④旋转位置编码RoPE, Rotary Positional EncodingGPT-NeoX、LLaMA 等常用通过对 Q、K 向量进行二维旋转让 dot-product 隐式包含位置信息好处保留相对位置信息对长序列泛化好计算高效7.Transformer中的掩码技术1Padding mask填充掩码为了把所有输入序列对齐到相同长度较短的序列就会在末尾进行填充。具体做法是将padding位置的注意力权重设置为负无穷经过 softmax 过后该位置权重就会变成0从而忽略该位置的影响。2前瞻掩码在 decoder 的第一个多头注意力层中为确保解码时模型不能访问到未来时间步的信息生成一个上三角矩阵上三角的值全部为 1下三角的值全部为 0对角线也是 0.这样避免信息泄露。8.手撕均方根归一化d hidden_dimr 可训练缩放参数不包含偏置b比 layernorm 更轻量import torch import torch.nn as nn class RMSNorm(nn.Module): def __init__(self, hidden_dim, eps1e-8): super().__init__() self.hidden_dim hidden_dim self.eps eps self.weight nn.Parameter(torch.ones(hidden_dim)) # 缩放参数 def forward(self, x): rms torch.sqrt(x.pow(2).mean(-1, keepdim True) self.eps) return (x/rms) * self.weight9.Transformer中的交叉注意力 decoder 和 encoder 是如何交互的在 decoder 的第二个多头注意力层中根据 encoder 输出的编码信息矩阵计算的到 K 和 V根据上一个 decoder block 的输出计算得到 Q这样做的目的是在解码时每一个单词都可以利用到编码的所有单词信息这些信息无需编码。10.Transformer与RNN相比有什么优势解决了哪些问题1解决了长距离依赖问题RNN 通过时间步逐步转递隐藏状态长距离依赖会因为梯度消失或爆炸而难以学习transformer通过自注意力机制self-attention直接建模任意两个位置的关系无论距离多远。2解决了并行问题RNN必须按照时间步顺序计算训练速度慢而transformer的自注意力层和全连接层完全并行计算提高训练效率。3避免信息瓶颈RNN最后一个时间步的隐藏状态需要编码整个序列的信息可能导致信息丢失而transformer通过多头注意力Multi-Head Attention和位置编码positional encoding保留所有位置的交互信息。11.手撕注意力机制# 多头注意力机制 import torch import torch.nn as nn import math class MultiHeadAttention(nn.Module): def __init__(self, hidden_dim, num_heads): super().__init__() self.hidden_dim hidden_dim self,num_heads num_heads self.d_k hidden_dim // num_heads def forward(self, x, maskNone): B, L, H x.shape q self.query(x) k self.key(x) v self.value(x) # reshape多分头 q q.view(B, L, self,num_heads, self.d_k).transpose(1, 2) # (B, h, L, d_k) k k.view(B, L, self,num_heads, self.d_k).transpose(1, 2) v v.view(B, L, self,num_heads, self.d_k).transpose(1, 2) attn_score torch.matmul(q, k.transpose(-2, -1) / math.sqrt(self.d_k) if mask is not None: attn_score attn_score.masked_fill(mask 0, float(-inf)) attn_weight torch.softmax(attn_score, dim -1) output torch.matmul(attn_weight, v) # (B, h, L, d_k) out output.transpose(1, 2).contiguous().view(B, L,H) out self.out(out) # 通过最终线性层 return out# 单头自注意力 import torch import torch.nn as nn import math class SelfAttention(nn.Module): def__init__(self, hidden_dim): super().__init__() self.hidden_dim hidden_dim self.query nn.Linear(hidden_dim, hidden_dim) self.key nn.Linear(hidden_dim, hidden_dim) self.value nn.Linear(hidden_dim, hidden_dim) def forward(self, x, mask None): B, L, H x.shape q self.query(x) k self.key(x) v self.value(x) scale math.sqrt(k.size(-1)) attn_score torch.matmul(q, k.transpose(-2, -1) / scale if mask is not None: attn_score attn_score.mask_fill(mask 0, float(-inf)) attn_weight torch.softmax(attn_score, dim -1) output torch.matmul(attn_weight, v) return output # (batch_size, seq_len, hidden_dim)Bert1.bert的输入组成WordPiece Embedding Positional Embedding Segment Embedding分词将单词划分为子词单元位置特征嵌入段落句子嵌入输入通常是两个句子拼接在一起为输入的每个token加一个段落嵌入区分是句子A还是B2.介绍一下bertBert是基于transformer的encoder部分的预训练模型通过双向的上下文信息来理解句子中的词语。本质就是在海量语料的基础上通过自监督学习为单词找到一个好的特征表示。该模型优点是可以根据具体的任务进行微调或者直接使用预训练的模型作为特征提取器。Transformer是一种序列到序列的模型通过self-attention机制并行处理整个序列这种机制使得模型可以同时考虑序列中所有的元素并学习上下文之间的关系。3.bert的两个任务masked language model next sentence prediction1.MLM通过随机掩盖句子里的token要求模型根据上下文来预测被掩盖的词。具体操作80%用mask来替换token10%用随机token替换10%保持原token不变2.NSP给定两个句子要求模型判断这两个句子是否为连续上下句具体操作语料中50%的句子选择其相应的下一句形成上下文作为正样本其余50%的句子选择非下一句作为负样本4.bert里面的cls标记是什么聚合上下文信息cls标记位置经过自注意力计算后能够融合整个输入序列各个位置的信息整合上下文语义为分类任务做准备cls标记的向量会整合整个句子的文本信息来判断该句话属于哪个分类GPT1.介绍一下GPT基于transformer的decoder部分通过自回归语言模型预训练来学习生成连贯文本的能力2.为什么现在的大模型大多数是decoder only而不是encoder only任务需求导致的。目前大模型主流是自回归生成的任务这就是decoder only在做的事情而encoder only更多的用于文本理解任务无法直接生成序列。训练效率。decoder only单一架构训练和推理更高效而encoder only需要全序列双向注意力成本比前者高。数据利用率高。decoder only通过因果语言建模预测下一个词在海量数据训练下效果十分显著而且可以用0样本或者小样本学习而encoder only通过掩码语言模型如果生成任务和预训练任务不同需要额外的微调手段。