首页 > 最新资讯 > 使用 cuDLA 在 NVIDIA Jetson Orin 上部署 YOLOv5
使用 cuDLA 在 NVIDIA Jetson Orin 上部署 YOLOv5

使用 cuDLA 在 NVIDIA Jetson Orin 上部署 YOLOv5

2023-10-08 17:43

#人工智能 #深度学习


 

NVIDIA Jetson Orin 是面向 AI 工作负载的领先嵌入式平台。Orin 平台的关键组件之一是第二代深度学习加速器(DLA),这是一个专用的深度学习推理引擎,可提供 AGX Orin 平台上三分之一的 AI 算力。

本文将从技术角度深入探讨使用 Orin 平台的嵌入式开发人员如何参照 YOLOv5 部署深度神经网络(DNN)。如要进一步了解 DLA 如何帮助实现深度学习应用性能的最大化,请参见使用 DLA 在 NVIDIA Jetson Orin 上最大限度地提高深度学习性能

YOLOv5 是一种物体检测算法。它是在 v3 和 v4 成功的基础上构建的,旨在提高实时对象检测任务的准确性和速度。YOLOv5 因出色地平衡了准确性与速度而闻名,成为计算机视觉领域研究人员和从业人员的热门选择。由于开放源码,开发人员能够利用预训练模型并根据具体目标对这些模型进行定制。

