惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
The Last Watchdog
The Last Watchdog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
T
Troy Hunt's Blog
L
LINUX DO - 最新话题
C
Check Point Blog
T
Threat Research - Cisco Blogs
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
罗磊的独立博客
V
Vulnerabilities – Threatpost
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
J
Java Code Geeks
Apple Machine Learning Research
Apple Machine Learning Research
大猫的无限游戏
大猫的无限游戏
S
Security @ Cisco Blogs
IT之家
IT之家
T
The Exploit Database - CXSecurity.com
The GitHub Blog
The GitHub Blog
D
Docker
Engineering at Meta
Engineering at Meta
AWS News Blog
AWS News Blog
S
Security Affairs
U
Unit 42
P
Palo Alto Networks Blog
V
Visual Studio Blog
Y
Y Combinator Blog
D
DataBreaches.Net
Forbes - Security
Forbes - Security
阮一峰的网络日志
阮一峰的网络日志
美团技术团队
Security Latest
Security Latest
aimingoo的专栏
aimingoo的专栏
Simon Willison's Weblog
Simon Willison's Weblog
A
Arctic Wolf
博客园_首页
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
H
Hacker News: Front Page
博客园 - 司徒正美
博客园 - Franky
宝玉的分享
宝玉的分享
TaoSecurity Blog
TaoSecurity Blog
Latest news
Latest news
Scott Helme
Scott Helme
MongoDB | Blog
MongoDB | Blog
量子位
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
C
Cisco Blogs
P
Privacy International News Feed
Application and Cybersecurity Blog
Application and Cybersecurity Blog

博客园_首页

