基于 FastDeploy

将 PicoDet 部署到 Jetson Nano 上

之 C++ 版

本文于2022年9月底发布,感谢飞桨达人创造营!!感谢 FastDeploy!!请大家到FD主页点star支持!

本文将从Jetson Nano 2G(创乐博套件)的开箱到目标检测模型的部署,做一个全流程的详解,力求为 Jetson Nano 新手提供一站式的手把手教程,如有不全面的地方,欢迎大家随时补充。

全文包括如下几个部分,最好按顺序操作:

  • 一、极简开箱照
  • 二、组装
  • 三、系统烧录
  • 四、扩充磁盘空间
  • 五、增加虚拟内存 swapfile
  • 六、开发环境搭建
  • 七、获取导出后的 PicoDet 模型
  • 八、基于 FastDeploy 的 C++ 部署
  • 九、使用 MIPI CSI 摄像头的 Demo
  • 十、总结和展望

其中部分内容会直接给出大佬的链接,以避免重复造轮子。(再次感谢巨人前辈提供肩膀)

一、极简开箱照

套件包括:主板、散热器、风扇、USB口wifi、保护壳、电源、micro usb数据线、HDMI线、网线、跳线、sd卡、读卡器、资料U盘。

二、组装

这步很简单,先把风扇装好就可以了。

【注意】:烧录成功之前不要装亚克力保护壳,因为装完之后会挡住插跳线的针脚。也可以先不装跳线针脚的那一面。

风扇电源线连接位置如图,注意方向不要插错了,错了也插不进去。

三、烧录

请注意,本文针对的是创乐博的套件。

如果是原厂套件,可以参考此文

同时,也建议使用创乐博的同学按照资料U盘里的视频教程操作。

总体来说,烧录分为两大部分:

  • 第一部分为烧录eMMC引导;

  • 第二部分是把Jetson Nano的系统镜像烧录到 SD 卡里。

这两部分缺一不可。

第1步:启动虚拟机

在你的PC机上,安装VMware,并载入资料U盘内提供的虚拟机文件:YourPath\2.虚拟机镜像\clb_jetson_ubuntu1804\clb_jetson.vmx

这个虚拟机镜像里已经准备好了烧录的环境,无需额外安装其他工具即可直接可以使用。

第2步:设置烧写模式

用跳线连接Nano主板的2、3针脚,既设置烧写模式,如下图:

第3步:连接数据线

连接PC机的USB口和Nano的Micro USB口,如下图:

第4步:上电

上电。

此时虚拟机会自动弹出检测到USB设备。选择连接到虚拟机。

第5步:开始烧录eMMC

在PC端的虚拟机内,进入到 Linux_for_Tegra 目录,找到 1.txt文件,将其中的命令复制粘贴到命令行,运行,并输入开机密码,即可开始烧录。

等待几分钟,看到如下提示,则烧录成功,此时可以退出虚拟机:

第6步:烧录SD卡

在PC上安装 Balena Etcher 烧录工具。

然后,将SD卡放入读卡器,并插入PC。

此后的SD卡烧录方法与原厂套件的烧录方法相同,此处不再赘述,直接按这篇文章里的步骤操作即可。

【注意】写入 SD 卡的数据以 Linux 的 ext4 格式存在,因此在 Windows 下面是无法识别的,请 Windows 使用者无需惊慌(有遇到不少用户在 Windows 下看不到数据,还以为自己没有安装成功)。

第7步:启动前的准备

【注意】一定要先拔掉Nano的电源,然后再把SD卡插入到Nano上。

【还要注意】再次上电之前,需要将跳线拔掉。

第8步:启动Nano

把Nano连接到显示器,再接上鼠标键盘,就可以上电启动了。

如果没有多余的显示器、鼠标、键盘,可以参考此文,通过远程桌面或者SSH的方式连接到Nano,此处不再赘述。

烧录问题汇总

  • 开机显示如下画面:

这是因为只做了SD卡的烧录,没有对eMMC进行烧录。

请按照eMMC烧录步骤操作,即可解决问题。

  • (更多问题会持续汇总更新,请大家在评论区留言,我会持续补充。)

四、扩充磁盘空间

在SD卡写入系统后,默认会有一部分可用磁盘空间是被隐藏的,因此我们需要把它释放出来。

操作方法很简单,在Nano上直接安装 gparted 工具(sudo apt-get install gparted),运行工具后找到SD卡(一般为/dev/sda1)
右击已分配的分区,resize,拖到很靠右又不是全部在右边的地方,然后就可以开始了。

这里有官方视频教程,请大家参考。

五、增加虚拟内存 swapfile

Jetson Nano 2GB 的内存相对弱势,所幸 Linux 提供了一种 SWAP 技术,能将存储设备空间作为虚拟内存使用,性能虽然不如物理内存,但也能支撑更多深度学习的计算。

