Skip to main content

使用 TensorRT 和 DeepStream SDK 支持在 NVIDIA Jetson 上部署 YOLOv8

本指南解释了如何将训练好的 AI 模型部署到 NVIDIA Jetson 平台,并使用 TensorRT 和 DeepStream SDK 进行推理。在这里,我们使用 TensorRT 来最大化 Jetson 平台上的推理性能。

前置条件

  • Ubuntu 主机 PC(本地或使用 VMware Workstation Player 的虚拟机)
  • reComputer Jetson 或任何运行 JetPack 4.6 或更高版本的 NVIDIA Jetson 设备

DeepStream 版本与 JetPack 版本的对应关系

为了使 YOLOv8 与 DeepStream 一起工作,我们使用了这个 DeepStream-YOLO 仓库,它支持不同版本的 DeepStream。因此,请确保根据正确的 DeepStream 版本使用正确的 JetPack 版本。

DeepStream 版本JetPack 版本
6.25.1.1
5.1
6.1.15.0.2
6.15.0.1 DP
6.0.14.6.3
4.6.2
4.6.1
6.04.6

为了验证本指南,我们在运行 JetPack 5.1.1reComputer J4012 系统上安装了 DeepStream SDK 6.2

将 JetPack 刷写到 Jetson

现在,您需要确保 Jetson 设备已刷写了包含 SDK 组件(如 CUDA、TensorRT、cuDNN 等)的 JetPack 系统。您可以使用 NVIDIA SDK Manager 或命令行将 JetPack 刷写到设备上。

有关 Seeed Jetson 驱动设备的刷写指南,请参考以下链接:

安装 DeepStream

在 Jetson 设备上安装 DeepStream 有多种方式。您可以参考此指南了解更多信息。然而,我们推荐通过 SDK Manager 安装 DeepStream,因为它可以保证安装过程简单且成功。

如果您通过 SDK Manager 安装 DeepStream,在系统启动后需要执行以下命令来安装 DeepStream 的额外依赖项:

sudo apt install \
libssl1.1 \
libgstreamer1.0-0 \
gstreamer1.0-tools \
gstreamer1.0-plugins-good \
gstreamer1.0-plugins-bad \
gstreamer1.0-plugins-ugly \
gstreamer1.0-libav \
libgstreamer-plugins-base1.0-dev \
libgstrtspserver-1.0-0 \
libjansson4 \
libyaml-cpp-dev

安装必要的软件包

  • 步骤 1. 访问 Jetson 设备的终端,安装 pip 并升级
sudo apt update
sudo apt install -y python3-pip
pip3 install --upgrade pip
  • 步骤 2. 克隆以下仓库
git clone https://github.com/ultralytics/ultralytics.git
  • 步骤 3. 打开 requirements.txt
cd ultralytics
vi requirements.txt
  • 步骤 4. 编辑以下行。在这里,您需要先按 i 进入编辑模式。编辑完成后按 ESC,然后输入 :wq 保存并退出
# torch>=1.7.0
# torchvision>=0.8.1

注意: 目前暂时排除 torch 和 torchvision,因为它们将在后续步骤中安装。

  • 步骤 5. 安装必要的软件包
pip3 install -r requirements.txt

如果安装程序提示 python-dateutil 包版本过旧,请通过以下命令升级:

pip3 install python-dateutil --upgrade

安装 PyTorch 和 Torchvision

由于 Jetson 平台基于 ARM aarch64 架构,我们无法通过 pip 安装 PyTorch 和 Torchvision。因此,需要手动安装预构建的 PyTorch pip wheel 文件,并从源码编译/安装 Torchvision。

访问此页面获取所有 PyTorch 和 Torchvision 的链接。

以下是 JetPack 5.0 及以上版本支持的一些版本:

PyTorch v1.11.0

支持 JetPack 5.0 (L4T R34.1.0) / JetPack 5.0.1 (L4T R34.1.1) / JetPack 5.0.2 (L4T R35.1.0),Python 3.8

文件名: torch-1.11.0-cp38-cp38-linux_aarch64.whl
URL: https://nvidia.box.com/shared/static/ssf2v7pf5i245fk4i0q926hy4imzs2ph.whl

PyTorch v1.12.0

支持 JetPack 5.0 (L4T R34.1.0) / JetPack 5.0.1 (L4T R34.1.1) / JetPack 5.0.2 (L4T R35.1.0),Python 3.8

