CANN体验官第四期——Ascend 310P 推理应用开发体验(CC++)随笔

2023-11-23 19:40

本文主要是介绍CANN体验官第四期——Ascend 310P 推理应用开发体验(CC++)随笔,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

活动介绍

CANN体验官第四期,是基于 Ascend 310P 进行推理应用开发体验,体验尝鲜 Ascend 310 → Ascend 310P 的应用迁移及Ascend 310P 的新特性:媒体数据处理V2版本接口!

注: Ascend 310P 应该就是Ascend 710,如果执行如下命令:

npu-smi info

可得

image.png

环境说明

  1. 华为官方提供了硬件和指导书,可以远程登录硬件使用,只是需要通过 VPN 登录,而 VPN 登录指导书和活动体验指引以及体验报告模板,可以到活动页面下载。
    关于 VPN 的登录,由于官方给的文档很详细,这里就不赘述了。远程登录推荐使用MobaXterm,非常好用!这里可能有的同学会更习惯 VS Code,不过使用 MobaXterm 亦可通过 VS Code 来编辑代码文件,没有错,是不是很棒,而且 MobaXterm 还提供了强大的代码文件比对功能,让你快速知道不同代码文件的差异,非常适合基于官方代码改进和完善的同学。

  2. CANN的toolkit是root用户安装的,运行在非root用户,需要先设置环境。以运行用户在任意目录下执行如下命令,打开.bashrc文件:

vi ~/.bashrc

在文件最后一行后面添加:

. /usr/local/Ascend/ascend-toolkit/set_env.sh  # 注意.和/之间有空格

执行命令保存文件并退出:

:wq!

最后记得执行命令使其立即生效:

source ~/.bashrc
  1. 配置环境变量
export DDK_PATH=/usr/local/Ascend/ascend-toolkit/latest/arm64-linux
export NPU_HOST_LIB=$DDK_PATH/acllib/lib64/stub
  1. 软硬件配置

image.png

活动体验

基础体验:体验 Ascend 310->Ascend 310P 的推理应用迁移

image.png

评分规则

image.png

我们可以看到官方的体验指引非常详细,而且给了参考案例,还贴心地给了提示。总的来说,这个体验还是比较简单的,主要是在于模型的转换,而官方也给了建议需将--soc_version 参数设置为 Ascend710 。剩下的就很简单了。

不过这里,我并没有选用官方推荐的案例,而是自选一个我认为更有意思的——基于Caffe ResNet-50网络实现图片分类(图片解码+抠图缩放+图片编码+同步推理)。

这里案例主要是基于Caffe ResNet-50网络(单输入、单Batch)实现图片分类的功能。根据运行应用的入参,可实现以下功能:

  1. 将一张YUV420SP格式的图片编码为*.jpg格式的图片。
  2. 将两张*.jpg格式的解码成两张YUV420SP NV12格式的图片,缩放,再进行模型推理,分别得到两张图片的推理结果后,处理推理结果,输出最大置信度的类别标识以及top5置信度的总和。
  3. 将两张*.jpg格式的解码成两张YUV420SP NV12格式的图片,抠图,再进行模型推理,分别得到两张图片的推理结果后,处理推理结果,输出最大置信度的类别标识以及top5置信度的总和。
  4. 将两张*.jpg格式的解码成两张YUV420SP NV12格式的图片,抠图贴图,再进行模型推理,分别得到两张图片的推理结果后,处理推理结果,输出最大置信度的类别标识以及top5置信度的总和。
  5. 将YUV420SP NV12格式的图片(分辨率81928192)缩放,得到40004000。

实现的功能更全面。注意这里用于推理的模型文件是*.om 文件(适配昇腾AI处理器的离线模型),转换模型时,需配置色域转换参数,用于将 YUV420SP 格式的图片转换为RGB 格式的图片,才能符合模型的输入要求。

按照指引,体验还是很流畅的,顺利通过了编译。

image.png

并可以成功运行。

image.png

这里我只展示了第一个功能,有兴趣的同学可以试试其他功能,多体验一下。

进阶体验一:体验 Ascend 310P 缩放功能

image.png

评分规则

image.png