Linux实操--组管理、权限管理和定时任务 Java + EasyExcel 实现单个接口导出多个Excel Mem0 源码解析系列(二):提示词工程的深度剖析 Openclaw TaskFlow究竟是什么?和普通Skill技能有什么区别 博文阅读密码验证 - 博客园 嘉立创开源:应该是全网MicroPython教程最多的开发板 Hermes Agent 集成实践:从协议到生产 2026年AI编程工具横评:Cursor、Codex、Claude Code、Zed、Windsurf Java程序员必看的RAG入门教程 2026 AI效率神器:Superpowers + Claude Code 保姆级教程 本地大模型部署全攻略:从 0 到 1 玩转 Ollama 【从0到1构建一个ClaudeAgent】内存管理-上下文压缩 .NET 高级开发 | 设计、实现一个事件总线框架 电子小白入门之NE555 3. WorkBuddy:隐藏玩法,一键召唤专家,让 AI 以"专家身份"给你干活 和AI一起搞事情#3:Claude Teammate 游戏开发翻车实录 【OpenClaw】通过 Nanobot 源码学习架构---(7)Memory C# .NET 周刊|2026年3月3期 我在 Debian 11 上把 K8s 单机搭起来了,过程没你想的那么顺(/opt 目录版) 深度学习进阶(七)Data-efficient Image Transformer CLI+Skill搭建浏览器AI自动化框架,告别一切重复枯燥任务 告别Token账单无底洞:OpenClaw本地部署,重塑企业数据主权的唯一解 FastAPI+Vue:文件分片上传+秒传+断点续传,这坑我帮你踩平了! SBTI 爆火后,我做了个程序员版的 CBTI。。已开源 + 附开发过程 多模态检索开始进入工程期:用 Sentence Transformers 搭建可落地的 Multimodal RAG 100多行代码实现一个最简单的Agent(用ReAct) Claude Code 通关手册(八):推荐 5 个 Hooks,代码质量提升 3 倍 老板:“有人截图了!”。安全部门:“收到,马上查暗水印!” - why技术 技术之外,皆是人间 C#/.NET/.NET Core技术前沿周刊 | 第 69 期(2026年4.01-4.12) Snack JSONPath 项目架构分析 Claude Code Buddy 小析:一个非核心功能,如何体现产品的细节完成度 AI新时代下的图床管理方案-Cloudflare图床+MCP+Skills方案指南 化繁为简:顺丰速运App如何通过 HarmonyOS SDK实现专业级空间测量 从零实现富文本编辑器#13-React非编辑节点的内容渲染 AI开发-python-langchain框架(3-23-OpenAI Functions风格Tool Calling智能助手) .NET + AI 进阶实战:基于类的技能开发 - 打造可治理的 Agent 能力模块 【从0到1构建一个ClaudeAgent】规划与协调-技能 上周热点回顾(4.6-4.12) 电子小白的工具三件套:面包板、杜邦线、万能板 单表五亿数据的查询优化 | Mysql、StarRocks 2. WorkBuddy:从“我是谁”到“帮我干活” C# 如何减少代码运行时间:7 个实战技巧 基于HelixToolkit.SharpDX 渲染3D模型 - 笺上知微 从零开始的双臂具身VLA起源及现阶段发展综述 - SkyXZ 记对 xonsh shell 的使用, 脚本编写, 迁移及调优 - pluvium27 受够了Vibe Coding的失控?换个起点,让AI事半功倍 从开始配置漏洞环境到漏洞复现流程 - 難しい 关于10年工作经验的程序员对OpenClaw的实战经验分享以及看法 - 虚无境 Any metadata 的内存布局 C# .NET 周刊|2026年3月2期 - InCerry 我帮你测过了,测试圈排名第二的 Skill 依然很牛逼 Skill Discovery | 无监督技能发现的经典工作总结 - MoonOut PbootCMS 网站内容数量多导致访问慢?这些实用优化方案帮你提速! - 家兴网络技术工作室 上下文工程是什么?过时了么?一文讲明白! - 一枫说码 网站漏洞怎么发现并修复?一篇实用指南(附完整流程) - 家兴网络技术工作室 开了 TUN 模式还是直连?90% 的人都踩过这个坑 Github日报|2026年04月12日 - AI一族 AScript扩展多种脚本语言 - rockey627 AI 学习笔记:Agent 的记忆机制 你能被装进一个文件里吗?——7 万人把同事"蒸馏"成了 AI - 我没有三颗心脏 Claude Code 通关手册(七):给 AI 装上技能包——Skills 完全指南 - 暮色之狐 在浏览器中快速编辑代码:VSCode Web 集成实践 - Newbe36524 蒸馏自己 skill?基于 Deepseek 的蒸馏器,丐版蒸馏方式,简单便捷 - To_Carpe_Diem Spring AI Aliababa和AgentScope,哪个更好? - 苏三说技术 Etsy 把 1000 个 MySQL 分片迁进 Vitess:425TB 数据背后的真正问题不是性能,而是运维规模 MicroPython LVGL基础知识和概念:底层渲染与性能优化 - FreakStudio 数据库草图算法 Python 潮流周刊#146:CPython 引入 Rust 的进展 - 豌豆花下猫 最小生成树 - mofei1116 红日靶场七:从外网入口、容器逃逸到 AD 接管的完整利用链复盘 - YouDiscovered1t 分享四款开源且实用的 Kafka 管理工具 - 追逐时光者 vLLM 权重加载机制全解析:从挑战到理想架构 LCT 学习笔记 - ACehomoxue Avalonia UI 12.0.0 正式发布:架构演进和性能飞跃 - 张善友 当 AI Agent 把调用链拉长,延迟开始成为一门生意 conhost.exe 无法显示 U+2717 - 145a 太秀了,我把自己蒸馏成了 Skill!已开源 - 程序员鱼皮 ASP.NET Core 内存缓存实战:一篇搞懂该怎么配、怎么避坑 基于 Ghostty 带有分割标签页和为 Claude 编程设计的通知终端 - BugShare AI 焊死入口:教育的“操作系统级”重塑 - 郝hai 初级Java开发工程师使用sql脚本编写代码的过程是简单而且不糊涂 - CoderOilStation Claude Code通关手册(六):MCP协议完全指南 - 暮色之狐 边框灯光环绕动画特效实现指南 - Newbe36524 开源:子木蒸馏版的 SEO 审计工具 seo-audit-skill v1.0 我所理解的Python元模型 【从0到1构建一个ClaudeAgent】规划与协调-TodoWrite - 程序员Seven Claude 和 Codex 在审计 Skill 上性能差异探究 - ACai_sec AScript如何实现中文脚本引擎 - rockey627 【渗透测试】HTB Season10 Garfield 全过程wp - dynasty_chenzi Android 开发者为什么必须掌握 AI 能力?端侧视角下的技术变革 树状数组正确性证明 - AC-wyr 你的 AI 焦虑,可能比 AI 本身更危险——ATM 机没有消灭银行柜员,但恐慌消灭了你的判断力 - 我没有三颗心脏 一个拉胯的分库分表方案有多绝望?整个部门都在救火! - 冰河团队 动态规划入门必学之走方格问题 - Ofnoname PostgREST 与 PostgreSQL 角色权限配置全解析(生产级实践) - SheepDog1998 使用 UEFI 图形输出协议 GOP 在屏幕上显示图像的方法 - 阿源- Claude Code通关手册(五):组建你的AI专家团队,子代理系统 - 暮色之狐 一个程序员到架构师的催婚路之感悟(整整10年后的催婚相亲感悟) - MisterLip 用 Agent Skill 自动生成工作周报 - 赵康
transformer系列:#3 深度解析多头注意力
AI-Frontiers · 2026-05-06 · via 博客园_首页


