将 nvOCDR 部署到 DeepStream
nvOCDR 库封装了用于光学字符检测和识别 (OCR) 的完整推理管线。此库使用在 TAO 上训练的 OCDNet 和 OCRNet 模型。无论您是构建监控系统、交通监控应用程序还是任何其他类型的视频分析解决方案,nvOCDR 库都是实现准确可靠结果的重要工具。本指南将逐步介绍将 nvOCDR 库集成到 DeepStream 中的步骤。有关 nvOCDR 的更多信息,请参阅 nvOCDR 文档。
要在 DeepStream 中部署 nvOCDR,您需要首先使用 TAO 训练 OCDNet 和 OCRNet 模型。您可以从 NVIDIA TAO PTM(预训练模型)开始使用模型,也可以使用 TAO 训练自己的模型。有关如何训练您自己的模型,请参阅 OCDNet 和 OCRNet 的训练文档。
从 NGC 下载 TAO PTM
请参阅 NGC 以设置您的环境来运行 ngc
命令。
您可以使用以下命令下载预训练的 OCDNet 和 OCRNet 模型
mkdir -p pretrained_models
ngc registry model download-version nvidia/tao/ocdnet:deployable_v1.0 --dest ./pretrained_models
ngc registry model download-version nvidia/tao/ocrnet:deployable_v1.0 --dest ./pretrained_models
预训练的 OCRNet ONNX 模型中包含一个 character_list.txt
文件。这是已训练的 OCRNet 模型的词汇表,nvOCDR 库会使用它。有关 character_list.txt
的更多信息,请参阅 OCRNet 文档的 准备数据集 部分。
获得预训练的 OCD/OCRNet 模型后,您可以使用一键式脚本构建软件环境,或按照分步指南进行操作。
一键式脚本
您可以在 nvOCDR 存储库的 deepstream
下找到该脚本。
./build_docker.sh <path_to_ocdnet_onnx> <path_to_ocrnet_onnx> <path_to_ocr_character_list> \
<ocdnet_height> <ocdnet_width> \
<ocdnet_max_batch_size> <gpu_id>
分步指南
如果您需要分步设置 DeepStream 开发环境,请执行以下操作
在 x86 平台上,您可以从以下容器开始
docker run --gpus=all -v <work_path>:<work_path> --rm -it --privileged --net=host nvcr.io/nvidia/deepstream:6.2-triton bash # install opencv apt update && apt install -y libopencv-dev
在 Jetson 平台上,您可以从 L4T 容器开始
docker run --gpus=all -v <work_path>:<work_path> --rm -it --privileged --net=host nvcr.io/nvidia/deepstream-l4t:6.2-triton bash # install opencv apt update && apt install -y libopencv-dev
在 Jetson 平台上,您还可以安装 Jetpack 5.1 或更高版本,并运行以下命令来安装 opencv
# install opencv apt update && apt install -y libopencv-dev
如果您使用的是 TensorRT 8.6 及更高版本,则可以跳过以下编译 TensorRT OSS 插件的步骤。
接下来,您需要编译 TensorRT OSS 插件,因为 OCDNet 需要 modulatedDeformConvPlugin
获取 TensorRT 存储库
git clone -b release/8.6 https://github.com/NVIDIA/TensorRT.git cd TensorRT git submodule update --init --recursive
编译 TensorRT
libnvinfer_plugin.so
文件mkdir build && cd build # On X86 platform cmake .. # On Jetson platform # cmake .. -DTRT_LIB_DIR=/usr/lib/aarch64-linux-gnu/ make nvinfer_plugin -j4
将库复制到系统库路径
cp libnvinfer_plugin.so.8.6.0 /usr/lib/x86_64-linux-gnu/libnvinfer_plugin.so.8.5.2 # On Jetson platform: # cp libnvinfer_plugin.so.8.6.0 /usr/lib/aarch64-linux-gnu/libnvinfer_plugin.so.8.5.2
设置环境后,您需要为 OCDNet 和 OCRNet 模型生成 TensorRT 引擎。此引擎用于在 GPU 上运行模型。使用以下命令为具有动态批大小以及特定高度和权重的 OCDNet 和 OCRNet 生成 TRT 引擎
使用
trtexec
生成 OCDNet TRT 引擎/usr/src/tensorrt/bin/trtexec --onnx=<path_to_pretrained ocdnet.onnx> --minShapes=input:1x3x736x1280 --optShapes=input:1x3x736x1280 --maxShapes=input:4x3x736x1280 --fp16 --saveEngine=<work_path>/ocdnet.fp16.engine
使用
trtexec
生成 OCRNet TRT 引擎/usr/src/tensorrt/bin/trtexec --onnx=<path_to_pretrained ocrnet.onnx> --minShapes=input:1x1x32x100 --optShapes=input:32x1x32x100 --maxShapes=input:32x1x32x100 --fp16 --saveEngine=<work_path>/ocrnet.fp16.engine
您必须构建 nvOCDR 库和 DeepStream 中介库。这些库用于将训练后的模型集成到 DeepStream 管线中。
获取 nvOCDR 存储库
git clone https://github.com/NVIDIA-AI-IOT/NVIDIA-Optical-Character-Detection-and-Recognition-Solution.git
编译
libnvocdr.so
nvOCDR 库cd NVIDIA-Optical-Character-Detection-and-Recognition-Solution make export LD_LIBRARY_PATH=$(pwd)
编译用于 DeepStream 的
libnvocdr_impl.so
nvOCDR 中介库cd deepstream make
最后,您可以运行 nvOCDR DeepStream 示例来测试训练后的模型集成到 DeepStream 管线中的情况。您可以使用 gst-launch-1.0
构建 DeepStream OCR 管线,或者在 github 上使用 C++ 示例运行它
使用 gst-launch-1.0 运行管线
以下命令运行一个 JPEG 图像输入管线,输入
batch-size=1
。输出图像将保存到output.jpg
gst-launch-1.0 filesrc location=<path_to_test_img> ! jpegparse ! nvv4l2decoder ! \ m.sink_0 nvstreammux name=m batch-size=1 width=1280 height=1080 ! \ nvdsvideotemplate customlib-name=<path to libnvocdr_impl.so> \ customlib-props="ocdnet-engine-path:<path to ocdnet.fp16.engine>" \ customlib-props="ocdnet-input-shape:3,736,1280" \ customlib-props="ocdnet-binarize-threshold:0.1" \ customlib-props="ocdnet-polygon-threshold:0.3" \ customlib-props="ocdnet-max-candidate:200" \ customlib-props="ocrnet-engine-path:<path to ocrnet.fp16.engine>" \ customlib-props="ocrnet-dict-path:<path to character_list.txt>" \ customlib-props="ocrnet-input-shape:1,32,100" ! \ nvmultistreamtiler rows=1 columns=1 width=1280 height=720 ! nvvideoconvert ! nvdsosd ! \ nvvideoconvert ! 'video/x-raw,format=I420' ! jpegenc ! jpegparse ! filesink location=output.jpg
以下命令运行一个 JPEG 图像输入管线,输入
batch-size=2
gst-launch-1.0 filesrc location=<path_to_test_img> ! jpegparse ! nvv4l2decoder ! \ m.sink_0 nvstreammux name=m batch-size=2 width=1280 height=1080 ! \ nvdsvideotemplate customlib-name=<path to libnvocdr_impl.so> \ customlib-props="ocdnet-engine-path:<path to ocdnet.fp16.engine>" \ customlib-props="ocdnet-input-shape:3,736,1280" \ customlib-props="ocdnet-binarize-threshold:0.1" \ customlib-props="ocdnet-polygon-threshold:0.3" \ customlib-props="ocdnet-max-candidate:200" \ customlib-props="ocrnet-engine-path:<path to ocrnet.fp16.engine>" \ customlib-props="ocrnet-dict-path:<path to character_list.txt>" \ customlib-props="ocrnet-input-shape:1,32,100" ! \ nvmultistreamtiler rows=1 columns=2 width=1280 height=720 ! nvvideoconvert ! nvdsosd ! \ nvvideoconvert ! 'video/x-raw,format=I420' ! jpegenc ! jpegparse ! filesink location=output.jpg \ filesrc location=<path to test image> ! jpegparse ! nvv4l2decoder ! m.sink_1
如果您在 Jetson 设备上遇到 JPEG 解码问题,请尝试将硬件解码器替换为软件解码器
jpegparse ! jpegdec ! nvvideoconvert ! "video/x-raw(memory:NVMM), format=NV12"
以下命令运行一个 MP4 视频输入管线,
batch-size=1
。输出视频将保存到output.mp4
gst-launch-1.0 filesrc location=<path to test.mp4> ! qtdemux ! h264parse ! nvv4l2decoder ! \ m.sink_0 nvstreammux name=m batch-size=1 width=1280 height=1080 ! \ nvdsvideotemplate customlib-name=<path to libnvocdr_impl.so> \ customlib-props="ocdnet-engine-path:<path to ocdnet.fp16.engine>" \ customlib-props="ocdnet-input-shape:3,736,1280" \ customlib-props="ocdnet-binarize-threshold:0.1" \ customlib-props="ocdnet-polygon-threshold:0.3" \ customlib-props="ocdnet-max-candidate:200" \ customlib-props="ocrnet-engine-path:<path to ocrnet.fp16.engine>" \ customlib-props="ocrnet-dict-path:<path to character_list.txt>" \ customlib-props="ocrnet-input-shape:1,32,100" ! \ nvmultistreamtiler rows=1 columns=1 width=1280 height=720 ! nvvideoconvert ! nvdsosd ! \ nvvideoconvert ! 'video/x-raw(memory:NVMM),format=I420' ! nvv4l2h264enc ! h264parse ! \ mux.video_0 qtmux name=mux ! filesink location=output.mp4
您可以从 此链接 下载测试视频。
配置 nvOCDR 库
您可以使用 nvdsvideotemplate
的 customlib-props
参数配置 nvOCDR 库参数。这是设置参数的模板
nvdsvideotemplate customlib-name=libnvocdr_impl.so customlib-props="<nvOCDR attribute>:<nvOCDR attr value>"
参数 | 数据类型 | 默认值 | 描述 | 支持 |
ocdnet-engine-path |
字符串 | – | OCDNet TensorRT 引擎的绝对路径 | – |
|
字符串 |
– |
OCDNet TensorRT 引擎的输入形状(CHW 格式)。 |
|
ocdnet-binarize-threshold |
浮点数 | – | 用于二值化 OCDNet 输出的阈值 | >0 |
ocdnet-unclip-ratio |
浮点数 | 1.5 | 检测到的文本区域的 unclip 比率,它决定了输出大小 | >0 |
|
浮点数 |
– |
用于基于多边形的置信度分数过滤从 OCDNet 后处理生成的多边形的阈值 |
[0, 1] |
ocdnet-max-candidate |
无符号整数 | – | 来自 OCDNet 的最大输出多边形数 | >0 |
|
无符号整数 |
0 |
用于启用 Rectifier 模块中倒置处理的标志。 |
0, 1 |
ocrnet-engine-path |
字符串 | – | OCRNet TensorRT 引擎的绝对路径 | – |
ocrnet-dict-path |
字符串 | – | OCRNet 词汇表文件的绝对路径 | – |
|
字符串 |
– |
OCRNet TensorRT 引擎的输入形状(CHW 格式)。 |
|
is_high_resolution |
无符号整数 | 0 | 用于为高分辨率输入启用基于裁剪的推理的标志 | 0, 1 |
overlap-ratio |
浮点数 | 0.5 | 用于基于裁剪的推理的裁剪块的重叠比率 | [0, 1] |
ocrnet-decode |
字符串 | CTC | OCRNet 的解码模式 | CTC、Attention |
Triton Inference Server 是一款开源推理服务软件,可简化 AI 推理。Triton 使团队能够部署来自多个深度学习和机器学习框架的任何 AI 模型,包括 TensorRT、TensorFlow、PyTorch、ONNX、OpenVINO、Python、RAPIDS FIL。
本指南逐步介绍了将 nvOCDR 库集成到 Triton 中的步骤。有关 nvOCDR 的更多信息,请参阅 nvOCDR 文档。
步骤 1:获取 nvOCDR 存储库
git clone https://github.com/NVIDIA-AI-IOT/NVIDIA-Optical-Character-Detection-and-Recognition-Solution.git
步骤 2:从 NGC 下载 TAO PTM。
注意请参阅 NGC 以设置您的环境来运行
ngc
命令。您可以使用以下命令下载预训练的 OCDNet 和 OCRNet 模型
mkdir -p pretrained_models ngc registry model download-version nvidia/tao/ocdnet:deployable_v1.0 --dest ./pretrained_models ngc registry model download-version nvidia/tao/ocrnet:deployable_v1.0 --dest ./pretrained_models
预训练的 OCRNet ONNX 模型中包含一个
character_list.txt
文件。这是已训练的 OCRNet 模型的词汇表,nvOCDR 库会使用它。有关character_list.txt
的更多信息,请参阅 OCRNet 文档的 准备数据集 部分。步骤 3:构建 Triton 服务器 Docker 镜像
cd NVIDIA-Optical-Character-Detection-and-Recognition-Solution/triton bash setup_triton_server.sh [OCD input height] [OCD input width] [OCD input max batchsize] [DEVICE] [ocd onnx path> [ocr onnx path] [ocr character list path] # For example bash setup_triton_server.sh 736 1280 4 0 model/ocd.onnx model/ocr.onnx model/ocr_character_list
步骤 4:构建 Triton 客户端 Docker 镜像
cd NVIDIA-Optical-Character-Detection-and-Recognition-Solution/triton bash setup_triton_client.sh
步骤 5:运行 nvocdr Triton 服务器
docker run -it --net=host --gpus all --shm-size 8g nvcr.io/nvidian/tao/nvocdr_triton_server:v1.0 bash CUDA_VISIBLE_DEVICES=<gpu idx> tritonserver --model-repository /opt/nvocdr/ocdr/triton/models/
高分辨率图像的推理。
nvocdr Triton 可以支持高分辨率图像作为输入,例如 4000x4000。您可以更改 Triton 服务器容器中的 spec 文件 /opt/nvocdr/ocdr/triton/models/nvOCDR/spec.json 以支持高分辨率图像推理。
# to support high resolution images is_high_resolution_input: true
注意高分辨率图像推理仅支持批大小为 1。
步骤 6:运行 nvocdr Triton 客户端
打开一个新的终端并运行以下命令
docker run -it --rm -v <path to images dir>:<path to images dir> --net=host nvcr.io/nvidian/tao/nvocdr_triton_client:v1.0 bash python3 client.py -d <path to images dir> -bs 1
- client.py 参数
-d:图像文件夹的路径,支持的图像格式包括 ‘.jpg’、‘.jpeg’、‘.png’。
-bs:推理的批大小,运行高分辨率推理时仅支持批大小为 1。
如果要更改 Triton 服务器的某些配置,您可以执行 Triton 服务器容器并停止 tritonserver 进程,然后修改 spec 文件 /opt/nvocdr/ocdr/triton/models/nvOCDR/spec.json。完成修改后,您可以启动 tritonserver 并转到客户端容器以运行推理。
以下是 spec 文件中的参数
参数 | 数据类型 | 默认值 | 描述 | 支持 |
ocdnet_trt_engine_path |
字符串 | – | OCDNet TensorRT 引擎的绝对路径 | – |
|
列表 |
– |
OCDNet TensorRT 引擎的输入形状(CHW 格式)。 |
|
ocdnet_binarize_threshold |
浮点数 | – | 用于二值化 OCDNet 输出的阈值 | >0 |
ocdnet_unclip_ratio |
浮点数 | 1.5 | 检测到的文本区域的 unclip 比率,它决定了输出大小 | >0 |
|
浮点数 |
– |
用于基于多边形的置信度分数过滤从 OCDNet 后处理生成的多边形的阈值 |
[0, 1] |
ocdnet_max_candidate |
无符号整数 | – | 来自 OCDNet 的最大输出多边形数 | >0 |
|
布尔值 |
true |
用于启用 Rectifier 模块中倒置处理的标志。 |
0, 1 |
ocrnet_trt_engine_path |
字符串 | – | OCRNet TensorRT 引擎的绝对路径 | – |
ocrnet_dict_file |
字符串 | – | OCRNet 词汇表文件的绝对路径 | – |
|
列表 |
– |
OCRNet TensorRT 引擎的输入形状(CHW 格式)。 |
|
is_high_resolution_input |
布尔值 | false | 用于为高分辨率输入启用基于裁剪的推理的标志 | true/false |
overlapRate |
浮点数 | 0.5 | 用于基于裁剪的推理的裁剪块的重叠比率 | [0, 1] |
ocrnet_decode |
字符串 | CTC | OCRNet 的解码模式 | CTC、Attention |