尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
**PyTorch 极简实现 Self‑Attention 可运行代码(带注释版)
下面给出缩放点积自注意力Scaled Dot‑Product Self‑Attention极简 PyTorch 实现全部代码可直接运行注释详细不含多头先实现基础版之后附带多头注意力。import torch import torch.nn as nn import torch.nn.functional as F class ScaledDotProductSelfAttention(nn.Module): def __init__(self, embed_dim): super().__init__() self.d_k embed_dim # Q,K向量维度 # 可训练权重矩阵 Wq, Wk, Wv self.W_q nn.Linear(embed_dim, embed_dim) self.W_k nn.Linear(embed_dim, embed_dim) self.W_v nn.Linear(embed_dim, embed_dim) def forward(self, x, maskNone): :param x: input, shape [batch_size, seq_len, embed_dim] :param mask: 掩码矩阵 [batch_size, seq_len, seq_len] GPT解码器用上三角maskBERT默认None :return out: [batch_size, seq_len, embed_dim] attn_weight: 注意力权重 [batch, seq_len, seq_len] batch, seq_len, _ x.shape # Step1生成 Q, K, V Q self.W_q(x) # (B, L, D) K self.W_k(x) V self.W_v(x) # Step2: Q K^T / sqrt(d_k) attn_score torch.matmul(Q, K.transpose(-2, -1)) / torch.sqrt(torch.tensor(self.d_k, dtypetorch.float32)) # 如果传入mask将mask为0的位置设置为‑infsoftmax之后权重趋近0 if mask is not None: attn_score attn_score.masked_fill(mask 0, -1e9) # Step3 softmax得到注意力权重 attn_weight F.softmax(attn_score, dim-1) # Step4 加权value得到输出 out torch.matmul(attn_weight, V) return out, attn_weight if __name__ __main__: # 超参设置 batch_size 2 seq_len 4 # 句子4个token embed_dim 64 # 词嵌入维度 # 随机模拟输入向量等价4个单词的embedding x torch.randn(batch_size, seq_len, embed_dim) # 实例化自注意力模块 self_attn ScaledDotProductSelfAttention(embed_dim) output, attn_weights self_attn(x) print(输出shape, output.shape) # torch.Size([2,4,64]) print(注意力权重shape, attn_weights.shape) # torch.Size([2,4,4])2. 拓展多头注意力 Multi‑Head‑AttentionPyTorch 实现class MultiHeadSelfAttention(nn.Module): def __init__(self, embed_dim, num_heads): super().__init__() assert embed_dim % num_heads 0, 嵌入维度必须可以被头数整除 self.d_model embed_dim self.num_heads num_heads self.d_k embed_dim // num_heads self.Wq nn.Linear(embed_dim, embed_dim) self.Wk nn.Linear(embed_dim, embed_dim) self.Wv nn.Linear(embed_dim, embed_dim) self.W_o nn.Linear(embed_dim, embed_dim) def forward(self, x, maskNone): B, L, _ x.shape Q self.Wq(x) K self.Wk(x) V self.Wv(x) # 将维度拆分多头: (B, heads, seq_len, d_k) Q Q.view(B, L, self.num_heads, self.d_k).permute(0,2,1,3) K K.view(B, L, self.num_heads, self.d_k).permute(0,2,1,3) V V.view(B, L, self.num_heads, self.d_k).permute(0,2,1,3) # 缩放点积注意力 attn_score torch.matmul(Q, K.transpose(-2,-1)) / torch.sqrt(torch.tensor(self.d_k, dtypetorch.float32)) if mask is not None: attn_score attn_score.masked_fill(mask 0, -1e9) attn_weight F.softmax(attn_score, dim-1) out torch.matmul(attn_weight, V) # 拼接多头结果 out out.permute(0,2,1,3).contiguous().view(B, L, self.d_model) out self.W_o(out) return out, attn_weight if __name__ __main__: batch 2 seq_len 4 embed_dim 64 heads 8 x torch.randn(batch, seq_len, embed_dim) mh_attn MultiHeadSelfAttention(embed_dim, heads) out, attn mh_attn(x) print(多头注意力输出shape, out.shape)3. 关键点总结Self‑Attention 条件Q、K、V 全部来自输入xCross‑Attention 则 Q 来自 decoder、K‑V 来自 encoderO(n2)复杂度序列长度变长比如几千 token计算量急剧变大该代码没有加入位置编码如果你要做 GPT/BERT 完整版本需要额外加入Positional Encoding。如果你需要我可以给你写带位置编码 残差 LayerNorm完整 Transformer Encoder 单层代码。Q 拿着问题挨个匹配 K匹配分数决定取用 V 的多少通俗拆解Q‑K‑V 逻辑结合数学过程讲明白1. 角色类比Q(Query)提问者每一个 token 带着自己的特征向量提出问题我应该重点关注序列里哪些单词K(Key)候选人的自我介绍序列中每个 token 拿出自身特征用来接受匹配V(Value)候选人真正携带的内容信息。K 只用来打分最终提取内容取自 V。举句子例子He ate appletokenate生成自己的 Q 向量剩下三个 tokenHe、ate、apple各自拿出 KQ 和每个 K 做内积计算相似度Q (ate) 和 K (apple) 内积数值很高Q (ate) 和 K (He) 内积偏低 得到原始分数[scoreHe​, scoreate​, scoreapple​]。2. 缩放 Softmax把分数变成权重除以dk​​缩放防止数值爆炸softmax 归一化所有权重取值 0‑1总和为 1weightssoftmax(dk​​QK⊤​) 这时 w1​(He)≈0.1w2​(ate)≈0.2w3​(apple)≈0.7。 含义ate这个单词 70% 的信息来自 apple10% 来自 He。3. 加权 V 获取输出outputate​w1​⋅VHe​w2​⋅Vate​w3​⋅Vapple​权重越高对应 V 的信息放进来越多权重很低的 V 几乎被忽略。一句话概括你的原话Q 拿着自身特征挨个比对全部 K算出相关性得分softmax 将得分转为权重用权重分配 V 里信息占比这就是自注意力的核心。4. 区分 Self‑Attention 和 Cross‑AttentionSelf‑Attention自注意力Q,K,V全部来自同一组输入句子。句子内部词语互相匹配。Cross‑Attention交叉注意力翻译场景Q 来自 Decoder目标语言K、V 来自 Encoder源语言。例如英译中中文 token 的 Q 去匹配英文单词的 K 和 V。5. 代码层面精简对应关系结合刚才代码attn_score Q K.transpose(-2,-1) / sqrt(d_k) # Q挨个匹配K attn_weight F.softmax(attn_score, dim-1) # 算出权重 out attn_weight V # 根据权重取用V6. 误区纠正Q、K、V 不是原始词向量是输入向量分别乘以可训练矩阵WQ​,WK​,WV​得到模型训练期间自动学习什么样的 Q/K/V 更容易捕捉语义关联内积为什么可以衡量相似度向量夹角越小内积越大特征方向越接近代表语义关联性越强。
RELATED

