一、引言:注意力机制的革命
在Transformer架构中,自注意力机制不仅是核心技术,更是实现并行化处理和长距离依赖建模的关键突破。与传统循环神经网络逐位置处理序列的方式不同,自注意力允许序列中的每个位置直接与其他所有位置交互,从而实现了真正的全局信息融合。本文将深入解析自注意力机制的工作原理、数学基础和实现细节。
二、自注意力机制的基本概念
1.从传统注意力到自注意力
传统注意力机制通常用于编码器-解码器架构,让解码器在生成每个词时关注编码器的不同部分。而自注意力(Self-Attention)让序列中的每个元素都能够直接关注序列中的所有其他元素,包括自身。

2.核心思想:动态权重分配
自注意力的核心思想是为序列中的每个位置计算一个权重分布,这个分布决定了在计算当前位置的表示时,应该"关注"序列中其他位置的强度。
三、缩放点积注意力详细解析
import torch
import torch.nn as nn
import math
class ScaledDotProductAttention(nn.Module):
def __init__(self, dropout=0.1):
super(ScaledDotProductAttention, self).__init__()
self.dropout = nn.Dropout(dropout)
def forward(self, query, key, value, mask=None):
"""
参数:
query: [batch_size, n_heads, seq_len_q, d_k]
key: [batch_size, n_heads, seq_len_k, d_k]
value: [batch_size, n_heads, seq_len_v, d_v]
mask: [batch_size, 1, seq_len_q, seq_len_k]
"""
# 步骤1: 计算Q和K的点积
scores = torch.matmul(query, key.transpose(-2, -1))
# 步骤2: 缩放操作
d_k = query.size(-1)
scores = scores / math.sqrt(d_k)
# 步骤3: 应用掩码(如果需要)
if mask is not None:
scores = scores.masked_fill(mask == 0, -1e9)
# 步骤4: Softmax归一化得到注意力权重
attention_weights = torch.softmax(scores, dim=-1)
attention_weights = self.dropout(attention_weights)
# 步骤5: 对Value进行加权求和
output = torch.matmul(attention_weights, value)
return output, attention_weights
1.计算过程逐步图解

让我们通过具体示例理解每一步的计算:
# 示例:计算两个词之间的注意力
def detailed_attention_example():
# 假设我们有2个词的嵌入向量,维度为4
word_embeddings = torch.tensor([
[0.1, 0.2, 0.3, 0.4], # 词1
[0.5, 0.6, 0.7, 0.8] # 词2
])
# 线性变换得到Q, K, V
W_q = torch.randn(4, 4) * 0.1
W_k = torch.randn(4, 4) * 0.1
W_v = torch.randn(4, 4) * 0.1
Q = torch.matmul(word_embeddings, W_q)
K = torch.matmul(word_embeddings, W_k)
V = torch.matmul(word_embeddings, W_v)
print("Q矩阵:", Q)
print("K矩阵:", K)
# 计算注意力分数
scores = torch.matmul(Q, K.transpose(0, 1))
print("原始分数:", scores)
# 缩放
scaled_scores = scores / math.sqrt(4)
print("缩放后分数:", scaled_scores)
# Softmax得到注意力权重
attention_weights = torch.softmax(scaled_scores, dim=-1)
print("注意力权重:", attention_weights)
# 加权求和
output = torch.matmul(attention_weights, V)
print("输出表示:", output)
return output
四、多头注意力机制
为什么需要多头注意力?
单一注意力头可能只捕捉到一种类型的依赖关系,多头注意力允许模型同时关注来自不同位置的不同类型的依赖关系。
class MultiHeadAttention(nn.Module):
def __init__(self, d_model, n_heads, dropout=0.1):
super(MultiHeadAttention, self).__init__()
assert d_model % n_heads == 0
self.d_model = d_model
self.n_heads = n_heads
self.d_k = d_model // n_heads
# 线性变换层
self.w_q = nn.Linear(d_model, d_model)
self.w_k = nn.Linear(d_model, d_model)
self.w_v = nn.Linear(d_model, d_model)
self.w_o = nn.Linear(d_model, d_model)
self.attention = ScaledDotProductAttention(dropout)
def forward(self, query, key, value, mask=None):
batch_size = query.size(0)
# 线性投影并分头
Q = self.w_q(query).view(batch_size, -1, self.n_heads, self.d_k).transpose(1, 2)
K = self.w_k(key).view(batch_size, -1, self.n_heads, self.d_k).transpose(1, 2)
V = self.w_v(value).view(batch_size, -1, self.n_heads, self.d_k).transpose(1, 2)
# 应用掩码
if mask is not None:
mask = mask.unsqueeze(1) # 为多头扩展维度
# 计算缩放点积注意力
x, attn_weights = self.attention(Q, K, V, mask=mask)
# 合并多头
x = x.transpose(1, 2).contiguous().view(
batch_size, -1, self.d_model
)
# 输出线性变换
output = self.w_o(x)
return output, attn_weights
多头注意力工作机制图解