我们可以看到,我们要实现的功能是使用媒体数据处理 V2 将一个图片做缩放,主要部分是对一张 1920 * 1080 分辨率、YUV420SP NV12 格式的图片(官方已提供)缩放为 1280 * 720 分辨率、YUV420SP NV12 格式的图片。

这里官方很好的给出了参考样例,我选择基于官方给出的参考样例进行改造,下面按照评分规则,逐项介绍。在此之前,先来看一下我们要处理的官方给出的 .yuv 原图,.yuv 格式无法直接查看,一般可以通过 ffmpeg 直接在服务器上查看,但服务器并没有安装,而由于没有 root 权限,我也无法自行安装,所以选择了下载到本地查看,这里介绍一个免费的查看工具 YUView,支持包括 Windows、Linux 和 Mac 主流平台,使用起来非常方便,而且提供了安装包,直接下载安装即可。

这里需要说明一下,直接打开后可能无法查看,因为 YUV 文件需要设置如下三项:

image.png

关于 YUV Format,可能没有上图中的选项,这时我们按照如下操作,勾选相应选项即可。

image.png

image.png

注意这里的Chroma Subsampling一定选择 420,因为我们这里所采用的格式都是 YUV420SP NV12 ,这一点要注意,如果遇到不是该格式的情况,请手动选择该格式,以便能正常显示。

下面我们来看看,来自官方的原始图片 dvpp_vpc_1920x1080_nv12.yuv,通过YUView可看到:

image.png

这张图片我们后面会一直用到哦。

对于评分规则第一点,是让我们跑通所给参考样例,按照 README 操作还是比较容易的,顺利完成编译和运行。

image.png

image.png

最后得到 resize_out.yuv 图片,我们来看看:

image.png

第一点实现还是比较简单的,由易到难,循序渐进,下面来看看第二点的要求。第二点要求我们缩放后的分辨率为 1280 * 720,也就是在第一点的基础上,改输出分辨率,通过查看代码和所用 API 的参数设置,可以很快解决。

首先,我们可以找到主函数,可以看到先设置了相关参数,其中就有outWidthoutHeight,通过查找资料和分析,可以知道这是设置输出图像的分辨率,我们将其分别设置成我们想要的 1280 和 720 就行了,之后按照之前的流程编译运行就好了,还是比较简单的。运行结果为:

image.png

image.png

我们来看看效果:

image.png

搞定!

第三点是在第二点的基础上,进一步做图片格式的转换,要求从之前的 YUV420SP NV12 格式转换成 RGB888 格式,也就是输出格式变了,我们还是先返回,看看代码。首先,通过查看官方文档,我们对

hi_mpi_vpc_resize(chnId, &inputPic, &outputPic, fx, fy, interpolation, &taskID, -1)

这个接口有了基本了解,而通过主函数的参数设置,结合查阅文档,我们基本知道了参数的意义。

    // 参数结构体VpcAttr g_vpc_attribute;// 输入图像宽度g_vpc_attribute.width = 1920;// 输入图像高度g_vpc_attribute.height = 1080;// 输入图像格式g_vpc_attribute.format = 1;// 输出图像宽度g_vpc_attribute.outWidth = 1280;// 输出图像高度g_vpc_attribute.outHeight = 720;// 输出图像格式g_vpc_attribute.outFormat = 1;// x方向的缩放比例,用于当输出宽高设置为0时,启动等比例缩放功能,根据参数配置宽高g_vpc_attribute.fx = 0;// y方向的缩放比例,用于当输出宽高设置为0时,启动等比例缩放功能,根据参数配置宽高g_vpc_attribute.fy = 0;// 缩放算法。其中0:bilinear,1:nearest neighborg_vpc_attribute.interpolation = 0;// 输入图像strcpy(g_vpc_attribute.inputFileName, "../data/dvpp_vpc_1920x1080_nv12.yuv");// 输出图像strcpy(g_vpc_attribute.outputFileName, "resize_output_dvpp_vpc_1280x720_nv12.yuv");

