CANN asnumpy:在 NPU 上跑 NumPy 工作负载

文章目录

前言

你写了几年科学计算代码,全是 import numpy as np,张量创建、矩阵乘法、随机数生成------这些操作在你的 CPU 上跑得好好的,突然老板说"搬到昇腾 NPU 上试试"。你搜了一圈,发现昇腾 CANN 生态里有个叫 asnumpy 的东西,号称"在 NPU 上跑 NumPy 工作负载"。

别被名字骗了------asnumpy 不是 NumPy。它是一个兼容层,让你不用重写代码,就能把原来在 CPU 上跑的 NumPy 风格操作搬到昇腾 NPU 上执行。打个比方:你在一个城市住了十年,每个路口都熟,现在换了个新城市。asnumpy 就是那个给你画了一份"老路名→新路名"对照表的向导------你不需要重新学认路,跟着走就行。

为什么需要 NumPy 兼容层?

科学计算领域的代码资产是巨大的。从天文学的星系模拟到生物信息学的基因测序,从金融工程的期权定价到物理仿真的流体计算,全球数百万研究人员用 NumPy 积累了十几年的代码。这些代码不是想扔就能扔的。

问题来了:昇腾 NPU 的算力很强,但生态里缺一个让科学计算用户无门槛进入的入口。用户不可能为了用 NPU 去学 PyTorch、学 MindSpore------他们只是想把手头的计算跑快一点。asnumpy 就是为这个场景设计的:不要求用户改变编程习惯,不要求重写算法逻辑,只是把执行后端从 CPU 换成 NPU

这就好像你有一把瑞士军刀,现在告诉你"换个刀片能用更大力气",但用法完全不用变。asnumpy 做的就是这件事。

它在 CANN 五层架构里的什么位置?

昇腾 CANN 的五层架构从下到上分别是:基础层、执行层、编译层、服务层、语言层。asnumpy 不在这五层里面------它属于五层之上的应用链,也就是第三层的便捷工具层。

为什么放在这个位置?让我们看看其他几层在干什么:

  • 基础层执行层负责最底层的硬件抽象和算子执行
  • 编译层做图优化和调度
  • 服务层提供推理服务框架
  • 语言层提供 Python、C++ 等编程接口

asnumpy 做的事情完全不同:它是面向终端用户的胶水层。它不自己实现算子,也不做编译优化,它做的是把 NumPy 风格的 API 调用翻译成底层算子库的调用。比如你要算矩阵乘,asnumpy 会在底下帮你调 ops-blas;要算三角函数、指数运算,它会去调 ops-math。就像你点外卖,你只管在 app 上点"宫保鸡丁",后厨是哪个师傅炒的你不用管------asnumpy 就是那个外卖 app,ops-math 和 ops-blas 是后厨。

核心能力:覆盖哪些 NumPy API?

asnumpy 目前支持的 NumPy API 可以分成几大类,每一类都对应底层的算子仓库:

ndarray 创建与管理

python 复制代码
import asnumpy as anp

# 在 NPU 显存上创建各种类型的数组
a = anp.zeros((1024, 1024), dtype=anp.float32)
b = anp.ones((512, 512), dtype=anp.float16)
c = anp.full((256, 256), 3.14159)
d = anp.eye(1024)  # 单位矩阵

# 从 Python 列表或 NumPy 数组导入
data = [[1, 2, 3], [4, 5, 6]]
e = anp.array(data, dtype=anp.float32)

# 查看张量形状和设备
print(f"Shape: {e.shape}, Dtype: {e.dtype}")

区别在于:这些张量住在 NPU 显存上,不在系统内存里。整个计算过程不需要 CPU 介入。

数学运算(底层调用 ops-math)

python 复制代码
# 基础数学函数 - 底层走 ops-math
x = anp.random.randn(1000, 1000)
y = anp.sin(x)           # 正弦
z = anp.cos(x)           # 余弦
w = anp.exp(z)           # 指数
v = anp.log(w)           # 对数
u = anp.sqrt(v)          # 平方根

# 元素级运算
result = anp.power(x, 2)   # x^2
result = anp.abs(x)        # 绝对值
result = anp.clip(x, -1, 1) # 截断

ops-math 提供了 conversion 类(张量形态变换)、math 类(基础数学运算)、random 类(随机数生成)。asnumpy 里的 anp.sin()anp.exp()anp.random.randn() 这些操作,最终都走到这里。