多头注意力的优势分析
| 头类型 | 可能捕捉的模式 | 示例 |
|---|---|---|
| 语法头 | 句法依赖关系 | 动词-宾语关系、修饰关系 |
| 语义头 | 语义相似性 | 同义词、反义词关系 |
| 指代头 | 指代消解 | 代词与其指代对象 |
| 位置头 | 相对位置关系 | 相邻词、固定距离词 |
# 可视化不同注意力头的关注模式
def visualize_attention_heads(attention_weights, sequence_tokens):
"""
attention_weights: [n_heads, seq_len, seq_len]
sequence_tokens: 序列的token列表
"""
n_heads = attention_weights.shape[0]
for head_idx in range(n_heads):
head_weights = attention_weights[head_idx]
print(f"\n注意力头 {head_idx + 1}:")
# 打印注意力权重矩阵
for i, token_i in enumerate(sequence_tokens):
for j, token_j in enumerate(sequence_tokens):
weight = head_weights[i, j].item()
if weight > 0.1: # 只显示显著权重
print(f" {token_i} -> {token_j}: {weight:.3f}")
四、注意力机制的类型与变体
不同类型的注意力机制
class VariousAttentionMechanisms:
@staticmethod
def additive_attention(query, key, value, w):
"""加性注意力"""
# 使用tanh和线性变换计算分数
scores = torch.matmul(w, torch.tanh(query + key))
attention_weights = torch.softmax(scores, dim=-1)
return torch.matmul(attention_weights, value)
@staticmethod
def causal_attention(Q, K, V):
"""因果注意力(用于解码器)"""
seq_len = Q.size(-2)
# 创建下三角掩码
mask = torch.tril(torch.ones(seq_len, seq_len))
mask = mask.unsqueeze(0).unsqueeze(0) # 增加批次和头维度
scores = torch.matmul(Q, K.transpose(-2, -1)) / math.sqrt(Q.size(-1))
scores = scores.masked_fill(mask == 0, -1e9)
attention_weights = torch.softmax(scores, dim=-1)
return torch.matmul(attention_weights, V)
@staticmethod
def local_attention(Q, K, V, window_size):
"""局部注意力 - 只关注局部窗口"""
seq_len = Q.size(-2)
scores = torch.matmul(Q, K.transpose(-2, -1)) / math.sqrt(Q.size(-1))
# 创建局部窗口掩码
for i in range(seq_len):
start = max(0, i - window_size // 2)
end = min(seq_len, i + window_size // 2 + 1)
scores[:, :, i, :start] = -1e9
scores[:, :, i, end:] = -1e9
attention_weights = torch.softmax(scores, dim=-1)
return torch.matmul(attention_weights, V)
注意力机制对比表
| 注意力类型 | 计算复杂度 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|---|
| 缩放点积注意力 | O(n²) | 通用场景 | 计算简单、效果好 | 序列较长时计算量大 |
| 加性注意力 | O(n²) | 早期模型 | 表达能力强 | 参数多、计算复杂 |
| 因果注意力 | O(n²) | 语言模型 | 保证自回归性 | 只能看到历史信息 |
| 局部注意力 | O(n×w) | 长序列 | 计算效率高 | 可能丢失全局信息 |
| 稀疏注意力 | O(n√n) | 超长序列 | 平衡效率效果 | 实现复杂 |
五、注意力权重的可视化与分析
实际案例分析
让我们分析一个具体句子中的注意力模式:
def analyze_sentence_attention(sentence, model, tokenizer):
"""分析句子中的注意力模式"""
# 分词和编码
tokens = tokenizer.tokenize(sentence)
input_ids = tokenizer.encode(sentence, return_tensors='pt')
# 获取注意力权重
with torch.no_grad():
outputs = model(input_ids, output_attentions=True)
attention_weights = outputs.attentions # 所有层的注意力权重
# 可视化最后一层的注意力
last_layer_attention = attention_weights[-1] # [batch, heads, seq_len, seq_len]
print(f"句子: {sentence}")
print(f"Token化: {tokens}")
# 分析每个注意力头的模式
for head in range(last_layer_attention.size(1)):
head_weights = last_layer_attention[0, head]
print(f"\n--- 注意力头 {head + 1} ---")
# 找出最显著的注意力关系
for i in range(len(tokens)):
max_weight, max_idx = torch.max(head_weights[i], dim=0)
if max_weight > 0.3: # 只显示较强的注意力
print(f" {tokens[i]} → {tokens[max_idx]} : {max_weight:.3f}")
return attention_weights
注意力模式示例
假设分析句子:“The animal didn’t cross the street because it was too tired”
典型的注意力模式可能包括:
头1 (指代解析):
it → animal : 0.82
it → tired : 0.15
头2 (语法依赖):
cross → street : 0.76
didn't → cross : 0.68
头3 (语义关联):
animal → tired : 0.45
street → cross : 0.52
六、高效注意力机制优化
应对长序列挑战
当序列长度很大时,标准注意力的O(n²)复杂度成为瓶颈。以下是一些优化方法:
class EfficientAttention:
@staticmethod
def linear_attention(Q, K, V):
"""线性注意力 - 通过核函数近似"""
# 使用特征映射φ来线性化softmax
def phi(x):
return torch.nn.functional.elu(x) + 1
Q_mapped = phi(Q)
K_mapped = phi(K)
# 计算方式改变为线性复杂度
KV = torch.einsum('bhlk,bhlv->bhkv', K_mapped, V)
Z = 1 / (torch.einsum('bhlk,bhk->bhl', Q_mapped, K_mapped.sum(dim=2)) + 1e-6)
V = torch.einsum('bhlk,bhkv,bhl->bhlv', Q_mapped, KV, Z)
return V
@staticmethod
def sliding_window_attention(Q, K, V, window_size):
"""滑动窗口注意力"""
seq_len = Q.size(2)
output = torch.zeros_like(Q)
for i in range(seq_len):
start = max(0, i - window_size)
end = min(seq_len, i + window_size + 1)
# 只计算窗口内的注意力
Q_i = Q[:, :, i:i+1, :]
K_window = K[:, :, start:end, :]
V_window = V[:, :, start:end, :]
scores = torch.matmul(Q_i, K_window.transpose(-2, -1)) / math.sqrt(Q.size(-1))
weights = torch.softmax(scores, dim=-1)
output[:, :, i:i+1, :] = torch.matmul(weights, V_window)
return output
七、注意力机制的理论解释
信息检索的类比
可以将自注意力机制理解为一个信息检索系统:
- 查询(Query):当前词的信息需求
- 键(Key):其他词的"标签"或"索引"
- 值(Value):其他词的实际内容信息
这个过程类似于:每个词都向序列中的所有其他词发出查询,根据匹配程度(注意力权重)检索相关信息,然后汇总这些信息来更新自己的表示。
如何学习大模型 AI ?
由于新岗位的生产效率,要优于被取代岗位的生产效率,所以实际上整个社会的生产效率是提升的。
但是具体到个人,只能说是:
“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。
这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。
我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。
我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

第一阶段(10天):初阶应用
该阶段让大家对大模型 AI有一个最前沿的认识,对大模型 AI 的理解超过 95% 的人,可以在相关讨论时发表高级、不跟风、又接地气的见解,别人只会和 AI 聊天,而你能调教 AI,并能用代码将大模型和业务衔接。
- 大模型 AI 能干什么?
- 大模型是怎样获得「智能」的?
- 用好 AI 的核心心法
- 大模型应用业务架构
- 大模型应用技术架构
- 代码示例:向 GPT-3.5 灌入新知识
- 提示工程的意义和核心思想
- Prompt 典型构成
- 指令调优方法论
- 思维链和思维树
- Prompt 攻击和防范
- …
第二阶段(30天):高阶应用
该阶段我们正式进入大模型 AI 进阶实战学习,学会构造私有知识库,扩展 AI 的能力。快速开发一个完整的基于 agent 对话机器人。掌握功能最强的大模型开发框架,抓住最新的技术进展,适合 Python 和 JavaScript 程序员。
- 为什么要做 RAG
- 搭建一个简单的 ChatPDF
- 检索的基础概念
- 什么是向量表示(Embeddings)
- 向量数据库与向量检索
- 基于向量检索的 RAG
- 搭建 RAG 系统的扩展知识
- 混合检索与 RAG-Fusion 简介
- 向量模型本地部署
- …
第三阶段(30天):模型训练
恭喜你,如果学到这里,你基本可以找到一份大模型 AI相关的工作,自己也能训练 GPT 了!通过微调,训练自己的垂直大模型,能独立训练开源多模态大模型,掌握更多技术方案。
到此为止,大概2个月的时间。你已经成为了一名“AI小子”。那么你还想往下探索吗?
- 为什么要做 RAG
- 什么是模型
- 什么是模型训练
- 求解器 & 损失函数简介
- 小实验2:手写一个简单的神经网络并训练它
- 什么是训练/预训练/微调/轻量化微调
- Transformer结构简介
- 轻量化微调
- 实验数据集的构建
- …
第四阶段(20天):商业闭环
对全球大模型从性能、吞吐量、成本等方面有一定的认知,可以在云端和本地等多种环境下部署大模型,找到适合自己的项目/创业方向,做一名被 AI 武装的产品经理。
- 硬件选型
- 带你了解全球大模型
- 使用国产大模型服务
- 搭建 OpenAI 代理
- 热身:基于阿里云 PAI 部署 Stable Diffusion
- 在本地计算机运行大模型
- 大模型的私有化部署
- 基于 vLLM 部署大模型
- 案例:如何优雅地在阿里云私有部署开源大模型
- 部署一套开源 LLM 项目
- 内容安全
- 互联网信息服务算法备案
- …
学习是一个过程,只要学习就会有挑战。天道酬勤,你越努力,就会成为越优秀的自己。
如果你能在15天内完成所有的任务,那你堪称天才。然而,如果你能完成 60-70% 的内容,你就已经开始具备成为一名大模型 AI 的正确特征了。
这份完整版的大模型 AI 学习资料已经上传优快云,朋友们如果需要可以微信扫描下方优快云官方认证二维码免费领取【保证100%免费】

910

被折叠的 条评论
为什么被折叠?