官方提供的操作方法在这里的“4.1增加交换空间大小”章节。如法炮制即可,此处不再赘述。

六、开发环境搭建

1. 建议移除LibreOffice

这会为系统省很多空间,而且这个软件对做深度学习和计算机视觉算法也没什么用。

sudo apt-get purge libreoffice

sudo apt-get clean

2. 安装必要的包

sudo apt-get install build-essential make cmake

sudo apt-get install git g++ pkg-config curl

此外,建议将cmake升级一下,参考这里的方法.

3. 安装jetson-stats工具包

该工具包的jtop工具可以实时显示系统资源情况、检测nano温度等。

按照这里的步骤操作即可。

通过 jtop 查得本文的主要硬件及软件版本如下:

  • Jetpack = 4.6.1
  • opencv = 4.1.1 compiled CUDA:NO
  • CUDA = 10.2.300
  • cuDNN = 8.2.1.32
  • TensorRT = 8.2.1.8

七、获取导出后的 PicoDet 模型

本文将采用 PicoDet-s-416 检测模型,实现对垃圾的检测。

关于模型的生产过程,请移步这里:基于PP-PicoDet v2 的路面垃圾检测

其中,导出好的模型,保存在本项目的此目录下:

~/work/PicoDet-s-416-DHQ-exported

同时,在此目录下也提供了一张测试图片:

trash01.png

需要说明的是,由于此模型是使用Demo数据训练的,因此精度不高。感兴趣的同学可以自行收集更多数据,参考原文重新训练。

八、基于 FastDeploy 的 C++ 部署

1. FastDeploy 在Nano + Linux下的环境要求

  • cmake >= 3.12

  • gcc/g++ >= 8.2

  • python >= 3.6

  • cuda >= 11.0 (Linux默认安装路径在/usr/local/cuda下)

  • cudnn >= 8.0

  • TensorRT、Paddle Inference、ONNXruntime等推理引擎,会在SDK中包含,不需要单独安装。

2. 在 Nano 上直接编译 FastDeploy 的 C++ SDK

  • 编译前,需安装patchelf:
sudo apt-get install patchelf
  • 然后开始拉取 FastDeploy的代码,并编译:
git clone https://github.com/PaddlePaddle/FastDeploy

cd FastDeploy

mkdir build && cd build

cmake .. -DBUILD_ON_JETSON=ON -DENABLE_VISION=ON -DCMAKE_INSTALL_PREFIX=${PWD}/fastdeploy_cpp_sdk

make -j8

make install

整个编译过程在Nano上进行,大概3-5分钟可以编译完成。之后在FastDeploy/build/fastdeploy_cpp_sdk目录下的即为编译产出的C++部署库。包括C++的实例代码也在里面。

【注意】FastDeploy在编译时会依赖第三方库Eigen,因此会自动拉取Gitlab上源码,如遇编译时拉取Eigen源码问题,可先使用如下命令配置git:

git config --global http.sslverify false

【还要注意】在Jetson上编译FastDeploy,当打开开关BUILD_ON_JETSON时,会默认开启ENABLE_ORT_BACKEND和ENABLE_TRT_BACKEND,即当前仅支持ONNXRuntime CPU或TensorRT两种后端分别用于在CPU和GPU上的推理。这一点,在后文演示推理时,还会提到。

3. PicoDet 的 C++ 部署示例

  • 配置依赖库的搜索路径

FastDeploy 非常贴心的准备了把依赖库导入环境变量的脚本:fastdeploy_init.sh,避免大家手动添加导致错误。

脚本位于:

YourPathTo/fastdeploy_cpp_sdk/

在此目录下,直接执行此命令,即可完成导入:

source fastdeploy_init.sh

导入结果如图:

  • FastDeploy 提供的示例代码位于:
YourPathTo/fastdeploy_cpp_sdk/examples/vision/detection/paddledetection/cpp/infer_picodet.cc
  • 进入以上的目录后,依次运行如下编译命令:
mkdir build && cd build

cmake .. -DFASTDEPLOY_INSTALL_DIR=YourPathTo/fastdeploy_cpp_sdk