相关推荐

【企业级GPTs部署白皮书】:从零搭建私有化GPTs工作流,支持SSO集成+审计日志+RBAC权限管控

【企业级GPTs部署白皮书】:从零搭建私有化GPTs工作流,支持SSO集成+审计日志+RBAC权限管控

更多请点击: https://codechina.net 第一章:企业级GPTs私有化部署的核心价值与架构全景 企业级GPTs私有化部署并非简单地将开源大模型运行在内网服务器上,而是构建一套安全可控、可审计、可扩展的智能服务基础设施。其核心价值体现在三大维度…

📅 2026/10/22 11:35:20
Gemma手机端Agent落地真相:离线推理与系统级工程挑战

Gemma手机端Agent落地真相:离线推理与系统级工程挑战

1. 项目概述:一场被标题“折叠”了真实技术路径的行业误读看到这个标题,我第一反应是放下手里的咖啡杯,把页面往上拉三遍——不是因为兴奋,而是本能地怀疑:这真的可能发生吗?Gemma模型跑在手机上、离线、还…

📅 2026/10/22 6:53:22
WaveTools鸣潮工具箱:5分钟解锁120帧+画质优化的终极指南

WaveTools鸣潮工具箱:5分钟解锁120帧+画质优化的终极指南

WaveTools鸣潮工具箱:5分钟解锁120帧画质优化的终极指南 【免费下载链接】WaveTools 🧰鸣潮工具箱 项目地址: https://gitcode.com/gh_mirrors/wa/WaveTools 还在为《鸣潮》游戏卡顿和60帧限制烦恼吗?WaveTools鸣潮工具箱是专为《鸣潮…

📅 2026/10/23 7:00:44
MORE NEWS

更多资讯

📰

Windows开机加速:5种启动项管理方法详解

1. 为什么Windows开机越来越慢?每次按下电源键后,看着屏幕上转圈的加载图标,是不是感觉等待时间越来越长?这个问题困扰着绝大多数Windows用户。开机速度变慢的核心原因,往往在于系统启动时自动加载的程序过多。这些程序…

📰

Edge兼容性修复实战:从翻车到可复现的完整指南

1. 从一次真实的翻车现场说起上个月帮一个朋友处理他公司内网系统的问题,前端同事信誓旦旦说"Chrome上跑得好好的",结果业务部门清一色用Windows自带的Edge打开,页面直接白屏,控制台一片红。这不是个例,我在…

📰

Aspose.Words for Java 14.9 离线破解版技术解析

简介:本资源是面向Java开发者与后端工程师的Aspose Words for Java 14.9破解版工具包,专为需在非商业场景下实现Word文档自动化处理(如生成报告、批量替换、格式转换、页眉页脚操作等)的技术人员设计。资源包含3个核心文件&#x…

📰

企业微信 iPad 方案怎么选?官方 API、自动化能力与风险边界

企业微信 iPad 方案怎么选?官方 API、自动化能力与风险边界 摘要 围绕“企业微信 iPad 协议”的讨论,常把设备形态、客户端自动化和企业级接口混在一起。选方案时更重要的问题不是能不能模拟某个客户端,而是业务是否获得了明确授权、数据能否…

📰

YOLOv10与红外成像在太阳能板缺陷检测中的应用

1. 项目概述:红外太阳能板缺陷检测的智能化突破去年夏天参观光伏电站时,现场工程师指着成排的太阳能板告诉我:"人工巡检2000块板子需要3个人忙活一整天,最头疼的是细微裂纹和热斑,等肉眼能看见时往往已经造成发电…

📰

PyTorch安装验证全链路指南:CUDA、驱动、Python版本精准校准

1. 这不是“点几下就完事”的安装,而是深度学习环境的第一道门槛 PyTorch 安装与验证,听起来像教科书里最基础的一节,但实际操作中,它往往是新手掉进的第一个深坑——你以为只是执行一条 pip install torch ,结果卡…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