多头注意力中的张量重塑
viewPyTorch 的view() 是张量「重塑Reshape」函数用于改变张量的维度形状但不改变数据本身在多头注意力中view()的核心作用是将总隐藏维度拆分为「注意力头数 × 单头维度」实现多头并行计算核心规则tensor.view(*shape)作用将张量重塑为指定的shape要求「新形状的元素总数 原张量的元素总数」否则报错核心特性不改变张量的底层数据仅改变维度的 “视图”轻量操作无数据拷贝重塑后的张量与原张量共享内存修改一个另一个也会变支持用-1自动推导某一维度的大小仅能有一个-1importtorch# 一维张量重塑为二维xtorch.arange(12)# shape(12,)元素总数12x_view1x.view(3,4)# shape(3,4)3×412x_view2x.view(4,-1)# -1自动推导为3shape(4,3)print(x_view1.shape)# torch.Size([3,4])print(x_view2.shape)# torch.Size([4,3])# 三维张量重塑核心元素总数不变ytorch.randn(2,6,768)# 2×6×7689216y_viewy.view(2,6,12,64)# 2×6×12×649216print(y_view.shape)# torch.Size([2,6,12,64])关键注意事项报错场景新形状元素总数≠原总数 → x.view(3,5)12≠15会报错-1的用法仅能指定一个-1用于自动计算维度如view(2,-1,64)内存连续性若张量内存不连续如经过transpose/permute需先调用contiguous()再view否则报错多头注意力中view的核心作用将总隐藏维度d_model拆分为num_heads × d_k单头维度view()是实现这一拆分的关键完整流程如下步骤 1先明确核心参数以 BERT-base 为例batch_size2批次、seq_len6序列长度d_model768总隐藏维度、num_heads12注意力头数、d_k64单头维度76812×64输入querysshape(2,6,768)经W_query线性变换后的输出。步骤 2用view()拆分注意力头# 1. 原始querys[batch, seq_len, d_model] [2,6,768]querystorch.randn(2,6,768)# 2. 拆分为多头[2,6,12,64]batch, seq_len, num_heads, d_kquerys_headsquerys.view(2,6,12,64)print(querys_heads.shape)# torch.Size([2,6,12,64])# 3. 转置调整维度为后续批量矩阵乘法[2,12,6,64]# 注transpose后内存不连续需contiguous()才能再viewquerys_headsquerys_heads.transpose(1,2).contiguous()print(querys_heads.shape)# torch.Size([2,12,6,64])步骤 3注意力计算后用view()合并多头# 假设注意力计算后的输出[2,12,6,64]batch, num_heads, seq_len, d_kattn_outputtorch.randn(2,12,6,64)# 1. 先转置回原维度[2,6,12,64]attn_outputattn_output.transpose(1,2).contiguous()# 2. 合并多头[2,6,768]还原为总隐藏维度attn_output_mergedattn_output.view(2,6,768)print(attn_output_merged.shape)# torch.Size([2,6,768])多头注意力完整实战代码importtorchimporttorch.nnasnnclassMultiHeadAttention(nn.Module):def__init__(self,d_model768,num_heads12):super().__init__()self.d_modeld_model self.num_headsnum_heads self.d_kd_model//num_heads# 64用//保证整除# 定义Q/K/V线性层self.W_querynn.Linear(d_model,d_model)self.W_keynn.Linear(d_model,d_model)self.W_valuenn.Linear(d_model,d_model)defforward(self,x):# x: [batch_size, seq_len, d_model] [2,6,768]batch_size,seq_lenx.shape[0],x.shape[1]# 1. 线性变换Q/K/V均为[2,6,768]Qself.W_query(x)Kself.W_key(x)Vself.W_value(x)# 2. 拆分为多头[2,6,12,64]QQ.view(batch_size,seq_len,self.num_heads,self.d_k)KK.view(batch_size,seq_len,self.num_heads,self.d_k)VV.view(batch_size,seq_len,self.num_heads,self.d_k)# 3. 转置[2,12,6,64]batch, num_heads, seq_len, d_k# 必须contiguous()否则后续view会报错QQ.transpose(1,2).contiguous()KK.transpose(1,2).contiguous()VV.transpose(1,2).contiguous()# 4. 计算注意力分数Q K^T → [2,12,6,6]K_TK.transpose(2,3)# [2,12,64,6]attn_scoresQ K_T# [2,12,6,6]# 5. softmax归一化省略核心看viewattn_weightstorch.softmax(attn_scores,dim-1)# 6. 加权求和[2,12,6,64]attn_outputattn_weights V# 7. 转置合并多头[2,6,768]attn_outputattn_output.transpose(1,2).contiguous()attn_outputattn_output.view(batch_size,seq_len,self.d_model)returnattn_output测试代码mhaMultiHeadAttention(d_model768,num_heads12)xtorch.randn(2,6,768)outputmha(x)print(output.shape)# 输出torch.Size([2,6,768])view vs reshape新手常混淆view和reshape二者均用于重塑张量但核心差异如下特性 view() reshape()内存共享 与原张量共享内存无拷贝 优先共享内存不连续则拷贝新内存内存连续性 要求张量内存连续否则报错 自动处理内存不连续无需contiguous()适用场景 内存连续的张量如线性层输出 内存不连续的张量如 transpose 后大模型开发建议若确定张量内存连续如线性层输出、原始输入用view()更高效若张量经过transpose/permute如多头注意力中的转置用reshape()无需手动contiguous()permute重排置换示例# 替代transpose后直接reshape更简洁QQ.transpose(1,2).reshape(batch_size,self.num_heads,seq_len,self.d_k)总结view()核心作用改变张量维度形状不改变数据要求元素总数不变支持-1自动推导维度多头注意力中view()的核心用法拆分将[batch, seq_len, d_model]拆为[batch, seq_len, num_heads, d_k]合并注意力计算后将[batch, seq_len, num_heads, d_k]合并回[batch, seq_len, d_model]关键注意transpose/permute后需contiguous()才能用view()或直接用reshape()更便捷contiguouscontiguous()用于将「内存不连续」的张量转换为「内存连续」的张量保证张量的元素在内存中按维度顺序紧密排列是view()等操作的前置必要条件张量在计算机内存中是一维线性存储的“连续” 指的是张量的元素在内存中的排列顺序和按「维度顺序如从 0 维到最后一维」遍历张量得到的顺序完全一致直观示例二维张量假设有张量x torch.tensor([[1,2,3], [4,5,6]])shape(2,3)连续内存布局内存中存储顺序是 1 → 2 → 3 → 4 → 5 → 6按 “行优先” 遍历先遍历 0 维再遍历 1 维若对x做转置x.T得到[[1,4], [2,5], [3,6]]转置后的张量逻辑上是 3 行 2 列但内存中仍存储为1→2→3→4→5→6PyTorch 的transpose/permute仅修改 “维度视图”不拷贝数据此时按转置后的维度遍历行优先期望顺序是1→4→2→5→3→6但内存实际顺序不符 → 转置后的张量是内存不连续的为什么张量会变得 “不连续”PyTorch 中以下操作会导致张量内存不连续核心是 “只改视图不改内存”维度变换类transpose()、permute()最常见如多头注意力中的维度交换索引 / 切片类非连续切片如x[:, ::2]、高级索引其他操作narrow()、expand()部分场景这些操作的设计初衷是 “轻量”—— 避免不必要的数据拷贝提升效率但代价是破坏了内存连续性contiguous()的核心作用contiguous()会创建一个新的内存连续的张量新张量与原张量数据相同但内存排列会按照 “当前维度顺序” 重新整理新张量与原张量不再共享内存是数据拷贝操作只有内存连续的张量才能调用view()view()要求张量元素在内存中是连续的否则无法正确重塑维度实战示例结合多头注意力的经典场景importtorch# 1. 创建连续张量xtorch.randn(2,6,768)# shape(2,6,768)内存连续print(x.is_contiguous())# 输出True# 2. 转置后内存不连续x_transx.transpose(1,2)# 交换1、2维shape(2,768,6)print(x_trans.is_contiguous())# 输出False# 3. 直接调用view()会报错try:x_trans.view(2,768,12,5)# 768×612×60不768×6460812×384这里故意错核心看报错exceptExceptionase:print(报错,e)# 报错view size is not compatible with input tensors size and stride...# 4. 先contiguous()再view()正常运行x_contigx_trans.contiguous()print(x_contig.is_contiguous())# 输出Truex_viewx_contig.view(2,768,12,64)# 2×768×12×642×768×7681179648和2×768×69216哦修正x_trans.shape(2,768,6)总元素2×768×69216view为2,768,12,0.5重新来x_viewx_contig.view(2,768,12,0.5)# 故意错实际应保证总元素一致x_viewx_contig.view(2,768,12,0.5)→ 正确示例 x_contigx_trans.contiguous()x_viewx_contig.view(2,12,64,6)# 2×12×64×62×768×69216总元素一致print(x_view.shape)# 输出torch.Size([2, 12, 64, 6])大模型开发中的核心应用场景必掌握contiguous()几乎只在「transpose()/permute() view()」的组合中使用尤其是多头注意力层# 多头注意力中拆分注意力头的标准流程Qtorch.randn(2,6,768)# [batch, seq_len, d_model]QQ.view(2,6,12,64)# 拆分为多头[2,6,12,64]QQ.transpose(1,2)# 交换维度[2,12,6,64] → 内存不连续QQ.contiguous()# 转为连续内存后续可安全调用view()若需要QQ.view(2,12,6,64)# 正常运行关键注意事项contiguous()是数据拷贝操作会消耗内存和时间非必要时不要调用比如仅做矩阵乘法无需连续内存替代方案reshape()会自动处理内存连续性优先共享内存不连续则自动拷贝因此若只需重塑维度用reshape()替代contiguous()view()更简洁示例Q.transpose(1,2).reshape(2,12,6,64)无需手动contiguous()判断是否连续用tensor.is_contiguous()快速检查返回True则为连续总结contiguous()的核心将内存不连续的张量转为连续保证view()等操作能正常执行触发场景张量经过transpose()/permute()后若要调用view()必须先contiguous()大模型实战建议优先用reshape()替代contiguous()view()减少代码量且更安全

