在本文中,我们将深入探讨推理优化过程,以在推理阶段提高机器学习模型的性能和效率。我们将讨论所采用的技术,例如推理计算图形简化、量化和降低精度。我们还展示了场景文本检测和识别模型的基准测试结果,其中比较了 ONNX 运行时 和 NVIDIA TensorRT 使用 NVIDIA Triton 推理服务器。
最后,我们总结了优化深度学习模型对于推理的重要性,以及使用端到端 NVIDIA 软件解决方案的优势,NVIDIA AI Enterprise 用于构建高效可靠的场景文本 OCR 系统。
在本系列的第一篇文章中,强大的场景文本检测和识别:简介 讨论了稳健场景文本检测和识别(STDR)在各行各业中的重要性以及所面临的挑战。第二篇博文 强大的场景文本检测和识别:实施 并讨论了如何使用先进的深度学习算法和技术(如增量学习和微调)实现 STDR 工作流。
推理优化
推理优化旨在提高推理阶段机器学习模型的性能和效率。它有助于减少作出预测所需的时间、计算资源和成本,在某些情况下还可以提高准确性。
我们通过使用推理计算图形简化、量化和降低精度等技术来优化推理性能。这些模型最初使用 PyTorch 库进行训练,随后导出为 torchScript 格式,再转换为ONNX格式,最终转换为NVIDIA TensorRT引擎。
为了执行 ONNX 到 TensorRT 的转换,我们使用了 TensorRT 版本 22.07 的 NGC 容器镜像。转换过程结束后,我们使用 NVIDIA Triton 推理服务器版本 22.07 部署了推理模型。系统性能在具有 16 GB GPU 显存的 NVIDIA A5000 笔记本电脑 GPU 上进行了基准测试。
我们稍后将讨论场景文本检测和识别 (STDR) 每个构建块的优化细节。
场景文本检测
场景文本检测是场景文本 OCR 系统的一个重要组件。此组件将场景图像作为输入,并输出图像中文本字段位置。在本文中,我们将预训练的 CRAFT 模型用于常规场景文本检测任务。该模型基于一组不同的图像进行训练,能够处理动态输入图像并准确定位文本字段。在我们的部署中,用作输入的图像的平均宽度约为 720 点。在此处,我们对两种图像输入大小进行了基准测试:(3720,720) 和 (31200,1200).
我们的基准测试表明,与用于推理的 TorchScript 相比,TensorRT 的速度提高了大约 2.3 倍。
部署的 CRAFT 模型是具有 FP32 精度的 TensorRT 引擎。以下代码示例是快速转换指南。
创建 conda 环境:
$ conda create –n <your_env_name> python = 3.8 $ conda activate <your_env_name> |
克隆 CRAFT 库并安装 requirement.txt:
$ git clone https: / / github.com / clovaai / CRAFT - pytorch.git $ cd CRAFT - pytorch $ pip install –r requirement.txt |
加载模型并将其转换为可呈现动态形状的 .onnx 格式:
input_tensor_detec = torch.randn(( 1 , 3 , 768 , 768 ), requires_grad = False ) input_tensor_detec = input_tensor_detec.to(device = "cuda”) # Load net net = CRAFT() net.load_state_dict(copyStateDict(torch.load(model_path))) net = net.cuda() net. eval () # Convert the model into ONNX torch.onnx.export(net, input_tensor_detec, output_dir, verbose = False , opset_version = 11 , do_constant_folding = True , export_params = True , input_names = [ "input" ], output_names = [ "output" , "output1" ], dynamic_axes = { "input" : { 0 : "batch" , 2 : "height" , 3 : "width" }}) |
简化 ONNX 计算图。通过ONNX Simplifier来简化 ONNX 模型。它能够推理整个计算图,并将多余的运算符替换为它们的常量输出(这一过程也被称为常量折叠)。以下代码示例展示了如何使用操作折叠来简化 CRAFT 模型的计算图:
$ onnxsim <path to non_simplified onnx model> <path to simplified onnx model> |
在本文中,使用 NVIDIA TensorRT 预配置的 Docker 容器将 ONNX 模型转换为 TensorRT 序列化计划文件。以下代码示例适用于 tensorrt:22.07-py3 NGC 容器:
~$ docker run - it - - gpus all - v <path to onnx model>: / models \ nvcr.io / nvidia / tensorrt: 22.07 - py3 root@ 576df0ec3a49 : / workspace #$ trtexec --onnx=/models/craft.onnx \ - - explicitBatch - - workspace = 5000 - - minShapes = input : 1x3x256x256 \ - - optShapes = input : 1x3x700x700 - - maxShapes = input : 1x3x1200x1200 \ - - buildOnly –saveEngine = / models / craft.engine |
以下代码示例显示了场景文本检测模型的 config.pbtxt 文件:
name: "craft" default_model_filename: "detec_trt.engine" platform: "tensorrt_plan" max_batch_size : 1 input [ { name: "input" data_type: TYPE_FP32 dims: [ 3 , - 1 , - 1 ] } ] output [ { name: "output" data_type: TYPE_FP32 dims: [ - 1 , - 1 , 2 ] }, { name: "output1" data_type: TYPE_FP32 dims: [ 32 , - 1 , - 1 ] } ] |
场景文本识别
场景文本识别是 STDR 流程的一个不可或缺的模块。我们使用了 PARseq 算法,这是一种先进的技术,可实现高效且可定制的文本识别,以获得准确的结果。
为了更大限度地提高流程性能,我们将 PARseq TorchScript 模型转换为 ONNX,然后进一步将其转换为 TensorRT 引擎,确保文本识别的低延迟,因为每个图像可能包含多个文本字段。
我们发现,事实证明,为模型使用 3x32x128 的输入大小是推理时间和准确性之间的最佳平衡。图 4 显示了 PARseq 模型的基准测试结果。与 TorchScript 推理相比,我们的基准测试加速约为原来的 3 倍。
我们发现预训练模型的作者发布的大多数案例都能很好地处理。如果您希望在自定义数据集上获得更准确的输出,您也可以对模型进行微调。以下代码示例展示了进行这些重要转换步骤的方法。
安装 PARSeq:
$ git clone https: / / github.com / baudm / parseq.git $ pip install - r requirements.txt $ pip install - e . |
您可以使用自己的微调模型或预训练模型,从 模型库 中获取,并将其转换为 .onnx 格式。请使用 ONNX 1.12.0 以下的版本。
from strhub.models.utils import load_from_checkpoint # To ONNX device = "cuda" ckpt_path = "..." onnx_path = "..." img = ... parseq = load_from_checkpoint(ckpt_path) parseq.refine_iters = 0 parseq.decode_ar = False parseq = parseq.to(device). eval () parseq.to_onnx(onnx_path, img, do_constant_folding = True , opset_version = 14 ) # opset v14 or newer is required # check onnx_model = onnx.load(onnx_path) onnx.checker.check_model(onnx_model, full_check = True ) = = > pass |
要转换为 TensorRT 格式,请使用ONNX Simplifier:
$ onnxsim <path to non_simplified onnx model> <path to simplified onnx model> |
在将模型转换为简化的 ONNX 格式后,可以使用 trtexec 转换工具进行进一步处理。此转换过程可在 TensorRT 容器版本 22.07 中完成。
~$ docker run - it - - gpus all - v <path to onnx model repository>: / models nvcr.io / nvidia / tensorrt: 22.07 - py3 root@ 576df0ec3a49 : / workspace # trtexec --onnx=/models/parseq_simple.onnx --fp16 \ - - workspace = 1024 - - saveEngine = / models / parseq_fp16.trt - - minShapes = input : 1x3x32x128 \ - - optShapes = input : 4x3x32x128 - - maxShapes = input : 16x3x32x128 |
以下代码示例展示了config.pbtxt
场景文本识别模型的文件:
name: "parseq" max_batch_size: 16 platform: "tensorrt_plan" default_model_filename: "parseq_exp_fp32.trt" input { name: "input" data_type: TYPE_FP32 dims: [ 3 , 32 , 128 ] } output { name: "output" data_type: TYPE_FP32 dims: [ 26 , 95 ] } instance_group [ { count: 1 kind: KIND_GPU } ] |
编排师
编排器模块是一个用于维护流程并对 STDR 管线执行预处理的Python 后端。为了进行管线基准测试,我们使用了 4 张具有不同图像尺寸的图像,以便于perf_analyzer
的使用。
我们创建了两个版本的工作流,一个使用 ONNX 运行时 CPU/GPU 后端的工作流,另一个使用 TensorRT 计划,以便工作流可在 GPU 和非 GPU 环境中运行。我们对工作流进行了基准测试,onnx_backend
管道和tensorrt_plan
使用 NVIDIA Triton 推理服务器的 NVIDIA RTX A5000 笔记本电脑 GPU (16 GB) 上的工作流。
基准测试的输入样本具有四种不同的图像,大小为 (3x472x338)、(3x3280x2625)、(3x512x413) 和 (3x1600x1200).
编排器是一个 Python 后端模块,用于协调场景文本检测和场景文本识别模型。编排器的配置文件如下所示:
name: "pipeline" backend: "python" max_batch_size: 1 input [ { name: "input" data_type: TYPE_UINT8 dims: [ - 1 , - 1 , 3 ] } ] output [ { name: "output" data_type: TYPE_STRING dims: [ - 1 ] } ] instance_group [ { count: 1 kind: KIND_GPU } ] |
总结
总而言之,部署场景文本检测和识别系统需要仔细考虑真实场景,优化深度学习模型以进行推理至关重要。
为确保生产就绪型优化和性能, NVIDIA 提供了端到端软件解决方案 NVIDIA AI Enterprise,该解决方案由一流的 AI 软件和工具(包括 TensorRT 和 Triton 推理服务器)组成,可轻松访问构建企业 AI 应用程序。该解决方案有助于在各种设备上实现低延迟和高性能推理。
通过使用这些技术,您可以为各种应用构建高效可靠的场景文本 OCR 系统。