原文:https://mp.weixin.qq.com/s/Cg-BR4oSAvvoZsvQGTfmCQ

欢迎关注公zh: Al-Frontiers

transformer往期文章推荐

收藏! transformer学习资源汇总

transformer进阶之路:#1 整体概述

transformer进阶之路:#2 工作原理详解

这是 Transformer 系列文章的第三篇,沿用前期「自上而下」的方式讨论 Transformer。前两篇里,我们了解了 Transformer 是什么、架构,工作机制。

本篇文章我们将深入探索 「多头注意力」——— Transformer 的大脑。

Transformer 中如何使用注意力

正如我们在第二篇 transformer进阶之路:#2 工作原理详解所讨论的,Transformer 在三个地方用到了注意力:

  1. 编码器中的自注意力:输入序列关注自己

  2. 解码器中的自注意力:目标序列关注自己

  3. 解码器中的编码器-解码器注意力:目标序列关注输入序列

1 Transformer 中如何使用注意力

注意力输入的参数:Query、Key 和 Value

注意力层接收三个参数形式的输入,分别叫做 Query(查询)Key(键)Value(值)

这三个参数的结构很相似:序列里的每个词都由一个向量来表示。

编码器自注意力

输入序列首先被送入输入嵌入和位置编码,该模块为输入序列中的每个词生成一个编码表示,该表示捕捉了每个词的含义和位置。然后,该编码表示被送入第一个编码器中的自注意力机制,该机制接收查询(Query)、键(Key)和值(Value)三个参数。自注意力机制随后也为输入序列中的每个词生成一个编码表示,但这次编码表示中加入了每个词的注意力分数。随着编码结果依次经过堆栈中的所有编码器,每个自注意力模块都会将自身的注意力分数添加到每个词的编码表示中。

2 编码器自注意力

解码器自注意力

在解码器栈中,目标序列首先被送入输出嵌入和位置编码,该过程会为目标序列中的每个词生成一个编码表示,该表示捕捉了每个词的含义和位置。

然后,该编码表示被送入第一个解码器中的自注意力机制,该机制会接收查询(Query)、键(Key)和值(Value)这三个参数。自注意力机制随后也会为目标序列中的每个词生成一个编码表示,该表示还包含了每个词的注意力得分。

经过层归一化之后,这个表示被传给第一个解码器中「编码器-解码器注意力」的 Query 参数。

编码器-解码器注意力

与此同时,编码器堆栈最后一个编码器的输出,被传给编码器-解码器注意力的 Value 和 Key 参数。

这样一来,编码器-解码器注意力同时拿到了两样东西:一个是目标序列的表示(来自解码器自注意力),另一个是输入序列的表示(来自编码器堆栈)。所以,它生成的表示里,既包含了目标序列每个词的注意力分数,也融入了输入序列注意力分数带来的影响。

当这个表示流过解码器堆栈里的所有解码器时,每一个自注意力层和每一个编码器-解码器注意力层,也都会把自己的注意力分数继续加进每个词的表示里。

多个注意力头

在 Transformer 里,注意力模块会把自己的计算并行地重复多次。每一次重复,就叫做一个「注意力头」。注意力模块会把它的 Query、Key 和 Value 参数按 N 份切开,然后把每一份独立地传给一个单独的头。所有这些相似的注意力计算结果,最后会被组合在一起,生成一个最终的注意力分数。这就是「多头注意力」的由来——它给了 Transformer 更强大的能力,去为每个词编码多重关系细微差别
3 多个注意力头

