Transformer架构详解:Self-Attention机制与位置编码原理是什么

来源:PHP教程作者:阿里山老登头衔:草根站长
导读:本期聚焦于阿里山老登创作的《Transformer架构详解:Self-Attention机制与位置编码原理是什么》,敬请观看详情。Transformer为什么能彻底改变自然语言处理乃至整个深度学习领域?核心答案藏在Self-Attention机制和位置编码这两个关键设计里。本文从整体架构入手,拆解编码器与解码器的组成模块,用逐步计算的方式讲清楚Query、Key、Value三个矩阵如何协同工作,推导缩放点积注意力公式中除以根号dk的真正原因,并分析多头注意力带来的多视角表达能力。随后解释模型为什么必须依赖位置编码,详解正弦位置编码的数学形式与相对位置特性,同时介绍可学习位置编码、旋转位置编码RoPE等主流改进方案,帮助你建立对Transformer完整而深入的理解。

自2017年Google提出以来,Transformer已经成为几乎所有大模型的底层骨架。它完全抛弃了RNN的循环结构,仅靠注意力机制就能捕捉序列中任意两个位置之间的依赖关系,训练时还可以完全并行化。要真正理解GPT、BERT这类模型的能力来源,就必须弄懂两个核心组件:Self-Attention(自注意力)机制和位置编码(Positional Encoding)。本文将结合公式和代码,把这两部分的设计原理讲透。

Transformer架构详解:Self-Attention机制与位置编码原理是什么

一、Transformer整体架构拆解

Transformer由编码器和解码器两大部分组成。原始论文中编码器有6层,每层包含两个子模块:多头自注意力(Multi-Head Self-Attention)和前馈神经网络(Feed-Forward Network)。解码器同样有6层,但比编码器多了一个编码器-解码器注意力模块,用于让解码器在生成每个词时能够关注输入序列的信息。

每个子模块外面都套了一个残差连接和层归一化,也就是所谓的Add & Norm结构。残差连接保证了梯度能够顺畅回传,层归一化则稳定了训练过程。前馈网络本身是两层全连接,中间夹一个激活函数,对每个位置的表示独立地进行非线性变换,可以理解为对注意力聚合后的信息做一次深加工。

整个模型的计算流程是:输入的词先经过embedding层映射成向量,然后叠加位置编码,再依次流过编码器的各层。解码器采用自回归方式生成输出,训练时通过掩码机制保证每个位置只能看到它之前的内容,防止信息泄露。

二、Self-Attention机制的原理与计算过程

Self-Attention的核心思想是:序列中的每个位置都直接和所有位置计算关联度,然后按关联度加权聚合信息。具体做法是把输入向量分别乘以三个可学习的投影矩阵W_Q、W_K、W_V,得到Query(查询)、Key(键)、Value(值)三个矩阵。可以把这个过程类比成一次检索:Query是你要查的问题,Key是每条记录的索引,Value是记录的实际内容。

注意力分数的计算公式为Attention(Q, K, V) = softmax(QK^T / √d_k)V。先用Q和K做点积得到相似度矩阵,接着除以√d_k进行缩放,再通过softmax归一化成权重,最后对V加权求和。为什么要除以√d_k?因为当向量维度较高时,点积的结果方差会随着维度线性增大,数值过大会导致softmax进入饱和区,梯度几乎为零。除以√d_k可以把方差拉回到1附近,让训练更稳定,这是一个非常实用的小技巧。

import torch
import torch.nn.functional as F

def self_attention(x, Wq, Wk, Wv):
    # x: (seq_len, d_model)
    Q = x @ Wq  # 查询矩阵
    K = x @ Wk  # 键矩阵
    V = x @ Wv  # 值矩阵
    d_k = Q.size(-1)
    # 缩放点积注意力,除以 sqrt(d_k) 防止softmax饱和
    scores = Q @ K.transpose(-2, -1) / (d_k ** 0.5)
    attn_weights = F.softmax(scores, dim=-1)
    return attn_weights @ V, attn_weights

多头注意力则把d_model维的空间切分成h个子空间,每个头在自己的低维空间里独立计算注意力,最后拼接起来再做一次线性投影。这样做的好处是不同的头可以关注不同类型的关系:有的头捕捉语法依赖,有的头关注远距离的语义关联,相当于从多个视角同时理解序列。

三、位置编码:为什么需要以及有哪些方案

