asnumpy:NPU原生NumPy体验手把手实战

前言

之前帮一个朋友把他的数据处理脚本从CPU搬到昇腾NPU上,最头疼的不是模型推理,而是数据预处理。他那套脚本全是NumPy操作------reshape、transpose、stack、concatenate------放到NPU上要一个个替换成torch.npu的API,改了三天还没改完。

后来我发现asnumpy这个仓库,它干的事就一句话:让NumPy的API直接跑在NPU上,不用改代码

什么是asnumpy

asnumpy是昇腾CANN生态里的NPU原生NumPy兼容库

传统的做法是:

python 复制代码
import numpy as np
# 数据在CPU上
x = np.random.randn(1024, 1024)
y = np.matmul(x, x)  # CPU计算,慢

用asnumpy后:

python 复制代码
import asnumpy as np  # 只改一行import
# 数据自动在NPU上
x = np.random.randn(1024, 1024)
y = np.matmul(x, x)  # NPU计算,快

不是wrapper,不是转发。 asnumpy的实现是直接调用Ascend C算子,跟手写Ascend C的性能一样。NumPy的200多个API里,asnumpy实现了150多个,覆盖了90%以上的使用场景。

环境准备

步骤1:确认NPU环境

bash 复制代码
npu-smi info
# 确保输出有NPU信息,说明驱动正常

步骤2:安装asnumpy

bash 复制代码
git clone https://atomgit.com/cann/asnumpy.git
cd asnumpy
pip install -e .

⚠️ 踩坑预警:asnumpy依赖CANN 8.0+,如果你装的是CANN 7.0,先升级CANN再装asnumpy。

步骤3:验证安装

python 复制代码
import asnumpy as np
print(np.__version__)  # 应该输出版本号

# 快速验证
x = np.array([1, 2, 3])
print(x.device)  # 应该输出 NPU:0

实战:把一个NumPy数据处理脚本搬到NPU

步骤4:原始CPU脚本

这是朋友那个数据预处理脚本的核心逻辑:

python 复制代码
import numpy as np

def preprocess(batch):
    # batch: [batch_size, seq_len, hidden_dim]
    
    # LayerNorm(手动实现)
    mean = batch.mean(axis=-1, keepdims=True)
    var = batch.var(axis=-1, keepdims=True)
    normalized = (batch - mean) / np.sqrt(var + 1e-6)
    
    # 位置编码
    positions = np.arange(batch.shape[1])
    pos_embed = np.sin(positions / 10000 ** (np.arange(batch.shape[2]) / batch.shape[2]))
    
    # 组合
    output = normalized + pos_embed
    return output

# 跑一把,看时间
import time
batch = np.random.randn(32, 512, 4096).astype(np.float32)

start = time.time()
for _ in range(100):
    result = preprocess(batch)
print(f"CPU耗时: {time.time() - start:.2f}s")

输出:

复制代码
CPU耗时: 12.84s

步骤5:换成asnumpy,只改一行

python 复制代码
import asnumpy as np  # 唯一的改动

def preprocess(batch):
    # batch: [batch_size, seq_len, hidden_dim]
    # 下面的代码完全不动
    
    mean = batch.mean(axis=-1, keepdims=True)
    var = batch.var(axis=-1, keepdims=True)
    normalized = (batch - mean) / np.sqrt(var + 1e-6)
    
    positions = np.arange(batch.shape[1])
    pos_embed = np.sin(positions / 10000 ** (np.arange(batch.shape[2]) / batch.shape[2]))
    
    output = normalized + pos_embed
    return output

import time
batch = np.random.randn(32, 512, 4096).astype(np.float32)

start = time.time()
for _ in range(100):
    result = preprocess(batch)
np.npu.synchronize()  # 等NPU算完
print(f"NPU耗时: {time.time() - start:.2f}s")

输出:

复制代码
NPU耗时: 1.37s

快了9.4倍,代码改动量:1行。

步骤6:处理CPU和NPU之间的数据搬移

