asnumpy让你的 NumPy 代码零改动跑在昇腾 NPU 上有个同事之前跟我说他写了一套数据预处理的 pipeline全是 NumPy 写的后来要迁移到昇腾 NPU 上跑“感觉天都要塌了”——几千行 NumPy 代码难道要全部重写后来他发现了 asnumpy这个东西基本上解决了这个问题。不需要改你的 NumPy 代码直接换一下 import数据搬上 NPU 跑原来的语法一个不动。先搞清楚 asnumpy 是什么asnumpy 不是 NumPy 的替代品它是昇腾 NPU 对 NumPy API 的一层兼容封装。你写的是 NumPy 代码但底层跑在了昇腾 NPU 的向量计算单元上。这里有个容易混淆的地方asnumpy 不等于 NumPy 本身。NumPy 是 CPU 上的 Python 数值计算库asnumpy 是昇腾 NPU 的同名实现API 签名几乎一致但底层硬件完全不同。如果你看到有人说用 asnumpy 替换 NumPy这个说法是不准确的——正确理解是用 asnumpy 的接口来写代码享受 NPU 的加速。asnumpy 属于 ops-tensor 仓库的一部分和 ops-math、ops-nn 这些算子库并列。同一个父项目下不同的算子能力asnumpy 主要负责向量级别的数值计算支持。为什么要用它标准 NumPy 在 CPU 上跑数据要先从 NPU 的显存里搬到 CPU 内存算完再搬回去。这个来回搬运的过程在数据量大的时候开销非常可观。举个例子你有一段图像预处理的代码importnumpyasnp# 原始 NumPy 版本CPUdefpreprocess(image):imageimage.astype(np.float32)/255.0meannp.array([0.485,0.456,0.406])stdnp.array([0.229,0.224,0.225])image(image-mean)/stdreturnimage如果你想在昇腾 NPU 上跑这个预处理通常的做法是把数据从 NPU 搬到 CPU用 NumPy 算完再搬回去——等于白加速了预处理部分。asnumpy 的思路是让这部分计算直接在 NPU 上完成不用搬运。importascendnumpyasnp# 直接替换 import# 同一个函数一个字不用改数据全程在 NPU 上defpreprocess(image):imageimage.astype(np.float32)/255.0meannp.array([0.485,0.456,0.406])stdnp.array([0.229,0.224,0.225])image(image-mean)/stdreturnimage这样预处理和模型推理都在 NPU 上数据零拷贝。这个零改动的体验是 asnumpy 最核心的价值。常用操作速查asnumpy 的 API 覆盖了 NumPy 的常用子集不是 100% 全覆盖但主流操作基本都有。我列几个最常用的importascendnumpyasnp# 张量创建anp.zeros((1024,1024),dtypenp.float32)bnp.ones((512,512))cnp.random.randn(256,256).astype(np.float16)# 数学运算dnp.matmul(a,b)# 矩阵乘法昇腾 NPU 硬件加速enp.sum(c,axis0)# 按列求和fnp.mean(c,axis1)# 按行求均值gnp.clip(a,0,1)# 截断# 数据类型转换asnumpy 特有ha.asnpu()# 转为 NPU 显存格式提交给模型推理用ih.ascpu()# 从 NPU 拿回 CPU结果导出用这里要特别说一说asnpu()和ascpu()这一对方法。这是 asnumpy 和标准 NumPy 最大的差异——你写的代码可以全程跑在 NPU 上但总有需要把结果拿回 CPU 的时候比如保存文件、打印日志、写磁盘。这两个方法就是连接 NPU 和 CPU 数据的桥。# 典型场景预处理在 NPU算完拿回 CPU 存图resultpreprocess(image_npu)result_cpuresult.ascpu()# 这步才是真正有开销的但只跑一次# 相反方向CPU 数据批量喂给 NPUimages[load_image(f)forfinimage_paths]# CPU 上读取images_npu[img.asnpu()forimginimages]# 批量上传 NPUasnumpy 和 catlass 的区别有人会问asnumpy 也能算矩阵乘法catlass 也是做矩阵运算的它们是什么关系这个问题问得好。简单说asnumpy 是给数据处理用的catlass 是给算子开发用的。asnumpy 的矩阵乘法是封装好的高层接口你调一下np.matmul它内部帮你把数据切块、调度硬件资源你不需要关心底层怎么实现的。catlass 是昇腾算子模板库提供了 GEMM通用矩阵乘法的底层开发框架你需要自己写 tiling 逻辑、SRAM 使用策略然后编译成可调用的算子。一个面向应用开发者一个面向算子开发者。日常写预处理脚本、做数据增强asnumpy 够用了如果你要开发新的融合算子、优化特定算子的性能上限那得看 catlass。昇腾异构计算架构里这两层的定位是不同的AscendCL应用层接口 └─ asnumpy数据处理API 友好 catlass算子开发层底层灵活 └─ opbase基础组件上面两个都依赖它几个容易踩的坑坑一不是所有 NumPy API 都支持。asnumpy 是 NumPy 的子集实现不支持 FFT用 ops-fft、稀疏矩阵、某些特殊的线性代数操作。如果你的代码里用到了先跑一遍看看报不报错。昇腾 CANN 的生态覆盖是逐步完善的缺的功能可以提 Issue 到社区。坑二ascpu()是隐性的性能杀手。这个方法会触发一次完整的数据从 NPU 到 CPU 的搬运有些场景下这一步会把前面的加速全部抵消。如果你的 pipeline 里频繁调用ascpu()比如每处理一张图就拿回 CPU 存一次实际上并没有省到搬运时间。正确的做法是批量处理完再统一导出或者干脆不导出直接喂给下游模型。# 低效写法每张图都搬运一次forimginimages:resultpreprocess(img)save(result.ascpu())# 每次都搬运慢了# 高效写法批量处理最后统一导出batchnp.stack([img.asnpu()forimginimages])resultspreprocess(batch)# 全程 NPUfinalresults.ascpu()# 只搬运一次坑三dtype 精度问题。asnumpy 的计算精度和 NumPy 有细微差异主要体现在 float16 和 bfloat16 上。昇腾 NPU 的向量单元对 float16 有原生支持asnumpy 默认会使用硬件加速如果你明确需要 float32 的精度需要显式指定 dtype但这样可能会触发额外的精度转换开销。这个坑在图像处理里不明显在科学计算场景里需要留意。结尾asnumpy 这个东西上手门槛很低你甚至不需要懂昇腾 NPU 的编程模型会 NumPy 就能用。但它解决的问题很实在——数据预处理不再需要绕道 CPUNPU 加速从头到尾覆盖到。如果你在昇腾 NPU 上跑 PyTorch 推理可以把数据预处理部分用 asnumpy 重写preprocess 推理统一在 NPU 上完成吞吐会比CPU 预处理 NPU 推理的串行方式高出不少。ops-tensor 仓库里除了 asnumpy还有 tensorapi 和 Blaze 等其他张量工具可以一起看看。源码在 https://atomgit.com/cann/ops-tensor。
asnumpy:让你的 NumPy 代码零改动跑在昇腾 NPU 上
发布时间:2026/5/22 1:03:13
asnumpy让你的 NumPy 代码零改动跑在昇腾 NPU 上有个同事之前跟我说他写了一套数据预处理的 pipeline全是 NumPy 写的后来要迁移到昇腾 NPU 上跑“感觉天都要塌了”——几千行 NumPy 代码难道要全部重写后来他发现了 asnumpy这个东西基本上解决了这个问题。不需要改你的 NumPy 代码直接换一下 import数据搬上 NPU 跑原来的语法一个不动。先搞清楚 asnumpy 是什么asnumpy 不是 NumPy 的替代品它是昇腾 NPU 对 NumPy API 的一层兼容封装。你写的是 NumPy 代码但底层跑在了昇腾 NPU 的向量计算单元上。这里有个容易混淆的地方asnumpy 不等于 NumPy 本身。NumPy 是 CPU 上的 Python 数值计算库asnumpy 是昇腾 NPU 的同名实现API 签名几乎一致但底层硬件完全不同。如果你看到有人说用 asnumpy 替换 NumPy这个说法是不准确的——正确理解是用 asnumpy 的接口来写代码享受 NPU 的加速。asnumpy 属于 ops-tensor 仓库的一部分和 ops-math、ops-nn 这些算子库并列。同一个父项目下不同的算子能力asnumpy 主要负责向量级别的数值计算支持。为什么要用它标准 NumPy 在 CPU 上跑数据要先从 NPU 的显存里搬到 CPU 内存算完再搬回去。这个来回搬运的过程在数据量大的时候开销非常可观。举个例子你有一段图像预处理的代码importnumpyasnp# 原始 NumPy 版本CPUdefpreprocess(image):imageimage.astype(np.float32)/255.0meannp.array([0.485,0.456,0.406])stdnp.array([0.229,0.224,0.225])image(image-mean)/stdreturnimage如果你想在昇腾 NPU 上跑这个预处理通常的做法是把数据从 NPU 搬到 CPU用 NumPy 算完再搬回去——等于白加速了预处理部分。asnumpy 的思路是让这部分计算直接在 NPU 上完成不用搬运。importascendnumpyasnp# 直接替换 import# 同一个函数一个字不用改数据全程在 NPU 上defpreprocess(image):imageimage.astype(np.float32)/255.0meannp.array([0.485,0.456,0.406])stdnp.array([0.229,0.224,0.225])image(image-mean)/stdreturnimage这样预处理和模型推理都在 NPU 上数据零拷贝。这个零改动的体验是 asnumpy 最核心的价值。常用操作速查asnumpy 的 API 覆盖了 NumPy 的常用子集不是 100% 全覆盖但主流操作基本都有。我列几个最常用的importascendnumpyasnp# 张量创建anp.zeros((1024,1024),dtypenp.float32)bnp.ones((512,512))cnp.random.randn(256,256).astype(np.float16)# 数学运算dnp.matmul(a,b)# 矩阵乘法昇腾 NPU 硬件加速enp.sum(c,axis0)# 按列求和fnp.mean(c,axis1)# 按行求均值gnp.clip(a,0,1)# 截断# 数据类型转换asnumpy 特有ha.asnpu()# 转为 NPU 显存格式提交给模型推理用ih.ascpu()# 从 NPU 拿回 CPU结果导出用这里要特别说一说asnpu()和ascpu()这一对方法。这是 asnumpy 和标准 NumPy 最大的差异——你写的代码可以全程跑在 NPU 上但总有需要把结果拿回 CPU 的时候比如保存文件、打印日志、写磁盘。这两个方法就是连接 NPU 和 CPU 数据的桥。# 典型场景预处理在 NPU算完拿回 CPU 存图resultpreprocess(image_npu)result_cpuresult.ascpu()# 这步才是真正有开销的但只跑一次# 相反方向CPU 数据批量喂给 NPUimages[load_image(f)forfinimage_paths]# CPU 上读取images_npu[img.asnpu()forimginimages]# 批量上传 NPUasnumpy 和 catlass 的区别有人会问asnumpy 也能算矩阵乘法catlass 也是做矩阵运算的它们是什么关系这个问题问得好。简单说asnumpy 是给数据处理用的catlass 是给算子开发用的。asnumpy 的矩阵乘法是封装好的高层接口你调一下np.matmul它内部帮你把数据切块、调度硬件资源你不需要关心底层怎么实现的。catlass 是昇腾算子模板库提供了 GEMM通用矩阵乘法的底层开发框架你需要自己写 tiling 逻辑、SRAM 使用策略然后编译成可调用的算子。一个面向应用开发者一个面向算子开发者。日常写预处理脚本、做数据增强asnumpy 够用了如果你要开发新的融合算子、优化特定算子的性能上限那得看 catlass。昇腾异构计算架构里这两层的定位是不同的AscendCL应用层接口 └─ asnumpy数据处理API 友好 catlass算子开发层底层灵活 └─ opbase基础组件上面两个都依赖它几个容易踩的坑坑一不是所有 NumPy API 都支持。asnumpy 是 NumPy 的子集实现不支持 FFT用 ops-fft、稀疏矩阵、某些特殊的线性代数操作。如果你的代码里用到了先跑一遍看看报不报错。昇腾 CANN 的生态覆盖是逐步完善的缺的功能可以提 Issue 到社区。坑二ascpu()是隐性的性能杀手。这个方法会触发一次完整的数据从 NPU 到 CPU 的搬运有些场景下这一步会把前面的加速全部抵消。如果你的 pipeline 里频繁调用ascpu()比如每处理一张图就拿回 CPU 存一次实际上并没有省到搬运时间。正确的做法是批量处理完再统一导出或者干脆不导出直接喂给下游模型。# 低效写法每张图都搬运一次forimginimages:resultpreprocess(img)save(result.ascpu())# 每次都搬运慢了# 高效写法批量处理最后统一导出batchnp.stack([img.asnpu()forimginimages])resultspreprocess(batch)# 全程 NPUfinalresults.ascpu()# 只搬运一次坑三dtype 精度问题。asnumpy 的计算精度和 NumPy 有细微差异主要体现在 float16 和 bfloat16 上。昇腾 NPU 的向量单元对 float16 有原生支持asnumpy 默认会使用硬件加速如果你明确需要 float32 的精度需要显式指定 dtype但这样可能会触发额外的精度转换开销。这个坑在图像处理里不明显在科学计算场景里需要留意。结尾asnumpy 这个东西上手门槛很低你甚至不需要懂昇腾 NPU 的编程模型会 NumPy 就能用。但它解决的问题很实在——数据预处理不再需要绕道 CPUNPU 加速从头到尾覆盖到。如果你在昇腾 NPU 上跑 PyTorch 推理可以把数据预处理部分用 asnumpy 重写preprocess 推理统一在 NPU 上完成吞吐会比CPU 预处理 NPU 推理的串行方式高出不少。ops-tensor 仓库里除了 asnumpy还有 tensorapi 和 Blaze 等其他张量工具可以一起看看。源码在 https://atomgit.com/cann/ops-tensor。