文件名: torch-1.12.0a0+2c916ef.nv22.3-cp38-cp38-linux_aarch64.whl
URL: https://developer.download.nvidia.com/compute/redist/jp/v50/pytorch/torch-1.12.0a0+2c916ef.nv22.3-cp38-cp38-linux_aarch64.whl

  • 步骤 1. 根据您的 JetPack 版本安装 torch,格式如下:
wget <URL> -O <file_name>
pip3 install <file_name>

例如,这里我们运行的是 JP5.0.2,因此选择 PyTorch v1.12.0

sudo apt-get install -y libopenblas-base libopenmpi-dev
wget https://developer.download.nvidia.com/compute/redist/jp/v50/pytorch/torch-1.12.0a0+2c916ef.nv22.3-cp38-cp38-linux_aarch64.whl -O torch-1.12.0a0+2c916ef.nv22.3-cp38-cp38-linux_aarch64.whl
pip3 install torch-1.12.0a0+2c916ef.nv22.3-cp38-cp38-linux_aarch64.whl
  • 步骤 2. 根据已安装的 PyTorch 版本安装对应的 Torchvision。例如,我们选择了 PyTorch v1.12.0,因此需要选择 Torchvision v0.13.0
sudo apt install -y libjpeg-dev zlib1g-dev
git clone --branch v0.13.0 https://github.com/pytorch/vision torchvision
cd torchvision
python3 setup.py install --user

以下是根据 PyTorch 版本需要安装的对应 Torchvision 版本列表:

  • PyTorch v1.11 - Torchvision v0.12.0
  • PyTorch v1.12 - Torchvision v0.13.0

如果您需要更详细的版本列表,请查看此链接

DeepStream 配置 YOLOv8

  • 步骤 1. 克隆以下仓库
cd ~
git clone https://github.com/marcoslucianops/DeepStream-Yolo
  • 步骤 2. 切换到以下提交版本
cd DeepStream-Yolo
git checkout 68f762d5bdeae7ac3458529bfe6fed72714336ca
  • 步骤 3.gen_wts_yoloV8.pyDeepStream-Yolo/utils 目录复制到 ultralytics 目录
cp utils/gen_wts_yoloV8.py ~/ultralytics
  • 步骤 4. 在 ultralytics 仓库中,下载 YOLOv8 releasespt 文件(以 YOLOv8s 为例)
wget https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov8s.pt

注意: 你可以使用自定义模型,但重要的是在 cfgweights/wts 文件名中保留 YOLO 模型的引用 (yolov8_),以便正确生成引擎。

  • 步骤 5. 生成 cfg、wts 和 labels.txt(如果可用)文件(以 YOLOv8s 为例)
python3 gen_wts_yoloV8.py -w yolov8s.pt

注意: 要更改推理尺寸(默认:640)

-s SIZE
--size SIZE
-s HEIGHT WIDTH
--size HEIGHT WIDTH

例如 1280:

-s 1280

-s 1280 1280
  • 步骤 6. 将生成的 cfgwtslabels.txt(如果生成)文件复制到 DeepStream-Yolo 文件夹
cp yolov8s.cfg ~/DeepStream-Yolo
cp yolov8s.wts ~/DeepStream-Yolo
cp labels.txt ~/DeepStream-Yolo
  • 步骤 7. 打开 DeepStream-Yolo 文件夹并编译库
cd ~/DeepStream-Yolo
CUDA_VER=11.4 make -C nvdsinfer_custom_impl_Yolo # 适用于 DeepStream 6.2/ 6.1.1 / 6.1
CUDA_VER=10.2 make -C nvdsinfer_custom_impl_Yolo # 适用于 DeepStream 6.0.1 / 6.0
  • 步骤 8. 根据你的模型编辑 config_infer_primary_yoloV8.txt 文件(以 YOLOv8s 和 80 类为例)
[property]
...
custom-network-config=yolov8s.cfg
model-file=yolov8s.wts
...
num-detected-classes=80
...
  • 步骤 9. 编辑 deepstream_app_config.txt 文件
...
[primary-gie]
...
config-file=config_infer_primary_yoloV8.txt
  • 步骤 10. 更改 deepstream_app_config.txt 文件中的视频源。这里加载了一个默认视频文件,如下所示
...
[source0]
...
uri=file:///opt/nvidia/deepstream/deepstream/samples/streams/sample_1080p_h264.mp4

运行推理

deepstream-app -c deepstream_app_config.txt