线性代数(底层调用 ops-blas)

python 复制代码
# 矩阵运算 - 底层走 ops-blas
A = anp.random.randn(2048, 1024)
B = anp.random.randn(1024, 512)

C = anp.dot(A, B)          # 矩阵乘法
D = anp.matmul(A, B)        # 另一种写法

# 向量运算
v1 = anp.random.randn(512)
v2 = anp.random.randn(512)
dot_product = anp.dot(v1, v2)  # 点积

# 范数计算
norm = anp.linalg.norm(A)       # Frobenius 范数

ops-blas 是高性能线性代数计算库,anp.dot()anp.matmul() 这些矩阵运算的幕后功臣。

线性代数求解器

python 复制代码
# 解线性方程组 Ax = b
A = anp.array([[3, 1], [1, 2]], dtype=anp.float32)
b = anp.array([9, 8], dtype=anp.float32)
x = anp.linalg.solve(A, b)

# SVD 分解
U, s, Vh = anp.linalg.svd(A)

# 特征值分解
eigenvalues, eigenvectors = anp.linalg.eigh(A)

FFT 频域变换

python 复制代码
# 快速傅里叶变换 - 科学计算常见操作
signal = anp.random.randn(1024)
fft_result = anp.fft.fft(signal)       # 一维 FFT
ifft_result = anp.fft.ifft(fft_result) # 逆变换

# 二维 FFT(图像处理常用)
image = anp.random.randn(512, 512)
fft_2d = anp.fft.fft2(image)

典型使用场景:三层递进

第一层:像用 NumPy 一样创建张量

python 复制代码
import asnumpy as anp

# 在 NPU 显存上创建一个张量
a = anp.zeros((1024, 1024))
# 数据默认驻留在 NPU 显存里,不需要手动搬运

看到没?跟 NumPy 的用法几乎一模一样。区别在于 a 这个张量住在 NPU 显存上,不在系统内存里。

第二层:科学计算的基本操作直接上 NPU

python 复制代码
b = anp.random.randn(1024, 1024)
c = anp.dot(a, b)           # 矩阵乘法 → 底层调 ops-blas
d = anp.exp(c)              # 指数运算 → 底层调 ops-math
e = anp.mean(d, axis=0)     # 求均值 → 底层调 ops-math

每一行代码在 CPU 上用 NumPy 也能写,但现在全部在 NPU 上跑。数据从头到尾没离开过显存,省掉了 CPU 和 NPU 之间来回搬运的功夫。

第三层:传统 ML 算法的迁移

很多科研人员和工程师手头有大量基于 NumPy 的传统机器学习代码------PCA、SVD、KMeans 这些算法自己用 NumPy 写的。这些代码要迁移到昇腾 NPU 上,重写成本很高。asnumpy 的价值就在这里:

python 复制代码
# 一段经典的 PCA 实现,原来跑在 CPU 上
def pca(X, n_components):
    # 中心化
    X_centered = X - anp.mean(X, axis=0)
    # 协方差矩阵
    cov = anp.dot(X_centered.T, X_centered) / X.shape[0]
    # 特征分解
    eigenvalues, eigenvectors = anp.linalg.eigh(cov)
    # 取前 n 个主成分
    idx = anp.argsort(eigenvalues)[::-1]
    return eigenvectors[:, idx[:n_components]]

# 把 X 换成 asnumpy 张量,剩下的不用改
X_npu = anp.array(X_cpu)
components = pca(X_npu, 50)

代码逻辑一行没改,计算从 CPU 搬到了 NPU。这就是 asnumpy 定位的典型场景:科学计算用户和传统 ML 迁移

性能对比:数据搬运的代价

为什么一定要在 NPU 上跑?关键在于数据搬运。如果数据在 CPU 和 NPU 之间反复移动,异步传输的开销可能抵消 NPU 计算带来的收益。asnumpy 的设计让数据从头到尾留在 NPU 显存里:

python 复制代码
# 传统做法:CPU 计算
import numpy as np
a_np = np.random.randn(4096, 4096)
b_np = np.dot(a_np, a_np)  # CPU 计算,可能很慢

# asnumpy 做法:NPU 计算
import asnumpy as anp
a_npu = anp.random.randn(4096, 4096)  # 直接在 NPU 创建
b_npu = anp.dot(a_npu, a_npu)         # 全程 NPU 计算
# 数据不需要在 CPU 和 NPU 之间搬运

对于大矩阵运算,这个差异是明显的。

