Kornia RandomTransplantation 的 MPS 后端空轴过滤 Bug 修复解析(4160)
计算机视觉人工智能深度学习图像处理【免费下载链接】kornia Geometric Computer Vision Library for Spatial AI项目地址https://gitcode.com/gh_mirrors/ko/kornia点击查看免费下载导读本文围绕 Kornia 版本迁移记录 changelog.d/migration-101.fixed.md 展开深入解析一个与 Apple MPS 后端直接相关的数据增强缺陷RandomTransplantation与RandomTransplantation3D在未指定excluded_labels时会在 MPS 设备上移植失败——输出完全等于输入。读完本文你将掌握该 Bug 的根因PyTorch MPS 后端对空轴all()的未定义求值、官方修复策略无物可排除时跳过过滤以及如何通过源码与测试用例验证修复行为。一、Bug 现象与影响范围1.1 现象描述根据 changelog.d/migration-101.fixed.md 的原始记录RandomTransplantationandRandomTransplantation3Dtransplanted nothing on MPS when noexcluded_labelswere given.也就是说在 Apple MPSMetal Performance Shaders后端上只要用户没有显式传入excluded_labels参数移植transplantation增强就会静默失效本应把批次中某张图的某个语义标签对应的像素区域复制粘贴到另一张图上结果输出与输入完全一致增强形同虚设。1.2 影响对象涉及两个公开 API均已在 kornia/augmentation/init.py 的__all__中导出RandomTransplantation、RandomTransplantation3D见 kornia/augmentation/init.pyRandomTransplantation2D 版本定义于 kornia/augmentation/_2d/mix/transplantation.py继承自MixAugmentationBaseV2RandomTransplantation3D3D 版本定义于 kornia/augmentation/_3d/mix/transplantation.py多重继承RandomTransplantation与AugmentationBase3D用于在AugmentationSequential容器内处理(B, C, D, H, W)体积数据。两者共享同一套核心逻辑因此 Bug 同时影响 2D 与 3D 场景。该增强算法源自论文《Semantic segmentation of surgical hyperspectral images under geometric domain shifts》sellner2023semantic常用于医学影像等需要跨样本语义对象复制的场景。二、RandomTransplantation 的工作原理回顾要理解这个 Bug先要理解移植增强的算法流程。根据 kornia/augmentation/_2d/mix/transplantation.py 的文档字符串其工作方式分为三步选定受体acceptor根据概率参数p从批次中挑选若干图像作为受体确定供体donor每个受体的供体是批次中位于其下方的一张图通过循环取模规则i - 1 mod B得到即donor_indices (acceptor_indices - 1) % batch_size见 params_from_input随机移植从供体的语义分割掩码中随机选取一个标签label把供体上该标签对应的图像特征与分割掩码区域整体复制到受体对应位置。移植由批次中第一个mask输入驱动可同时作用于图像DataKey.INPUT形状(B, C, *spatial)与掩码DataKey.MASK形状(B, *spatial)。数据键的默认顺序为[DataKey.INPUT, DataKey.MASK]见init。2.1 excluded_labels 参数的作用excluded_labels是移植增强的黑名单sequence of labels which should not be transplanted from a donor. This can be useful if only parts of the image are annotated and the non-annotated regions (with a specific label index) should be excluded from the augmentation.它常用于图像只有部分区域被标注的场景——例如标签 0 代表未标注区域此时应把标签 0 排除在可移植标签之外避免把无标注区域复制到其他样本上。构造函数中该参数默认值为None会被归一化为空列表再转为空张量见initif excluded_labels is None: excluded_labels [] if not isinstance(excluded_labels, torch.Tensor): excluded_labels torch.tensor(excluded_labels) self.excluded_labels: torch.Tensor excluded_labels2.2 标签筛选的底层实现在 params_from_input 中供体掩码的唯一标签会与excluded_labels做差集过滤if selected_labels not in params and selection not in params: if self.excluded_labels.device ! mask.device: self.excluded_labels self.excluded_labels.to(mask.device) donor_labels: list[torch.Tensor] [] eligible: list[int] [] for d in range(len(params[donor_indices])): current_mask mask[params[donor_indices][d]] labels current_mask.unique() if self.excluded_labels.numel() 0: labels labels[(labels.view(1, -1) ! self.excluded_labels.view(-1, 1)).all(dim0)] ...关键逻辑在于labels.view(1, -1) ! self.excluded_labels.view(-1, 1)这行它构造一个标签 × 排除项的布尔矩阵随后沿排除项轴dim0做.all()归约从而筛选出不等于任何排除标签的候选标签。三、Bug 根因MPS 后端对空轴all()的未定义求值3.1 为什么默认情况下会触发由于excluded_labels默认为空numel() 0当用户不传该参数时布尔矩阵的排除项维度大小为 0。此时沿空轴做all()归约在 CPU 与 CUDA 后端上会返回True数学上空集的全称命题为真即全标签都保留但在PyTorch 的 MPS 后端PyTorch 2.9上对空轴的all()求值结果是未定义的通常返回False。返回值一旦是False就意味着每一个供体标签都会被过滤掉labels被清空为长度为 0 的张量len(labels) 0判断失败该供体被判定为无合格标签其对应的受体从acceptor_indices中被剔除params_from_inputbatch_prob对应项被清零结果就是所有受体都不再是受体输出等于输入。这正是迁移记录中描述的transplanted nothing的完整机制。需要注意此处all()的语义是沿排除项这一空轴归约而非沿标签轴因此修复不能简单地替换all()的调用方式。3.2 为什么这是一个隐蔽的跨后端一致性问题同类归约在 CPU/CUDA 与 MPS 上的行为不一致属于典型的**后端语义差异backend semantic divergence**问题。同样的代码在 Linux/CUDA 环境测试通过一旦迁移到 Apple Silicon 的 MPS 环境增强器会静默失效且不抛任何异常——这对训练管线极具迷惑性因为增强无效果不会导致报错只会降低数据多样性、影响模型泛化且极难定位。四、官方修复方案无物可排除时跳过过滤4.1 修复后的源码修复的核心思路非常直接当excluded_labels为空时完全跳过差集过滤步骤不做空轴all()归约。修复后的代码在 kornia/augmentation/_2d/mix/transplantation.py 中体现为# Remove any label which is part of the excluded labels. Skip the reduction when there is nothing # to exclude: on MPS (PyTorch 2.9) all over an empty axis yields an undefined result, usually # False, where CPU and CUDA return True, and the filter would then discard every label. if self.excluded_labels.numel() 0: labels labels[(labels.view(1, -1) ! self.excluded_labels.view(-1, 1)).all(dim0)]修复后空排除表场景下labels直接保留current_mask.unique()的全部结果标签抽取labels[torch.randperm(len(labels))[0]]得以正常进行移植逻辑恢复可用。4.2 修复的边界影响需要特别指出的是该修复没有改变以下既有行为这些行为仍由 kornia/augmentation/_2d/mix/transplantation.py 中的逻辑保证当供体掩码本身没有任何标签如全空掩码时len(labels) 0依旧为假该供体仍会被判为无物可给其受体照常被剔除——这是算法设计的预期行为与排除表无关当excluded_labels非空、但恰好排除了供体的全部标签时过滤逻辑正常运行此时归约轴非空MPS 行为确定受体同样会被剔除标签抽取仍基于全局 CPU 随机生成器的torch.randperm测试test_convention_label_draw_uses_the_cpu_generator_whatever_the_device验证了这一点无论掩码位于何种设备随机状态不受影响。五、测试用例如何验证修复修复并非孤立的代码改动而是伴随一套可执行测试用于固化约定并防止回归。围绕移植增强的约定测试集中在 tests/augmentation/test_conventions_transplantation.py 与 tests/augmentation/test_conventions_3d.py 中相关变更记录见 changelog.d/4695.added.mdDocument the conventions ofRandomTransplantationandRandomTransplantation3D... with executable tests。与本文 Bug 直接相关的测试覆盖点包括默认空排除表的行为例如test_convention_transplant_follows_the_device_and_dtype_of_its_inputstests/augmentation/test_conventions_transplantation.py在构造RandomTransplantation(p1.0, excluded_labels[0])时明确注释 the exclusion list starts on the CPU验证排除列表会随输入迁移到目标设备且移植结果等于整行滚动image.roll(1, dims0)空掩码的边界情况测试注释明确 An empty mask has no label at all, so nothing is eligible: empty in, empty out, no raise见 tests/augmentation/test_conventions_transplantation.py说明空供体掩码的无合格标签路径与空排除表的路径是两条独立逻辑前者仍按设计剔除受体供体无需是受体test_convention_donor_need_not_be_an_acceptor验证供体取完整批次中的前驱(i - 1) mod B即使该前驱本身未被选中为受体也照常充当供体tests/augmentation/test_conventions_transplantation.py3D 类的容器行为tests/augmentation/test_conventions_3d.py 枚举 3D 子类确认RandomTransplantation3D是容器中唯一携带 mixinverse抛RuntimeError的 3D 增强并验证p_batch0.0时完全跳过。这些测试同时锁定了_params中batch_prob、acceptor_indices、donor_indices、selected_labels、selection等字段的契约确保后续任何后端相关的改动不会破坏参数重放replay语义。六、对使用者的实操建议结合本次修复在实际使用RandomTransplantation/RandomTransplantation3D时有几点值得注意升级即修复该修复随 migration-101 合入当前仓库主干。若你在 Apple Silicon MPS 环境下使用 Kornia且观察到移植增强无效输出等于输入升级到包含 #4160 修复的版本即可解决默认参数是安全的修复后不传excluded_labels即默认空表在 MPS、CPU、CUDA 上行为一致无需为了规避 Bug 而刻意传入空列表或占位排除项显式排除表的语义不变如果你用excluded_labels排除未标注区域如标签 0请确保排除列表确实与掩码中的标签值对应一旦供体掩码中剩余标签为空对应受体仍会被剔除这是设计行为见 params_from_input批次其余部分照常移植注意容器中的排名约束在AugmentationSequential中使用时2D 图像用RandomTransplantation、5D 体积用RandomTransplantation3D且移植类在容器中只能作为第一步——一旦其他增强运行过容器会把掩码递进为(B, 1, H, W)移植类会因排名规则拒绝处理详见 kornia/augmentation/_2d/mix/transplantation.py 的约定说明与 issue #4707跨设备迁移注意excluded_labels张量初始创建在 CPU构造函数中torch.tensor(excluded_labels)会在params_from_input中自动迁移到掩码所在设备kornia/augmentation/_2d/mix/transplantation.py无需手动干预。七、总结本次 #4160 修复是典型的后端语义差异导致的静默失效案例PyTorch MPS 后端2.9对空轴all()返回未定义值通常False而 CPU/CUDA 返回True导致RandomTransplantation/RandomTransplantation3D在默认无excluded_labels时过滤掉全部供体标签输出等于输入。修复方案简单而精准——无物可排除时跳过过滤归约配合 tests/augmentation/test_conventions_transplantation.py 与 tests/augmentation/test_conventions_3d.py 中的可执行约定测试保证了跨后端行为的一致性。对于在 Apple Silicon 上做语义分割数据增强的开发者这一修复直接关系到移植增强是否真正生效值得纳入升级清单。赞分享计算机视觉人工智能深度学习图像处理【免费下载链接】kornia Geometric Computer Vision Library for Spatial AI项目地址https://gitcode.com/gh_mirrors/ko/kornia点击查看免费下载相关推荐Kornia 修复 RandomTransplantation 在 MPS 上的移植失效空 excluded_labels 触发的 all() 归约陷阱与规避方案Kornia 修复 RandomTransplantation 在 MPS 上的移植失效空 excluded_labels 触发的 all 归约陷阱与规避方案计算机视觉深度学习人工智能图像处理Kornia 修复 Apple MPS 后端 SVD 8192 元素上限_torch_svd_cast 的 CPU 回退机制解析Kornia 修复 Apple MPS 后端 SVD 8192 元素上限 _torch_svd_cast 的 CPU 回退机制解析 导读 本文围绕 Korni计算机视觉人工智能深度学习图像处理Kornia 修复 MPS 等加速器后端的空张量转换YUV420/YUV422 空输入语义与 reshape 歧义问题深度解析Kornia 修复 MPS 等加速器后端的空张量转换YUV420/YUV422 空输入语义与 reshape 歧义问题深度解析 导读 本文围绕 Kornia计算机视觉深度学习人工智能图像处理创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Mosquitto 1.4.2 版本剖析:Broker 与客户端库关键缺陷修复详解