上述结果是在 Jetson AGX Orin 32GB H01 Kit 上运行的,使用 FP32 和 YOLOv8s 640x640。我们可以看到 FPS 大约为 60,但这并不是真实的 FPS,因为当我们在 deepstream_app_config.txt 文件的 [sink0] 下设置 type=2 时,FPS 被限制为显示器的刷新率,而我们用于测试的显示器是 60Hz。然而,如果将该值更改为 type=1,则可以获得最大 FPS,但不会有实时检测输出。

对于相同的视频源和上述相同的模型,在 [sink0] 下将 type=1 后,可以获得以下结果。

如你所见,我们可以获得大约 139 的 FPS,这与真实的 FPS 值相符。

INT8 校准

如果您希望使用 INT8 精度进行推理,需要按照以下步骤操作:

  • 步骤 1. 安装 OpenCV
sudo apt-get install libopencv-dev
  • 步骤 2. 使用 OpenCV 支持编译/重新编译 nvdsinfer_custom_impl_Yolo
cd ~/DeepStream-Yolo
CUDA_VER=11.4 OPENCV=1 make -C nvdsinfer_custom_impl_Yolo # 适用于 DeepStream 6.2/ 6.1.1 / 6.1
CUDA_VER=10.2 OPENCV=1 make -C nvdsinfer_custom_impl_Yolo # 适用于 DeepStream 6.0.1 / 6.0
  • 步骤 3. 对于 COCO 数据集,下载 val2017,解压并移动到 DeepStream-Yolo 文件夹

  • 步骤 4. 为校准图像创建一个新目录

mkdir calibration
  • 步骤 5. 运行以下命令,从 COCO 数据集中随机选择 1000 张图像用于校准
