首页/新闻资讯/正文详情

Kornia 修复 MPS/CUDA 跨设备增强 RuntimeError:batch_prob 掩码的设备迁移与 branchless 混合原理

发布时间:2026/9/24 3:19:41 来源:云帆数科 栏目:资讯中心
Kornia 修复 MPS/CUDA 跨设备增强 RuntimeError:batch_prob 掩码的设备迁移与 branchless 混合原理
计算机视觉人工智能深度学习图像处理【免费下载链接】kornia Geometric Computer Vision Library for Spatial AI项目地址https://gitcode.com/gh_mirrors/ko/kornia点击查看免费下载本指南讲解 Kornia 增强模块在 CPU 生成随机参数、输入位于 MPS 或 CUDA 加速器时抛出跨设备RuntimeError的根因与官方修复方案changelog 条目migration-109.fixed.mdissue #4164。读完本文你将掌握batch_prob门控掩码的生成与消费路径、四处torch.wherebranchless 混合的实现细节以及修复后augmentation(x_accelerator)的正确用法与残留限制。问题背景默认 CPU 随机数生成与加速器输入之间的矛盾Kornia 的增强模块kornia.augmentation在设计上有一个重要约定随机参数默认在 CPU 上生成与输入张量的设备无关。这一约定体现在 kornia/augmentation/base.py 的基类构造函数中def __init__( self, p: float 0.5, p_batch: float 1.0, same_on_batch: bool False, keepdim: bool False, ) - None: super().__init__() self.p p self.p_batch p_batch self.same_on_batch same_on_batch self.keepdim keepdim self._params: Dict[str, torch.Tensor] {} self._param_generator: Optional[RandomGeneratorBase] None self.flags: Dict[str, Any] {} self.set_rng_device_and_dtype(torch.device(cpu), torch.get_default_dtype())也就是说模块实例化后其 RNG 相关状态包括self.device与self.dtype默认落在 CPU。这样做的好处是跨设备可复现同一随机种子在不同设备上采样出完全一致的增强参数便于训练/评估结果对齐。其中最关键的门控张量是batch_prob它由__batch_prob_generator__生成kornia/augmentation/base.pydef __batch_prob_generator__( self, batch_shape: Tuple[int, ...], p: float, p_batch: float, same_on_batch: bool, ) - torch.Tensor: batch_prob: torch.Tensor if p_batch 1: batch_prob torch.ones(1, deviceself.device, dtypeself.dtype) elif p_batch 0: batch_prob torch.zeros(1, deviceself.device, dtypeself.dtype) else: batch_prob (torch.rand(1, deviceself.device) p_batch).to(self.dtype) elem_prob: torch.Tensor if p 1: elem_prob torch.ones(batch_shape[0], deviceself.device, dtypeself.dtype) elif p 0: elem_prob torch.zeros(batch_shape[0], deviceself.device, dtypeself.dtype) elif same_on_batch: elem_prob (torch.rand(1, deviceself.device) p).to(self.dtype).expand(batch_shape[0]) else: elem_prob (torch.rand(batch_shape[0], deviceself.device) p).to(self.dtype) # Branchless combine (replaces the>staticmethod def _blend_by_prob( transformed: torch.Tensor, not_transformed: torch.Tensor, to_apply: torch.Tensor ) - torch.Tensor: Select transformed vs non-transformed samples element-wise by to_apply. When the two branches share a shape this is a torch.where blend (onnx- and fullgraph-friendly). Shape-changing augmentations (e.g. crop/resize) whose branches differ in spatial size fall back to a Python branch on to_apply.any(), which is not onnx-exportable. if transformed.shape not_transformed.shape and transformed.shape[0] to_apply.shape[0]: to_apply_expanded to_apply.view(-1, *([1] * (len(transformed.shape) - 1))).to(transformed.device) return torch.where(to_apply_expanded, transformed, not_transformed) return transformed if bool(to_apply.any()) else not_transformed关键一行是to_apply_expanded to_apply.view(-1, *([1] * (len(transformed.shape) - 1))).to(transformed.device)先沿 batch 维把形状为(B,)的掩码广播展开为(B, 1, 1, ...)再迁移到transformed所在设备最后执行torch.where。2. 2D 几何/仿射矩阵路径kornia/augmentation/_2d/base.py 的RigidAffineAugmentationBase2D.generate_transformation_matrixbatch_prob params[batch_prob] to_apply torch.atleast_1d(batch_prob 0.5) in_tensor self.transform_tensor(input) trans_matrix_applied self.compute_transformation(in_tensor, paramsparams, flagsflags) if self.p 1.0 and self.p_batch 1.0: # Always applied (static probabilities): skip building the identity and the where. trans_matrix trans_matrix_applied if is_autocast_enabled(): trans_matrix trans_matrix.type(input.dtype) return trans_matrix trans_matrix_identity self.identity_matrix(in_tensor) if is_autocast_enabled(): trans_matrix_applied trans_matrix_applied.type(input.dtype) trans_matrix_identity trans_matrix_identity.type(input.dtype) if trans_matrix_applied.shape[0] to_apply.shape[0] trans_matrix_identity.shape[0]: to_apply_expanded to_apply.view(-1, *([1] * (trans_matrix_applied.dim() - 1))).to( trans_matrix_applied.device ) trans_matrix torch.where(to_apply_expanded, trans_matrix_applied, trans_matrix_identity) else: # e.g. VideoSequential passes B-sized batch_prob into a B*T-sized input trans_matrix trans_matrix_applied if bool(to_apply.any()) else trans_matrix_identity这里还有一处值得注意的配套优化当p 1.0且p_batch 1.0静态全应用时直接返回计算矩阵跳过身份矩阵的构建与torch.where混合——注释指出该矩阵路径约占一次 flip forward 开销的 40%这是针对热路径的额外加速与本次设备修复同属本次变更的一部分。3. 3D 矩阵路径kornia/augmentation/_3d/base.py 与 2D 版本对称同样在torch.where前执行.to(trans_matrix_applied.device)batch_prob params[batch_prob] to_apply torch.atleast_1d(batch_prob 0.5) in_tensor self.transform_tensor(input) trans_matrix_applied self.compute_transformation(in_tensor, paramsparams, flagsflags) trans_matrix_identity self.identity_matrix(in_tensor) if trans_matrix_applied.shape[0] to_apply.shape[0] trans_matrix_identity.shape[0]: to_apply_expanded to_apply.view(-1, *([1] * (trans_matrix_applied.dim() - 1))).to( trans_matrix_applied.device ) trans_matrix torch.where(to_apply_expanded, trans_matrix_applied, trans_matrix_identity) else: trans_matrix trans_matrix_applied if bool(to_apply.any()) else trans_matrix_identity4. Mix 增强路径kornia/augmentation/_2d/mix/base.py 的transform_inputbatch_prob params[batch_prob] to_apply torch.atleast_1d(batch_prob 0.5) ori_shape input.shape in_tensor self.transform_tensor(input) # Compute the non-transform branch first; if no element is to be transformed, short-circuit # (mix transforms like RandomJigsaw subset their input internally and cant operate on an # empty subset). non_applied self.apply_non_transform(in_tensor, params, flags) if not bool(to_apply.any()): output non_applied return _transform_output_shape(output, ori_shape) if self.keepdim else output applied self.apply_transform(in_tensor, params, flags) applied_post self.apply_non_transform(applied, params, flags) if applied_post.shape non_applied.shape and applied_post.shape[0] to_apply.shape[0]: to_apply_expanded to_apply.view(-1, *([1] * (applied_post.dim() - 1))).to(applied_post.device) output torch.where(to_apply_expanded, applied_post, non_applied) else: # Shape-changing mix augmentations (e.g. RandomMosaic with different output_size) # cannot be where-blended. Fall back to the all-applied branch. output applied_post return _transform_output_shape(output, ori_shape) if self.keepdim else outputMix 路径除了设备迁移还保留了“形状变化时退化为全应用分支”的兜底逻辑——例如RandomMosaic在output_size与输入尺寸不一致时无法做逐元素where混合只能整体应用。修复后的行为与正确用法修复后最直观的变化是直接对加速器张量调用增强模块即可无需再手动迁移模块或其 RNG。修复前需要这样绕过#4151 中的 workaroundimport torch from kornia.augmentation import RandomHorizontalFlip x torch.randn(4, 3, 224, 224, devicecuda) # 或 mps # 修复前必须把模块连同其 RNG 状态先搬到加速器 aug RandomHorizontalFlip(p0.5).to(cuda) y aug(x)修复后可以直接调用import torch from kornia.augmentation import RandomHorizontalFlip x torch.randn(4, 3, 224, 224, devicecuda) # 或 torch.device(mps) aug RandomHorizontalFlip(p0.5) # 保持默认RNG 在 CPU y aug(x) # 修复后正常返回无跨设备错误这一用法对所有继承链均生效2D 强度/几何增强走_blend_by_prob与 2D 矩阵路径3D 增强走 3D 矩阵路径如 kornia/augmentation/_3d/base.py 的generate_transformation_matrixMix 增强走 kornia/augmentation/_2d/mix/base.py 的transform_input包括 MixUp、CutMix、RandomJigsaw、RandomMosaic 等。同时保持了两个既有优势不变CPU 随机数生成batch_prob与各类参数仍在 CPU 采样torch.manual_seed后在不同设备上得到一致的采样序列跨设备可复现性不受影响ONNX / fullgraph 友好混合仍是无 Python 分支的torch.where形式torch.compile(fullgraphTrue)与 ONNX 导出路径不受破坏形状变化的增强除外见下文。边界情况与已知限制修复并非万能以下几点需要在使用中留意均可在源码注释与文档中找到依据形状变化的增强仍不可 ONNX 导出_blend_by_prob的 docstring 明确说明当变换/非变换分支形状不同如 crop、resize 类时会退化为基于to_apply.any()的 Python 分支该路径不可 ONNX 导出torch.compile的fullgraphTrue也因此对这类增强不保证成立kornia/augmentation/base.py。静态概率快速路径p 1.0 and p_batch 1.0时直接返回变换结果连batch_prob门控都不计算kornia/augmentation/_2d/base.py这同时让Resize这类形状变化的增强在静态概率下可以 fullgraph 编译。mix 的 mask/boxes/keypoints/class 数据键不走torch.wherekornia/augmentation/_2d/mix/base.py 中的transform_mask、transform_boxes、transform_keypoint、transform_class使用sum(to_apply)的 Python 分支选择不涉及跨设备混合因此不受此 bug 影响。set_rng_device_and_dtype迁移不完整文档与源码kornia/augmentation/base.py均提醒该方法会更新门控与参数生成器的采样器但部分生成器仍保留内部 CPU 张量或忽略指定精度某些生成器/设备组合在 forward 期间仍可能失败issue #4426。因此推荐做法仍是“RNG 留在 CPU、由混合边界负责掩码迁移”而不是依赖set_rng_device_and_dtype把采样搬到加速器。B 0空批次空批次在多数类上返回空输出但并非全库保证少数类在B 0时会抛异常。测试验证本次修复的回归验证覆盖在增强测试套件中。tests/augmentation/container/test_augmentation_sequential.py通过device/dtype参数化测试包括使用get_cuda_or_mps_device_if_available这类测试辅助函数获取可用加速器其名称出现在 tests/api_surface.json 的公开工具清单中在 CUDA 与 MPS 设备上验证 2D、3D 与 mix 增强的前向行为其中包含对 MPS 上float64输入的专门判断if device.type mps and image_dtype torch.float64。结合本修复这些测试确认了augmentation(x_accelerator)在各设备上的正常执行。小结migration-109这项修复issue #4164解决的是一个典型的“设备归属”问题torch.where的掩码与操作数必须同设备而 Kornia 有意让随机参数留在 CPU。修复在四个 branchless 混合边界统一执行to_apply.to(transformed.device)以极小的改动同时满足了三点诉求——加速器输入直接可用、CPU RNG 跨设备可复现、ONNX/fullgraph 友好的混合结构不受破坏。理解这条变更的细节有助于你在使用 Kornia 增强管线时正确安排模块与数据的设备关系并规避形状变化增强与 RNG 迁移方面的已知坑位。赞分享计算机视觉人工智能深度学习图像处理【免费下载链接】kornia Geometric Computer Vision Library for Spatial AI项目地址https://gitcode.com/gh_mirrors/ko/kornia点击查看免费下载相关推荐Kornia 跨设备增强修复解析CPU 随机掩码与 MPS/CUDA 输入的设备一致性方案Kornia 跨设备增强修复解析CPU 随机掩码与 MPS/CUDA 输入的设备一致性方案 本篇技术文章围绕 Kornia 仓库 changelog 中的 计算机视觉深度学习人工智能图像处理Kornia 增强模块 CUDA torch.compile 常量搬运规避与采样器设备/dtype 迁移修复Kornia 增强模块 CUDA torch.compile 常量搬运规避与采样器设备/dtype 迁移修复 本篇文章围绕 Kornia 增强augmenta计算机视觉人工智能深度学习图像处理Kornia RandomAffine 与 RandomPerspective 的 CUDA 编译修复与随机生成器设备迁移语义Kornia RandomAffine 与 RandomPerspective 的 CUDA 编译修复与随机生成器设备迁移语义 导读 本篇文章围绕 Kornia计算机视觉深度学习人工智能图像处理创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