make -j
  • 进入到 YourPathTo/fastdeploy_cpp_sdk/examples/vision/detection/paddledetection/cpp/build 目录,可找到编译后的可执行文件: infer_picodet_demo

  • 将导出后的 PicoDet 模型和测试图片拷贝到当前build目录下

  • 可尝试用以下3种方法推理(其实只有2种可用)。命令行的最后一个参数可以是[0, 1, 2],用于设置推理的方式。

    • CPU推理
    ./infer_picodet_demo ./PicoDet-s-416-DHQ-exported trash01.png 0
    

    CPU推理耗时 380ms,推理结果的图片,会保存在当前可执行文件目录下。

    推理框上的text内容为 {类别ID,置信度}

    • GPU推理
    ./infer_picodet_demo ./PicoDet-s-416-DHQ-exported trash01.png 1
    

    【再次注意】

    编译FastDeploy时,当打开开关BUILD_ON_JETSON时,会默认开启ENABLE_ORT_BACKEND和ENABLE_TRT_BACKEND,即当前仅支持ONNXRuntime CPU或TensorRT两种后端分别用于在CPU和GPU上的推理。因此,这里的GPU推理并不会生效,而是会自动转成CPU推理。

    • GPU上TensorRT推理
    ./infer_picodet_demo ./PicoDet-s-416-DHQ-exported trash01.png 2
    

    FastDeploy 默认采用TRT-FP32的推理。如果需要使用TRT-FP16的推理,设置的方法很简单,只需要在代码中加入一行 option.EnableTrtFP16() 即可。

    细心的朋友会发现,在使用TRT推理时,每次初始化非常耗时,感觉是一直卡在这里:

    [INFO] fastdeploy/backends/tensorrt/trt_backend.cc(416)::BuildTrtEngine Start to building TensorRT Engine...
    

    实际上,FP32的初始化需要3分钟左右,FP16的初始化需要10分钟!!

    那么,如何提速呢?

    方法也很简单,在代码中加入一行:option.SetTrtCacheFile(“./picodet.trt”)

    这样,第一次初始化完成之后,就会在当前目录下保存TRT的缓存文件 picodet.trt,

    这样以后每次运行就直接读取该文件了,避免重复初始化。

    【格外注意】当需要在TRT-FP32和TRT-FP16之间切换时,别忘了先删除保存的 picodet.trt 缓存文件。

九、使用 MIPI CSI 摄像头的 Demo

1. CSI 摄像头的安装

【注意】一定要先断电!!!

这里放几张示意图:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

详情请参考大佬的安装步骤

安装成功后,先看一下是否可以被系统识别到:

ls /dev/vid*

直接运行命令测试一下:

gst-launch-1.0 nvarguscamerasrc ! 'video/x-raw(memory:NVMM),width=3820, height=2464, framerate=21/1, format=NV12' ! nvvidconv flip-method=0 ! 'video/x-raw,width=960, height=616' ! nvvidconv ! nvegltransform ! nveglglessink -e

2. CSI 摄像头的调用

CSI接口的摄像头调用,比USB的要复杂,但并不难。

C++版本的调用方法如下:

// 定义gstreamer pipeline
std::string gstreamer_pipeline (int capture_width, int capture_height, int display_width, int display_height, int framerate, int flip_method)
{ // DHQ added 20220927
    return "nvarguscamerasrc ! video/x-raw(memory:NVMM), width=(int)" + std::to_string(capture_width) + ", height=(int)" +
           std::to_string(capture_height) + ", format=(string)NV12, framerate=(fraction)" + std::to_string(framerate) +
           "/1 ! nvvidconv flip-method=" + std::to_string(flip_method) + " ! video/x-raw, width=(int)" + std::to_string(display_width) + ", height=(int)" +
           std::to_string(display_height) + ", format=(string)BGRx ! videoconvert ! video/x-raw, format=(string)BGR ! appsink";
}


。。。


// 在主函数中设置参数,并调用gstreamer管道

int capture_width = 1280 ;
int capture_height = 720 ;
int display_width = 1280 ;
int display_height = 720 ;
int framerate = 60 ;
int flip_method = 0 ;

//创建管道
std::string pipeline = gstreamer_pipeline(capture_width,
capture_height,
display_width,
display_height,
framerate,
flip_method);
std::cout << "使用gstreamer管道: \n\t" << pipeline << "\n";

//管道与视频流绑定
cv::VideoCapture cap(pipeline, cv::CAP_GSTREAMER);


// 然后再 cap.read() 就可以了。

完整的Demo代码已经放到work文件夹里了:

work/infer_picodet_dhq.cc

如果是使用python调用,可以参考这里

3. Demo展示

PicoDet-s-416 在Nano上实测速度:

  • CPU: ~380ms

  • GPU开启TRT-FP32:~80ms

  • GPU开启TRT-FP16:~60ms

TRT-FP16 效果展示的视频如下:

https://www.bilibili.com/video/BV1xP411n7cF

运行检测时的系统资源情况,可以通过 jtop 查看,如下:

总结与展望

  • FastDeploy:部署从未如此简单!请大家多多到FD主页点star支持!

  • 下一步会尝试 晶晨芯片的开发板,据说比 Nano快不少!敬请期待~

如果有不准确的地方,请大家在评论区留言,多多批评指正,谢谢。

此文章为搬运
原项目链接

Logo

学大模型,用大模型上飞桨星河社区!每天8点V100G算力免费领!免费领取ERNIE 4.0 100w Token >>>

更多推荐