大家好,我是王硕,项目原因需要在Jetson nano平台上跑yolov8s ,需要使用TensorRt加速,看了网上的教程,写的太差了,资料零零散散的,故详细介绍一下步骤。
如果想使用jetson Nano平台部署yolov8,并用TensorRT加速,需要以下环境要求:
JetPack 4.6 (烧进系统的默认自带的,不用管)
Python3.8 (需要自己编译)
Cuda 10.2 (烧进系统的默认自带的,不用管)
torch 1.11.0-cp38-GPU (python3.8下的pytorch GPU版本;本文提供)
TensorRT 8.2 (需要自己编译)
废话不多说,按照以下步骤走,就能行。
1.下载python源码并编译
$ sudo apt install zlib1g-dev libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev libsqlite3-dev libbz2-dev
$ cd ~/
$ mkdir build-python-3.8.1 & cd build-python-3.8.1/
$ wget https://www.python.org/ftp/python/3.8.1/Python-3.8.1.tar.xz
$ tar xvf Python-3.8.1.tar.xz
$ ../Python-3.8.1/configure --enable-optimizations
$ make -j8
$ sudo -H make altinstall
$ cd ../
等待编译完成(大概5分钟)
2.编译Cmake源码,因为自带的cmake版本太低了,需要手动编译高版本。
$ cd ~/
$ mkdir cmake & cd cmake
$ sudo apt-get install -y protobuf-compiler libprotobuf-dev openssl libssl-dev libcurl4-openssl-dev
$ wget https://github.com/Kitware/CMake/releases/download/v3.13.5/cmake-3.13.5.tar.gz
$ tar xvf cmake-3.13.5.tar.gz
$ cd cmake-3.13.5/
$ ./bootstrap --system-curl
$ make -j8
$ echo 'export PATH='${PWD}'/bin/:$PATH' >> ~/.bashrc
$ source ~/.bashrc
$ cd ../
$reboot #可以省略此步骤,主要是让环境变量生效,保险起见,重启一下吧
3.准备编译TensorRT (重点!!!,容易出错)
jetson nano自带的tensorrt是基于python3.6版本,太老了,没办法用,故重新编译python3.8环境下的TensorRT。
$ cd ~/build-python-3.8.1/
$ mkdir python3.8
$ mkdir python3.8/include
$ wget https://launchpad.net/ubuntu/+source/python3.8/3.8.0-3~18.04/+build/17998540/+files/libpython3.8-dev_3.8.0-3~18.04_arm64.deb
#网络卡的话,可手动下载。
$ ar x libpython3.8-dev_3.8.0-3~18.04_arm64.deb
$ tar -xvf data.tar.xz
#这个./usr 哈,一定要带./usr,当前路径下的usr文件夹。当前路径下的usr文件夹,当前路径下的usr文件夹
$ cp ./usr/include/aarch64-linux-gnu/python3.8/pyconfig.h Python-3.8.1/Include/
$ mkdir python3.8
$ mkdir python3.8/include
$ cp -r Python-3.8.1/Include/* python3.8/include/
到目前为止的目录结构,下面开始克隆pybind11,生成动态库 :
$ cd ~/
$ mkdir external & cd external
$ cp -r ../python_source_3_8/python3.8 ./
$ git clone https://github.com/pybind/pybind11.git
$ git clone -b release/8.2 https://github.com/NVIDIA/TensorRT.git
$ cd TensorRT
$ git submodule update --init --recursive
$ cd python/
$ sudo ./build.sh
接下来会出现各种错误,首先出现的错误就是找不到nvcc编译器,输入以下代码解决
export PATH=/usr/local/cuda/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH
export CUDA_ROOT=/usr/local/cuda
在输入nvcc --version,如果出现以下信息,说明成功
解决完此错误,继续执行以下命令:
sudo ./build.sh
执行完成后,会报各种错误,同时在当前吗目录生成Makefile,截图如下,文件中包含Makefile
生成Makefile后,继续执行以下命令:
sudo make -j8
会出现以下错误,找不到cub/cub.cuh头文件:
编辑Tensor目录下的CmakeList.txt文件
$ vim ~/external/TensorRT/CMakeLists.txt #编辑Cmake
#把第101行代码
if(NOT CUB_ROOT_DIR)
if (CUDA_VERSION VERSION_LESS 11.0)
set(CUB_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/cub CACHE STRING "directory of
CUB installation")
endif()
endif()
改成:
if(NOT CUB_ROOT_DIR)
if (CUDA_VERSION VERSION_LESS 11.0)
set(CUB_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/cub CACHE STRING "directory of CUB installation")
endif()
endif()
#强制生效CUB_ROOT_DIR变量
set(CUB_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/cub CACHE STRING "directory of CUB installation")
修改~/TensorRT/python/.build.sh文件,如下所示:
#python版本
PYTHON_MAJOR_VERSION=${PYTHON_MAJOR_VERSION:-3}
PYTHON_MINOR_VERSION=${PYTHON_MINOR_VERSION:-8}
#架构
TARGET=${TARGET:-aarch64}
#ROOT_PATH为TensorRT根目录
ROOT_PATH=${TRT_OSSPATH:-/home/nwd/external/TensorRT}
#external目录路径
EXT_PATH=${EXT_PATH:-/home/nwd/external}
WHEEL_OUTPUT_DIR=${ROOT_PATH}/python/build
mkdir -p ${WHEEL_OUTPUT_DIR}
pushd ${WHEEL_OUTPUT_DIR}
# Generate tensorrt.so
echo $(ls ${ROOT_PATH}/python/include)
cmake .. -DCMAKE_BUILD_TYPE=Release \
-DTARGET=${TARGET} \
-DPYTHON_MAJOR_VERSION=${PYTHON_MAJOR_VERSION} \
-DPYTHON_MINOR_VERSION=${PYTHON_MINOR_VERSION} \
-DEXT_PATH=${EXT_PATH} \
-DCUDA_INCLUDE_DIRS=/usr/local/cuda/include \
-DTENSORRT_ROOT=${ROOT_PATH} \
-DTENSORRT_BUILD=${ROOT_PATH}/build/ \
-DCMAKE_CUDA_COMPILER=/usr/local/cuda-10.2/bin/nvcc
make -j
# Generate wheel
TRT_MAJOR=$(awk '/^\#define NV_TENSORRT_MAJOR/ {print $3}' ${ROOT_PATH}/include/NvInferVersion.h)
TRT_MINOR=$(awk '/^\#define NV_TENSORRT_MINOR/ {print $3}' ${ROOT_PATH}/include/NvInferVersion.h)
TRT_PATCH=$(awk '/^\#define NV_TENSORRT_PATCH/ {print $3}' ${ROOT_PATH}/include/NvInferVersion.h)
TRT_BUILD=$(awk '/^\#define NV_TENSORRT_BUILD/ {print $3}' ${ROOT_PATH}/include/NvInferVersion.h)
TRT_VERSION=${TRT_MAJOR}.${TRT_MINOR}.${TRT_PATCH}.${TRT_BUILD}
TRT_MAJMINPATCH=${TRT_MAJOR}.${TRT_MINOR}.${TRT_PATCH}
echo "Generating python ${PYTHON_MAJOR_VERSION}.${PYTHON_MINOR_VERSION} bindings for TensorRT ${TRT_VERSION}"
expand_vars_cp () {
test -f ${1} || (echo "ERROR: File: ${1} does not exist!" && exit 1); \
sed -e "s|\#\#TENSORRT_VERSION\#\#|${TRT_VERSION}|g" \
-e "s|\#\#TENSORRT_MAJMINPATCH\#\#|${TRT_MAJMINPATCH}|g" \
${1} > ${2}
}
pushd ${ROOT_PATH}/python/packaging
for dir in $(find . -type d); do mkdir -p ${WHEEL_OUTPUT_DIR}/$dir; done
for file in $(find . -type f); do expand_vars_cp $file ${WHEEL_OUTPUT_DIR}/${file}; done
popd
python3 setup.py -q bdist_wheel --python-tag=cp${PYTHON_MAJOR_VERSION}${PYTHON_MINOR_VERSION} --plat-name=linux_${TARGET}
popd
修改完成后,重新编译。编译完成会在build目录生成tensorrt.so文件,如下图:
如果没有生成tensorrt.so文件,说明pybind11路径设置有问题,或架构设置不是aarch64,仔细检查一下,如果你不想自己编译,也可以下载我编译好的TensorRT。
安装TensorRt,这里有一个坑,不能直接使用命令安装Tensorrt,需要手动安装,否则会报错,手动安装也非常简单,
a. 首先查看pip的位置:
$ pip --version
结果:
pip 22.3.1 from /home/nwd/archiconda3/envs/yolov8s/lib/python3.8/site-packages/pip (python 3.8)
其中/home/nwd/archiconda3/envs/yolov8s/lib/python3.8/site-packages/ 为包路径,开始手动复制TensorRT包到路径下:
$ sudo cp -r tensorrt /home/nwd/archiconda3/envs/yolov8s/lib/python3.8/site-packages/
测试安装的TensorRT
#直接打开python解释器,导入Tensorrt的包。并打印版本信息
$ python3.8
>>> import tensorrt
>>> print(tensorrt.__version__)
运行结果:
“8.2.3.0”
4.部署yolov8
在部署yolov8之前,因为yolov8要求python3.8及以上的python版本,需要安装专门为JetsonNano平台下,python3.8编译GPU驱动版本的pyorch,需要从pytorch源码编译,有想自己编译的可参考如下链接:
https://i7y.org/en/pytorch-build-on-jetson-nano/
编译大概需要13个小时,因此本文使用编译好的pytorch文件,这个包会在文章末尾下载(百度云盘),输入以下命令直接安装:
$ pip3.8 install torch-1.11.0a0+gitbc2c6ed-cp38-cp38-linux_aarch64.whl
$ pip3.8 install torchvision-0.12.0a0+9b5a3fe-cp38-cp38-linux_aarch64.whl
到此为止我们安装了:tensorRT 8.2.3.0 、pytorch 1.11.0 、torchvision 0.12.0。
开始安装yolov8,很简单,输入如下命令:
$ pip install ultralytics
$ pip install onnx
$ pip uninstalll numpy #numpy需要换成指定版本,故卸载重装其他版本
$ pip install numpy==1.23.2
$ pip install onnxslim
安装完成,就可以测试了,新建python脚本,并输入以下测试代码:
from ultralytics import YOLO
# Load the YOLOv8 model
model = YOLO("yolov8s.pt")
# Export the model to TensorRT format
model.export(format="engine") # creates 'yolov8n.engine'
# Load the exported TensorRT model
tensorrt_model = YOLO("yolov8s.engine")
# Run inference
#这里的图片路径换成自己想要识别的
results = tensorrt_model("/home/nwd/yolov8/YOLOv8-TensorRT/data/bus.jpg")
print(results)
运行发现报错,找不到onnxruntime_gpu的错误
因此,我们继续安装onnxruntime的GPU版本,这个包主要是来把.pt文件转成onnx文件。
这个包,官方为我们编译好了,( Jetson Nano的JetPack 版本默认是4.6 !!!) ,别下载错了。。下载链接(文章末尾百度云也提供了)。
https://elinux.org/Jetson_Zoo#ONNX_Runtime
下载完成后。直接安装
$ pip install onnxruntime_gpu-1.7.0-cp38-cp38-linux_aarch64.whl
到此为止,在进行测试,发现就可以运行了。强调,因为跑模型需要大量内存,可以关闭jetson nano的图形界面,为了省此内存,参考这位同志的教程:
Jetson Nano 关闭开启图形界面减少内存占用_jetson nano 关闭图形界面-CSDN博客
如果要跑yolov8s,就不用关闭图形界面。推理流程依赖关系
模型转换关系:yolov8s.pt ----->yolov8s.onnx----->yolov8s.engine
推理:TensorRT加载yolov8s.engine权重文件进行加速。
主要难度是编译TensorRT,如果编译不成功,不会生成Tensort.so动态库文件。只要编译成功就会在build/tensorRT文件夹中找到Tensort.so文件。
文中涉及的资源:通过网盘分享的文件:yolov8
链接: https://pan.baidu.com/s/1-d3jEkHK-ts-LvsU3fyUjw 提取码: ws66