将自定义模型与 DeepStream 结合使用#
NVIDIA® DeepStream SDK 在 NVIDIA® Tesla® 或 NVIDIA® Jetson 平台上可以进行自定义,以支持用于对象检测和分类的自定义神经网络。您可以创建自己的模型。您必须在 nvinfer
配置文件(例如,config_infer_primary.txt
)的 [property] 组中指定适用的配置参数。您必须指定的配置参数包括
model-file (Caffe 模型)
proto-file (Caffe 模型)
onnx-file (ONNX 模型)
model-engine-file,如果已生成
INT8 模式的 int8-calib-file
mean-file,如果需要
offsets,如果需要
maintain-aspect-ratio,如果需要
parse-bbox-func-name(仅限检测器)
parse-classifier-func-name(仅限分类器)
custom-lib-path
network-type
model-color-format
process-mode
engine-create-func-name
infer-dims (UFF 模型)
自定义模型实现接口#
nvinfer 支持以下用途的接口
用于自定义神经网络检测器和分类器的自定义边界框解析
对于 NVIDIA® TensorRT™ 本身不支持的层的 IPlugin 实现
在网络具有多个输入层的情况下初始化非图像输入层
使用 TensorRT Layer API 而不是模型解析 API 创建 CUDA 引擎。在此处阅读有关 TensorRT 文档的更多信息: https://docs.nvda.net.cn/deeplearning/tensorrt/developer-guide/index.html
IModelParser 接口,用于解析模型并在 INetworkDefinition 中填充层
模型的所有接口实现都必须放入单个独立的共享库中。 nvinfer 使用 dlopen()
动态加载库,使用 dlsym()
查找已实现的接口,并根据需要调用接口。有关接口的更多信息,请参阅头文件 nvdsinfer_custom_impl.h
。
自定义输出解析#
对于检测器,您必须编写一个库,该库可以从输出层解析边界框坐标和对象类别。对于分类器,库必须从输出层解析对象属性。例如,在分割模型中,库必须从输出层解析边界框、对象类别和掩码。您可以在源代码目录 sources/libs/nvdsinfer_customparser
中找到示例代码和 makefile。生成的库路径和函数名称必须使用配置参数指定,如自定义模型部分所述。sources/libs/nvdsinfer_customparser
中的 README 文件包含如何使用此自定义解析器的示例。当前版本支持以下输出解析器
MaskRCNN
SSD
YoloV3 / YoloV3Tiny / YoloV2 / YoloV2Tiny
DetectNet
IPlugin 实现#
DeepStream 支持包含 TensorRT 不支持但通过 IPlugin 接口的实现支持的网络的层。objectDetector_SSD、objectDetector_FasterRCNN 和 objectDetector_YoloV3 示例应用程序显示了 IPlugin 实现的示例。DeepStream 支持用于自定义层的 NVIDIA® TensorRT™ 插件。 Gst-nvinfer 插件现在支持 TensorRT 5.0 中引入的 IPluginV2 和 IPluginCreator 接口。对于 caffemodel 以及为了向后兼容现有插件,它还支持以下接口
nvinfer1::IPluginFactory
nvuffparser::IPluginFactory
nvuffparser::IPluginFactoryExt
nvcaffeparser1::IPluginFactory
nvcaffeparser1::IPluginFactoryExt
nvcaffeparser1::IPluginFactoryV2
有关新的和已弃用的插件接口的详细信息,请参阅 TensorRT 文档。
如何使用 IPluginCreator#
要使用新的 IPluginCreator 接口,您必须在独立的自定义库中实现该接口。必须通过使用 custom-lib-path 键指定库的路径名,将此库传递给 Gst-nvinfer 插件。 Gst-nvinfer 使用 dlopen()
打开库,这会导致插件在 TensorRT 中注册。自定义库和 Gst-nvinfer 之间没有进一步的直接交互。 TensorRT 根据需要调用自定义插件函数。 SDK 随附的 SSD 示例提供了使用 IPluginV2 和 IPluginCreator 接口的示例。此示例已从 TensorRT 调整。
如何使用 IPluginFactory#
要使用 IPluginFactory 接口,您必须在独立的自定义库中实现该接口。通过在插件的配置文件中使用 custom-lib-path 键指定库的路径名,将此库传递给 Gst-nvinfer 插件。自定义库必须实现适用的函数
NvDsInferPluginFactoryCaffeGet
NvDsInferPluginFactoryCaffeDestroy
NvDsInferPluginFactoryUffGet
NvDsInferPluginFactoryUffDestroy
NvDsInferPluginFactoryRuntimeGet
NvDsInferPluginFactoryRuntimeDestroy
这些结构在 nvdsinfer_custom_impl.h
中定义。函数定义必须与头文件中的名称相同。 Gst-nvinfer 使用 dlopen()
打开自定义库并查找名称。
对于 Caffe 文件#
在解析和构建 Caffe 网络期间,Gst-nvinfer 查找 NvDsInferPluginFactoryCaffeGet
。如果找到,它会调用该函数以获取 IPluginFactory 实例。根据返回的 IPluginFactory 的类型,Gst-nvinfer 使用 ICaffeParser 接口的方法 setPluginFactory()
、setPluginFactoryExt()
或 setPluginFactoryV2()
之一设置工厂。在构建和序列化网络后,Gst-nvinfer 查找 NvDsInferPluginFactoryCaffeDestroy
并调用它以销毁 IPluginFactory 实例。
对于 Uff 文件#
在解析和构建 Caffe 网络期间,Gst-nvinfer 查找 NvDsInferPluginFactoryUffGet
。如果找到,它会调用该函数以获取 IPluginFactory 实例。根据返回的 IPluginFactory 的类型,Gst-nvinfer 使用 IUffParser 接口的方法 setPluginFactory()
或 setPluginFactoryExt()
之一设置工厂。在构建和序列化网络后,Gst-nvinfer 查找 NvDsInferPluginFactoryUffDestroy
并调用它以销毁 IPluginFactory 实例。
在反序列化期间#
如果反序列化模型需要 NvInfer1::IPluginFactory
的实例,则自定义库还必须实现 NvDsInferPluginFactoryRuntimeGet()
和可选的 NvDsInferPluginFactoryRuntimeDestroy()
。在反序列化期间,Gst-nvinfer 调用库的 NvDsInferPluginFactoryRuntimeGet()
函数以获取 IPluginFactory 实例,然后在 Gst-nvinfer 反初始化期间找到该函数时,调用 NvDsInferPluginFactoryRuntimeDestroy
以销毁该实例。 SDK 随附的 FasterRCNN 示例提供了将 IPluginV2+nvcaffeparser1::IPluginFactoryV2
接口与 DeepStream 结合使用的示例。此示例已从 TensorRT 调整。它还提供了使用旧版 IPlugin + nvcaffeparser1::IPluginFactory + Gst-nvinfer 1::IPluginFactory
接口以实现向后兼容性的示例。
输入层初始化#
DeepStream 支持为具有多个输入层的网络初始化非图像输入层。这些层仅在首次推理调用之前初始化一次。 objectDetector_FasterRCNN 示例应用程序显示了实现的示例。
自定义模型的 CUDA 引擎创建#
DeepStream 支持为非 Caffe、UFF 或 ONNX 格式的模型或必须从 TensorRT Layer API 创建的模型创建 TensorRT CUDA 引擎。 objectDetector_YoloV3 示例应用程序显示了实现的示例。当在管道中使用单个自定义库用于多个 nvinfer 插件实例时,每个实例都可以有自己的 engine-create-func-name 实现,这可以在配置文件中指定。一个示例是具有不同类型的 yolo 模型的背靠背检测器管道。
用于自定义模型解析的 IModelParser 接口#
这是用于解析和填充 TensorRT 网络 (INetworkDefinition) 的“CUDA 引擎创建”接口的替代方案。objectDetector_YoloV3
示例应用程序显示了实现的示例。