当前位置: 首页 > article >正文

从 0 到 1:10 分钟跑通第一个 Ascend ACL 推理程序

第一次在昇腾 NPU 上跑推理很多人卡在第一步环境装好了ATC 模型转换也成功了一跑推理程序就报aclInit failed或者load model failed。我当年第一次跑 ACL 推理环境装了 3 遍模型转了 5 遍推理程序编译通过但运行就 core dump。最后发现是环境变量没配全——LD_LIBRARY_PATH少了/usr/local/Ascend/nnrt/latest/acllib/lib64导致运行时找不到libascendcl.so。这篇文章把我踩过的坑全部列出来你照着做10 分钟内必能跑通。第一步CANN 环境安装1.1 确认硬件和环境先确认你有昇腾 NPU910/910B/310 都行且系统是 Ubuntu 18.04/20.04 或 CentOS 7.x。# 看有没有 NPU 设备 ls /dev/davinci* # 有输出比如 /dev/davinci0说明驱动装好了没输出先装驱动。去昇腾社区下载对应版本的驱动[https://www.hiascend.com/hardware/firmware-drivers]按文档装完重启。1.2 安装 CANN Toolkit 和 NNRtCANN 有两个包Toolkit开发用含编译工具链和NNRt运行时含 ACL 库。# 下载 CANN 8.0.RC1 版本示例具体版本看你 NPU 驱动版本 # 去 https://www.hiascend.com/software/cann/community-history 下载 # 安装 Toolkit开发机装 ./Ascend-cann-toolkit_8.0.RC1_linux-x86_64.run --full # 安装 NNRt运行机装如果开发运行同一台机器两个都装 ./Ascend-cann-nnrt_8.0.RC1_linux-x86_64.run --full90% 新手都会踩的坑 No.1装完不配环境变量。 装完 CANN 一定要配环境变量否则编译时找不到头文件运行时找不到库。第二步环境变量配置这是最容易出问题的地方。很多人以为/etc/profile里配一次就完事了其实每次开新终端都要 source。创建环境变量配置文件~/.cannrc# ~/.cannrc export ASCEND_HOME/usr/local/Ascend export CANN_HOME$ASCEND_HOME/nnrt/latest export PATH$ASCEND_HOME/toolkit/latest/bin:$PATH export LD_LIBRARY_PATH$CANN_HOME/acllib/lib64:$ASCEND_HOME/driver/lib64:$LD_LIBRARY_PATH export ASCEND_OPP_PATH$ASCEND_HOME/nnrt/latest/opp每次开新终端都要 sourcesource ~/.cannrc或者写进~/.bashrc一劳永逸echo source ~/.cannrc ~/.bashrc验证环境变量是否配好# 看能不能找到 ATC 工具 which atc # 输出应该是 /usr/local/Ascend/toolkit/latest/bin/atc # 看能不能找到 ACL 库 ldconfig -p | grep ascendcl # 输出应该有一行 libascendcl.so90% 新手都会踩的坑 No.2LD_LIBRARY_PATH配了但没生效。 用ldconfig -p | grep ascendcl验证。如果没输出说明库路径没配进去。检查~/.cannrc里的路径是否真实存在比如nnrt/latest是不是软链接有时候装完叫nnrt/8.0.RC1。第三步模型转换ATCACL 推理需要 OM 格式的模型离线模型。你手里的 ONNX/PyTorch/TensorFlow 模型需要先转成 OM。3.1 准备 ONNX 模型如果手头没有 ONNX 模型用 PyTorch 导出一个 ResNet-50# export_resnet50.py import torch import torchvision model torchvision.models.resnet50(pretrainedFalse) model.eval() dummy_input torch.randn(1, 3, 224, 224) torch.onnx.export(model, dummy_input, resnet50.onnx, input_names[input], output_names[output])3.2 用 ATC 转 OMatc --modelresnet50.onnx \ --framework5 \ --outputresnet50 \ --input_formatNCHW \ --input_shapeinput:1,3,224,224 \ --loginfo参数解释解释 WHY 而非 WHAT--framework5ONNX 的格式编号是 51Caffe, 3TensorFlow, 5ONNX, 6PyTorch--input_formatNCHWNPU 要求输入是 NCHW 格式跟 PyTorch 一致--outputresnet50输出的 OM 模型叫resnet50.om自动加.om后缀转换成功会看到ATC run success生成resnet50.om文件。90% 新手都会踩的坑 No.3模型转换成功但推理时报load model failed。 原因ATC 转换时用的 CANN 版本跟推理程序编译时链接的 CANN 版本不一致。解决保证转换和运行用同一个 CANN 版本比如都是 8.0.RC1。第四步写 ACL 推理代码C这是核心。ACL 推理分 5 步初始化 → 加载模型 → 准备输入 → 执行推理 → 解析输出。4.1 目录结构acl_inference/ ├── CMakeLists.txt # 编译配置 ├── main.cpp # 主程序 ├── resnet50.om # 模型文件ATC 转换生成 └── test_image.bin # 输入数据二进制文件4.2 完整 C 代码// main.cpp #include acl/acl.h #include acl/ops/acl_dvpp.h #include iostream #include fstream #include vector // 检查 ACL 返回值的宏不写 try-catch直接判错 #define CHECK_RET(ret, msg) \ if ((ret) ! ACL_SUCCESS) { \ std::cerr msg , ret ret std::endl; \ return -1; \ } int main() { // 第 1 步初始化 ACL aclError ret aclInit(nullptr); CHECK_RET(ret, aclInit failed); // 指定要用的 NPU 设备0 号设备 ret aclrtSetDevice(0); CHECK_RET(ret, aclrtSetDevice failed); // 第 2 步加载 OM 模型 uint32_t model_id 0; ret aclmdlLoadFromFile(resnet50.om, model_id); CHECK_RET(ret, aclmdlLoadFromFile failed); // 获取模型描述信息输入/输出的 shape、数据类型 aclmdlDesc *model_desc aclmdlCreateDesc(model_id); ret aclmdlGetDesc(model_desc, model_id); CHECK_RET(ret, aclmdlGetDesc failed); // 第 3 步准备输入数据 // 读二进制输入文件假设已经把图片预处理成了 1×3×224×224 的 float32 数组 std::ifstream infile(test_image.bin, std::ios::binary); std::vectorfloat input_data(1 * 3 * 224 * 224); infile.read(reinterpret_castchar*(input_data.data()), input_data.size() * sizeof(float)); infile.close(); // 申请 NPU 显存输入数据要从 Host 拷到 NPU size_t input_size aclmdlGetInputSizeByIndex(model_desc, 0); void *input_dev nullptr; ret aclrtMalloc(input_dev, input_size, ACL_MEM_MALLOC_HUGE_FIRST); CHECK_RET(ret, aclrtMalloc failed); // 把 Host 数据拷到 NPU ret aclrtMemcpy(input_dev, input_size, input_data.data(), input_size, ACL_MEMCPY_HOST_TO_DEVICE); CHECK_RET(ret, aclrtMemcpy failed); // 创建输入 datasetACL 要求用 dataset 封装输入输出 aclmdlDataset *input_dataset aclmdlCreateDataset(); aclDataBuffer *input_buffer aclCreateDataBuffer(input_dev, input_size); ret aclmdlAddDatasetBuffer(input_dataset, input_buffer); CHECK_RET(ret, aclmdlAddDatasetBuffer failed); // 第 4 步执行推理 // 创建输出 dataset aclmdlDataset *output_dataset aclmdlCreateDataset(); for (size_t i 0; i aclmdlGetNumOutputs(model_desc); i) { size_t output_size aclmdlGetOutputSizeByIndex(model_desc, i); void *output_dev nullptr; ret aclrtMalloc(output_dev, output_size, ACL_MEM_MALLOC_HUGE_FIRST); CHECK_RET(ret, aclrtMalloc output failed); aclDataBuffer *output_buffer aclCreateDataBuffer(output_dev, output_size); ret aclmdlAddDatasetBuffer(output_dataset, output_buffer); CHECK_RET(ret, aclmdlAddDatasetBuffer output failed); } // 执行模型推理 ret aclmdlExecute(model_id, input_dataset, output_dataset); CHECK_RET(ret, aclmdlExecute failed); // 第 5 步解析输出 // 把输出从 NPU 拷回 Host for (size_t i 0; i aclmdlGetNumOutputs(model_desc); i) { aclDataBuffer *output_buffer aclmdlGetDatasetBuffer(output_dataset, i); void *output_dev aclGetDataBufferAddr(output_buffer); size_t output_size aclGetDataBufferSize(output_buffer); std::vectorfloat output_data(output_size / sizeof(float)); ret aclrtMemcpy(output_data.data(), output_size, output_dev, output_size, ACL_MEMCPY_DEVICE_TO_HOST); CHECK_RET(ret, aclrtMemcpy output failed); // 打印前 10 个输出值真实场景要接后处理比如 argmax 取分类结果 std::cout Output i (first 10 values): ; for (int j 0; j 10 j output_data.size(); j) { std::cout output_data[j] ; } std::cout std::endl; } // 清理资源 ret aclmdlUnload(model_id); CHECK_RET(ret, aclmdlUnload failed); ret aclrtResetDevice(0); CHECK_RET(ret, aclrtResetDevice failed); ret aclFinalize(); CHECK_RET(ret, aclFinalize failed); std::cout Inference success! std::endl; return 0; }4.3 代码关键解释为什么用aclmdlDataset封装输入输出ACL 的接口设计是面向 Dataset的——一个模型可能有多个输入比如 GPT 的input_ids和attention_mask用 Dataset 封装可以一次性传多个输入。为什么输入数据要从 Host 拷到 NPUNPU 只能直接访问自己的显存HBM。Host 内存的数据必须显式拷贝用aclrtMemcpy。为什么aclrtMalloc要用ACL_MEM_MALLOC_HUGE_FIRSTNPU 的 HBM 支持大页内存Huge Page用这个标志申请内存会优先用大页性能好 10-15%。第五步编译写CMakeLists.txtcmake_minimum_required(VERSION 3.10) project(acl_inference) set(CMAKE_CXX_STANDARD 14) # 找 CANN 包装在 /usr/local/Ascend find_package(Ascend REQUIRED) # 包含 ACL 头文件路径 include_directories(${ASCEND_INCLUDE_DIRS}) # 编可执行文件 add_executable(acl_inference main.cpp) # 链 ACL 库 target_link_libraries(acl_inference ${ASCEND_LIBRARIES})编译mkdir build cd build cmake .. make -j90% 新手都会踩的坑 No.4编译通过但运行时报error while loading shared libraries: libascendcl.so。 原因LD_LIBRARY_PATH没配全。运行时的库路径要在~/.cannrc里配好见第二步。第六步运行# 确保环境变量已 source source ~/.cannrc # 把 resnet50.om 拷到运行目录 cp ../resnet50.om . # 运行需要有 NPU 权限加 sudo 或把用户加入 HwAiUser 组 ./acl_inference成功输出Output 0 (first 10 values): 0.0023 -0.0156 0.0089 ... Inference success!为什么模型能转换成功但运行失败这是新手问的最多的问题。我总结了 4 个原因原因 1CANN 版本不匹配ATC 转换时用的 CANN 版本跟推理程序编译/运行时用的 CANN 版本不一致。OM 模型格式可能变了导致aclmdlLoadFromFile失败。排查# 看 ATC 版本 atc --version # 看推理程序链接的 ACL 库版本 ldd acl_inference | grep ascendcl解决统一版本重新转换模型、重新编译程序。原因 2NPU 驱动版本跟 CANN 不匹配CANN 8.0 要求驱动版本 24.1.0。如果驱动太老ACL 初始化就失败aclInit failed。排查# 看驱动版本 npu-smi info解决升级驱动到 CANN 要求的版本。原因 3输入 Shape 跟模型要求的不一致ATC 转换时指定了input_shapeinput:1,3,224,224但推理时输入数据的 shape 不对比如你传了1,3,256,256的数据导致aclmdlExecute失败。排查打印输入数据的尺寸跟 ATC 转换时指定的 shape 对比。解决推理前把输入数据 resize/crop 到模型要求的 shape。原因 4权限问题运行推理程序需要访问/dev/davinci0设备文件普通用户没权限。排查ls -l /dev/davinci0 # 如果 owner 是 root你需要 sudo 或加入 HwAiUser 组解决sudo usermod -aG HwAiUser $USER # 注销重新登录就有权限了90% 新手都会踩的坑完整版坑编号问题描述原因解决方法1装完 CANN 找不到头文件/库环境变量没配写~/.cannrc每次开终端 source2编译通过运行时libascendcl.so找不到LD_LIBRARY_PATH没配全ldconfig -p3模型转换成功推理时load model failedCANN 版本不匹配统一转换和运行用的 CANN 版本4aclInit failed驱动版本太老升级驱动到 CANN 要求的版本5推理输出全是 0 或 NaN输入数据没归一化图片预处理要跟训练时一致比如 ImageNet 的 mean/std排错方法总结遇到问题按这个顺序排查看返回值所有 ACL 接口都返回aclError用CHECK_RET宏检查看环境变量echo $LD_LIBRARY_PATH确认库路径看设备状态npu-smi info确认 NPU 在线看模型信息atc --modedisplay_model_info --omresnet50.om确认模型输入/输出 shape简化复现先跑 CANN 自带的样例比如/usr/local/Ascend/nnrt/latest/samples/inference/modelInference/工程经验第一次跑不通别慌。ACL 的错误码很详细比如ACL_ERROR_INVALID_RESOURCE 107002去昇腾社区搜错误码90% 的问题都有现成答案。https://atomgit.com/cann/runtime https://atomgit.com/cann/asc-devkit https://atomgit.com/cann/cann-samples