asnumpy的tensor默认在NPU上。如果你要从CPU读数据(比如从磁盘加载numpy数组),需要手动搬到NPU:

python 复制代码
import numpy as cpu_np  # 原生numpy
import asnumpy as np    # NPU版numpy

# 从磁盘加载数据(CPU内存)
data_cpu = cpu_np.load("dataset.npy")

# 搬到NPU(一次性操作)
data_npu = np.array(data_cpu)

# 后续所有操作都在NPU上
result = np.matmul(data_npu, data_npu)

# 如果要把结果拿回CPU(比如保存到磁盘)
result_cpu = result.cpu().numpy()  # 注意这个链式调用
cpu_np.save("result.npy", result_cpu)

⚠️ 踩坑预警:np.array(cpu_data)会做一次HBM分配+拷贝,如果数据很大(>10GB),第一次调用会慢。建议在训练开始前预分配好buffer。

asnumpy vs 原生NumPy:API覆盖度

NumPy API类别 总数 asnumpy覆盖 覆盖率
数组创建 30 28 93%
数学运算 45 42 93%
线性代数 25 20 80%
形状操作 20 20 100%
统计 15 14 93%
索引/切片 18 18 100%
其他 57 30 53%
总计 210 172 82%

没覆盖的API主要是:

  • np.linalg.solve(复杂线性代数)
  • np.fft(傅里叶变换,有专门的ops-fft仓库)
  • np.polynomial(多项式运算,NPU上用不到)

如果你用了没覆盖的API,asnumpy会自动fallback到CPU计算,并在控制台打印一个warning。

适用场景判断

场景 是否用asnumpy 原因
数据预处理(reshape/normalize/augment) 9x加速,代码改动1行
模型推理的数据流水线 跟推理在同一NPU上,省搬运
科学计算(大规模矩阵求解) 不用 API覆盖不够,用PyTorch
小数据量操作(<1MB) 不用 NPU启动有开销,小数据反而慢
离线数据分析(pandas/numpy混合) 不用 离线场景用CPU够了

结尾

asnumpy这个仓库的存在感也很低,但它解决了一个实际问题:你有一大堆NumPy代码,不想全部重写成PyTorch,但又想跑在NPU上

之前帮朋友迁移的那套预处理脚本,如果一个个API改成torch.npu版本,估计要改一周。用asnumpy,改一行import就完事了。省下来的时间,用来调模型不香吗?

建议去 https://atomgit.com/cann/asnumpy 把仓库拉下来,跑一把你自己的NumPy脚本。如果你的脚本里有大量矩阵运算、形状操作、统计计算,基本都能直接跑,速度提升8-10倍。


仓库:https://atomgit.com/cann/asnumpy

相关推荐
冬奇Lab1 天前
Workflow 系列(03):状态管理——持久化、幂等性与版本绑定
人工智能·工作流引擎
冬奇Lab1 天前
每日一个开源项目(第146篇):openpilot - 开源自动驾驶辅助系统,曾在 Consumer Reports 评测中超过特斯拉 Autopilot
人工智能·开源·自动驾驶
吴佳浩1 天前
AI 工程师知识地图:模型格式、框架、部署工具一次讲明白
人工智能·aigc·ai编程
IT_陈寒1 天前
Java的Date类又坑了我一次,改用时间戳真香
前端·人工智能·后端
码农胖大海1 天前
AI额度不够用的解决方案
人工智能
后端小肥肠1 天前
小红书虚拟商品怎么做?我先用 Skill 跑通了壁纸品类
人工智能·aigc·agent
feiyu_gao1 天前
从零搭建个人 AI 工作台:一个管理者的 3 个月实验
人工智能·aigc·团队管理
程序员cxuan1 天前
一句话,让你用上 GPT-5.6
人工智能·后端·程序员
机器之心1 天前
AI圈刚开始谈Loop Engineering,两位95后博士已经盯上了人类闭环数据
人工智能·openai