ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

TensorRT Python 入门实战:用 ONNX Parser 导入 ResNet-50 模型并完成端到端推理

TensorRT Python 入门实战:用 ONNX Parser 导入 ResNet-50 模型并完成端到端推理 TensorRT Python 入门实战用 ONNX Parser 导入 ResNet-50 模型并完成端到端推理【免费下载链接】TensorRTNVIDIA® TensorRT™ is an SDK for high-performance deep learning inference on NVIDIA GPUs. This repository contains the open source components of TensorRT.项目地址: https://gitcode.com/GitHub_Trending/tens/TensorRT本文基于 NVIDIA TensorRT 开源仓库中的introductory_parser_samplesPython 示例系统讲解如何借助 TensorRT 自带的 ONNX Parser将 ONNX 格式的 ResNet-50 模型转换为 TensorRT 推理引擎Engine并完成从图像预处理、引擎构建到 GPU 推理、结果解析的完整流程。读完本文你将掌握trt.OnnxParser的核心用法、强类型网络构建的关键 API以及一套可复用的ONNX 模型 → TensorRT 引擎 → 推理Python 代码骨架。示例概览introductory_parser_samples 是什么introductory_parser_samples是 TensorRT 官方提供的 Python 入门示例位于仓库的 samples/python/introductory_parser_samples 目录核心文件包括onnx_resnet50.py示例主程序完成引擎构建与推理requirements.txtPython 依赖清单README.md官方使用说明本文主题文档。该示例使用 TensorRT 及其内置的 ONNX Parser对以 ONNX 格式保存的 ResNet-50 分类模型执行推理。其核心价值在于演示了如何用约百行 Python 代码把一个任意框架导出的 ONNX 模型文件通常是.onnx变成可在 NVIDIA GPU 上高性能运行的 TensorRT 引擎。由于 ONNX 已成为跨框架的开放模型交换格式这一流程天然适用于 PyTorch、TensorFlow 等任意支持 ONNX 导出的框架——只要模型能导出为 ONNX就能走通本示例的导入链路。工作原理ONNX Parser 如何把模型翻译成 TensorRT 网络核心流程示例的完整链路可以概括为四个阶段读取 ONNX 模型以二进制方式读入ResNet50.onnx文件解析建网trt.OnnxParser将 ONNX 图graph逐节点翻译为 TensorRT 的INetworkDefinition网络定义这一过程把 ONNX 算子映射为 TensorRT 层Layer构建引擎IBuilder结合IBuilderConfig对网络进行优化、层融合与内核选择产出序列化引擎serialized engine反序列化与推理trt.Runtime反序列化引擎创建执行上下文IExecutionContext完成 GPU 推理。其中第 2 步是解析器Parser的核心职责。从 include/NvOnnxParser.h 的接口定义可以看到nvonnxparser::IParser是 ONNX 解析器的底层 C 接口Python 端的trt.OnnxParser正是通过 python/src/parsers/pyOnnx.cpp 的 PyBind11 绑定暴露出来的其核心方法包括方法作用parse(data)解析内存中的序列化 ONNX 模型二进制 protobuf写入网络定义parseFromFile(path)从磁盘文件解析 ONNX 模型支持二进制 protobuf 或文本格式内部调用parsesupportsOperator(op_name)查询某个 ONNX 算子是否可能被解析器支持注意返回 true 不保证所有情况都支持可能存在误报getNbErrors()/getError(i)获取解析失败时的错误数量与错误详情supportsModelV2(...)在真正解析前预检整个 ONNX 模型是否被支持返回 true 即可直接进入引擎构建setFlags()/getFlags()/setFlag()/clearFlag()设置/查询 ONNX 解析器的行为标志详见下文解析器高级特性loadModelProto()/loadInitializer()/parseModelProto()分步加载模型、注入自定义初始权重、再触发解析onnx_resnet50解析器与任意框架的适配示例的核心函数build_engine_onnx见 onnx_resnet50.py演示了标准建网姿势def build_engine_onnx(model_file): builder trt.Builder(TRT_LOGGER) network builder.create_network(1 int(trt.NetworkDefinitionCreationFlag.STRONGLY_TYPED)) config builder.create_builder_config() parser trt.OnnxParser(network, TRT_LOGGER) config.set_memory_pool_limit(trt.MemoryPoolType.WORKSPACE, common.GiB(1)) # Load the Onnx model and parse it in order to populate the TensorRT network. with open(model_file, rb) as model: if not parser.parse(model.read()): print(ERROR: Failed to parse the ONNX file.) for error in range(parser.num_errors): print(parser.get_error(error)) return None engine_bytes builder.build_serialized_network(network, config) runtime trt.Runtime(TRT_LOGGER) return runtime.deserialize_cuda_engine(engine_bytes)几个值得展开的细节强类型网络create_network(1 int(trt.NetworkDefinitionCreationFlag.STRONGLY_TYPED))创建的是强类型strongly typed网络。在 include/NvInfer.h 中kSTRONGLY_TYPED被标记为在 TensorRT 11.0 起已废弃但保留兼容——网络现在始终是强类型的每个张量的数据类型由输入类型与算子类型规则自动推断不允许再手动设置层精度与层输出类型。示例 README 的 Changelog 中October 2025: Migrate to strongly typed APIs对应的正是这一迁移。对初学者而言只需知道当前写法即可不必再关心精度手动指定问题。工作空间内存池config.set_memory_pool_limit(trt.MemoryPoolType.WORKSPACE, common.GiB(1))把构建期工作空间workspace上限设为 1 GiBcommon.GiB定义于 samples/python/common.py即val * 1 30。工作空间是引擎构建时临时 GPU 内存影响某些算子如卷积的算法选择空间。错误诊断parser.parse()返回布尔值失败时通过parser.num_errors与parser.get_error(error)遍历输出全部解析错误——这是排查ONNX 算子不支持类问题的主要手段。序列化-反序列化闭环build_serialized_network返回序列化引擎字节流engine_bytes再由trt.Runtime.deserialize_cuda_engine还原为可用的ICudaEngine。序列化引擎可以落盘保存实现一次构建、处处部署这也是 TensorRT 部署链路的标准形态。环境准备安装 Python 依赖进入示例目录后执行pip3 install -r requirements.txtrequirements.txt 中锁定的依赖如下Pillow11.3.0 # 图像加载与缩放Image.LANCZOS 重采样 cuda-python12.9.0 # CUDA Python 绑定用于流与显存管理 pywin32; platform_system Windows # 仅 Windows 平台需要 pyyaml6.0.3 requests2.32.4 tqdm4.66.4 numpy1.26.4其中cuda-python被 samples/python/common_runtime.py 使用from cuda.bindings import driver as cuda, runtime as cudart, nvrtc负责 CUDA 流的创建与销毁、页锁定主机内存pinned memory分配以及异步拷贝Pillow与numpy用于图像的读取、缩放与归一化。此外还需确保环境中已安装与 GPU 驱动匹配的 TensorRT Python 包import tensorrt as trt。准备样本数据示例运行需要 TensorRT 样本数据包sample data其中包含ResNet50.onnx示例模型文件binoculars.jpeg、reflex_camera.jpeg、tabby_tiger_cat.jpg三张测试图片class_labels.txtImageNet 类别标签1000 行。若数据未安装在默认位置NGC 容器中通常挂载于/usr/src/tensorrt/data需要先下载并解压 TensorRT sample data 包然后通过环境变量TRT_DATADIR或命令行参数-d指定数据目录。完整的下载、解压与目录结构说明见主示例文档 samples/README.md 的 Preparing sample data 一节——解压后数据目录应包含int8_api/、mnist/、resnet50/等子目录本示例使用其中的resnet50/。运行示例基本运行在 samples/python/introductory_parser_samples 目录下直接执行python3 onnx_resnet50.py如果 TensorRT 样本数据不在默认位置必须用-d指定数据目录例如python3 onnx_resnet50.py -d $TRT_DATADIR数据目录解析逻辑位于 samples/python/common.py 的find_sample_data它会优先拼接数据目录/resnet50子路径若不存在则回退使用所给目录本身最终通过locate_files逐一确认 5 个必需文件是否存在任一缺失都会抛出FileNotFoundError。验证运行结果示例从三张测试图中随机挑选一张进行推理。若运行成功会输出类似下面的结果Correctly recognized data/samples/resnet50/reflex_camera.jpeg as reflex camera判定逻辑见 onnx_resnet50.py取输出概率向量中最大值的下标映射到class_labels.txt中的类别名再与该图片文件名中隐含的真实类别比对输出Correctly recognized ...正确或Incorrectly recognized ...错误。命令行选项--help示例的完整选项如下-h/--help可随时查看usage: onnx_resnet50.py [-h] [-d DATADIR] Runs a ResNet50 network with a TensorRT inference engine. optional arguments: -h, --help show this help message and exit -d DATADIR, --datadir DATADIR Location of the TensorRT sample data directory. (default: /usr/src/tensorrt/data)注意两点一是-d的默认值为/usr/src/tensorrt/data与 NGC 容器内的挂载路径一致二是find_sample_data中该参数声明为actionappend的列表因此可以多次传入解析器会依次搜索多个数据目录以先找到的文件为准。推理流程源码解析从预处理到结果输出main()onnx_resnet50.py展示了与建网解析器无关的通用推理范式——如源码注释所言无论用哪个解析器构建引擎推理过程都是一样的因为模型架构已经固定。1. 图像预处理load_normalized_test_caseonnx_resnet50.py完成三件事def normalize_image(image): c, h, w ModelData.INPUT_SHAPE # (3, 224, 224) image_arr ( np.asarray(image.resize((w, h), Image.LANCZOS)) .transpose([2, 0, 1]) # HWC - CHW .astype(trt.nptype(ModelData.DTYPE)) # 转 float32 .ravel() ) return (image_arr / 255.0 - 0.45) / 0.225缩放到模型要求的224×224Image.LANCZOS高质量重采样从HWC转置为CHW并展平通过trt.nptype()把 TensorRT 数据类型映射为 numpy 类型ModelData.DTYPE trt.float32做均值归一化(x / 255.0 - 0.45) / 0.225——这是该 ResNet-50 模型特有的预处理要求。预处理后的数据被拷贝到页锁定主机内存pinned host memory中为后续异步 H2D 拷贝做准备。2. 缓冲区分配与执行上下文inputs, outputs, bindings common.allocate_buffers(engine) context engine.create_execution_context()allocate_bufferssamples/python/common_runtime.py为引擎的每个 I/O 张量分配主机端页锁定内存 设备端显存对HostDeviceMem并把设备指针收集到bindings列表供引擎寻址遇到 BF16、FP8、INT4 等 numpy 无对应类型的精度时会自动退化为原始字节缓冲。CudaStreamContext则通过上下文管理器with语句保证 CUDA 流创建与销毁的生命周期安全。3. 执行推理with common.CudaStreamContext() as stream: test_image random.choice(test_images) test_case load_normalized_test_case(test_image, inputs[0].host) trt_outputs common.do_inference( context, engineengine, bindingsbindings, inputsinputs, outputsoutputs, streamstream, ) pred labels[np.argmax(trt_outputs[0])] common.free_buffers(inputs, outputs)do_inferencesamples/python/common_runtime.py内部执行标准的异步流水通过context.set_tensor_address为每个 I/O 张量绑定设备地址用cudaMemcpyAsync把输入从主机拷入显存调用context.execute_async_v3(stream_handle...)异步执行引擎用cudaMemcpyAsync把输出拷回主机cudaStreamSynchronize同步等待完成。输出是一个长度 1000 的一维张量每个元素代表输入图像对应某个 ImageNet 类别的概率np.argmax取出最大概率下标即可索引labels得到最终分类结果。推理完成后显式调用free_buffers释放 CUDA 资源虽然__del__也有兜底清理但显式释放更可靠。ONNX Parser 高级特性从示例走向生产示例只用了OnnxParser的冰山一角。结合 include/NvOnnxParser.h以下几类能力对实际项目很有价值解析器标志OnnxParserFlag标志默认说明kNATIVE_INSTANCENORM开对 InstanceNormalization 节点优先使用 TensorRT 原生层实现而非插件实现构建版本兼容/硬件兼容引擎时的必需项kENABLE_UINT8_AND_ASYMMETRIC_QUANTIZATION_DLA关在 Quantize/Dequantize 节点中启用 UINT8 与非对称量化非零零点引擎须面向 DLA 版本 ≥ 3.16 构建kREPORT_CAPABILITY_DLA关按 DLA 逐节点校验模型模型不完全支持 DLA 则解析失败需配合setBuilderConfig提供合法的IBuilderConfigkENABLE_PLUGIN_OVERRIDE关允许与 ONNX 算子同名的已加载插件覆盖默认实现适用于自定义高性能插件kADJUST_FOR_DLA关机会式改写/调整层使其更适合在 DLA 上运行可用parser.set_flag(...)/parser.clear_flag(...)单独增删或用parser.set_flags(1 flag | ...)整体覆盖。错误码体系ErrorCode解析失败时get_error(i)返回的错误对象携带code()错误码与desc()描述错误码从kSUCCESS0到kREFIT_FAILED14共 15 种常见的有kUNSUPPORTED_GRAPH/kUNSUPPORTED_NODE图的整体结构或某个算子不受支持kUNSUPPORTED_NODE_ATTR/kUNSUPPORTED_NODE_INPUT/kUNSUPPORTED_NODE_DATATYPE/kUNSUPPORTED_NODE_DYNAMIC/kUNSUPPORTED_NODE_SHAPE算子的属性、输入、数据类型、动态特性或形状不受支持kMODEL_DESERIALIZE_FAILEDONNX 模型反序列化失败文件损坏或 IR 版本/opset 不受支持。此外错误对象还带有出错的文件、行号、函数、ONNX 节点索引与节点名等信息可用于精准定位模型中哪个算子无法导入。支持性预检与分步导入supportsOperator(op_name)在解析前单独探测某个算子supportsModelV2(...)整体预检模型是否可被支持返回True后可直接进入引擎构建配合getNbSubgraphs、isSubgraphSupported、getSubgraphNodes可查看子图级别的支持情况结合kREPORT_CAPABILITY_DLA可用于 DLA 场景loadModelProto()→loadInitializer(name, data, size)→parseModelProto()分步加载模型并注入自定义 initializer 权重适合需要外部提供权重的场景。权重重拟合IParserRefitter对于同一架构、仅更新权重的需求nvonnxparser::IParserRefitter提供了基于 ONNX 模型的权重重拟合refit能力refitFromFile/refitFromBytes直接对已构建的引擎进行权重替换要求传入的 ONNX 模型与建引擎时完全一致。仓库中的 engine_refit_onnx_bidaf 示例正是这一能力的配套演示。若你的 ONNX 模型包含 TensorRT 不支持的算子可参考 onnx_packnet 示例了解如何以自定义层plugin方式补齐。变更记录与已知问题Changelog来自示例 READMEOctober 2025迁移至强类型strongly typedAPIAugust 2025移除对 Python 3.10 的支持August 2023移除对 Python 3.8 的支持August 2022移除 Caffe 与 UFF 解析器相关选项February 2019重写、更新并审阅本 README。已知问题示例当前无已知问题。延伸阅读围绕用 Python 导入模型到 TensorRT可继续在仓库内深入以下内容include/NvOnnxParser.hONNX Parser 的完整 C 接口定义IParser/IParserRefitter/ErrorCode/OnnxParserFlagpython/src/parsers/pyOnnx.cpptrt.OnnxParser的 Python 绑定实现samples/python/common.py 与 samples/python/common_runtime.py本示例依赖的通用工具库数据查找、缓冲区分配、异步推理samples/README.md全部官方示例的索引与样本数据准备说明include/NvInfer.hIBuilder、INetworkDefinition、NetworkDefinitionCreationFlag等核心类型定义。示例代码以 Apache-2.0 许可发布见仓库根目录 LICENSE。从ONNX 文件 → 引擎 → 推理结果这一最小闭环出发再逐步引入动态形状、INT8 量化、DLA、权重重拟合等高级特性即可平滑地从示例走向真实生产部署。【免费下载链接】TensorRTNVIDIA® TensorRT™ is an SDK for high-performance deep learning inference on NVIDIA GPUs. This repository contains the open source components of TensorRT.项目地址: https://gitcode.com/GitHub_Trending/tens/TensorRT创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进