先说结构,再说里面最重要的注意力机制,需要经过前馈神经网络层( FeedForward )/残差/归一化等处理,得到输出下一个词的概率。transformer通过自注意力机制,找到语义关系。
transformer的原理:通过头部文件超参数实现encoder decoder,encoder 是转换为向量,每一轮decoder都会把encoder 的输出结果加入到某个隐藏层,decoder的输出会作为下一轮decoder的输入。
decoder中有多头注意力机制,然后经过liner softmax输出结果。
里面最重要的注意力机制:head
可以当做注意力机制的一个“量词”,一个head
就是一组QKV计算
单头注意力的计算方法: 第1步,初始化输入
>>> head_size = 16 # 人为定义的注意力维度
>>> x = torch.randn(1, 8, 16) # 单批次 (B=1), 8个token, 每个token 16维特征
>>> B, T, C = x.shape # B=1, T=8, C=16
第2步:计算 Key/Query/Value 第3步:计算注意力分数 (Q·Kᵀ) 并缩放 第4步:应用掩码 第5步:Softmax 归一化 第6步:聚合 Value
总结:公式如下
-
是查询矩阵,维度为
,n是查询数量;
-
是键矩阵,维度为
,m是键的数量;
-
是值矩阵,维度为
,m是值的数量(与键的数量相同);
-
是键和查询的维度;
-
是缩放因子,用于防止点积过大导致梯度消失;
根据得到的张量,我们可以预测“下一个token”,比如out[1]
是用token1 ~ 2
的信息计算而来,用来预测token3
。
multi-head只是对多个head的concat 操作、
引入FeedForward(FFN通过ReLU激活引入非线性,使模型能拟合更复杂的函数)、
残差神经网络:直接把输入x跨层传递到后续层,解决训练中出现的梯度消失问题。 Add指 X+MultiHeadAttention(X),是一种残差连接,通常用于解决多层网络训练的问题,可以让网络只关注当前差异的部分,在 ResNet 中经常用到.
投影(Projection):是一种将输入数据从当前向量空间映射到另一个向量空间的操作,在我们的实现中,就是简单的一个线性层。
层归一化(Layer Normalization, LayerNorm ) :就是Norm,神经网络中,层归一化(Layer Normalization, LayerNorm) 是一种用于加速训练、提升模型稳定性的重要技术,LayerNorm 对单个样本的所有特征进行归一化,使其均值为0、方差为1,再通过可学习的参数调整分布。
Dropout:是一种广泛使用的正则化技术,旨在防止神经网络过拟合。它通过随机丢掉部分神经元的结果,来迫使模型学习更鲁棒的特征表示.
为什么必须用Linear和Softmax这两层?
Linear层:从抽象特征到词语分数的映射
类比解释:
假设模型在处理句子“我想吃__”,解码器输出一个向量表示“期待食物类词语”。Linear层将这个向量与所有词语的嵌入向量做点积,计算出每个词的匹配分数(如“苹果”=9.5,“跑步”=1.2)。
- Linear的必要性:
解码器输出的向量是抽象语义,需转换为具体词语的匹配度。 直接输出词嵌入空间的点积效率更高(比计算5万次相似度快)。
- Softmax的必要性:
模型需要概率形式的输出来支持交叉熵损失计算(如预测“苹果”概率90% vs 标签100%,计算损失)。 概率化后的结果可直接用于贪婪解码(选最高概率)或采样(按概率随机选)。
“Linear层把模型的抽象思考转成词语分数,Softmax层将分数变为概率,二者共同决定了Transformer最终说出的词。”
Softmax层:从分数到概率的终极转换
核心作用: 将Linear层输出的分数转换为概率分布,使所有词语的概率和为1,并放大高分值的优势。
指数运算:将分数差异放大(例如 9.5→exp(9.5)=13,360
,1.2→exp(1.2)=3.32
)。
归一化:计算每个词的概率占比(如“苹果”概率为13,360/(13,360+3.32+...其他词)≈99%)。
超参数
比如
-batch_size = 32 # 每个批次的大小
-block_size = 8 # 每个序列的最大长度
-learning_rate = 1e-2 # 学习率
-n_embed = 32 # 嵌入层的维度
-n_head = 4 # 多头注意力的头数
-n_layer = 3# block的数量
+batch_size = 64 # 每个批次的大小
+block_size = 256 # 每个序列的最大长度
+learning_rate = 3e-4 # 学习率
+n_embed = 384 # 嵌入层的维度
+n_head = 6 # 多头注意力的头数
+n_layer = 6# block的数量
调整参数,可以确定多大的模型,比如: 调整前,是一个3层、4头、32维度,参数量为437,764的“K级超小模型”。
调整后,是一个6层、6头、384维度,参数量为15,466,756的“15M模型”,至少也能用B做单位了,是一个“0.0155B”的模型