为了准确理解数据在内部是怎么处理的,我们还是以训练一个翻译任务为例,一步步走过注意力模块的工作流程。我们只用一个训练样本:输入序列是英文 "You are welcome",目标序列是西班牙语 "De nada"。

注意力的超参数

有三个超参数决定了数据的维度:

  • 嵌入尺寸:嵌入向量的宽度(我们的例子里用了宽度 6)。这个维度会贯穿整个 Transformer 模型,所以有时候也会被叫成别的名字,比如模型尺寸等等。

  • 查询尺寸(等于 Key 和 Value 的尺寸):三个线性层用来生成 Query、Key 和 Value 矩阵时,各自使用的权重的尺寸(我们的例子里,查询尺寸用了 3)。

  • 注意力头的数量(我们的例子里用了 2 个头)。

除此之外,还有个批量大小,它给了我们一个表示样本数量的维度。

输入层

输入嵌入和位置编码层,产出一个形状为 (样本数, 序列长度, 嵌入尺寸) 的矩阵。这个矩阵被喂给堆栈里第一个编码器的 Query、Key 和 Value。
4 输入层

为了让图示更简单,我们会丢掉批量这个维度,只关注剩下的维度。

4-1 输入层

线性层

Query、Key 和 Value 各自有一个独立的线性层,每个层有自己的权重。输入数据穿过这些线性层,就产生了 Q、K 和 V 矩阵。

5 线性层

把数据拆分到各个注意力头

现在,数据要被拆分到多个注意力头上,这样每个头才能独立处理。

但有个关键点需要理解:这仅仅是逻辑上的拆分。Query、Key 和 Value 并不是真的被切成了一个个独立的物理矩阵——每个头一个。相反,Query、Key 和 Value 各自仍然是一个单独的数据矩阵,只不过矩阵里为每个头划出了逻辑上独立的分区。同样,也不是每个头都有自己独立的线性层。实际上,所有注意力头共享同一个线性层,只不过它们在自己的那一块逻辑数据分区上操作。

线性层的权重也按头做了逻辑分区

这种逻辑拆分,是通过把输入数据线性层的权重,都均匀地划分到各个注意力头上实现的。我们可以通过设定下面的查询尺寸来达到这一点:

查询尺寸 = 嵌入尺寸 / 头的数量

6 线性层的权重也按头做了逻辑分区

在我们的例子里,查询尺寸 = 6 / 2 = 3。尽管线性层的权重(和输入数据)是一个单独的矩阵,但我们可以把它想象成:每个头的独立层权重,被堆叠在了一起。

6.1 线性层的权重也按头做了逻辑分区

因此,所有头的计算可以通过一次矩阵运算完成,而不需要 N 次独立的运算。这让计算更高效,也让模型保持简洁,因为需要的线性层更少了,但同时仍然保留了独立注意力头的强大能力。

重塑 Q、K 和 V 矩阵

线性层输出的 Q、K 和 V 矩阵会被重塑,以显式地包含一个「头」的维度。现在,每个切片就对应每个头的矩阵。

这个矩阵会被再次重塑——这次是交换「头」和「序列」这两个维度。尽管图示里没有画出批量维度,但 Q 现在的维度变成了 (批量, 头, 序列, 查询尺寸)。

7 重塑 Q、K 和 V 矩阵

下面的图示展示了我们的示例 Q 矩阵,从线性层出来后,被拆分的完整过程。

最后一个步骤只是为了可视化——虽然 Q 矩阵仍然是一个单独的矩阵,但我们可以把它想象成每个头有一个逻辑上独立的 Q 矩阵。

7.1 重塑 Q、K 和 V 矩阵

现在,我们准备好计算注意力分数了。

为每个头计算注意力分数

现在我们有了 Q、K 和 V 这三个矩阵,并且它们已经被拆分到了各个头上。下面就用它们来计算注意力分数。

我们会只使用最后两个维度(序列和查询尺寸)来展示单个头的计算,同时跳过前两个维度(批量和头)。本质上,我们可以想象这些计算会为每个头、批量里的每个样本重复进行——尽管很明显,它们实际上是作为一次矩阵运算发生的,而不是一个循环。

第一步,是做一个 Q 和 K 之间的矩阵乘法。

8 计算每个头部的注意力得分

然后,一个掩码值会被加到结果上。在编码器自注意力里,这个掩码用来屏蔽掉填充值,让它们不参与注意力分数的计算。

