• 【CNN】:卷积依靠卷积网络的深度来捕捉长距离依赖,太多层卷积的堆叠则有可能导致信息的丢失

  • 【RNN】:Y=f(wX+b),加入隐状态H(H可以①提取特征②转换为输出),则
         编码:H1=f(uH0+wX1+b),H2=f(uH1+wX2+b),……。
         解码:Y1=softmax(vH1+c)。
         符合类似结构的都可以称为encoder-decoder模型。
         【RNN局限】:若句子较长,RNN不断用前一个状态计算后一个状态,会导致【RNN只有短期记忆,会忘记长序列中前面的内容】。

  • 【LSTM(Long Short Term Memory,长短期记忆)】:设有 遗忘门、输入门、输出门,用于决定 记住谁、忘记谁,初步具备【注意力】

  • 【GRU(gate recurrent unit门控循环单元)】:LSTM的优化,遗忘门+输入门=>更新门

  • 【Encoder-Decoder模式】:上述RNN\LSTM\GRU都可以称为Encoder-Decoder模型,都符合先编码(压缩特征)、后解码(转换为输出)的pattern
         【Encoder-Decoder局限】:只用一个【向量c】来传递信息,且长度固定。

  • 【Attention】:
         h_j:【上下文句子context】中第j个单词的语义编码,【文章-上下文句子context】编码器状态 H:(h1,h2,h3,…,hn)
         x_i:【问题】中第i个单词的语义编码【提出问题的句子】解码器状态 X:(x1,x2,x3,…,xn)
         Q_i:Q_i = W_q * x_i
         K_j:K_j = W_k * h_j
         V_j:V_j = W_v * h_j(与k同源)
         f(q,k):f(q,k)=W3* tanh(Wq* x_i + Wk* h_j )= Q_i^T K_j / √d_k=f(Q_i,K_j) ,通过除以√d_k,将方差重新缩放回1,防止softmax梯度消失
         a_ij:a_ij = softmax(f(x_i, h_j))=softmax( f(Q_i,K_j) ),【输出】第i个单词时,【上下文句子context】中第j个单词的【注意力权重】
         c_i: c_i = a_i1 * h1 + a_i2 * h2 + a_i3 * h3 + … = Σa_ij*h_j (j∈[1, 上下文句子context的长度])=softmax( f(Q_i,K_j) )*V_j,【输出/解码】第i个单词时所需的【编码向量c_i】
         Attention(Q,K,V) = Σc_i = softmax(QK^T/√d_k)V
    ①不再是【一个向量c(enc->[c]->dec)】,而是用【若干个向量c_i(enc->[c1,c2,c3,…,cn]->dec)】传递信息
    ②最重要的是c_i【加权求和】的过程
    ③生成句子的过程:y1=f1(c1),y2=f1(c2,y1),y3=f1(c3,y1,y2)

  • 【自注意力机制Self-Attention】:
         Self-Attention与Attention的区别:QKV都是相同的序列。
              输入序列: X = {x_1,…,x_n},
              Q_i = W_q * x_i
              K_i = W_k * x_i
              V_i = W_v * x_i
              ```其余推导与上述【Attention】相同
    在 Encoder 的输出中,每个 token 的表示是 【自身与其它所有 token 表示的加权和】,权重由自注意力机制计算得出,类似一种【对自己的全连接】。
    捕捉token之间的长距离依赖关系,一次多义调整表示,生成更高质量的上下文表示。

  • 【Self-Attention 计算实例】:
    假设输入序列为:[“The”, “cat”, “ate”, “the”, “fish”]。
    每个 token 的初始表示(词嵌入 + 位置编码):
    “The”:[0.1, 0.2, 0.3]
    “cat”:[0.4, 0.5, 0.6]
    “ate”:[0.7, 0.8, 0.9]
    “the”:[1.0, 1.1, 1.2]
    “fish”:[1.3, 1.4, 1.5]
    “cat” 的表示是 “The”、“cat”、“ate”、“the”、“fish” 的加权和,权重分别为 [0.1, 0.6, 0.2, 0.05, 0.05]。权重越高越相关。
    “ate” 的表示是 “The”、“cat”、“ate”、“the”、“fish” 的加权和,权重分别为 [0.05, 0.2, 0.5, 0.1, 0.15]。
    “cat” 的输出表示:0.1⋅[0.1,0.2,0.3]+0.6⋅[0.4,0.5,0.6]+0.2⋅[0.7,0.8,0.9]+0.05⋅[1.0,1.1,1.2]+0.05⋅[1.3,1.4,1.5],计算结果为 [0.45, 0.55, 0.65]。
    “ate” 的输出表示:0.05⋅[0.1,0.2,0.3]+0.2⋅[0.4,0.5,0.6]+0.5⋅[0.7,0.8,0.9]+0.1⋅[1.0,1.1,1.2]+0.15⋅[1.3,1.4,1.5],计算结果为 [0.75, 0.85, 0.95]。
    “cat” 的输出表示 [0.45, 0.55, 0.65] 不仅包含自身的语义信息 [0.4, 0.5, 0.6],还包含了与 “ate” 和 “fish” 的关系信息。
    “ate” 的输出表示 [0.75, 0.85, 0.95] 不仅包含自身的语义信息 [0.7, 0.8, 0.9],还包含了与 “cat” 和 “fish” 的关系信息。

  • 【Transformer-GPT-BERT 进化关系】
    Transformer(2017):
         首次提出【自注意力机制】+【多头注意力机制】,
         并提供了【编码器】(理解输入序列)和【解码器】(生成输出序列)架构,
         主要用于 seq2seq的机器翻译。
    GPT(2018):
         继承了Transformer的基础架构,但是只使用【解码器】,
         引入了【预训练+微调】的训练范式,预训练任务是自回归地【生成下一个词】,单向建模(单向生成),
         主要用于 文本生成、对话系统 等【生成任务】。
    BERT(2018):
         继承了Transformer的基础架构,但是只使用【编码器】,
         继承了GPT的【预训练+微调】的训练范式,预训练任务是【mask掉一个词+判断两句话是否是上下文】,双向建模(注意到了前后所有单词),
         主要用于 语义理解、问答、文本分类等【理解任务】。

  • 【encoder与decoder】
         encoder:没有掩码(Mask),可以同时看到整个输入序列。
             输出:编码后的上下文表示(Contextualized Representations)。
         decoder:使用掩码,防止模型看到未来的信息(自回归生成)。
             输出:目标序列的下一个词的概率分布。

  • 【mask】
         BERT 预训练时的 mask:掩码机制(MLM)是 预训练任务的一部分,用于让模型学会预测被掩码的词。
         encoder的 mask:不使用掩码,编码时可以同时看到整个输入序列,做到双向建模。
         decoder的 mask:使用掩码,看不到下文,解码时只能根据当前内容完成 单向的 自回归生成。

  • 【模型部件】
         embedding:处理输入序列的语义、位置、分段信息。
         自注意力机制:捕捉序列内部的依赖关系,动态分配权重。
         多头注意力机制:扩展自注意力机制,捕捉不同子空间的信息。类似卷积核。
         前馈神经网络:对每个位置的表示进行非线性变换,增强表达能力。

  • 【embedding阶段】
         ①都有【词向量嵌入】,从离散的token映射为向量,拥有训练好的【词向量矩阵W_token】
         ②都有【位置编码】,transformer使用固定的正弦余弦函数计算位置编码,gpt、bert有自己可学习的【位置向量矩阵W_pos】
         ③仅bert有【分段嵌入segment】,用于区分不同的句子段落(如 问题-答案),有自己的【分段嵌入矩阵W_seg】
         关于token本身,transformer无特殊token,gpt有[SOS][EOS],bert有[CLS][SEP]
    transformer、gpt、bert的【输入形状】都是(batch_size, seq_len),如(1,512),
             【输出阶段形状】都是(batch_size, seq_len, 词嵌入维度),如(1, 512, 1024),
             该信息即将进入encoder,包含着【词嵌入信息+位置信息(+分段嵌入信息)】。
    ps:最后的embedding结果由【语义、位置、分段】三种信息相加得到,它们无法直接分离每个部分的贡献。

  • 【多头注意力机制】:
         目的:为了【在不同子空间内 学习到更丰富的特模式】,做到并行化学习。
         实现:计算时,Q/K/V从(batch_size, seq_len, d_model=1024)被重塑为(batch_size, h=8, seq_len, d_k=128),每个头独立计算注意力分数, 计算后的所有8个头的输出再拼接在一起,拼回(batch_size, seq_len, d_model),再通过W_o投影融合,强制不同头的特征交互,避免子空间孤立。
         头数与并行与硬件:头数通常选为2的幂次(如8、16)的硬件友好向,便于GPU并行计算时的内存对齐和线程调度,
    同时 头数需满足d_model % h = 0,且d_k≥64(经验阈值)
         训推头数不一致:训练(【8】x128)与推理(【16】x64)时分出来的头数不一样时,存在需要微调的可能性。

  • 【前馈神经网络FFN】
    标准ffn:mma+激活函数relu+mma(+dropout)+ 残差 + layernrom,FFN(x)=ReLU(xW 1 +b 1 )W 2 +b 2
    ​bert的ffn:layernorm+mma+激活函数gelu+mma(+dropout)+ 残差 + layernrom,①开头多了个laynernorm②使用gelu而不是relu
    为什么是layernorm不是bn:
         layernorm在channelC维度做归一化,bn在batch维度做归一化;
         ①文本是变长序列,bn不好处理
         ②layernorm在channelC特征维度做归一化更适合文本数据的特性
         ③layernorn在训练与推理时行为一致不受batch size影响
    为什么是gelu不是relu:
         ①relu在x=0处不可导,训练效果不好
         ②gelu公式是【x*高斯正态分布(x)】,平滑可导适合深度训练,且可以看作是对输入的概率加权,适合处理文本中的概率分布

  • 【Bert large模型结构】
    1 BertModel(
    2 (embeddings): BertEmbeddings(
    3   (word_embeddings): Embedding(30522, 1024, padding_idx=0)
    4   (position_embeddings): Embedding(512, 1024)
    5   (token_type_embeddings): Embedding(2, 1024)
    6   (LayerNorm): LayerNorm((1024,), eps=1e-12, elementwise_affine=True)
    7   (dropout): Dropout(p=0.1, inplace=False)
    8 )
    9 (encoder): BertEncoder(
    10   (layer): ModuleList(
    11    (0-23): 24 x BertLayer(
    12     (attention): BertAttention(
    13      (self): BertSdpaSelfAttention(
    14       (query): Linear(in_features=1024, out_features=1024, bias=True)
    15       (key): Linear(in_features=1024, out_features=1024, bias=True)
    16       (value): Linear(in_features=1024, out_features=1024, bias=True)
    17       (dropout): Dropout(p=0.1, inplace=False)
    18      )
    19      (output): BertSelfOutput(
    20       (dense): Linear(in_features=1024, out_features=1024, bias=True)
    21       (LayerNorm): LayerNorm((1024,), eps=1e-12, elementwise_affine=True)
    22       (dropout): Dropout(p=0.1, inplace=False)
    23      )
    24     )
    25     (intermediate): BertIntermediate(
    26      (dense): Linear(in_features=1024, out_features=4096, bias=True)
    27      (intermediate_act_fn): GELUActivation()
    28     )
    29     (output): BertOutput(
    30       (dense): Linear(in_features=4096, out_features=1024, bias=True)
    31        (LayerNorm): LayerNorm((1024,), eps=1e-12, elementwise_affine=True)
    32        (dropout): Dropout(p=0.1, inplace=False)
    33       )
    34     )
    35    )
    36   )
    37   (pooler): BertPooler(
    38    (dense): Linear(in_features=1024, out_features=1024, bias=True)
    39    (activation): Tanh()
    40   )
    41 )

  • 【Bert Large shape计算流描述】
    【embeddding阶段】——设置bert large词向量长度【d】是1024,token长度【n】是512
        输入:三份【1, 512】的token、mask、seg信息,
        经过三份对应的权重W_token[30522, 1024],W_mask[512, 1024],W_seg[2, 1024](只有0与1)的gather算子,
        最后经过一个layernrom算子,输出:【1, 512, 1024】
    【encoder阶段】
        【attention】
          【Wq、Wk、Wv[1024, 1024]】
          【X_emb * Wq = Q[1, 512, 1024],X_emb * Wk = K[1, 512, 1024],X_emb * Wv = V[1, 512, 1024]】
          其中自然意义是8个head,每个head 128维; 因芯片有16个spc,实际上是16x64地去计算。
          【Q1[512, 64] * K1^T[64, 512] = Q1K1[512, 512],
            softmax( Q1K1)[512, 512]*V1[512, 64]=multihead1[512, 64]】
          【multihead1】~【multihead16】 concat在一起,得到【Attention[512, 64x16]=Attention[512, 1024]】
        【ffn】
           Attention【512, 1024】->【layernorm1024, 1024】
               ->[512, 1024]->【gelu1024, 4096】
               ->[512, 4096]->【layernorm4096, 1024】
               ->encoder_out【512, 1024】
    Nx【encoder阶段】
        bert large是24个encoder头尾链接(输入输出都是[512, 1024]),bert base是12个(bert large词向量长度是768)
    【任务阶段】
        第24个encoder结束后,可以连接不同的后处理算子,达到做不同任务的目的,
        如 问答任务、命名实体识别任务、情绪判定任务等。

更多推荐