for jpg in $(ls -1 val2017/*.jpg | sort -R | head -1000); do \
cp ${jpg} calibration/; \
done

注意: NVIDIA 建议至少使用 500 张图像以获得较好的精度。在本示例中,选择了 1000 张图像以获得更高的精度(更多的图像 = 更高的精度)。更高的 INT8_CALIB_BATCH_SIZE 值将提高精度并加快校准速度。根据您的 GPU 内存进行设置。您可以通过修改 head -1000 来调整,例如,对于 2000 张图像,使用 head -2000。此过程可能需要较长时间。

  • 步骤 6. 使用所有选定的图像创建 calibration.txt 文件
realpath calibration/*jpg > calibration.txt
  • 步骤 7. 设置环境变量
export INT8_CALIB_IMG_PATH=calibration.txt
export INT8_CALIB_BATCH_SIZE=1
  • 步骤 8. 更新 config_infer_primary_yoloV8.txt 文件

...
model-engine-file=model_b1_gpu0_fp32.engine
#int8-calib-file=calib.table
...
network-mode=0
...

更改为

...
model-engine-file=model_b1_gpu0_int8.engine
int8-calib-file=calib.table
...
network-mode=1
...
  • 步骤 9. 在运行推理之前,在 deepstream_app_config.txt 文件中的 [sink0] 下设置 type=2,以获得最大 FPS 性能。

  • 步骤 10. 运行推理

deepstream-app -c deepstream_app_config.txt

在这里,我们获得了大约 350 的 FPS 值!

多流配置

NVIDIA DeepStream 允许您在单个配置文件中轻松设置多流,以构建多流视频分析应用程序。我们将在本 Wiki 的后续部分演示高 FPS 性能的模型如何真正帮助多流应用程序,并提供一些基准测试。

这里我们以 9 个流为例。我们将修改 deepstream_app_config.txt 文件。

  • 步骤 1.[tiled-display] 部分中,将行和列更改为 3 和 3,以便我们可以拥有一个 3x3 的网格,包含 9 个流
[tiled-display]
rows=3
columns=3
  • 步骤 2.[source0] 部分中,设置 num-sources=9 并添加更多的 uri。这里我们将简单地将当前示例视频文件复制 8 次,以组成总共 9 个流。不过,您可以根据您的应用程序更改为不同的视频流
[source0]
enable=1
type=3
uri=file:///opt/nvidia/deepstream/deepstream/samples/streams/sample_1080p_h264.mp4
uri=file:///opt/nvidia/deepstream/deepstream/samples/streams/sample_1080p_h264.mp4
uri=file:///opt/nvidia/deepstream/deepstream/samples/streams/sample_1080p_h264.mp4
uri=file:///opt/nvidia/deepstream/deepstream/samples/streams/sample_1080p_h264.mp4
uri=file:///opt/nvidia/deepstream/deepstream/samples/streams/sample_1080p_h264.mp4
uri=file:///opt/nvidia/deepstream/deepstream/samples/streams/sample_1080p_h264.mp4
uri=file:///opt/nvidia/deepstream/deepstream/samples/streams/sample_1080p_h264.mp4
uri=file:///opt/nvidia/deepstream/deepstream/samples/streams/sample_1080p_h264.mp4
uri=file:///opt/nvidia/deepstream/deepstream/samples/streams/sample_1080p_h264.mp4
num-sources=9

现在,如果您再次使用 deepstream-app -c deepstream_app_config.txt 命令运行应用程序,您将看到以下输出

trtexec 工具

在示例目录中包含了一个名为 trtexec 的命令行包装工具。trtexec 是一个无需开发自己的应用程序即可使用 TensorRT 的工具。trtexec 工具有以下三个主要用途:

  • 在随机或用户提供的输入数据上对网络进行基准测试。
  • 从模型生成序列化引擎。
  • 从构建器生成序列化的时间缓存。

在这里,我们可以使用 trtexec 工具快速对不同参数的模型进行基准测试。但首先,你需要一个 ONNX 模型,我们可以通过使用 ultralytics yolov8 生成这个 ONNX 模型。

  • 步骤 1. 使用以下命令生成 ONNX:
yolo mode=export model=yolov8s.pt format=onnx
  • 步骤 2. 使用 trtexec 生成引擎文件,命令如下:
cd /usr/src/tensorrt/bin
./trtexec --onnx=<path_to_onnx_file> --saveEngine=<path_to_save_engine_file>

例如:

./trtexec --onnx=/home/nvidia/yolov8s.onnx --saveEngine=/home/nvidia/yolov8s.engine

这将输出性能结果,并生成一个 .engine 文件。默认情况下,它会将 ONNX 转换为 FP32 精度的 TensorRT 优化文件,输出如下:

在这里,我们可以看到平均延迟为 7.2ms,相当于 139FPS。这与我们在之前 DeepStream 演示中获得的性能相同。

然而,如果你想要 INT8 精度以获得更好的性能,可以执行以下命令:

./trtexec --onnx=/home/nvidia/yolov8s.onnx --int8 --saveEngine=/home/nvidia/yolov8s.engine 

在这里,我们可以看到平均延迟为 3.2ms,相当于 313FPS。

YOLOv8 基准测试结果

我们对不同的 YOLOv8 模型在 reComputer J4012AGX Orin 32GB H01 KitreComputer J2021 上进行了性能基准测试。

想了解更多我们使用 YOLOv8 模型进行的性能基准测试,请查看我们的博客

多流模型基准测试

在 reComputer Jetson Orin 系列产品上运行多个 deepstream 应用程序后,我们使用 YOLOv8s 模型进行了基准测试。

  • 首先,我们使用单个 AI 模型,并在同一个 AI 模型上运行多个流。
  • 其次,我们使用多个 AI 模型,并在多个 AI 模型上运行多个流。

所有这些基准测试均在以下条件下进行:

  • YOLOv8s 640x640 图像输入
  • 禁用 UI
  • 开启最大功率和最大性能模式

从这些基准测试中可以看出,对于最高端的 Orin NX 16GB 设备,使用单个 YOLOv8s 模型在 INT8 模式下,你可以使用大约 40 个摄像头以大约 5fps 的速度运行;而使用多个 YOLOv8s 模型在 INT8 模式下为每个流运行时,你可以使用大约 11 个摄像头以大约 15fps 的速度运行。对于多模型应用,由于设备的 RAM 限制以及每个模型占用大量 RAM,摄像头数量会减少。

总之,当仅运行 YOLOv8 模型而不运行其他应用程序时,Jetson Orin Nano 8GB 可以支持 4-6 个流,而 Jetson Orin NX 16GB 可以在最大容量下管理 16-18 个流。然而,在实际应用中,随着 RAM 资源的使用,这些数字可能会减少。因此,建议将这些数字作为指导,并在您的具体条件下进行测试。

资源

技术支持与产品讨论

感谢您选择我们的产品!我们致力于为您提供多种支持,确保您在使用我们的产品时获得尽可能顺畅的体验。我们提供多种沟通渠道,以满足不同的偏好和需求。

Loading Comments...