华为昇腾Atlas200DK. CANN模型推理——目标检测结果不对(无检测结果)的问题解决

前言

上周我在华为昇腾Atlas200DK中部署nanodet和yolov5时,出现了目标检测结果不对(没有检测到任何物体),困扰了整整三天,最后找到原因并圆满解决,在这里记录一下debug过程。

以上测试均在python中完成。

问题描述

第一天上午,我首先将nanodet由pytorch的.pth模型转换为.onnx模型,并通过cv2.dnn模块实现仅依赖于opencv的nanodet推理部署main_nanodet.py,该部署文件能够得到正确的检测结果。

随后,我通过atlas_utils(上一篇博客中提到的CANN官方封装接口)将main_nanodet.py改造成在CANN上推理部署的acl_nanodet.py,并且仔细梳理了该acl实现的流程和细节,如下图所示:

Environment
Process
CANN模型加载
pyACL初始化
python模块导入
np后处理
CANN模型推理
np图像预处理
cv2读入图像数据

其中预处理模块如下:

    def pre_process(self, image):
        """
        preprocess
        """
        image_resized = self.padding_resize_image(image)
        image_norm = self._normalize(image_resized.astype(np.float32))
        image_inp = np.transpose(image_norm, (2, 0, 1))
        return image_inp

然后通过CANN atc工具将.onnx模型转换成为.om模型,并运行acl_nanodet.py,运行中无任何报错,后处理模块将输出结果保存在了outputs文件夹中

随后我通过ssh scp工具将结果拷贝到主机上,发现没有任何检测框,开始查错(踩坑)。

问题排查1.后处理模块

我将acl_nanodet.py中模型推理execute()的结果打印出来,发现模型推理有输出,而后处理没有检测出目标,合理怀疑时后处理出了问题,于是我仔细排查了acl_nanodet.py的后处理代码,发现没啥问题,因此我将main_nanodet.py中onnx模型推理的输出,通过np.save()保存下来,直接喂给acl_nanodet.py的后处理,结果outputs文件夹中得到了正确的检测结果,表明后处理没问题,bug在其他地方。

问题排查2.预处理模块

将main_nanodet.py预处理后的数据和acl_nanodet.py预处理后的数据通过np.save()保存后,进行比对,发现几乎没有区别,表明预处理没问题,bug在其他地方。

问题排查3.模型

将main_nanodet.py于acl_nanodet.py模型推理得到的输出通过np.save()保存,发现两者模型推理结果有很大差异,表明是模型推理出现问题。

合理怀疑atc模型转换出现问题,根据官方转换方法重新将.onnx模型转换成.om模型,然后测试,发现推理结果仍然不对,我十分疑惑。

此时我自己debug的经验已经吃不住了,到昇腾官方论坛寻找类似结果,未果。到华为atlas官方文档寻找资料,未果。

然后我将nanodet的onnx模型更换为nanodet_m的onnx模型,这两个模型只在层数和输出尺寸上有区别,因此acl_nanodet.py可以共用,修改超参数就行。

结果仍然不能获得目标检测结果。

问题排查4.算法bug

由于nanodet是较新的算法,可能有一些比较新的算子导致AI芯片计算出现问题,因此第二天我又将yolov5算法移植到atlas200dk中,发现仍然无法检测到目标????人比较懵了

问题排查5.AI板卡

由于后处理、预处理和模型都没问题,因此怀疑该AI板卡芯片出现bug。因此我把Ascend samples中的yolov4例程拷贝下来并进行测试,得到正确的检测结果,表明板卡没问题,此时心里是真的????不知所措

问题排查6.模型精度

根据我的嵌入式模型部署经验,一般模型精度从fp32到fp16不大影响检测结果,而fp16到int8则会造成检测精度掉点,但也不会完全检测不出来东西。

死马当活马医,使用atc模型,将精度设定flag为不改变原模型精度,但仍然没有检测结果,没啥心里感受(因为知道大概不是精度问题)

问题排查6.模型推理

经过了一整天的debug,仍然未找到问题,但由于预处理和后处理没问题,板卡没问题,因此一定是模型推理的问题。

第三日晚,偶然看到官方samples的issue里其他开发者提到无检测结果的问题,官方回复是检查预处理、模型和后处理。

想了想既然检查了预处理,那有没有可能输入模型的数据根本没有预处理,或者说只是”假预处理“?

于是将模型输入数据用np.save()保存下来,发现真的和main_nanodet.py的模型输入数据不同!

问题解决:模型输入数据与预处理不同

我是通过函数的方法,将imread读入的image通过pre_process(): return预处理结果image_inp,然后将预处理结果进行execute([image_inp, ]),但是execute的输入却与image_inp不同

然后我又查阅了pyACL的原生C接口,发现execute()这个函数封装的acl模型推理接口是直接读取内存中指定位置的数据,而execute()封装的实现是把image_inp这个数据的内存地址拷贝到模型读数据的内存地址,也就是说image_inp的内存地址储存的数据并没有进行预处理。

回到pre_process()的实现中,有一句

        image_inp = np.transpose(image_norm, (2, 0, 1))

numpy.transpose这个函数是个”lazy“函数,不对内存中的数据进行重排,仅仅改变读取方式(也就是读取轴顺序),这就导致了传入execute()中的image_inp实际上是没有真正transpose的。

解决方法很简单,为transpose后的image_inp开辟一块新内存就行了,比如numpy.copy()深拷贝:

    def pre_process(self, image):
        """
        preprocess
        """
        image_resized = self.padding_resize_image(image)
        image_norm = self._normalize(image_resized.astype(np.float32))
        image_inp = np.transpose(image_norm, (2, 0, 1))
        return image_inp.copy()

后记

踩坑很痛苦,解决很快乐~

  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
Atlas 200I DK A2是华为发布的一款AI开发套件,用于进行AI模型的训练和推理。关于Atlas 200I DK A2的详细信息可以参考华为官方文档。对于yolov5模型的适配,可以使用模型适配工具,该工具预置了一些典型模型,包括目标检测模型(VOLO V7模型)、图像分类模型(Mobilenet模型)、图像分割模型(Unet模型)和关键点检测模型(Alphapose模型)。同时,该工具还提供了UI操作界面,可以上传自己的数据集并进行标注,创建模型训练任务,并使用PC的CPU算力进行训练。训练完成后,可以对模型进行打包,然后拷贝到Atlas 200I DK A2进行推理。关于Atlas 200I DK A2的安装和使用,可以通过官网下载制卡工具,并选择在线制卡方式进行烧录,根据需要选择基础镜像或E2E镜像,其中E2E镜像包含了更多的样例应用。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [Atlas 200I DK A2(小藤) 开箱](https://blog.csdn.net/qq_47997583/article/details/131196482)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *2* [【2023 · CANN训练营第一季】初识新一代开发者套件Atlas 200I DK A2 第二章 安装配置Atlas 200I DK A2跑通...](https://blog.csdn.net/Lnko666/article/details/130138871)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值