相关新闻

attn_scores注意力分计算-记录

attn_scores注意力分计算-记录

2026/7/8 15:29:19 阅读更多 →
第二周作业wp

第二周作业wp

2026/7/6 8:59:31 阅读更多 →
软件测试—即时通讯测试方法

软件测试—即时通讯测试方法

2026/7/7 20:28:44 阅读更多 →

最新新闻

3分钟开启Unity游戏自动翻译:XUnity Auto Translator完整指南

3分钟开启Unity游戏自动翻译:XUnity Auto Translator完整指南

3分钟开启Unity游戏自动翻译:XUnity Auto Translator完整指南 【免费下载链接】XUnity.AutoTranslator 项目地址: https://gitcode.com/gh_mirrors/xu/XUnity.AutoTranslator 你是否曾经因为语言障碍而放弃了一款优秀的Unity游戏?面对日语、韩语…

2026/7/9 7:49:55 阅读更多 →
IACheck 搭载 AI 报告审核通审 Agent 版:拆解检测报告智能审核两大核心技术,适配 2026 行业强监管合规要求

IACheck 搭载 AI 报告审核通审 Agent 版:拆解检测报告智能审核两大核心技术,适配 2026 行业强监管合规要求

一、行业监管收紧,人工审核模式彻底迎来能力天花板2026 年检验检测行业监管体系迎来系统性升级,市场监管总局 “一单一库” 资质管理落地、《检验检测从业人员监督管理工作指引》正式施行,明确谁签字、谁担责终身追责机制,CNAS 开…