相关文章:

从 0 到 1:10 分钟跑通第一个 Ascend ACL 推理程序

第一次在昇腾 NPU 上跑推理,很多人卡在第一步:环境装好了,ATC 模型转换也成功了,一跑推理程序就报 aclInit failed 或者 load model failed。 我当年第一次跑 ACL 推理,环境装了 3 遍,模型转了 5 遍&#…...

2026 软考中级《多媒体应用设计师》备考全攻略(附全套资料)

大家好,最近很多朋友问我软考多媒体应用设计师的备考方法和资料整理问题,今天就把我自己整理的备考资料和实用经验一次性分享给大家,帮你少走弯路,高效备考~ 📚 我的备考资料整理(4 大模块全覆…...

WT32-S3-DK开发板全解析:从硬件设计到物联网项目实战

1. 项目概述:一块“小而全”的物联网开发板最近在捣鼓一个智能家居的传感器节点项目,需要一块性能足够、接口丰富、最好还带屏幕的开发板。市面上ESP32-S3的方案很多,但要么是核心板,需要自己配底板和屏幕,要么就是功能…...

基于ZYNQ与IgH的EtherCAT主站方案:软硬协同实现工业实时控制

1. 项目概述:当工业实时网络遇上可编程SoC在工业自动化领域,实时性和确定性是永恒的核心诉求。EtherCAT作为高性能的工业以太网协议,以其独特的“飞读飞写”数据处理机制和极低的通信抖动,成为了众多高精度运动控制、机器人、半导…...

ZYNQ平台开源EtherCAT主站部署与实时运动控制优化实践

1. 项目概述与核心价值最近在做一个基于ZYNQ的工业运动控制项目,客户对多轴同步的实时性和抖动要求非常高,传统的脉冲或总线方案在复杂轨迹规划下显得有些力不从心。经过一番调研和选型,最终决定上马EtherCAT总线。作为工业以太网领域的“性能…...

Linux内核调试利器:/proc/sysrq-trigger原理与实战指南

1. 内核调试的“后门”:/proc/sysrq-trigger 深度解析在Linux内核开发和系统调试的深水区,当系统完全无响应、键盘鼠标失灵,甚至SSH连接都彻底中断时,常规的调试手段往往束手无策。这时,一个隐藏在/proc文件系统中的特…...

AI Agent Harness Engineering 在餐饮行业的应用:智能点餐与库存管理

标题选项 《从排队到零浪费:AI Agent Harness Engineering 重构餐饮智能点餐与库存管理全链路》 《AI Agent 落地餐饮行业实战:基于Harness框架打造高可用智能点餐+库存联动系统》 《告别漏单、超卖、食材浪费:AI Agent Harness 工程化在餐饮场景的落地指南》 《垂直行业Age…...

AI Agent Harness Engineering 技术选型指南:根据场景选择合适的大模型与框架

AI Agent Harness Engineering 技术选型指南:根据场景选择合适的大模型与框架 引言 痛点引入 你是否遇到过这样的场景?产品经理拍板要做一个**“能帮企业HR自动筛选简历、邀约面试、生成入职指南并跟进试用期转正材料”**的“超级HR助手”AI Agent——…...

自动化文件管理:基于Python的网盘批量处理方案

自动化文件管理:基于Python的网盘批量处理方案 【免费下载链接】BaiduPanFilesTransfers 百度网盘批量转存、分享和检测工具 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduPanFilesTransfers 在数字资源日益丰富的时代,百度网盘用户面临着批…...

38 - Go 命令行参数处理:从 os.Args 到 flag 的底层设计

文章目录38 - Go 命令行参数处理:从 os.Args 到 flag 的底层设计为什么需要命令行参数?命令行参数的本质最基础的参数处理:os.Args基础使用示例获取单个参数flag 标准库:Go 官方参数解析器最简单的 flag 示例为什么 flag.String 返…...

RK3588 Android系统签名实战:为APK获取系统权限完整指南

1. 项目概述与核心价值在嵌入式Android开发领域,尤其是基于瑞芯微(Rockchip)平台如RK3588进行产品研发时,我们常常会遇到一个核心需求:如何让一个普通的第三方APK应用,获得系统级(System&#x…...

2025亲测好用的论文降AI工具,降重稳还不打乱原格式

说真的,现在写论文最慌的已经不是重复率飘红,而是AI检测率超标。尤其是用过AI辅助写作或者改写的同学,检测报告一出来AI率直奔80%,导师一句“这是你自己写的?”就能让人瞬间心脏骤停。 我最近花了一周时间,…...

全志T113-i平台UB37三模无线模组驱动移植与调试实战

1. 项目概述:当国产工业芯遇上新一代无线技术最近在做一个挺有意思的项目,客户想在一块国产的工业级核心板上,集成最新的星闪(NearLink)无线通信功能。核心板用的是全志的T113-i,无线模组是支持Wi-Fi 6、蓝…...

全志T113-S3开发板网络配置实战:从DHCP到静态IP与故障排查

1. 项目概述:从零上手T113-S3的网络配置刚拿到一块新的全志T113-S3开发板,比如眺望电子的EVM-T113-S3,第一件事你会做什么?我的习惯是,先把它“连上网”。这听起来简单,但却是后续所有高级操作——无论是通…...

RK3588开发板接口测试实战:USB、CAN、UART、GPIO全解析

1. 项目概述与核心价值作为一名在嵌入式开发领域摸爬滚打了十多年的老工程师,我深知拿到一块新开发板后,那种既兴奋又有点无从下手的感觉。特别是像RK3588这样功能强大的核心板,接口丰富,性能强劲,但如何快速验证这些基…...

3个理由告诉你:为什么Notepad2-mod是你开启开源贡献的最佳起点

3个理由告诉你:为什么Notepad2-mod是你开启开源贡献的最佳起点 【免费下载链接】notepad2-mod LOOKING FOR DEVELOPERS - Notepad2-mod, a Notepad2 fork, a fast and light-weight Notepad-like text editor with syntax highlighting 项目地址: https://gitcode…...

VM振弦采集模块精度实测:从标准信号源到误差分析全流程

1. 项目概述与核心价值最近在做一个岩土工程安全监测的项目,其中有个环节让我琢磨了好一阵子:如何准确地评估我们用的那批VM振弦采集模块的测量精度。这玩意儿在结构健康监测、桥梁隧道、边坡稳定性监测里用得非常多,核心任务就是读取振弦式传…...

Midjourney中画幅风格不生效?5个致命配置错误正在 silently 毁掉你的成片率

更多请点击: https://kaifayun.com 第一章:Midjourney中画幅风格失效的真相与底层机制 Midjourney 中的中画幅(Medium Format)风格常被用户以 --style medium-format 或关键词 medium format film 调用,但大量实测表…...

振弦采集模块精度检测实战:从原理到环境测试全解析

1. 项目概述与核心目标在工程监测领域,振弦式传感器因其长期稳定性好、抗干扰能力强、信号传输距离远等优点,被广泛应用于桥梁、大坝、隧道、边坡等结构物的应力、应变、位移和压力监测。而VM系列振弦采集模块,作为连接传感器与数据采集系统的…...

提示词失效?Midjourney印象派出图不稳的8大陷阱,资深AIGC架构师逐帧解析SD/MJ风格迁移差异

更多请点击: https://codechina.net 第一章:提示词失效的本质:当语义熵击穿Midjourney的隐空间边界 当“cyberpunk cat wearing neon sunglasses, ultra-detailed, 8k”生成结果突然坍缩为 a blurry humanoid silhouette with cat ears&…...

消费电子贴膜的光学技术革新:圆偏振光与磁控溅射AR的原理解析

摘要随着用户对屏幕使用健康关注的提升,消费电子贴膜行业正在经历从“物理防护”到“光学级视觉守护”的技术升级。本文从光学原理出发,解析圆偏振光柔光标准与磁控溅射AR抗眩镀膜两项核心技术的工作机制,并分析其在屏幕保护场景中的应用逻辑…...

Linux ln 软硬链接详解——底层原理+生产实战+彻底区分(零踩坑)

前言很多新手永远分不清软硬链接,只会背“软链接像快捷方式、硬链接像副本”,一旦遇到生产删文件、日志切割、程序部署就翻车。本文从inode底层原理讲起,配合完整实战、对比、生产场景,让你彻底吃透 ln 软硬链接,面试、…...

AhMyth:跨平台Android远程管理工具的完整指南与实战教程

AhMyth:跨平台Android远程管理工具的完整指南与实战教程 【免费下载链接】AhMyth Cross-Platform Android Remote Administration Tool | The only maintained version of AhMyth on github | A revival of the original repository at https://GitHub.com/AhMyth/A…...

软考高项案例分析8:项目风险管理

软考高项案例分析8:项目风险管理 一、项目风险管理过程 1、规划风险管理; 2、识别风险; 3、实施定性风险分析; 4、实施定量风险分析; 5、规划风险应对; 6、实施风险应对; 7、监督风险; 二、案例分析知识点 1. 风险应对措施 威胁应对策略:上报、规避、转移、…...

透明化智慧港口码头•装载·存储·集散全流程透明化管控方案

一、方案前言本方案依托黎阳之光镜像孪生、时空AI拓扑、无感全域定位、视频实景融合、边缘实时算力五大核心技术,聚焦港口码头货物装载、堆场存储、集疏运集散三大核心业务,打造实景可视、数字镜像、智能调度、全程透明、风险可控、全程可溯的智慧管控体…...

TV Bro:终极智能电视浏览器解决方案 - 让大屏上网变得简单快速

TV Bro:终极智能电视浏览器解决方案 - 让大屏上网变得简单快速 【免费下载链接】tv-bro Simple web browser for android optimized to use with TV remote 项目地址: https://gitcode.com/gh_mirrors/tv/tv-bro 您是否曾经对着智能电视的浏览器感到沮丧&…...

向量化智能矩阵系统的语义坍塌:当10万条内容同时找“相似“,为什么你的数据库扛不住?

摘要:智能矩阵系统从"关键词匹配"进化到"语义匹配"之后,遇到了一个被严重低估的性能瓶颈——向量检索的语义坍塌。本文从向量数据库原理、ANN近似最近邻算法、HNSW图索引、向量量化技术四个底层技术出发,拆解向量化智能矩…...

系统设计 012:从用户系统出发,吃透缓存、数据库与高并发设计

系统设计 012:从用户系统出发,吃透缓存、数据库与高并发设计Bilibili 同步视频一、用户系统,藏着后端设计的核心考点💡二、4S 分析法:先读懂用户系统的流量挑战📊1. Scenario:四大需求&#xff…...

基于java的畅阅读系统小程序设计与实现(源码+数据库+文档)

畅阅读系统小程 目录 基于java的畅阅读系统小程序设计与实现 一、前言 二、系统功能设计 三、系统实现 四、数据库设计 1、实体ER图 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取: 博主介绍:✌️大厂码农|毕设布道师&a…...

2025-2026年护眼灯品牌推荐:十大评测专业排行防蓝光伤眼价格特点

摘要 当消费者对家庭光环境的认知从“照亮空间”跃迁至“健康护眼”,如何从纷繁复杂的市场中精准选择一盏真正经得起科学检验的护眼灯,已成为现代家庭决策者的核心焦虑。根据全球知名市场研究机构Grand View Research发布的报告,全球LED照明市…...