注意力机制本身是置换不变的,也就是说把输入序列打乱顺序,输出的每个位置结果也只是跟着换位置,模型感知不到先后关系。但语言显然是有序的,"猫追狗"和"狗追猫"意思完全不同,所以必须把位置信息注入到输入表示中,这就是位置编码的由来。

原始Transformer采用的是正弦位置编码,公式为PE(pos, 2i) = sin(pos / 10000^(2i/d_model)),PE(pos, 2i+1) = cos(pos / 10000^(2i/d_model))。不同维度对应不同频率的正弦波,低维变化快,高维变化慢,有点像二进制计数器。这种编码有个优雅的性质:任意固定偏移量k,PE(pos+k)都可以表示为PE(pos)的线性变换,这意味着模型能轻松学到相对位置关系,而且不受训练序列长度的限制,可以外推到更长的序列。

后来出现的改进方案各有利弊。BERT使用可学习的位置编码,直接把位置embedding当作可训练参数,简单灵活但无法外推到训练时没见过的长度。目前大模型里最主流的是旋转位置编码RoPE,它通过复数旋转的方式把相对位置信息融入Q和K向量,在长文本场景下表现优异,Llama、Qwen等模型都在使用。此外还有ALiBi这种直接在注意力分数上按距离加线性惩罚的方案,实现极其简单,外推能力也不错。

import numpy as np

def sinusoidal_position_encoding(seq_len, d_model):
    pe = np.zeros((seq_len, d_model))
    position = np.arange(seq_len)[:, np.newaxis]
    div_term = np.exp(np.arange(0, d_model, 2) * -(np.log(10000.0) / d_model))
    pe[:, 0::2] = np.sin(position * div_term)  # 偶数维用sin
    pe[:, 1::2] = np.cos(position * div_term)  # 奇数维用cos
    return pe

四、动手实现一个简化版Transformer

理解原理之后,动手写一遍代码是最好的巩固方式。PyTorch已经内置了nn.MultiheadAttention模块,但自己实现一遍缩放点积注意力能加深对细节的理解,比如掩码的处理、缩放因子的位置等。

import torch
import torch.nn as nn

class MultiHeadAttention(nn.Module):
    def __init__(self, d_model, num_heads):
        super().__init__()
        assert d_model % num_heads == 0
        self.d_k = d_model // num_heads
        self.num_heads = num_heads
        self.Wq = nn.Linear(d_model, d_model)
        self.Wk = nn.Linear(d_model, d_model)
        self.Wv = nn.Linear(d_model, d_model)
        self.out = nn.Linear(d_model, d_model)

    def forward(self, x, mask=None):
        batch, seq_len, d_model = x.shape
        # 拆分成多头: (batch, num_heads, seq_len, d_k)
        Q = self.Wq(x).view(batch, seq_len, self.num_heads, self.d_k).transpose(1, 2)
        K = self.Wk(x).view(batch, seq_len, self.num_heads, self.d_k).transpose(1, 2)
        V = self.Wv(x).view(batch, seq_len, self.num_heads, self.d_k).transpose(1, 2)
        scores = Q @ K.transpose(-2, -1) / (self.d_k ** 0.5)
        if mask is not None:
            scores = scores.masked_fill(mask == 0, float("-inf"))
        attn = torch.softmax(scores, dim=-1)
        output = attn @ V
        output = output.transpose(1, 2).reshape(batch, seq_len, d_model)
        return self.out(output)

上面的代码中,掩码部分值得注意:解码器的因果掩码是一个下三角矩阵,把上三角(未来位置)填充为负无穷,softmax之后这些位置的权重就变成0,从而保证自回归生成的正确性。这也是GPT类模型训练时最关键的细节之一。

五、总结

Transformer的成功并非某个单点突破,而是一系列精心设计的组合:Self-Attention提供全局建模能力,缩放点积保证数值稳定,多头机制带来多视角表达,位置编码补上了顺序信息,残差连接和层归一化让深层堆叠成为可能。理解了这些组件,再去阅读GPT的 decoder-only结构、BERT的双向编码设计,以及各种注意力优化方案(如Flash Attention、稀疏注意力)就会顺畅很多。建议读者对照公式亲手推导一遍注意力计算,并跑通自己实现的代码,这是从知道到掌握最短的路径。

Transformer架构Self-Attention位置编码修改时间:2026-09-13 14:54:47

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/20260913/56073.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。