Mosquitto 1.4.2 版本剖析:Broker 与客户端库关键缺陷修复详解

后端消息队列消息路由 【免费下载链接】mosquitto Eclipse Mosquitto - An open source MQTT broker 项目地址: https://gitcode.com/gh_mirrors/mos/mosquitto 点击查看 免费下载 Mosquitto 1.4.2 是 Eclipse Mosquitto 在 2015 年 5 月发布的一个纯缺陷修复&…

2026/9/24 2:58:15 阅读更多 →
AI正在拆掉传统界面:从表单到对话,人机交互的范式转移

AI正在拆掉传统界面:从表单到对话,人机交互的范式转移

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/24 2:58:15 阅读更多 →
Segment Anything (SAM) 实战指南:在 AI-Research-SKILLs 中用点、框与掩码提示实现零样本图像分割

Segment Anything (SAM) 实战指南:在 AI-Research-SKILLs 中用点、框与掩码提示实现零样本图像分割

AI 技能人工智能大模型深度学习 【免费下载链接】AI-Research-SKILLs Comprehensive open-source library of AI research and engineering skills for any AI model. Package the skills and your claude code/codex/gemini agent will be an AI research agent with full hor…

2026/9/24 2:58:15 阅读更多 →

最新新闻

弱口令致240万勒索损失:攻击链路与防守实操