和 CANN 其他仓库怎么配合?

asnumpy 不是一个人在战斗。它的上游是三个算子仓库:

  • ops-math ------提供 conversion 类(张量形态变换)、math 类(基础数学运算)、random 类(随机数生成)。asnumpy 里 anp.sin()anp.exp()anp.random.randn() 这些操作,最终都走到这里。
  • ops-blas ------高性能线性代数计算。anp.dot()anp.matmul() 这些矩阵运算的幕后功臣。
  • ascend-boost-comm------算子公共平台,南向对接算子库,北向支撑加速库,负责 M×N 的算子复用。

有一个很容易搞混的点:asnumpy 和 ops-nn 的关系。它们不是竞争关系,而是互补的。ops-nn 覆盖的是神经网络域------Conv2D、LayerNorm、GELU 这些深度学习算子;asnumpy 覆盖的是 NumPy 域------张量创建、数学运算、线性代数这些科学计算操作。你做深度学习用 ops-nn,做科学计算用 asnumpy,各管各的赛道。

它们的关系可以这样理解:

python 复制代码
# 深度学习场景 → ops-nn
import AscendBridge
conv = AscendBridge.Conv2d(in_channels, out_channels, kernel_size)
output = conv(input)

# 科学计算场景 → asnumpy
import asnumpy as anp
result = anp.dot(matrix_a, matrix_b)

谁适合用 asnumpy?

两类人:

  1. 科学计算用户------物理仿真、金融建模、生物信息学,手头大量 NumPy 代码想在昇腾 NPU 上加速跑。
  2. 传统 ML 迁移------用 NumPy 手写的 PCA、SVD、聚类算法等,要搬上昇腾但不打算全部重写成 PyTorch。

如果你已经在用 PyTorch 做深度学习,那其实不需要 asnumpy------直接用 PyTorch + ops-nn + ops-transformer 这条链路更合适。asnumpy 解决的是另一个问题:让不会用深度学习框架的人,也能用上昇腾 NPU 的算力。

环境准备与快速验证

要使用 asnumpy,需要满足以下环境条件:

bash 复制代码
# 1. 确认昇腾 NPU 驱动已安装
npu-smi

# 2. 确认 CANN 已安装(需要对应版本)
python -c "import acl"
# 无报错说明 ACL 就绪

# 3. 安装 asnumpy(从 atomgit 拉取或使用预装版本)
pip install asnumpy

简单验证脚本:

python 复制代码
import asnumpy as anp

# 创建一个简单张量验证环境
a = anp.ones((100, 100))
b = anp.dot(a, a)
print(f"Result shape: {b.shape}")
print("NPU 计算验证通过!")

想动手试试?

https://atomgit.com/cann/asnumpy 看仓库里的 README 和示例代码。先把环境搭好(需要一台带昇腾 NPU 的机器和对应版本的 CANN),然后试着把你手头最简单的 NumPy 脚本改一下 import------把 import numpy as np 换成 import asnumpy as anp,看看能不能直接跑起来。大概率是可以的。跑通了再往复杂场景走。

asnumpy 的目标很简单:让每一个会用 NumPy 的人,都能直接用上昇腾 NPU 的算力,不需要学新框架,不需要改算法逻辑。这就是它存在的价值。

相关推荐
2301_818730563 天前
numpy的学习(笔记)
学习·numpy
张登杰踩3 天前
DINOv2 with Registers 系列模型详解:Giant 版本规格、Register Token 机制与使用指南
python·numpy
晚霞的不甘4 天前
CANN asnumpy 深度解析:NPU 原生 NumPy 的使用指南
人工智能·python·numpy
灰灰勇闯IT4 天前
asnumpy:NPU 原生的 NumPy 体验
numpy
毋语天4 天前
NumPy 完全入门指南:核心数据结构与高效数值计算
数据结构·numpy
Omics Pro5 天前
填补蛋白质组深度学习预处理教学空白
人工智能·python·深度学习·plotly·numpy·pandas·scikit-learn
bloxed5 天前
【AI大模型--NumPy-02】-数组创建与高级索引完全指南
人工智能·numpy
沉下去,苦磨练!7 天前
python的数据分析numpy
python·数据分析·numpy
深兰科技9 天前
深兰科技签约乌兹别克斯坦智慧城市项目,推动中国AI出海规模化
人工智能·beautifulsoup·numpy·智慧城市·fastapi·matplotlib·深兰科技