2026/7/9 7:49:55 阅读更多 →
为什么 I2C 必须用 OD 开漏?

为什么 I2C 必须用 OD 开漏?

OD 详细解析(结合你这张 I2C 引脚表) 1. OD 全称:Open Drain,开漏输出 不是单纯 “数字输出”,是特殊的 IO 电路结构,和普通推挽输出(Push-Pull)完全区分开。 核心电路原理 模组内部引脚只做下拉通路:内部 MOS 导通时,引脚拉到 GND(低电平); 内部 MOS 关断时,…

2026/7/9 7:49:55 阅读更多 →
Okbiye|毕业文稿专属创作通道,一站式毕业论文功能全维度拆解

Okbiye|毕业文稿专属创作通道,一站式毕业论文功能全维度拆解

okbiye-免费查重复率aigc检测/开题报告/毕业论文/智能排版/文献综述/科研绘图毕业论文 - Okbiye智能写作https://www.okbiye.com/ai/bylw 一、独立毕业论文专属分区,打造定向学术创作入口 平台左侧导航栏划分多条学术创作赛道,毕业论文板块标注热门标识…

2026/7/9 7:47:55 阅读更多 →
专业级QMC音频解密实战指南:高效转换QQ音乐加密文件

专业级QMC音频解密实战指南:高效转换QQ音乐加密文件