弱口令致240万勒索损失:攻击链路与防守实操

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/24 3:36:40 阅读更多 →
DeepSeek Harness调研一览

DeepSeek Harness调研一览

1. 项目定位 DeepSeek Harness(简称 dsh)是 DeepSeek 官方开源的 Agent Harness。它可以概括为:Agent Model(大脑) Harness(工具、记忆、流程与运行环境)。 官方的定位是“一切皆插件”。 熟…

2026/9/24 3:36:40 阅读更多 →
区域PSS综述:从建模、选址到时滞补偿与自适应协调控制

区域PSS综述:从建模、选址到时滞补偿与自适应协调控制

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/24 3:36:40 阅读更多 →
实测|夸克网盘新用户 1TB 空间领取完整攻略(附官方规则解读 + 避坑清单)

实测|夸克网盘新用户 1TB 空间领取完整攻略(附官方规则解读 + 避坑清单)

写在前面 前几天整理资料的时候,系统又弹出那个熟悉的提示:存储空间不足。 默认那 10GB,放两部高清电影、几套网课视频就见底了。删吧舍不得,充会员吧又觉得为了偶尔存点东西开月卡不值当。 后来在群里看到有人甩了个夸克网盘的链…

2026/9/24 3:36:39 阅读更多 →
N1盒子刷Armbian安装CasaOS:轻量级NAS搭建与内网穿透指南

