基于弹性云服务器的昇腾AI应用开发随笔【与云原生的故事】
什么是弹性云服务器?
下面来介绍下我在弹性云服务器上基于Ascend 310的应用开发,这其实是在参加CANN训练营,这里推荐一下,硬核AI技术 · 新手+进阶定制化课程 更有无人机等超级大奖等你来!!感兴趣的同学,可以来参加一下,小白亦可,有新手班,还是不错的!
昇腾AI应用开发
这里主要是基于Ascend 310处理器的弹性云服务器做应用开发,偏向于媒体数据处理,并最终应用于AI模型推理,更多详情,可参考媒体数据处理精讲与实战。
应用第一弹
前情提要
1. 按照官方B站视频介绍,接收镜像,并创建云服务器;如果不想看视频,可以参照其他开发者的教程配置环境,推荐教程【CANN训练营进阶班应用课笔记】大作业1实战趟坑记录。
2. ssh登录服务器,可以用MobaXterm,也可以直接用Visual Studio Code,这里选择前者,因为MobaXterm支持X server,简单来说,就是支持图形界面,方便我们后续查看yuv文件,如果有朋友不熟悉,推荐教程【CANN训练营进阶班应用课笔记】大作业1实战趟坑记录。
准备工作
1. 安装ffmepg。方便通过ffplay查看yuv文件。在root用户下执行如下命令即可:
sudo apt-get install ffmpeg
2. 切换到用户HwHiAiUser。因为默认是root用户登陆,但是运行代码用HwHiAiUser用户才行,否则报错。
具体操作
1. 将jpeg图片解码成yuv格式(输入文件是dog1_1024_683.dog,尺寸为1024 x 683)先来看看输入jpg文件
接下来操作!
# 确保已经切换到HwHiAiUser用户
cd /home/HwHiAiUser/samples/cplusplus/level2_simple_inference/0_data_process/jpegd/scripts
# 注意下面命令运行时,会弹出架构选项,因为我们的CPU是x86架构的,所以这里选择x86,如下图所示
bash sample_build.sh
bash sample_run.sh
最终程序运行成功截图:
我们到这个目录下可以看到生成的.yuv文件:
/home/HwHiAiUser/samples/cplusplus/level2_simple_inference/0_data_process/jpegd/out/output
如下图所示:
接下来,我们查看图片,在root用户下执行命令:
# 注意在root用户下执行,如果不是root用户,可执行su root进行切换
ffplay -f rawvideo -video_size 1024x683 dvpp_output.yuv
可以看到,如下图片,注意这是依赖了MobaXterm的X Server
此时程序运行截图:
可以看到yuv格式的文件上方有一条黄边,在使用ffplay查看时,需要设置图像大小,这里设置的是解码之前的jpeg文件大小,即1024 x 683,而得到的yuv文件,要符合DVPP的宽128对齐,高16对齐要求,原文件宽度没问题,高度要调整对齐,则应为1024 x 688(688是16的倍数),即高度增加了,接下来,我们运行如下代码试试:
ffplay -f rawvideo -video_size 1024x688 dvpp_output.yuv
得到如下图片:
上方的黄边没了,但是下方多了一条绿边,应该就是因为高度对齐带来的吧,正如作业文档提到的那样:
2. 对yuv格式进行resize(输入是上一步得到的yuv格式文件)
# 注意之前可能是root用户,这里我们通过su HwHiAiUser切换为HwHiAiUser用户
cd /home/HwHiAiUser/samples/cplusplus/level2_simple_inference/0_data_process/resize/scripts
# 注意下面命令运行时,仍然会弹出架构选项,因为我们的CPU是x86架构的,所以这里选择x86,如下图所示
bash sample_build.sh
我们希望resize第一步生成的yuv文件,并设置resize大小,所以先将之前生成的yuv文件拷贝到当前程序的输入目录
cp /home/HwHiAiUser/samples/cplusplus/level2_simple_inference/0_data_process/jpegd/out/output/dvpp_output.yuv /home/HwHiAiUser/samples/cplusplus/level2_simple_inference/0_data_process/resize/data/
接下来,修改运行脚本sample_run.sh,主要是输入图片的路径和resize的分辨率:
cd ../scripts/
vim sample_run.sh
# 将sample_run.sh的第10行,替换为如下,表示输入yuv文件路径是../data/dvpp_output.yuv,大小是1024 x 688,resize后大小是224 224
running_command="./main ../data/dvpp_output.yuv 1024 688 ./output/output.yuv 224 224 "
# 运行程序
bash sample_run.sh
我们来看下运行成功截图:
下面看看resize后的yuv文件
# 查看yuv文件要root用户,所以先切换
su root
# 切换到输出的yuv文件目录
cd ../out/output
# 查看yuv文件
ffplay -f rawvideo -video_size 224x224 output.yuv
可以看到明显变小了,而且没有绿边或黄边,这应该是因为DVPP的输入是符合前面提到的宽高对齐要求的。但要注意的是我们设置的resize大小224 x 224的宽度是不符合128对齐的。
3. resize后的yuv文件编码成jpg图片(输入是上一步得到的resize后的yuv格式文件)
# 注意之前可能是root用户,这里我们通过su HwHiAiUser切换为HwHiAiUser用户
cd /home/HwHiAiUser/samples/cplusplus/level2_simple_inference/0_data_process/jpege/scripts
# 修改main.cpp文件,执行输入yuv文件路径和大小
# 切换到main.cpp所在文件夹
cd /home/HwHiAiUser/samples/cplusplus/level2_simple_inference/0_data_process/jpege/src
# 修改文件
vim main.cpp
# 在第242行,将该行替换为如下:
PicDesc testPic = {"../data/output.yuv", 224, 224};
# 注意下面命令运行时,仍然会弹出架构选项,因为我们的CPU是x86架构的,所以这里选择x86
bash sample_build.sh
# 接下来,我们要将上一步得到的resize后的yuv文件拷贝过来作为输入
cp /home/HwHiAiUser/samples/cplusplus/level2_simple_inference/0_data_process/resize/out/output/output.yuv /home/HwHiAiUser/samples/cplusplus/level2_simple_inference/0_data_process/jpege/data/dvpp_output.yuv
# 运行程序
bash sample_run.sh
最终运行成功截图:
最终得到编码后的图片
至此,我们完成了全部流程,对于输入文件是dog1_1024_683.dog,尺寸为1024 x 683的jpg文件——> 解码为YUV文件——>resize到224 x 224 大小——>编码为jpg文件,最终得到了编码后的,如上图所示的jpg文件。
应用第二弹
这是在前一步的基础上的延伸和拓展,一脉相承
前情提要
1. 按照官方B站视频介绍,接收镜像,并创建云服务器;如果不想看视频,可以参照其他开发者的教程配置环境,推荐教程【CANN训练营进阶班应用课笔记】大作业1实战趟坑记录。
2. ssh登录服务器,可以用MobaXterm,也可以直接用Visual Studio Code,这里选择前者,因为MobaXterm支持X server,简单来说,就是支持图形界面,方便我们后续查看yuv文件,如果有朋友不熟悉,推荐教程【CANN训练营进阶班应用课笔记】大作业1实战趟坑记录。
准备工作
1. 安装ffmepg。方便做视频解码和通过ffplay查看yuv文件。在root用户下执行如下命令即可:
sudo apt-get install ffmpeg
2. 切换到用户HwHiAiUser。因为默认是root用户登陆,但是运行代码用HwHiAiUser用户才行,否则报错。
3. 任务要求。从开发手册可以看到
首先,明确输入是一段.mp4封装的视频,输出是jpeg图片(注意,图片的“分辨率”与输入视频不同),具体来说,整个过程是
本地.mp4封装的视频(无法直接对mp4格式封装的视频做解码,需要先转换为H.264/H.265视频流)------>硬解码为H.264/H.265视频流——>解码得到YUV图片(一张或多张))——>缩放(修改分辨率,一张或多张)——>硬编码为jpeg文件(一张或多张)
这里提供一段mp4格式封装的视频,分辨率为1920 x 1080(1080P),帧率为25,编码为AVC(H.264),下载链接为:
链接:https://pan.baidu.com/s/10b3x15HfGHRmam16M1sGrw
提取码:fo6c
预览一下视频!这是一段经典的视频,一般用于展示行人检测或跟踪的应用效果。
具体操作
1. 将输入的mp4文件解码为H.264或H.265视频流
接下来操作!因为昇腾处理器中的视频编解码专用硬件电路无法直接对mp4格式封装的视频操作,要求输入是H.264/H.265视频流,所以我们先对输入的mp4视频做“拆装”,可以通过ffmpeg来做:
# 注意,我们要先将视频文件TownCentreXVID_1920_1080_25_AVC_H264.mp4上传到
# /home/HwHiAiUser/samples/cplusplus/level2_simple_inference/0_data_process/vdec/data/下
# 上传操作也很简单,直接在MobaXterm上打开到上述目录,点击上传即可
ffmpeg -i TownCentreXVID_1920_1080_25_AVC_H264.mp4 -vcodec h264 TownCentreXVID_1920_1080_25_AVC_H264.h264
运行过程截图:
运行结果截图:
好了,我们现在得到想到的H.264视频流了(即 TownCentreXVID_1920_1080_25_AVC_H264.h264),下面要开始解码了,得到YUV格式文件:
首先要修改下main.cpp中的一些参数设置:
# 进入main.cpp所在目录
cd /home/HwHiAiUser/samples/cplusplus/level2_simple_inference/0_data_process/vdec/src
# vim修改文件
vim main.cpp
# 首先,修改输入文件路径和名称,将第22行的std::string filePath= "../data/vdec_h265_1frame_rabbit_1280x720.h265"; 修改为
std::string filePath= "../data/TownCentreXVID_1920_1080_25_AVC_H264.h264";
# 其次,修改输入视频大小
# 将第23行的const int inputWidth = 1280; 修改为
const int inputWidth = 1920;
# 将第24行的const int inputHeight = 720; 修改为
const int inputHeight = 1080;
# 这样才和我们的输入视频大小相匹配
# 最后修改解码设定,将第 40行的int32_t enType_ =0 ; 改为
int32_t enType_ =3 ;
# 参照注释,可知这对应H.264
/* 0:H265 main level
* 1:H264 baseline level
* 2:H264 main level
* 3:H264 high level
*/
接下来,来运行试试!
# 确保已经切换到HwHiAiUser用户
cd /home/HwHiAiUser/samples/cplusplus/level2_simple_inference/0_data_process/vdec/scripts
# 注意下面命令运行时,会弹出架构选项,因为我们的CPU是x86架构的,所以这里选择x86,如下图所示
bash sample_build.sh
bash sample_run.sh
最终程序运行成功截图:
运行速度很快,体验不错!我们到这个目录下可以看到生成的.yuv文件:
cd /home/HwHiAiUser/samples/cplusplus/level2_simple_inference/0_data_process/vdec/out/output
如下图所示,可以看到我们得到的10张图片
接下来,我们查看图片,在root用户下执行命令:
# 注意在root用户下执行,如果不是root用户,可执行su root进行切换
ffplay -f rawvideo -video_size 1920x1080 image1.yuv
可以看到,如下图片,注意这是依赖了MobaXterm的X Server
此时程序运行截图:
我们还可以查看其他yuv图片,注意到展示的图片有些色彩疑似有问题,暂时先不管了。
2. 对yuv格式进行resize(输入是上一步得到的yuv格式文件)
其实到这一步的话,就和第一次大作业的过程基本一致了,这也是此次作业的目的之一,巩固上次的学习成果,连续性还是很不错的,可见老师设计的时候也是经过深思熟虑和精心安排的,同时这种视频编解码、resize和图片编解码的操作是在计算机操作中很常见的,在AI推理和训练中也常用,非常有学习价值和意义,更重要的是,一般来说,都会配有专门的硬件电路来加速,这也是DVPP的作用。
那这里,就选择image1.yuv来操作吧!
# 注意之前可能是root用户,这里我们通过su HwHiAiUser切换为HwHiAiUser用户
# 首先将image1.yuv拷贝到我们resize操作的数据输入目录
cp /home/HwHiAiUser/samples/cplusplus/level2_simple_inference/0_data_process/vdec/out/output/image1.yuv /home/HwHiAiUser/samples/cplusplus/level2_simple_inference/0_data_process/resize/data
# 接下来修改运行脚本sample_run.sh,主要是输入图片的路径和resize的分辨率:
# 首先进入脚本所在路径
cd /home/HwHiAiUser/samples/cplusplus/level2_simple_inference/0_data_process/resize/scripts
# vim修改文件第10行,修改为
running_command="./main ../data/image1.yuv 1920 1080 ./output/output.yuv 224 224 "
# 这表示我们处理的是./main ../data/image1.yuv文件,该文件尺寸为1920 x 1080,设置输出路径是./output/output.yuv ,输出文件outpu.yuv的大小是224 x 224
# 注意下面命令运行时,仍然会弹出架构选项,因为我们的CPU是x86架构的,所以这里选择x86,如下图所示
bash sample_build.sh
bash sample_run.sh
resize后的文件为output.yuv,我们来看看
# 来到output.yuv保存路径
cd /home/HwHiAiUser/samples/cplusplus/level2_simple_inference/0_data_process/resize/out/output
# 注意在root用户下执行,如果不是root用户,可执行su root进行切换
ffplay -f rawvideo -video_size 224x224 output.yuv
可以看到图片尺寸确实缩小了,而且没有绿边或黄边,这应该是因为DVPP的输入是符合前面提到的宽高对齐要求的。但要注意的是我们设置的resize大小224 x 224的宽度是不符合128对齐的。
应该没啥问题,接着来吧!
3. resize后的yuv文件编码成jpg图片(输入是上一步得到的resize后的yuv格式文件)
# 注意之前可能是root用户,这里我们通过su HwHiAiUser切换为HwHiAiUser用户
# 将上一步生成的output.yuv拷贝到指定路径,方便后续jpeg编码
cp /home/HwHiAiUser/samples/cplusplus/level2_simple_inference/0_data_process/resize/out/output/output.yuv /home/HwHiAiUser/samples/cplusplus/level2_simple_inference/0_data_process/jpege/data
# 进行路径
cd /home/HwHiAiUser/samples/cplusplus/level2_simple_inference/0_data_process/jpege/scripts
# 修改main.cpp文件,执行输入yuv文件路径和大小
# 切换到main.cpp所在文件夹
cd /home/HwHiAiUser/samples/cplusplus/level2_simple_inference/0_data_process/jpege/src
# 修改文件
vim main.cpp
# 在第242行,将该行替换为如下:
PicDesc testPic = {"../data/output.yuv", 224, 224};
# 注意下面命令运行时,仍然会弹出架构选项,因为我们的CPU是x86架构的,所以这里选择x86
bash sample_build.sh
# 接下来,我们要将上一步得到的resize后的yuv文件拷贝过来作为输入
cp /home/HwHiAiUser/samples/cplusplus/level2_simple_inference/0_data_process/resize/out/output/output.yuv /home/HwHiAiUser/samples/cplusplus/level2_simple_inference/0_data_process/jpege/data/dvpp_output.yuv
# 运行程序
bash sample_run.sh
接下来,到输出路径看看,之后下载到本地查看即可。因为MobaXterm很好的文件交互性和可视化,我们可以直接双击该输出文件,就能自动下载查看了
最终得到编码后的图片
至此,我们完成了全部流程,最终得到了编码后的,如上图所示的jpg文件。
应用第三弹
首先来看下要求
简单来说,就是利用所学,完成YOLOv3完整的推理过程!下面来逐步操作吧。
1. 完成模型转换
注意,模型转换要涉及处理模型输入数据的大小和格式,这一点要明确。这里先参照开发手册上提供的模型和配套教程走一遍,验证下流程。
先建一个文件夹用来保存整个过程的文件
mkdir yolov3_detection
# 接下来建立model文件夹,保存模型
mkdir model
# 接下来,下载模型和配置文件
wget https://modelzoo-train-atc.obs.cn-north-4.myhuaweicloud.com/003_Atc_Models/AE/ATC%20Model/Yolov3/yolov3.caffemodel
wget https://modelzoo-train-atc.obs.cn-north-4.myhuaweicloud.com/003_Atc_Models/AE/ATC%20Model/Yolov3/yolov3.prototxt
wget https://modelzoo-train-atc.obs.cn-north-4.myhuaweicloud.com/003_Atc_Models/AE/ATC%20Model/Yolov3/aipp_nv12.cfg
运行截图:
接下来,参照指导,进行模型转换:
# 注意,这里使用的是官方给的命令,会导致转换的模型后缀为.om.om,不建议使用
atc --model=yolov3.prototxt --weight=yolov3.caffemodel --framework=0 --output=yolov3_framework_caffe_aipp_1_batch_1_input_int8_output_FP32.om --soc_version=Ascend310 --insert_op_conf=aipp_nv12.cfg
# 建议使用本命令,这样转换得到的模型是.om后缀
atc --model=yolov3.prototxt --weight=yolov3.caffemodel --framework=0 --output=yolov3_framework_caffe_aipp_1_batch_1_input_int8_output_FP32 --soc_version=Ascend310 --insert_op_conf=aipp_nv12.cfg
注意,参照教程这里的--output是以.om结尾,但是发现这会导致生成的模型是 yolov3_framework_caffe_aipp_1_batch_1_input_int8_output_FP32.om.om,即是以.om.om结尾,有点奇怪,不过不影响运行,毕竟只是个名字,但是这会影响到后续的执行,因为教程后续用的是
yolov3_framework_caffe_aipp_1_batch_1_input_int8_output_FP32.om
而我们实际生成的是
yolov3_framework_caffe_aipp_1_batch_1_input_int8_output_FP32.om.om
这在系统看来完全是两个不同的模型,因此,要注意统一名称,只要保持先后一致即可,这里我选择的是直接用实际生成的.om.om模型吧!
再次需要注意的是这里仅仅是对样例说明,如果将模型用于推理,则一定要用.om模型,如果再用.om.om模型就会报错(当然,也可能是权限不够,因为我们运行时,使用的是HwHiAiUser用户),因此,从规范和长远角度来说,应该用.om模型,我这里的选择用.om.om模型是不明智的,有些糟糕,建议大家直接用上方转换模型的第二条命令,直接得到.om模型,推荐!推荐!推荐!
这个模型转换过程资源消耗较大,需要稍等一下,运行成功截图:
接下来,使用使用msame工具推理,先来准备一下,这里官方提供了较为详细的教程,跟着做就行了:
git clone https://gitee.com/ascend/tools.git
export DDK_PATH=/home/HwHiAiUser/Ascend/ascend-toolkit/latest
export NPU_HOST_LIB=/home/HwHiAiUser/Ascend/ascend-toolkit/latest/acllib/lib64/stub
cd $HOME/tools/msame/
chmod +x build.sh
./build.sh g++ $HOME/tools/msame/out
cd out
# 注意,这里的--model和--output路径根据实际模型存放路径和你想输出的路径填写
./msame --model /home/HwHiAiUser/yolov3_detection/model/yolov3_framework_caffe_aipp_1_batch_1_input_int8_output_FP32.om.om --output /home/HwHiAiUser/yolov3_detection/model/msame_infer --outfmt TXT --loop 100
程序运行成功的部分截图:
可以到我们指定的输出路径下看到生成的结果文件
至此的整个过程按照开发文档中提供的教程操作即可,还是比较简单的。
2. 结合所学,完成模型推理
这里参考了官仓的样例,基于上述得到的模型进行推理,完整代码会提交在作业帖中,并附有README,分为模型准备和转换、编译和运行三部分,正常运行推理后可得到结果
至此,基本应用开发就完成了,算是初识,如果日后用到,算是有个印象,但想深入研究的话,还是要多看看文档,了解底层硬件,特别是这种应用,根据硬件特性做针对性加速很重要。
与ModelArts相关的一些
这里主要是在ModelArts平台,基于华为Ascend 910解决训练网络精度调优的问题,可参见训练网络精度调优精讲与实战获取更多详情。
前情提要
1. PyCharm常用操作和配置ModelArts插件使用,官方文档和介绍较为详细,这里不在叙述
2. 需要说明的是,我是用的插件版本是3.3.5,比教程中的应该是新一些,所以有些配置不同,主要是两点:(1)Image Path按照教程设置无效,导致无法启动训练作业,直接不设置就行了;(2)Data Path,即数据集存放路径,必须是本人账号的桶路径才行(也可能是因为教程中的桶区域不是北京四),所以无法按照教程设置,我下载数据集后,上传到自己的桶中,并指定路径即可。
具体操作
1. 直接运行,可以得到:
性能指标约为sec / step: 0.01,即每训练一步耗费的时间约为0.01秒,这应该是在纯CPU运行的情况下,即全部跑在鲲鹏处理器上。从负载图上,也能看到基本都是CPU在承担任务:
进行NPU迁移
参照社区文档和老师的讲解,可以较好完成模型迁移,迁移后运行:
可以看到性能约为sec / step :0.002,提升了5倍,NPU果然效果显著,我想这还不是极限,因为目前仅迁移,还没有做性能调优,从系统负载图,也能看到NPU在承担计算任务了,但利用率不是很高,有很大提升空间。
大约15分40秒的时间,模型训练完成,如图所示:
性能和精度还是不错的。
2. 验证完成NPU迁移
这里要说明一下: 因不习惯使用ModelArts插件,所以我下载了数据集和代码,并进行了修改,已适配ModelArts的NoteBook的Ascend环境,故以下操作都是在ModelArts的NoteBook运行,而非训练作业。ModelArts的NoteBook的规格为
运行日志保存在./test/output//train_.log中,可以查看信息,我们来看看Ascend 910运行情况:
我们可以看到NPU的AI Core的利用率、Memory-Usage,这都显示已经运行在NPU上了,这里的利用率过低是因为同时进行了溢出检测等操作,而且这是同时在跑两个程序。如果不进行溢出检测,仅运行一个程序就好多了,如下图所示
3. 混合精度 + Loss Scale 使能
这里,我使用了静态Loss Scale,设置loss_scale = 1024,方便后续附加作业打印
4. 完成溢出检测使能
可以到overflow文件夹下查看信息,大体如图所示:
5. 附加题,使能 lossscale 后,打印出 loss scale 的具体值
查看./test/output//train_.log,可以看到打印的loss scale数值
至此,基本完成了。还是挺有意思的!
好了,到这里就要结束了,如果有问题,可联系tjulitianyi@163.com或在下方评论,谢谢。
【与云原生的故事】有奖征文火热进行中:https://bbs.huaweicloud.com/blogs/345260
- 点赞
- 收藏
- 关注作者
评论(0)