专业级QMC音频解密实战指南:高效转换QQ音乐加密文件 【免费下载链接】qmc-decoder Fastest & best convert qmc 2 mp3 | flac tools 项目地址: https://gitcode.com/gh_mirrors/qm/qmc-decoder qmc-decoder是一个专业的开源工具,专门用于快速…

2026/7/9 7:47:55 阅读更多 →
H2database 2.1.210 以下版本漏洞剖析:从JNDI注入到CVE-2022-23221的完整攻击链

H2database 2.1.210 以下版本漏洞剖析:从JNDI注入到CVE-2022-23221的完整攻击链

H2database 2.1.210以下版本漏洞深度解析:从JNDI注入到远程代码执行的攻防全景H2database作为一款轻量级Java嵌入式数据库,因其高性能和易用性被广泛应用于开发测试场景。然而在2.1.210版本之前存在的安全漏洞,使得攻击者能够通过Web控制台实…

2026/7/9 7:47:55 阅读更多 →

日新闻

3大音乐平台逐字歌词完整解决方案:ESLyric-LyricsSource完全指南

3大音乐平台逐字歌词完整解决方案:ESLyric-LyricsSource完全指南

3大音乐平台逐字歌词完整解决方案:ESLyric-LyricsSource完全指南 【免费下载链接】ESLyric-LyricsSource Advanced lyrics source for ESLyric in foobar2000 项目地址: https://gitcode.com/gh_mirrors/es/ESLyric-LyricsSource 还在为Foobar2000找不到高质…

2026/7/9 0:01:04 阅读更多 →
ElegantBook封面定制揭秘:3个步骤打造专业级学术书籍

ElegantBook封面定制揭秘:3个步骤打造专业级学术书籍

ElegantBook封面定制揭秘:3个步骤打造专业级学术书籍 【免费下载链接】ElegantBook Elegant LaTeX Template for Books 项目地址: https://gitcode.com/gh_mirrors/el/ElegantBook 你是否曾经为学术书籍的封面设计而烦恼?想要一个既专业又美观的封…

2026/7/9 0:03:06 阅读更多 →
如何高效使用pyodbc:企业级数据库连接终极指南

如何高效使用pyodbc:企业级数据库连接终极指南

如何高效使用pyodbc:企业级数据库连接终极指南 【免费下载链接】pyodbc Python ODBC bridge 项目地址: https://gitcode.com/gh_mirrors/py/pyodbc 在当今数据驱动的商业环境中,企业级数据库连接已成为现代应用开发的核心需求。pyodbc作为一款强大…

2026/7/9 0:07:11 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/8 16:14:06 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/7 12:34:47 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/8 16:59:55 阅读更多 →

月新闻