N1盒子刷Armbian安装CasaOS:轻量级NAS搭建与内网穿透指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/24 3:36:39 阅读更多 →
Cadence IC618+180nm PDK双平衡吉尔伯特混频器仿真全流程

Cadence IC618+180nm PDK双平衡吉尔伯特混频器仿真全流程

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/24 3:35:39 阅读更多 →

日新闻

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为…

2026/9/24 0:00:19 阅读更多 →
单细胞注释实战:基于Scanpy的标记基因与参考映射流程解析

单细胞注释实战:基于Scanpy的标记基因与参考映射流程解析

简介:一份基于单细胞RNA测序数据的细胞类型注释算法研究Python毕业设计源码,针对计算机相关专业正在做毕设或需要项目实战的学习者,可用于课程设计与期末大作业。项目代码完整、经导师指导评审通过,可直接运行,覆盖数据…

2026/9/24 0:00:19 阅读更多 →
C#源生成器实战:用增量生成器替代反射,告别AOT崩溃

C#源生成器实战:用增量生成器替代反射,告别AOT崩溃

第一次在项目里被反射卡住,是在一个老旧的WinForms模块里:几十个类依赖PropertyChanged通知,运行时反射读属性、发通知,每次启动慢半拍不说,一上.NET Native/AOT裁剪模式几乎全面崩盘。后来我把这段逻辑全部改成C#源生…

2026/9/24 0:00:19 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/23 4:55:02 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/23 4:49:06 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/23 9:53:41 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/23 9:53:40 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/23 9:53:40 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/23 9:53:40 阅读更多 →