已在GitHub开源与本博客同步的YOLOv8_Ascend310B_object_detect项目地址https://github.com/A7bert777/YOLOv8_Ascend310B_object_detect详细使用教程可参考README.md或参考本博客第七章 模型部署注本文是以Ascend 310B SoC进行示例昇腾其他系列SoC的部署流程也基本一致如需帮助可通过Github仓库的 README.md 沟通。文章目录一、项目回顾二、文件梳理三、CANN四、模型训练五、PT转ONNX六、ONNX转OM七、模型部署一、项目回顾博主之前主要使用瑞芯微系列的SoC及对应生态现在逐渐转向Ascend系列因为拥有更加完善的生态环境和算子支持博主本人使用的是华为Atlas 200I DK A2开发套件如下图所示SoC为Ascend 310B但发现CSDN上目前没有什么比较详细的免费文章与开源项目供大家入手因此自己尝试进行完整流程的部署遂以此文分享供大家一起学习。博主之前有写过在瑞芯微RK系列SoC上的YOLOv8目标检测图像分割、YOLOv10目标检测、MoblieNetv2图像分类的模型训练、转换、部署文章感兴趣的小伙伴可以了解下【YOLO11-obb部署至RK3588】模型训练→转换RKNN→开发板部署【YOLO11部署至RK3588】模型训练→转换RKNN→开发板部署【YOLOv10部署RK3588】模型训练→转换rknn→部署流程【YOLOv8-obb部署至RK3588】模型训练→转换RKNN→开发板部署【YOLOv8-pose部署至RK3588】模型训练→转换RKNN→开发板部署【YOLOv8seg部署RK3588】模型训练→转换rknn→部署全流程【YOLOv8部署至RK3588】模型训练→转换rknn→部署全流程【YOLOv7部署至RK3588】模型训练→转换RKNN→开发板部署【YOLOv6部署至RK3588】模型训练→转换RKNN→开发板部署【YOLOv5部署至RK3588】模型训练→转换RKNN→开发板部署【MobileNetv2图像分类部署至RK3588】模型训练→转换rknn→部署流程【ResNet50图像分类部署至RK3588】模型训练→转换RKNN→开发板部署YOLOv8n部署RK3588开发板全流程pt→onnx→rknn模型转换、板端后处理检测如果已经熟悉或使用过瑞芯微的RK系列SoC即对应SDK生态此处贴一下华为Ascend生态与瑞芯微RK的对比对于模型结构来说极为核心的一点是昇腾310B是可以支持FP16的也就是半精。而瑞芯微是对INT8有强依赖的对于量化的需求非常高因此在选择量化校正数据集时需要极为仔细的筛选这就耗费了大家很长的时间去制作校正数据集而Ascend生态是可以避免这个情况的因为310B对FP16是强支持的而我们训练PT模型时常规是FP32但通常ultralytics会帮我们做AMP用半精去取代FP32训练以降低模型参数量实现模型的轻量化而PT转ONNX是保持原精度的因此从PT到ONNX再到OM很多不敏感的参数可以做到不进行替换的只有部分敏感的FP32需要量化为FP16因此从整体模型精度上而言Ascend是远优于RKNN的。二、文件梳理之前博主发布过YOLOv8转RKNN模型并在开发板上部署的流程现在尝试在华为的Atlas 200I DK A2开发套件上使用华为Ascend 310B NPU进行YOLOv8目标检测模型的部署。OK进入正题模型转换需要以下工具第一个文件github上的yolov8项目第二个文件gitee上的Ascend/samples仓库第三个文件可以使用博主本人的Github仓库YOLOv8_Ascend310B_object_detect三、CANN博主使用的是Atlas 200I DK A2也是使用官方烧录的镜像烧录方式参考官网https://www.hiascend.com/hardware/developer-kit-a2/resource绝大多数情况下CANN 安装在 /usr/local/Ascend 目录下。ls/usr/local/Ascend# 如果看到 ascend-toolkit 或者 driver 目录说明装了检查版本信息最准确 查看安装信息文件cat/usr/local/Ascend/ascend-toolkit/latest/aarch64-linux/ascend_toolkit_install.info# 或者cat/etc/ascend_install.info检查环境变量 尝试执行 ATC 命令或 NPU 状态命令npu-smi info这里介绍一下Ascend所要用到的CANN、ATC、AIPP、libascendcl.so、libacllite.so这五个核心内容:1. CANN (Compute Architecture for Neural Networks)地位华为昇腾AI的软件底座全栈解决方案。定义CANN 是华为针对 AI 场景推出的异构计算架构。它不是某一个单一的软件而是一整套软件栈Software Stack。它向上支持 PyTorch/MindSpore 等框架向下屏蔽了不同型号 NPU310B, 310P, 910的硬件差异。RK3588 类比RK3588你平时用的 RKNPU2 SDK rknn-toolkit2 Linux NPU Driver RGA这一大堆东西加在一起勉强可以看作是 RK 的“简易版 CANN”。AtlasCANN 更加庞大和标准化它包含了算子库、图编译引擎、执行引擎等所有软件层面的东西。2. ATC (Ascend Tensor Compiler)地位模型转换的核心工具翻译官。定义昇腾张量编译器。它的核心作用是将开源框架的模型ONNX, TensorFlow, Caffe“翻译”成昇腾 NPU 专用的指令代码.om 格式。工作原理图优化把 ONNX 里零散的算子合并比如 ConvBNRelu 合并成一个大算子。算子编译你之前看到的 kernel_meta 文件夹就是 ATC 在把算子逻辑编译成 NPU 内部的二进制机器码。内存排布提前计算好每一层中间结果需要多少内存怎么搬运。RK3588 类比RK3588rknn-toolkit2 中的 rknn.build() 函数。Atlasatc 命令行工具。为什么叫“离线”因为这个编译过程发生在 PC 或服务器上而不是运行时的开发板上。3. AIPP (Artificial Intelligence Pre-Processing)地位集成在模型里的硬件预处理加速器免费的午餐。定义人工智能预处理。它是 NPU 内部的一个特殊硬件单元专门处理图像数据。为什么需要它模型训练时通常需要RGB 格式、0.0-1.0 归一化、减均值/除方差。摄像头出来的通常是NV12/YUV 格式、0-255 整数。如果没有 AIPP你需要在 CPU 上用 OpenCV 做 cvtColor 和 convertTo这非常消耗 CPU 资源导致帧率上不去。有了 AIPP你在 ATC 转换时通过 aipp.cfg 告诉 NPU“我给你的是 NV12你自己帮我转成 RGB 并归一化”。这个过程是 NPU 顺手做的几乎不消耗额外时间。RK3588 类比RK3588RGA (Rockchip Graphic Acceleration)。但 RGA 是独立的硬件你需要写代码显式调用。AtlasAIPP 是隐式的。一旦转模型时开启了你执行 aclmdlExecute 时硬件自动先做预处理再做推理。4. libascendcl.so (AscendCL)地位真正的“大老板”核心驱动库。全称Ascend Computing Language。定义这是 CANN 开放给开发者的最底层、最核心的 C 语言 API 接口库。功能资源管理aclInit (初始化), aclrtSetDevice (指定 NPU)。内存管理aclrtMalloc (在 NPU 上申请内存), aclrtMemcpy (CPU - NPU 数据搬运)。模型推理aclmdlLoadFromFile (加载 .om), aclmdlExecute (执行推理)。RK3588 类比RK3588librknnrt.so。你在 RK 上调用的 rknn_init, rknn_run 都在这个库里。Atlaslibascendcl.so 是系统库随 CANN 安装通常在 /usr/local/Ascend/ascend-toolkit/…/lib64 下。5. libacllite.so (ACLLite)地位封装好的“小助手”辅助工具库。定义这不是华为 CANN 官方驱动的一部分而是华为 Samples 团队为了降低新手入门难度基于 AscendCL 封装的一套 C 类库。为什么有它原生 AscendCL 接口非常底层写一个推理可能需要 200 行代码处理内存、Context、Stream 等。ACLLite 把它封装成了 InitResource(), Process() 等简单函数让你 20 行代码就能跑起来。RK3588 类比RK3588它相当于 rknn_model_zoo 里的 common 文件夹或者 utils.cc。只不过 RK 是直接给你源码让你编译进项目而华为 Samples 让你把它编译成了一个 .so 库来调用。来源它来自你刚才下载的 samples 仓库是你自己编译安装到 /usr/local/Ascend/thirdpart 下的。如果你已经有了并非常熟悉这些内容可以直接跳过该步骤四、模型训练YOLOv8的模型训练环境配置、训练步骤网上的很多相关教程很多基础不多叙述大家可以直接参考其他文章这是博主的train.py:fromultralyticsimportYOLO# 加载模型modelYOLO(/xxx/Algorithm/YOLOv8/ultralytics-main/yaml/yolov8.yaml)# 从头开始构建新模型#model YOLO(yolov8n.pt) # 加载预训练模型推荐用于训练# Use the modelresultsmodel.train(data/xxx/Algorithm/YOLOv8/ultralytics-main/yaml/construction.yaml,epochs300,batch32)# 训练模型训练完成后在当前路径下的runs/detect下生成我们的best.pt我将其重命名为construction_yolov8n_best.pt博主比较喜欢实用ReLU激活函数因此netron打开模型后如下所示五、PT转ONNX在之前第三步的路径下使用pt2onnx.py将自己的pt模型转成onnx格式博主的pt2onnx.py如下所示fromultralyticsimportYOLO# 加载训练好的模型modelYOLO(construction_yolov8n_best.pt)#相对路径# 导出为 ONNX 格式model.export(formatonnx,imgsz640,# 输入尺寸与训练一致opset12,# ONNX 算子集版本建议12dynamicFalse,# 是否启用动态维度True 适用于可变输入尺寸simplifyTrue,# 启用 ONNX Simplifier 优化模型taskdetect,# 指定任务类型目标检测#taskkeypoint, # 指定任务类型关键点检测)执行转换命令python pt2onnx.py终端结果如下所示在当前路径下生成了和我们的pt模型同名的onnx模型此时用netron打开我们的onnx模型应该如下所示此处的输入大家应该都是[1,3,640,640]的但是输出会不一样博主的ONNX模型输出是[1,11,8400]其中11大家会不一致因为中间数字为通道数即Channels楼主总共有7个类别所以加上坐标参数就是11六、ONNX转OM这里先解释一下什么是OM:全称Offline Model离线模型。含义在瑞芯微RKNN中.rknn 是 NPU 能够识别的模型格式。在华为昇腾CANN中.om 就是 NPU达芬奇架构能够直接识别并执行的二进制指令集。为什么叫“离线” (Offline)这里的“离线”是指编译阶段是离线的。与之相对的是“在线编译”比如在 TensorFlow/PyTorch 运行时实时编译图。华为为了极致的推理性能要求开发者在 PC 或服务器上提前把模型ONNX/Caffe通过 ATC 工具完全编译好生成固定的指令流。当模型在开发板上运行时NPU 不需要再做任何图优化或编译工作直接加载指令“无脑”执行速度最快。OM转换有两种方法第一种是在开发板上直接转换第二种是在X86虚拟机或Linux服务器上直接转换此处都给大家介绍一下流程一、开发板上转换下面开始OM转换先将自己的ONNX模型复制到开发板上的model文件夹如下所示同时要注意修改好自己的aipp.cfg这里说一下aipp.cfg的作用就是提前告诉NPU我们要进行哪些预处理操作华为有一个类似瑞芯微的 RGA 但更紧耦合的黑科技叫 AIPP (Artificial Intelligence Pre-Processing)。它可以在 NPU 内部直接完成 YUV420 - RGB、Resize (部分)、归一化 (Mean/Std)。一般来说大家的aipp.cfg都差不多如果是YOLOv8模型那可以参考我的aipp.cfg如下所示aipp_op{aipp_mode:staticinput_format:YUV420SP_U8src_image_size_w:640src_image_size_h:640csc_switch:truerbuv_swap_switch:falsematrix_r0c0:256matrix_r0c1:0matrix_r0c2:359matrix_r1c0:256matrix_r1c1:-88matrix_r1c2:-183matrix_r2c0:256matrix_r2c1:454matrix_r2c2:0input_bias_0:0input_bias_1:128input_bias_2:128crop:trueload_start_pos_h:0load_start_pos_w:0crop_size_w:640crop_size_h:640min_chn_0:0min_chn_1:0min_chn_2:0var_reci_chn_0:0.0039215686274509803921568627451var_reci_chn_1:0.0039215686274509803921568627451var_reci_chn_2:0.0039215686274509803921568627451}然后在model文件夹下执行如下命令atc--modelconstruction_yolov8n_best.onnx\--framework5\--outputconstruction_yolov8n_best\--input_shapeimages:1,3,640,640\--soc_versionAscend310B1\--insert_op_confaipp.cfg终端结果如下所示现在需要等待开发板的速度比较慢大概10minX86服务器上的速度会快一些此时可以看到我们可以通过其他终端看到ATC在疯狂转换OM模型中CPU负载基本占到一个核在转换过程中会看到model文件夹下出现kernel…的文件夹这里介绍下kernel_meta_temp… 文件夹是干啥的kernel_meta_temp… 文件夹是 ATC 工具在进行 TBE (Tensor Boost Engine) 算子编译 时生成的中间产物。它的含义当 ATC 在你的模型中发现一些算子Operator没有现成的、预编译好的二进制文件可用或者因为你要插入 AIPP预处理它就需要现场“写代码”并编译出适合 Ascend 310B NPU 的算子内核。它的存在证明ATC 并没有挂起它正在后台疯狂地编译 CCE (CUBE/Vector) 代码。千万不要手动删除这些文件夹等转换完成后它们通常会自动清理或者保留作为缓存。运行结果后终端如下所示可以看到终端显示ATC已经成功将ONNX模型转成OM模型了我们在当前列表下可以看到二、X86虚拟机上转换此时我们要现在开发上输入如下命令cat/usr/local/Ascend/ascend-toolkit/latest/aarch64-linux/ascend_toolkit_install.info结果如下所示博主的开发板上显示的是7.0.RC1此时打开昇腾社区开发资源https://www.hiascend.com/developer/download/community/result?modulecanncann7.0.0.beta1选选择左边的CANN版本即7.0然后右侧选择run找打X86的run文件然后点击下载如果你的CANN是别的版本也以此类推下载好如下所示将该下载好的run文件复制到虚拟机中输入chmodx Ascend-cann-toolkit_7.0.0_linux-x86_64.run./Ascend-cann-toolkit_7.0.0_linux-x86_64.run此时需要等待一会等待安装完成…安装完成后可以直接将上文提到的aipp.cfg和你的onnx模型一起复制到虚拟机中然后执行同样的编译命令博主操作的流程如下所示可以看到一样也得到了om模型而且博主测试过om模型在x86和arm开发板上转换是一样的只是平台不同都可以在Ascend310B上运行。这里要说一下ATC工具最好是在X86上使用因为Ascend 310B的SoC上的CPU肯定是不如X86的ATC的转换主要是通过CPU完成的所以在开发板上运行转换会很慢博主自己测试在开发板上转换om大概要20min而X86虚拟机的转换时间在3-4min左右推荐大家按照方法二在X86虚拟机上进行om转换。这里要提一下我们习惯每次将转换得到的模型用netron打开查看一下结构但是Ascend转换得到的om模型用netron打开后往往会报错这并不代表你的模型有问题如下所示原因如下所示OM 模型本质是“二进制指令”.onnx就像是源代码逻辑清晰人类和通用工具易读。.om就像是编译后的可执行文件.exe 或 .o。它是 ATC 编译器针对华为 NPU 硬件架构达芬奇架构进行了深度优化、算子融合Fusion、内存重排后的二进制指令集。Netron 打开.om文件实际上是在尝试“反编译”这个二进制文件来还原图结构。ATC 的内部优化导致命名冲突报错中的Relu_147/same_input_conv_split:1是 ATC 编译器在优化过程中自动生成的内部节点名称。Graph Fusion图融合ATC 会把原来的 ONNX 中的很多算子合并比如 ConvBNRelu 合并成一个或者为了并行计算把数据进行 Split拆分。在 Ascend 310B 的编译过程中可能生成了某种特殊的内存共享结构Netron 的解析器Parser无法理解这种专有的硬件优化结构误以为出现了重复的节点名称从而报错崩溃。Netron 对 OM 的支持并不完美Netron 对.om格式的支持属于“实验性”的并不是官方完美支持。华为 CANN 的版本更新很快你用的是最新的 Ascend 310B 架构Netron 可能还没有适配最新版本的指令集格式。七、模型部署在完成上述流程后我们已经得到了符合要求的om模型了此时打开第三个项目文件即博主的个人仓库我已经把自己的onnx模型和om模型放到了Github项目的model文件夹下、测试图片放到data文件夹下大家 git clone 后可直接先把编译的相关内容删掉然后重新编译再用我的om模型和图片直接运行测试如果项目对大家有所帮助希望点个免费的小星星在开始之前需要先在开发板上手动安装好ACLLite博主的情况是使用了华为昇腾官方的镜像烧录后发现开发板上没有ACLLite所以只好手动安装此时就需要用到上文提到的第二个文件即在gitee上的Ascend/samples操作流程如下所示gitclone https://gitee.com/ascend/samples.gitcdxxx/samples/cplusplus/common/aclliteexportCPU_ARCHaarch64exportTHIRDPART_PATH/usr/local/Ascend/thirdpartexportINSTALL_DIR/usr/local/Ascend/ascend-toolkit/latest# 编译make# 安装makeinstall如果上述命令执行顺利的话可以通过如下命令检查是否顺利安装成功ls/usr/local/Ascend/thirdpart/lib/libacllite.sols/usr/local/Ascend/thirdpart/include/acllite/AclLiteUtils.h博主安装完后检查如下所示安装成功安装好后开始编译工作1.先删除掉build下的之前编译的所有内容2.修改include/label.h将label改成我们自己的类别3.打开sampleYOLOV8.cpp找到GetResult函数将其中的“classNum”改成自己的类别数4.打开sampleYOLOV8.cpp找到最下面的main函数修改模型路径改成你自己的模型名5.完成修改后保存文件然后在build路径下执行如下命令cmake..make终端结果如下所示然后在build路径下执行命令./ascend_310b_yolov8_demo终端结果如下所示检测结果如下所示上述即博主此次更新的YOLOv8部署华为Atlas 200I DK A2开发套件适配Ascend310B NPU的全部流程包含PT转ONNX转OM的完整步骤欢迎交流