Qt静态交叉编译实战:aarch64嵌入式部署与避坑指南
Qt静态交叉编译实战:aarch64嵌入式部署与避坑指南

/* 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:19:23

Kornia LAF 补丁提取的 CPU 半精度采样修复:float32 回退与批处理 grid_sample 优化解析
Kornia LAF 补丁提取的 CPU 半精度采样修复:float32 回退与批处理 grid_sample 优化解析

计算机视觉深度学习人工智能图像处理 【免费下载链接】kornia 🐍 空间人工智能的几何计算机视觉库 项目地址: https://gitcode.com/kornia/kornia 点击查看 免费下载 导读 本文围绕 changelog.d/migration-110.fixed.md 记录的一次关键修复展开&#x… · 2026/9/24 3:18:59

Qt 6.8 LTS与Qt for MCUs 2.9深度解析:嵌入式GUI选型与迁移实战
Qt 6.8 LTS与Qt for MCUs 2.9深度解析:嵌入式GUI选型与迁移实战

/* 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:18:52

Triton Inference Server C API 内嵌模式指南:通过 libtritonserver.so 将推理服务直接集成进 C/C++ 应用
Triton Inference Server C API 内嵌模式指南:通过 libtritonserver.so 将推理服务直接集成进 C/C++ 应用

模型推理服务AI 应用后端 【免费下载链接】server The Triton Inference Server provides an optimized cloud and edge inferencing solution. 项目地址: https://gitcode.com/gh_mirrors/server117/server 点击查看 免费下载 本篇技术指南以 Triton Inference S… · 2026/9/24 4:08:28

图腾柱驱动电路设计:MOSFET高效开关的工程实践指南
图腾柱驱动电路设计:MOSFET高效开关的工程实践指南

/* 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 4:08:28

Mineradio 2.2.0 沉浸式音乐播放器技术指南:Electron 架构、NSIS 构建与更新分发机制解析
Mineradio 2.2.0 沉浸式音乐播放器技术指南:Electron 架构、NSIS 构建与更新分发机制解析

桌面应用音视频 【免费下载链接】Mineradio-paused 一款以电影镜头、粒子视觉和歌词舞台为核心的沉浸式音乐播放器。 项目地址: https://gitcode.com/gh_mirrors/mi/Mineradio-paused 点击查看 免费下载 Mineradio 是一款以电影镜头、粒子视觉和歌词舞台为核心的 W… · 2026/9/24 4:08:21

STM32上CORDIC算法实现高速sin/cos计算:原理、代码与实测对比
STM32上CORDIC算法实现高速sin/cos计算:原理、代码与实测对比

/* 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 4:08:21

Razzle 集成 styled-components:服务端渲染下 CSS-in-JS 样式的收集与注入完整指南
Razzle 集成 styled-components:服务端渲染下 CSS-in-JS 样式的收集与注入完整指南

前端构建工具前端构建后端 【免费下载链接】razzle ✨ Create server-rendered universal JavaScript applications with no configuration 项目地址: https://gitcode.com/gh_mirrors/ra/razzle 点击查看 免费下载 本文围绕 Razzle 官方示例 with-styled-componen… · 2026/9/24 4:08:03

Convex 自托管数据清理完全指南:用空快照导入安全重置数据库
Convex 自托管数据清理完全指南:用空快照导入安全重置数据库

数据库后端 【免费下载链接】convex-backend The open-source reactive database for app developers 项目地址: https://gitcode.com/gh_mirrors/co/convex-backend 点击查看 免费下载 数据清除(Clearing Data)是自托管 Convex 部署运维中最… · 2026/9/24 4:07:57

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

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

1D-CNN时间序列建模实战:从Conv1d原理到工业落地
1D-CNN时间序列建模实战:从Conv1d原理到工业落地

简介:面向时间序列数据建模的一维卷积神经网络完整实现,适合深度学习入门者及需要快速验证时序模型的研究者,能够从音频、文本、传感器或股价等序列中挖掘局部特征与时间依赖。压缩包体积很小,只有3KB,内含3个Python脚… · 2026/9/24 0:00:26

柔软的L:汉语语流中被忽视的舌肌张力控制
柔软的L:汉语语流中被忽视的舌肌张力控制

1. 这个“L”不是字母表里的L,而是舌尖上的L最近在几个方言群和语音教学社群里,反复看到有人发一句:“也说字母L:柔软的长舌”。初看以为是英语发音课笔记,点开才发现全是方言爱好者、播音系学生、语言康复师甚至戏曲演… · 2026/9/24 0:00:44

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码