尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Kornia 修复解析:warp_affine、warp_perspective 与 remap 空目标在 MPS 上的崩溃(4032、4354)
计算机视觉深度学习图像处理【免费下载链接】kornia Geometric Computer Vision Library for Spatial AI项目地址https://gitcode.com/GitHub_Trending/ko/kornia点击查看免费下载本指南聚焦 kornia 的一次关键缺陷修复对应 changelog 条目 changelog.d/migration-041.fixed.mdwarp_affine、warp_perspective与remap在 MPSApple Silicon后端处理空目标dsize某一维为 0或remap的零尺寸 map时的崩溃问题。文章将结合 imgwarp.py 的源码实现与 test_imgwarp.py 的测试用例从崩溃根因、修复思路、1×1 占位采样机制、批量语义对齐到验证方法做完整剖析帮助你理解几何变换算子空张量路径的工程细节。一、问题背景空目标 warp 在 MPS 上的崩溃1.1 崩溃现象在修复之前以下三类调用在 MPS 后端torch 2.14 之前会直接崩溃warp_affine(src, M, dsize(0, 4))、dsize(3, 0)或(0, 0)——输出高度或宽度为零warp_perspective(src, H, dsize(0, 4))等零维输出remap(image, map_x, map_y)其中map_x/map_y的H或W为 0零尺寸 map。底层报错来自 PyTorch[srcBuf length] 0 INTERNAL ASSERT FAILED ... Placeholder tensor is empty!这是 MPS 后端对grid_sample的空操作数断言在 torch 2.14 之前MPS 的grid_sample拒绝任何零元素操作数哪怕只是采样网格grid为零元素、而源图像非空。而旧版空目标路径恰恰会构造一个零元素网格去采样非空源图从而触发该内部断言。1.2 为什么此前能正常工作的后端没事CPU 与 CUDA 的grid_sample允许零元素操作数因此空目标 warp 在 CPU/CUDA 上碰巧能返回一个空结果。但 MPS 的实现更严格只要网格或批次维度出现零元素就断言失败。由于 kornia 支持 torch 2.0见 pyproject.toml 的依赖声明而 MPS 修复要等到 torch 2.14kornia 必须自己在算子层兜底不能依赖用户升级 PyTorch。二、修复思路用 1×1 占位采样替代零元素采样2.1 核心设计修复的核心思想是空目标路径不再把零元素网格喂给grid_sample而是采样一个连通的 1×1 占位stand-in再把采样结果扩展expand成请求的空形状。源码中该逻辑位于 imgwarp.py 的_empty_warp_output_2d辅助函数# grid_sample must never receive a zero-element operand here. # MPS before torch 2.14 raises [srcBuf length] 0 ... Placeholder tensor is empty! sample_batch max(src_batch, 1) sample_channels max(src.shape[1], 1) grid_zero transform.reshape(-1)[:1].sum() * 0.0 grid grid_zero.reshape(1, 1, 1, 1).expand(sample_batch, 1, 1, 2) src_zero src.reshape(-1)[:1].sum() * 0.0 sample_src src_zero.reshape(1, 1, 1, 1).expand(sample_batch, sample_channels, 1, 1)这里有两个关键细节占位元素必须连通connected占位张量不能是独立创建的全零张量而是通过对输入张量的元素求和再乘以 0.0 派生而来src.reshape(-1)[:1].sum() * 0.0。这样占位张量在 autograd 图中与src、transform保持依赖关系后续expand出的空结果仍然连接在计算图上梯度能够正确回传尽管是零梯度。占位是 1×1 而非dsize形状占位采样只做 1×1这样无论dsize的非零侧有多大空 warp 的成本都恒定。测试 test_imgwarp.py 专门验证了这一点——对一个dsize(0, 2_000_000)的目标spy 捕获到的grid_sample网格形状始终是(1, 1, 1, 2)而不是物化两百万个采样点。正如测试注释所言空结果会丢弃采样到的内容如果按dsize物化采样空 warp 的成本会比真实 warp 更高——对零元素结果而言是无界的。2.2 采样后的展开采样得到 1×1 结果后再通过expand展开为请求的空形状并保持 dtype、device 与原始语义一致sampled F.grid_sample(sample_src, grid, align_cornersalign_corners, modemode, padding_modepadding_mode) out_zero sampled.reshape(-1)[:1].sum() * 0.0 return out_zero.reshape(1, 1, 1, 1).expand(src_batch, src.shape[1], dsize[0], dsize[1])expand是 stride-0 视图零拷贝因此输出是一个(B, C, 0, W)或(B, C, H, 0)的空张量numel() 0但 autograd 链接完整保留。2.3 保留的校验契约占位路径并未绕过原有校验而是以 1×1 采样保留契约、以展开恢复形状dtype 校验grid_sample要求采样网格与源图同 dtype。占位路径通过_matrix_warp_grid_dtypeimgwarp.py预先推导非空路径会产生的网格 dtype空路径据此做同样的 dtype 检查——既不比非空路径更严格也不更宽松浮点校验CPU/CUDA 的非空路径中整型src会在grid_sample内部失败空路径则在占位采样前显式抛出NotImplementedError见_empty_warp_output_2d开头的if not src.is_floating_point()检查错误信息指向src而非其他操作数device 校验src与变换/映射必须同设备否则抛出RuntimeErrorpadding_modefill支持当padding_mode fill且允许填充时占位路径走_fill_and_warp同样在 1×1 占位上执行fill_value缺省时按src.shape[1]通道数构造零填充向量imgwarp.py。三、批量batch语义对齐空路径与非空路径行为一致修复的另一个重点是空目标路径的输出 batch 必须与非空路径完全一致包括单例广播与不匹配批量的拒绝。三个算子对单例 batch 的广播规则各不相同见 imgwarp.py 的transform_batch_broadcast参数算子广播规则语义warp_perspectivenone要求src与M的 batch 严格相等warp_affinesrc_when_larger仅当源 batch 大于 1 时把单例矩阵 batch 扩展为源 batchremapsrc无条件把单例 map batch 扩展为图像 batch含零 batch在_empty_warp_output_2d中batch 解析发生在任何钳制clamping之前src_batch src.shape[0] transform_batch transform.shape[0] broadcasts_singleton transform_batch_broadcast src or ( transform_batch_broadcast src_when_larger and src_batch 1 ) if transform_batch 1 and broadcasts_singleton: transform_batch src_batch if transform_batch ! src_batch: raise RuntimeError( fExpected src and {operand} with the same batch size, got {src_batch} and {transform.shape[0]}. )注释解释了为什么必须提前解析占位张量被钳制到非零1×1如果不先解析 batch0/1 或 1/0 的 batch 组合会在占位路径中被静默当作 1/1 接受而对应的非空路径要么广播、要么拒绝——空路径就会悄悄返回错误的 batch 基数。测试 test_imgwarp.py 覆盖了(src_batch, transform_batch)的全部 6 种组合(0,1)、(1,0)、(0,0)、(2,1)、(1,2)、(2,2)并采用以非空调用为准的对照策略先跑非空路径得到期望 batch 或期望异常再断言空路径行为与之完全一致。四、remap 的专门处理remap的空路径判断基于 map 的空间尺寸当map_xy的 H 或 W 维为零时进入空路径imgwarp.pyif map_xy.shape[-3] 0 or map_xy.shape[-2] 0: return _empty_warp_output_2d( image, map_xy, (map_xy.shape[-3], map_xy.shape[-2]), mode, padding_mode, align_corners, _remap_grid_dtype(map_xy, normalized_coordinates), transform_batch_broadcastsrc, allow_fillFalse, operandmap, )这里有两个remap特有的参数operandmapremap没有transform参数它把堆叠的map_x/map_y委托给空路径因此错误信息中应称为map而不是transform_remap_grid_dtypeimgwarp.pyremap 的网格 dtype 推导逻辑不同——已归一化normalized_coordinatesTrue或浮点 map 直接保留自身 dtype整型/布尔 map 则先经normalize_pixel_coordinates提升为默认浮点 dtype。这里通过零元素张量的类型提升map_xy.reshape(-1)[:0] * 1.0读取默认浮点 dtype而不是torch.get_default_dtype()因为后者在 TorchScript 中不可用。非空路径下remap的map_xy需要expand(batch_size, -1, -1, -1)模拟grid_sample不支持的 batch 广播imgwarp.py空路径的src广播规则与之对应。五、3D 变体的对称实现同样的问题也存在于warp_affine3d与warp_perspective3d它们共享_empty_warp_output_3dimgwarp.py。3D 版本使用 5 维网格占位(1, 1, 1, 1, 1).expand(transform.shape[0], dsize[0], dsize[1], dsize[2], 3)并在源图任一空间维为零时同样构造 1×1×1 源占位。两个 3D 算子在dsize任一维为 0 时进入该路径imgwarp.py 与 imgwarp.py。六、兼容性与验证6.1 行为不变性修复明确保证CPU 与 CUDA 上的输出、autograd 链接与既有的空源策略empty-source policy完全不变。MPS 修复只是把空目标路径的实现从直接喂零元素网格改为1×1 占位 展开对非 MPS 后端而言结果张量与计算图结构均无差异。6.2 测试覆盖tests/geometry/transform/test_imgwarp.py 提供了针对性的回归测试test_empty_destination_forward_runs_on_every_backendL51-L70参数化warp_affine/warp_perspective×dsize ∈ {(0,4),(3,0),(0,0)}×batch ∈ {0,1,2}断言输出形状为(batch, 3, *dsize)、numel() 0、device 与 dtype 正确——该测试仅做前向因此也能覆盖 torch 2.14 之前缺少反向内核的 MPStest_empty_destination_matches_nonempty_batch_semanticsL73-L102覆盖三个算子 × 6 种 batch 组合对照非空路径验证广播与拒绝语义test_empty_destination_samples_a_constant_1x1_stand_inL105-L125通过 monkeypatchtorch.nn.functional.grid_sample断言空路径只做 1×1 采样成本恒定梯度测试由_skip_if_mps_lacks_grid_sample_backward保护L30-L38MPS 在 torch 2.14 之前缺少aten::grid_sampler_2d_backward此时跳过反向检查但前向契约在所有后端运行。另外tests/geometry/transform/test_affine.py 的test_zero_output_size印证了零输出维返回 autograd 连接的空张量是 kornia 几何变换算子含resize的一致约定空结果仍附着在计算图上退化到零尺寸输出的 batch 仍能贡献零梯度。6.3 文档中的新约定修复后三个算子的 docstring 均明确了空目标语义例如 imgwarp.py 的warp_perspective约定a zero output dimension returns an autograd-connected empty tensor; negative output dimensions raiseValueErrorremap则额外说明零 map 轴返回 autograd 连接的空输出包括源图对应轴也为空的情况imgwarp.py。负的dsize维始终抛出ValueError如 imgwarp.py 的Output size must be non-negative这一契约保持不变。七、实践建议与小结在 kornia 中处理可能产生空输出的 warp 场景可以遵循以下实践空目标是合法输入dsize某一维为 0 或零尺寸 remap map 不再需要特殊规避MPS 上也会返回正确的空张量而非崩溃空结果可参与反向传播由于占位张量与输入保持连接空 warp 输出.backward()会向src、M或 map回传零梯度动态 batch如(0, ...)不会打断训练图注意 batch 广播差异warp_perspective严格等 batchwarp_affine仅在源 batch 1 时广播单例矩阵remap无条件广播单例 map——空目标时同样遵守写动态 shape 代码时应明确期望的广播规则负维度仍是非法的dsize出现负数时三个算子统一抛ValueError空零与非法负语义有清晰边界。本次修复关联 issue/PR #4032、#4354的本质是让grid_sample在任何后端都绝不收到零元素操作数用恒定的 1×1 占位采样 expand展开空结果从而在保留 dtype/device/批次校验与 autograd 连接的前提下消除 MPS 上 torch 2.14 之前的内部断言崩溃同时保证 CPU/CUDA 行为零变化。赞分享计算机视觉深度学习图像处理【免费下载链接】kornia Geometric Computer Vision Library for Spatial AI项目地址https://gitcode.com/GitHub_Trending/ko/kornia点击查看免费下载相关推荐Kornia 空目标几何变换深度解析修复 warp_affine、warp_perspective 与 remap 在 MPS 及零尺寸 dsize 下的崩溃Kornia 空目标几何变换深度解析修复 warp_affine 、 warp_perspective 与 remap 在 MPS 及零尺寸 dsize 下的人工智能计算机视觉深度学习图像处理Kornia 修复 RandomTransplantation 在 MPS 上的移植失效空 excluded_labels 触发的 all() 归约陷阱与规避方案Kornia 修复 RandomTransplantation 在 MPS 上的移植失效空 excluded_labels 触发的 all 归约陷阱与规避方案人工智能计算机视觉深度学习图像处理Kornia MPS SVD 8192 元素上限修复几何求解器在 Apple Silicon 上的 CPU 回退方案Kornia MPS SVD 8192 元素上限修复几何求解器在 Apple Silicon 上的 CPU 回退方案 本篇文章围绕 Kornia 的一条变更记人工智能计算机视觉深度学习图像处理上一篇FunASR项目中SenseVoiceSmall模型部署问题解析下一篇3小时搭建基于Arduino-ESP32的低成本激光雕刻机实战指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED

相关推荐

艾尔登法环存档怎么改SteamID?ER-Save-Editor实战避坑指南

艾尔登法环存档怎么改SteamID?ER-Save-Editor实战避坑指南

艾尔登法环存档怎么改SteamID?ER-Save-Editor实战避坑指南 【免费下载链接】ER-Save-Editor Elden Ring Save Editor. Compatible with PC and Playstation saves. 项目地址: https://gitcode.com/GitHub_Trending/er/ER-Save-Editor 换了新电脑、换了 Steam…

📅 2026/11/2 6:13:11
Minke自定义快捷键教程:如何设置8个高频操作,快速驾驭AI桌面智能体

Minke自定义快捷键教程:如何设置8个高频操作,快速驾驭AI桌面智能体

【免费下载链接】Minke 🐳 DeepSeek Harness Desktop 项目地址: https://gitcode.com/gh_mirrors/mink/Minke 点击查看 免费下载 Minke 是一款基于 DeepSeek Harness 的本地优先 AI 桌面智能体工作台,把对话、文件、终端和共享浏览器整合到一…

📅 2026/11/2 6:13:11
Hydra Launcher 快速上手:3 步配齐游戏库、下载与云存档

Hydra Launcher 快速上手:3 步配齐游戏库、下载与云存档

Hydra Launcher 快速上手:3 步配齐游戏库、下载与云存档 【免费下载链接】hydra Hydra Launcher is an open-source gaming platform created to be the single tool that you need 项目地址: https://gitcode.com/GitHub_Trending/hy/hydra 游戏散在各下载站…

