本文基于昇腾CANN和昇腾NPU,围绕 pyACL Python 推理 技术展开。

ACLNN 是 C++ 接口,pyACL 是 Python 版的 AscendCL 封装。import acl 就能在 NPU 上加载 OM 模型并完成推理部署、管理 Tensor、提交推理、取回结果。用 NumPy 准备输入数据,pyACL 自动做 Host→Device 搬运——整个流程不用写一行 C++。

ACLNN 适合需要极致控制推理链路的场景,pyACL 适合快速验证和 Python 生态集成。两者的底层走的是同一套 ACL Runtime API。


第一个 pyACL 推理程序

# pyACL 推理——加载 ResNet-50 的 OM 模型

import acl
import numpy as np

# 1. 初始化 Runtime
acl.init()
acl.rt.set_device(0)
context, _ = acl.rt.create_context(0)
stream = acl.rt.create_stream()

# 2. 加载编译好的 OM 模型
model_id, model_desc = acl.mdl.load_from_file("resnet50.om")

# 3. 构造输入——NumPy 自动转 NPU Tensor
img = np.random.randn(1, 3, 224, 224).astype(np.float16)
input_buf, input_buf_id = acl.create_tensor(img)
input_ds = acl.mdl.create_dataset()
acl.mdl.add_dataset_buffer(input_ds, input_buf)

# 4. 分配输出 Buffer
out_size = acl.mdl.get_output_size_by_index(model_desc, 0)
out_buf, out_buf_id = acl.rt.malloc(out_size,
                                     acl.ACL_MEM_MALLOC_NORMAL_ONLY)
out_ds = acl.mdl.create_dataset()
acl.mdl.add_dataset_buffer(out_ds, out_buf)

# 5. 异步推理
acl.mdl.execute_async(model_id, input_ds, out_ds, stream)
acl.rt.synchronize_stream(stream)

# 6. 取结果回 NumPy
result = acl.get_tensor_data(out_ds, 0)  # NumPy ndarray
pred = np.argmax(result)
print(f"预测类别: {pred}")

# 7. 清理
acl.rt.free(out_buf)
acl.mdl.unload(model_id)
acl.rt.destroy_stream(stream)
acl.rt.destroy_context(context)
acl.rt.reset_device(0)
acl.finalize()

pyACL 的 Tensor 管理

acl.create_tensor(numpy_array) 做了三件事:在 NPU 显存上分配等量空间,把 NumPy 数据搬过去,返回 Device 侧 Buffer 指针和 ID。内部走 aclrtMemcpy 做 Host→Device 拷贝——跟 C++ 接口一致。

数据搬回去acl.get_tensor_data(dataset, index)——从输出 Dataset 里取第 index 个 Buffer,拷贝回 Host 返回 NumPy 数组。如果结果很大(比如 128K×4096 的 Logits),这一步是推理后最大的延迟来源——DDR → CPU 的 PCIe 带宽约 32GB/s(PCIe 4.0 x16)。


常见踩坑

  1. acl.init() 只能调一次。多进程部署时每个子进程独立 init,同一进程内重复 init 直接报错。
  2. Tensor dtype 必须匹配 OM 模型。ATC 编译时指定 FP16,Python 端传 FP32 不会报错——但 acl.create_tensor 不会自动转换,结果全乱。
  3. 异步执行要 sync。execute_async 之后取结果前必须 synchronize_stream。忘了 sync 读到的是未初始化的显存。

跟 C++ ACLNN 的对比

pyACL 链路:
  NumPy → acl.create_tensor → execute_async → get_tensor_data → NumPy

ACLNN 链路:
  float[] → aclrtMemcpy → aclnnMatMul → aclrtMemcpy → float[]

底层是同一套 Runtime。区别在开发效率——pyACL 省了显存管理代码和 C++ 编译链路,但性能完全一致。


参考仓库

pyACL Python 推理接口

CANN Samples Python 示例

推理 Recipes

CANN 学习中心

Logo

小龙虾开发者社区是 CSDN 旗下专注 OpenClaw 生态的官方阵地,聚焦技能开发、插件实践与部署教程,为开发者提供可直接落地的方案、工具与交流平台,助力高效构建与落地 AI 应用

更多推荐