下面将通过一个端到端 YOLOv5 cuDLA 示例(https://github.com/NVIDIA-AI-IOT/cuDLA-samples/)向您展示:

使用量化感知训练(QAT)训练 YOLOv5 模型,并将其导出以部署到 DLA 上。

通过 TensorRT 和 cuDLA 使用 CUDA 部署网络并运行推理。

针对目标进行 YOLOv5 准确性验证和性能剖析。

我们通过这个示例演示了如何使用 DLA INT8 在 COCO 数据集上实现 37.3 mAP(官方 FP32 mAP 为 37.4)。我们还展示了如何在单个 NVIDIA Jetson Orin DLA 上获得超过 400 FPS 的 YOLOv5。(Orin 上共有两个 DLA 实例。)

用于 DLA 的 QAT 训练和导出

 

为了平衡 YOLOv5 的推理性能和准确性,必须在模型上进行量化感知训练(QAT)。由于在撰写本文时,DLA 不支持通过 TensorRT 进行 QAT,因此必须在推理之前将 QAT 模型转换为训练后量化(PTQ)模型。具体步骤如图 1 所示。

图 1. 将 QAT 模型转换为 PTQ 模型的关键步骤

QAT 训练流程

 

使用 TensorRT pytorch-quantization 工具包量化 YOLOv5。第一步是在神经网络图中添加量化器模块。该工具包提供了一组用于常见 DL 操作的量化层模块。如果某个模块不在所提供的量化模块之列,可以在模型中的适当位置创建自定义量化模块。

第二步是校准模型,获取每个量化/反量化(Q/DQ)模块的尺度值。校准完成后,选择一个训练计划并使用 COCO 数据集对校准后的模型进行微调。

图 2:QAT 训练工作流程的步骤

添加 Q/DQ 节点

 

可通过两种方法在网络中添加 Q/DQ 节点:

方法 1:

根据建议,在 TensorRT Q/DQ 处理网络中放置 Q/DQ 节点。这种方法遵循的是 Q/DQ 层的 TensorRT 融合策略。这些 TensorRT 策略主要针对 GPU 推理进行调整。为使其与 DLA 兼容,可添加额外的 Q/DQ 节点,这些节点可通过 Q/DQ 转换器使用相邻层的标度得出。

否则,任何缺失的标度都会导致某些图层以 FP16 运行。这可能会导致 mAP 略有下降,也可能致使性能大幅下降。Orin DLA 针对 INT8 卷积进行了优化,性能大约是 FP16 密集性能的 15 倍(或将 FP16 密集性能与 INT8 稀疏性能相比较时的 30 倍)。

方法 2:

在每一层插入 Q/DQ 节点,以确保所有张量都有 INT8 标度。使用该方法可以在模型微调期间获得所有层的尺度。不过,在 GPU 上运行推理时,这个方法可能会影响带有 Q/DQ 层的 TensorRT 融合策略,并导致 GPU 上的延迟增加。另一方面,对于 DLA,使用 PTQ 尺度的经验法则是:“可用的尺度越多,延迟就越低”。

实验证实,我们的 YOLOv5 模型在分辨率为 672 x 672 像素的 COCO 2017 验证数据集上得到了验证。方法 1 和方法 2 获得的 mAP 分数分别为 37.1 和 37.0。

请根据您的需求选择最佳的方法。如果您已经有用于 GPU 的 QAT 流程并希望尽可能保留该流程,那么方法 1 可能更好。(您可能还需要扩展 Q/DQ 转换器来推断更多的缺失尺度,以便将 DLA 延迟降至最低。)

但如果您正在寻找一种将 Q/DQ 节点插入所有层,并与 DLA 兼容的 QAT 训练方法,那么方法 2 可能更适合您。

Q/DQ 转换器的工作流程

 

Q/DQ 转换器用于将使用 QAT 训练的 ONNX 图形转换成 PTQ 张量尺度和无 Q/DQ 节点的 ONNX 模型。

可以从 QAT 模型中的 Q/DQ 节点提取该 YOLOv5 模型的量化尺度。使用相邻层的信息来推理其他层的输入/输出尺度,比如 YOLOv5 SiLU 中的 Sigmoid 和 Mul 或者 Concat 节点。在提取尺度后,导出不含 Q/DQ 节点的 ONNX 模型和(PTQ)校准缓存文件,以便 TensorRT 能够使用它们构建 DLA 引擎。

将网络部署到 DLA 以运行推理

 

下一步是部署网络,并通过 TensorRT 和 cuDLA 使用 CUDA 运行推理。

 

使用 TensorRT 构建可加载程序

 

使用 TensorRT 构建 DLA 可加载程序,可以为 DLA 加载项的构建提供一个简单易用的界面,并且可以在需要时与 GPU 无缝集成。有关 TensorRT-DLA 的更多信息,参见 TensorRT 开发者指南中的“使用 DLA”:https://docs.nvidia.com/deeplearning/tensorrt/developer-guide/index.html#dla_topic

trtexec 是 TensorRT 提供的用于构建引擎和性能基准测试的便捷工具。请注意,DLA 可加载程序是通过 DLA 编译器成功编译 DLA 的结果,TensorRT 可以将 DLA 可加载程序打包到序列化引擎中。

首先,准备 ONNX 模型和上一节中生成的校准缓存。只需一条命令即可构建 DLA 可加载程序。通过 --safe 选项,整个模型就可以在 DLA 上运行,这样就可以直接将编译结果保存为序列化的 DLA 可加载程序(没有 TensorRT 引擎包裹)。有关此步骤的更多详情,请参见 NVIDIA 深度学习 TensorRT 文档:https://docs.nvidia.com/deeplearning/tensorrt/developer-guide/index.html#using-trtexec-gen-dla-load

trtexec --onnx=model.onnx --useDLACore=0 --safe --saveEngine=model.loadable --inputIOFormats=int8:dla_hwc4 --outputIOFormats=fp16:chw16 --int8 --fp16 --calib=qat2ptq.cache

 

请注意,如果您的模型输入符合条件,从性能角度考虑,强烈推荐使用输入格式 dla_hwc4 。该输入最多只能有四个输入通道并通过一个卷积消耗。在 INT8格式下,DLA 可以从特定的硬件和软件优化中获益,而如果使用 --inputIOFormats=int8:chw32 则无法获得这种优化。

 

使用 cuDLA 运行推理

 

cuDLA 是 DLA 的 CUDA 运行时接口,它是集成 DLA 与 CUDA 的 CUDA 编程模型的扩展。借助 cuDLA,您可以通过 TensorRT 运行时隐式运行推理,也可以显式调用 cuDLA API。本示例演示了后一种方法,即通过显式调用 cuDLA API 在混合模式和独立模式中运行推理。

cuDLA 混合模式和独立模式的主要区别在于同步。在混合模式中,DLA 任务被提交到 CUDA 流,因此可以与其他 CUDA 任务实现无缝同步。

而在独立模式中,cudlaTask 结构须按照规定来指定等待和信号事件,cuDLA 必须分别等待和发出信号,作为 cudlaSubmitTask 的一部分。

简而言之,使用 cuDLA 混合模式可以实现与其他 CUDA 任务的快速集成。使用 cuDLA 独立模式可以防止创建 CUDA 上下文,因此能够在整个流程没有 CUDA 上下文的情况下节省资源。

下面将详细介绍 YOLOv5 示例中使用的主要 cuDLA 应用程序接口。

cudlaCreateDevice 创建 DLA 设备。

cudlaModuleLoadFromMemory 载入供 DLA 使用的引擎内存。

调用 cudaMalloc 和 cudlaMemRegister,首先在 GPU 上分配内存,然后让 CUDA 指针注册到 DLA(仅限混合模式)。

调用 cudlaImportExternalMemory 和 cudlaImportExternalSemaphore,导入外部 NvSci 缓冲区和同步对象(仅限独立模式)。

cudlaModuleGetAttributes 从载入的模块中获取模块属性。

调用 cudlaSubmitTask 以提交推理任务。在混合模式中,用户需要指定 CUDA 流,以便让 cuDLA 任务在该 CUDA 流上运行。在独立模式中,用户需要指定信号事件和等待事件,以便让 cuDLA 等待并在相应栅栏到期时发出信号。

针对目标进行验证和剖析

需要注意 GPU 和 DLA 在数值上的差异。底层硬件的不同使得计算无法达到逐位准确。由于网络训练是在 GPU 上完成后部署到目标 DLA 的,因此针对目标进行验证非常重要,尤其是在量化时。另外,与参考基准进行比较也很重要。

YOLOv5 DLA 准确性验证

 

我们使用 COCO 数据集进行验证。图 3 显示了推理工作流的架构。首先,加载图像数据并对其进行规范化处理。由于 DLA 仅支持 INT8/FP16,因此需要对推理的输入和输出进行额外的重新格式化。

推理结束后,对推理结果进行解码并执行 NMS(非最大抑制)以获得检测结果。最后,保存结果并计算 mAP。

图 3. 任务映射到不同计算引擎的推理工作流

在使用 YOLOv5 的情况下,最后三个卷积层的特征图对最终检测信息进行了编码。当量化到 INT8 时,与 FP16/FP32 相比,边界框坐标的量化误差会变得很明显,从而影响最终的 mAP。

我们的实验表明,在 FP16 中运行最后三个卷积层可将最终 mAP 从 35.9 提高到 37.1。由于 Orin DLA 采用了专为 INT8 高度优化的特殊硬件设计,因此当这三个卷积层在 FP16 中运行时,我们会发现性能有所下降。

图 4. 不同精度配置下的 YOLOv5 引擎

表 1. 最后三个卷积层的混合精度配置一览

请注意,这些 mAP 结果是基于上一节中的 Q/DQ 节点方法 1 得出的。您也可以将相同的原则应用于方法 2。

YOLOv5 DLA 的性能

 

借助两个 DLA 内核,DLA 为 Orin AGX 平台提供了三分之一的 AI 算力。有关 Orin DLA 性能的一般基准,请参见 GitHub 上的 Deep-Learning-Accelerator-SW:https://github.com/NVIDIA/Deep-Learning-Accelerator-SW#orin-dla-performance

在最新版本的 DLA 3.14.0(DOS 6.0.8.0 和 JetPack 6.0)中,DLA 编译器加入了若干性能的优化,尤其适用于基于 INT8 CNN 架构的模型:

原生 INT8 Sigmoid(以前以 FP16 运行并且必须来回转换于 INT8;也适用于 Tanh)

将 INT8 SiLU 融合到单个 DLA 硬件操作中(取代独立 Sigmoid 和独立逐元素 Mul)

将 INT8 SiLU 硬件操作与之前的 INT8 Conv 硬件操作融合(也适用于独立的 Sigmoid 或 Tanh)

与以前的版本相比,这些改进可使 YOLO 架构的速度提高 6 倍。例如在使用 YOLOv5 的情况下,推理性能从 INT8 时的 13 毫秒跃升至 2.4 毫秒(有几层在 FP16 中运行),提高了 5.4 倍。此外,您还可以使用 cuDLA 示例对您的 DNN 进行逐层剖析、找出瓶颈并通过修改网络来提高其性能。

开始使用 DLA

 

本文介绍了如何在专用深度学习加速器上使用 YOLOv5 来最高效地运行 Orin 上的整个对象检测流水线。请记住,GPU 等其他 SoC 组件或是处于空闲状态,或是以非常小的负载运行。假设一台摄像机以 30 fps 的速度产生输入数据,那么一个 DLA 实例的负载大约只有 10%。因此,您有足够的空间为应用添加更多的功能。

准备好一探究竟了吗?YOLOv5 示例复制了本文所述的整个工作流程。您可以将它作为您自己用例的参照。

GitHub 上的 Jetson_dla_tutorial 为初学者演示基本的 DLA 工作流程,可帮助您开始将简单的模型部署到 DLA:https://developer.nvidia.com/deep-learning-accelerator

关于如何使用 DLA 来充分利用 NVIDIA DRIVE 或 NVIDIA Jetson 的其他示例和资源,请访问 GitHub 上的 Deep-Learning-Accelerator-SW:https://github.com/NVIDIA/Deep-Learning-Accelerator-SW/

有关 cuDLA 的更多信息,请访问 Deep-Learning-Accelerator-SW/samples/cuDLA:https://github.com/NVIDIA/Deep-Learning-Accelerator-SW/tree/main/samples/cuDLA

<p style="\'margin-bottom:" 0px;outline:="" 0px;font-family:="" system-ui,="" -apple-system,="" blinkmacsystemfont,="" "helvetica="" neue",="" "pingfang="" sc",="" "hiragino="" sans="" gb",="" "microsoft="" yahei="" ui",="" yahei",="" arial,="" sans-serif;letter-spacing:="" 0.544px;text-wrap:="" wrap;background-color:="" rgb(255,="" 255,="" 255);text-align:="" center;\'="">

相关新闻