📅 2026/11/2 6:13:11
MORE NEWS

更多资讯

📰

微电网中光伏与空调负荷的优化控制策略

1. 项目背景与核心价值去年夏天参与某工业园区微电网项目时,我亲历了这样一个场景:当光伏发电达到峰值时,配电变压器却因空调集中启动导致过载跳闸。这个典型矛盾促使我开始深入研究如何协调可再生能源波动与空调负荷的关系。这项研究本质上要…

📰

ERP库存上下限管理:设置技巧与预警优化

1. 库存上下限管理的核心价值与业务场景库存上下限设置是ERP系统中最为基础却又极其关键的库存管控功能。在管家婆云辉煌ERP中,这个功能模块直接关系到企业的库存周转效率和资金占用情况。根据我多年实施ERP系统的经验,合理设置库存上下限可以帮助企业实…

📰

基于MCP协议构建跨平台AI指挥中心的技术实践

1. 项目概述:构建跨平台AI指挥中心去年在为一个跨国团队做技术支持时,我遇到了一个棘手问题:团队成员分散在Slack和Telegram两个平台,关键消息经常被遗漏。这促使我开始研究如何通过MCP协议打造一个真正的跨平台AI指挥中心。MCP&a…

📰

C++ STL全排列:next/prev_permutation避坑

刷算法题也好&#xff0c;写实际业务代码也好&#xff0c;只要碰到“把一堆元素的所有排列都列出来”这种需求&#xff0c;C 选手脑子里第一时间蹦出来的基本就是next_permutation和prev_permutation这两个函数。它们藏在<algorithm>头文件里&#xff0c;用起来一行就能推…

📰

档案管理系统设计与实现:从架构到安全

1. 项目概述"记录档案1"这个项目名称看似简单&#xff0c;却蕴含着丰富的信息管理内涵。作为一名从业多年的数据管理专家&#xff0c;我理解这类项目通常涉及信息收集、分类存储、快速检索等核心功能。在实际工作中&#xff0c;一个高效的档案管理系统能够显著提升工…

📰

VeRL框架与PPO算法在机器人控制中的应用实践

1. VeRL框架与PPO算法背景解析在深度强化学习领域&#xff0c;VeRL(Verifiable Reinforcement Learning)框架因其独特的可验证性设计而备受关注。这个框架特别适合需要高可靠性的应用场景&#xff0c;比如机械臂控制、足式机器人运动规划等。我最早接触VeRL是在开发仓储自动化项…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

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

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

📞 💬