在解码器自注意力和解码器的编码器-解码器注意力里,会用到不同的掩码,我们稍后在流程中会讲到。

8.1

接下来,结果被缩放:除以查询尺寸的平方根。然后对它应用一个 Softmax

8.2

最后,再做一次矩阵乘法:这次是 Softmax 的输出 与 V 矩阵相乘。

8.3

编码器自注意力里,完整的注意力分数计算如下所示:

8.4

把每个头的注意力分数合并起来

现在我们为每个头都得到了独立的注意力分数,需要把它们合并成一个单一的分数。这个合并操作,基本上就是拆分操作的逆过程。

它的做法很简单:重塑结果矩阵,去掉这个维度。具体步骤是:

  • 通过交换序列维度,来重塑注意力分数矩阵。换句话说,矩阵形状从 (批量, 头, 序列, 查询尺寸) 变成 (批量, 序列, 头, 查询尺寸)。

  • 再通过重塑成 (批量, 序列, 头 * 查询尺寸),来坍缩掉「头」维度。这实际上就是把每个头的注意力分数向量,拼接成了一个合并后的注意力分数。

因为 嵌入尺寸 = 头数量 * 查询尺寸,所以合并后的分数维度是 (批量, 序列, 嵌入尺寸)。下面的图示展示了示例分数矩阵合并的完整过程。

9 将每个头部注意力得分合并在一起

端到端的多头注意力

把上面所有步骤整合起来,就是多头注意力的端到端流程。

10 端到端的多头注意力

多头拆分如何带来更丰富的解读

一个嵌入向量承载了一个词的含义。正如我们所见,在多 head 注意力里,输入(和目标)序列的嵌入向量会被逻辑上拆分到多个头上。这有什么意义呢?

11 多头拆分如何带来更丰富的解读

这意味着:嵌入向量的不同部分,可以去学习每个词含义的不同方面——特别是当这个词与序列里其他词产生关联的时候。这让 Transformer 能够捕捉到对序列更丰富的解读

下面的例子可能不太现实,但能帮你建立直觉。比方说,嵌入向量的一个部分可能捕捉名词的性别属性(阳性、阴性、中性),而另一个部分可能捕捉名词的数量属性(单数 vs 复数)。这在翻译时可能很重要——因为很多语言里,到底该用哪个动词,取决于这些属性。

解码器自注意力和掩码

解码器自注意力的工作方式,与编码器自注意力几乎一样,唯一的区别是,它操作的是目标序列的每个词。

12 解码器自注意力和掩码

类似地,这里的掩码,也是用来屏蔽掉目标序列里的填充词。

解码器中的编码器-解码器注意力和掩码

编码器-解码器注意力,从两个来源接收输入。因此,它和那两种自注意力都不一样:

  • 编码器自注意力计算的是:每个输入词与其他输入词之间的交互。

  • 解码器自注意力计算的是:每个目标词与其他目标词之间的交互。

  • 编码器-解码器注意力计算的是:每个目标词与每个输入词之间的交互。

13 解码器中的编码器-解码器注意力和遮蔽

所以,最终注意力分数矩阵里的每个格子,都对应一个 Query(也就是一个目标序列词)与所有 Key(输入序列词)和所有 Value(输入序列词)之间的交互。

同样,这里的掩码也会屏蔽掉目标输出中位置靠后的词。关于这一点,在系列的第二篇文章里已经详细解释过了。

结语

希望本篇文章能让读者对 Transformer 中的注意力模块的功能有一个大致的了解。结合我们在前面文章中介绍的 Transformer 整体端到端流程,现在已经详细阐述了整个 Transformer 架构的运作方式。

现在我们已完全理解了 Transformer 的工作原理。但是,我们还没有完全解答 Transformer 的 Attention 为什么要执行这些计算。为什么会使用查询、键和值的概念,以及为什么会执行我们刚才看到的矩阵乘法?

我们从直觉上介绍了 Transformer是捕捉每个词与其他词之间的关系,但这究竟是什么意思?是如何赋予 Transformer 的注意力机制理解序列中每个词的细微差别的能力的?

我们将在下篇文章给大家回答上述问题。

感谢阅读文章,如果觉得不错,欢迎点赞、关注、转发!

参考资料

Transformers Explained Visually (Part 3): Multi-head Attention, deep dive