可以看到,我们可以设置输出图像格式,那就简单了,不过这个图像格式是直接用数字来指代,这一点很常用,比如在 OpenCV 中就很多参数是用数字来指代,那么指代关系怎么找呢?换句话说,我们想要的 RGB888 格式是哪个数字表示呢?这里说句题外话,我们根据上述代码中的 1 推断,1 应该直达的就是 YUV420SP NV12了,一会验证一下。通过查看文档,我们可以得到:

image.png

更全的在这里:

HI_PIXEL_FORMAT_YUV_400 = 0,            // YUV400 8bit
HI_PIXEL_FORMAT_YUV_SEMIPLANAR_420 = 1, // YUV420SP NV12 8bit
HI_PIXEL_FORMAT_YVU_SEMIPLANAR_420 = 2, // YUV420SP NV21 8bit
HI_PIXEL_FORMAT_YUV_SEMIPLANAR_422 = 3, // YUV422SP NV12 8bit
HI_PIXEL_FORMAT_YVU_SEMIPLANAR_422 = 4, // YUV422SP NV21 8bit
HI_PIXEL_FORMAT_YUV_SEMIPLANAR_444 = 5, // YUV444SP NV12 8bit
HI_PIXEL_FORMAT_YVU_SEMIPLANAR_444 = 6, // YUV444SP NV21 8bit
HI_PIXEL_FORMAT_YUYV_PACKED_422 = 7,    // YUV422P YUYV 8bit
HI_PIXEL_FORMAT_UYVY_PACKED_422 = 8,    // YUV422P UYVY 8bit
HI_PIXEL_FORMAT_YVYU_PACKED_422 = 9,    // YUV422P YVYU 8bit
HI_PIXEL_FORMAT_VYUY_PACKED_422 = 10,   // YUV422P VYUY 8bit
HI_PIXEL_FORMAT_YUV_PACKED_444 = 11,    // YUV444P 8bit
HI_PIXEL_FORMAT_RGB_888 = 12,           // RGB888
HI_PIXEL_FORMAT_BGR_888 = 13,           // BGR888
HI_PIXEL_FORMAT_ARGB_8888 = 14,         // ARGB8888
HI_PIXEL_FORMAT_ABGR_8888 = 15,         // ABGR8888
HI_PIXEL_FORMAT_RGBA_8888 = 16,         // RGBA8888
HI_PIXEL_FORMAT_BGRA_8888 = 17,         // BGRA8888
HI_PIXEL_FORMAT_YUV_SEMIPLANAR_440 = 1000, // YUV440SP NV12 8bit
HI_PIXEL_FORMAT_YVU_SEMIPLANAR_440 = 1001, // YUV440SP NV21 8bit

看样子,我们想要的 RGB888 格式应该就是用 12 来指代了,顺便验证一下 1 应该就是 YUV420SP NV12 了,是 8 bit表示的。当然,这里除了用数字指代,我们还可以直接用HI_PIXEL_FORMAT_BGR_888,不过代码相应的要改一下,把之前的映射去掉。这一点就随意了,都可以。

对了,输出文件那里也要改下,不能再叫.yuv了。

之后,就是编译和推理了,也很顺利。

image.png

image.png

最后因为输出不能直接查看,这里通过 Python 代码转化为 .bmp 格式查看。

image.png

好了,下面看看第四点,要求从中心区域抠出一个分辨率 600 * 800 的子图,也就是抠图了,这个还是要看文档和代码,好好啃文档吧。这里主要修改的是:

    // 裁剪图片的宽度。g_vpc_attribute.cropWidth = 600;// 裁剪图片的高度。g_vpc_attribute.cropHeight = 800;// 裁剪图片的左偏移。g_vpc_attribute.cropX = (g_vpc_attribute.width - g_vpc_attribute.outWidth) / 2;// 裁剪图片的上偏移。g_vpc_attribute.cropY = (g_vpc_attribute.height - g_vpc_attribute.outHeight) / 2;// 剪裁图片数量,硬件支持剪裁多张图片。g_vpc_attribute.multiCount = 1;

最后的结果为:

image.png

当然,啃文档还是挺无聊的,不过慢慢啃,慢慢理解,就有意思了,特别是时而的柳暗花明,会带给人意外的惊喜,果然,实战才是最好的老师啊。

进阶体验二:体验 Ascend 310P 的 JPEG 解码 + 缩放组合功能

image.png

评分规则

image.png

纸上得来终觉浅,绝知此事要躬行,这里就不详细展开了,说多了,都是探索的“喜悦”,讲多了也作用不大,还是要自己亲自动手做一遍,即使不成功,也能有不错的理解,结合文档和参考样例,多试试就好了。这里展示下结果:

对于第一点:

image.png

对于第二点:

image.png

对于第三点:

image.png

可以看到最下方有些绿边,应该是在联合使用 JPEG 图片解码、图片缩放处理后的输出图片,由于图片宽、高的对齐约束所致。如果后续用于推理,可能会影响最终进度,可以通过“抠图”或其他方法解决,更多详情可参考 JPEGD + VPC + 模型推理(含AIPP)串联使用时的精度提升建议。

这里要说一下,在昇腾710 AI处理器上,JPEGD + VPC串联使用时,由于 JPEGD解码后的输出图片的宽stride高stride有6416对齐的约束,因此解码后的输出图片的宽、高有一些补边的无效数据,所以 VPC 在处理图片前,应首先对 JPEGD 对齐后的输出图片进行原分辨率裁剪(可以考虑进阶体验一中的抠图,抠出原分辨率大小的图,原则上方法很多,大家可以考虑下其他的方法),目的是去除无效数据对图像精度的影响。

好了,到此,基本就告一段落了,有机会再来更新!

这篇关于CANN体验官第四期——Ascend 310P 推理应用开发体验(CC++)随笔的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/420284

相关文章

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

水位雨量在线监测系统概述及应用介绍

在当今社会,随着科技的飞速发展,各种智能监测系统已成为保障公共安全、促进资源管理和环境保护的重要工具。其中,水位雨量在线监测系统作为自然灾害预警、水资源管理及水利工程运行的关键技术,其重要性不言而喻。 一、水位雨量在线监测系统的基本原理 水位雨量在线监测系统主要由数据采集单元、数据传输网络、数据处理中心及用户终端四大部分构成,形成了一个完整的闭环系统。 数据采集单元:这是系统的“眼睛”,

Hadoop企业开发案例调优场景

需求 (1)需求:从1G数据中,统计每个单词出现次数。服务器3台,每台配置4G内存,4核CPU,4线程。 (2)需求分析: 1G / 128m = 8个MapTask;1个ReduceTask;1个mrAppMaster 平均每个节点运行10个 / 3台 ≈ 3个任务(4    3    3) HDFS参数调优 (1)修改:hadoop-env.sh export HDFS_NAMENOD

【C++ Primer Plus习题】13.4

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: main.cpp #include <iostream>#include "port.h"int main() {Port p1;Port p2("Abc", "Bcc", 30);std::cout <<

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

C++包装器

包装器 在 C++ 中,“包装器”通常指的是一种设计模式或编程技巧,用于封装其他代码或对象,使其更易于使用、管理或扩展。包装器的概念在编程中非常普遍,可以用于函数、类、库等多个方面。下面是几个常见的 “包装器” 类型: 1. 函数包装器 函数包装器用于封装一个或多个函数,使其接口更统一或更便于调用。例如,std::function 是一个通用的函数包装器,它可以存储任意可调用对象(函数、函数

hdu1394(线段树点更新的应用)

题意:求一个序列经过一定的操作得到的序列的最小逆序数 这题会用到逆序数的一个性质,在0到n-1这些数字组成的乱序排列,将第一个数字A移到最后一位,得到的逆序数为res-a+(n-a-1) 知道上面的知识点后,可以用暴力来解 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#in

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

OpenHarmony鸿蒙开发( Beta5.0)无感配网详解

1、简介 无感配网是指在设备联网过程中无需输入热点相关账号信息,即可快速实现设备配网,是一种兼顾高效性、可靠性和安全性的配网方式。 2、配网原理 2.1 通信原理 手机和智能设备之间的信息传递,利用特有的NAN协议实现。利用手机和智能设备之间的WiFi 感知订阅、发布能力,实现了数字管家应用和设备之间的发现。在完成设备间的认证和响应后,即可发送相关配网数据。同时还支持与常规Sof