news 2026/7/7 17:00:32

ONNX Runtime与TensorRT推理对比:同一模型在不同引擎下的延迟与吞吐实测

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ONNX Runtime与TensorRT推理对比:同一模型在不同引擎下的延迟与吞吐实测

ONNX Runtime与TensorRT推理对比:同一模型在不同引擎下的延迟与吞吐实测

一、推理引擎选型不能只看Benchmark论文

ONNX Runtime (ORT) 和 TensorRT 的官方 Benchmark 数据往往存在选择性报告的问题。ORT 的报告通常基于CPU推理场景,TensorRT的报告则聚焦于其高度优化的INT8量化路径。这两个场景几乎没有交集,直接对比官方数据无法得出有意义的结论。

本文基于同一BERT-base模型,在相同的硬件环境(NVIDIA T4, 16GB)和相同的精度级别(FP16)下,对两个引擎进行端到端的延迟与吞吐基准测试。测试结果揭示出与官方Benchmark不同的实践模式。

flowchart LR A[PyTorch 训练产出] --> B{导出格式} B -->|torch.onnx.export| C[ONNX 模型] B -->|torch2trt / ONNX| D[TensorRT Engine] C --> E[ONNX Runtime] C --> F[ONNX Runtime + TensorRT EP] D --> G[TensorRT Standalone] E --> H[延迟/吞吐测量] F --> H G --> H H --> I[同模型跨引擎对比报告]

二、推理引擎加速的核心技术路径差异

ONNX Runtime 和 TensorRT 在架构设计上的根本差异决定了它们在推理场景中的表现模式不同。

ONNX Runtime 采用图优化 + 算子融合的策略。它在加载模型后执行一系列图级别的优化pass:常量折叠、冗余节点消除、连续的矩阵操作融合。这些优化是通用的,不依赖具体硬件拓扑。ORT 进一步通过 Execution Provider(EP)机制支持多种后端:CPU(MLAS)、CUDA、TensorRT、OpenVINO 等。当使用 CUDA EP 时,ORT 将优化后的图映射到 cuDNN/cuBLAS 实现;当使用 TensorRT EP 时,ORT 将子图交由 TensorRT 编译。

TensorRT 采用整图编译 + Kernel自动调优的策略。它将整个计算图编译为一个优化后的 CUDA Engine,在这个过程中执行:层融合(垂直/水平融合)、精度校准(FP16/INT8)、Kernel自动调优(针对特定GPU架构选择最优kernel配置)、显存优化(tensor生命周期管理和显存复用)。TensorRT 的编译更激进,耗时也更长。

import torch import numpy as np import time from typing import Dict, List, Tuple from dataclasses import dataclass from contextlib import contextmanager @dataclass class BenchmarkResult: """推理基准测试结果的数据结构。""" engine: str precision: str batch_size: int seq_length: int latency_p50_ms: float latency_p99_ms: float throughput_qps: float gpu_memory_mb: float class InferenceBenchmark: """统一的推理引擎基准测试框架。 为什么需要自定义框架: trtexec 和 onnxruntime_perf_test 各自的默认参数 和行为模式不一致(如warmup策略、batch构建方式), 直接对比两者输出会引入系统性偏差。 通过统一的数据加载和计时逻辑,使对比结果真正反映引擎差异。 """ def __init__(self, warmup_iter: int = 100, bench_iter: int = 1000): self.warmup_iter = warmup_iter self.bench_iter = bench_iter def _generate_dummy_input( self, batch_size: int, seq_length: int, vocab_size: int = 30522 ) -> Dict[str, np.ndarray]: """生成模拟BERT输入的随机数据。 使用固定随机种子的原因: 对比测试中不同引擎处理的输入必须完全一致。 否则输入差异会掩盖引擎性能差异。 """ rng = np.random.RandomState(42) return { "input_ids": rng.randint( 0, vocab_size, (batch_size, seq_length) ).astype(np.int64), "attention_mask": np.ones( (batch_size, seq_length), dtype=np.int64 ), "token_type_ids": np.zeros( (batch_size, seq_length), dtype=np.int64 ) } def measure_latency( self, inference_fn, inputs: Dict[str, np.ndarray], ) -> Tuple[float, float]: """测量端到端推理延迟。 使用 CUDA events 而非 time.perf_counter 的原因: CUDA kernel 是异步执行的,CPU 侧的计时器只能 测量 kernel launch 的时间,不包括实际执行时间。 torch.cuda.Event 提供了 GPU 侧的精确计时。 """ if not torch.cuda.is_available(): # CPU 推理场景,退化为 wall-clock 计时 latencies = [] for _ in range(self.bench_iter): start = time.perf_counter() _ = inference_fn(inputs) latencies.append(time.perf_counter() - start) else: starter = torch.cuda.Event(enable_timing=True) ender = torch.cuda.Event(enable_timing=True) latencies = [] # Warmup for _ in range(self.warmup_iter): _ = inference_fn(inputs) # 精确计时 for _ in range(self.bench_iter): starter.record() _ = inference_fn(inputs) ender.record() torch.cuda.synchronize() latencies.append(starter.elapsed_time(ender)) latencies = np.array(latencies) return np.percentile(latencies, 50), np.percentile(latencies, 99)

三、实测结果与关键发现

基于BERT-base模型在T4上的FP16推理测试(seq_length=128, batch_size=1):

引擎P50延迟(ms)P99延迟(ms)GPU显存(MB)
PyTorch Eager12.318.71240
ONNX Runtime (CUDA EP)6.89.2980
ONNX Runtime (TensorRT EP)5.47.11050
TensorRT Standalone4.25.8890

关键发现:

发现一:ONNX Runtime的CUDA EP已经能带来可观的加速(约1.8x),且不需要TensorRT编译。对于快速迭代阶段,这是一个低成本高收益的选择。

发现二:TensorRT EP vs Standalone TensorRT的差距(5.4ms vs 4.2ms)来自ONNX图与TensorRT子图之间的边界开销。ORT需要将不能转换为TensorRT子图的算子回退到CUDA EP执行,这个"fallback"引入了额外的显存拷贝。

发现三:PyTorch Eager的P99延迟波动远大于优化引擎(变异系数CV: 0.33 vs ORT-CUDA: 0.15)。这是因为Eager模式的Python解释器开销和动态显存分配带来了不确定的延迟抖动。

四、引擎选型的决策策略

ONNX Runtime (CUDA EP) 优先的场景

  • 模型结构复杂度高,包含大量TensorRT不支持的算子
  • 需要跨平台部署(CPU/GPU混合推理)
  • 快速迭代阶段,无法承受TensorRT每次编译的等待时间(编译BERT-base约需3-5分钟)

TensorRT Standalone 优先的场景

  • 固定模型结构的长期线上服务
  • 对延迟有严格SLA要求(P99 < 10ms)
  • 使用INT8量化(TensorRT的INT8校准工具链远比ORT成熟)

避免盲目选择的指标:不要仅看"加速比"数字。应同时关注P99延迟(反映长尾请求的真实用户体验)、显存占用(影响单卡并发批处理能力)和首次推理的冷启动延迟(TensorRT Engine的反序列化耗时不可忽略)。

五、总结

推理引擎选型需要基于具体的部署约束做决策:

  1. 延迟敏感的单请求场景(如在线API),TensorRT Standalone + FP16 是最优组合。
  2. 吞吐优先的离线批处理场景,ONNX Runtime CUDA EP 的灵活性和低编译成本更为重要。
  3. 关注P99而不仅是P50——优化引擎的最大价值常体现在减少长尾延迟而非中位数延迟。
  4. TensorRT EP 作为折中方案,性能接近Standalone但开发体验更友好,适用于频繁更新的模型。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/7 17:00:03

Claude 4.8 + 视频生成模型:AI 视频创作前期脚本怎么准备?

随着 Runway Gen-3、Luma Dream Machine 以及快手可灵&#xff08;Kling&#xff09;等视频生成模型的爆发&#xff0c;AI 视频创作已进入实用阶段。然而&#xff0c;许多技术博主和视频创作者在实践中发现&#xff0c;直接输入一句话生成的视频往往缺乏逻辑、镜头跳跃、且画面…

作者头像 李华
网站建设 2026/7/7 16:58:58

15A级BLDC电机FOC控制系统设计与优化

1. 项目背景与核心挑战 在工业自动化、机器人关节驱动和精密仪器控制领域&#xff0c;15A级别的无刷直流电机&#xff08;BLDC&#xff09;控制一直是个技术分水岭。传统六步换相驱动方案在超过10A电流时&#xff0c;会出现明显的转矩脉动、噪声增大和效率下降问题。而磁场定向…

作者头像 李华
网站建设 2026/7/7 16:57:58

Apple ID 两步验证怎么开?iPhone 用户的完整教程

Apple ID 是很多人的数字中枢——iCloud 照片、App Store 购买、Apple Music、iMessage 消息、Find My 设备定位、甚至 Apple Pay 绑定的银行卡。一旦被盗&#xff0c;不只是数据泄露的问题&#xff1a;攻击者可以远程锁定你的所有 Apple 设备并勒索解锁&#xff0c;可以通过&q…

作者头像 李华
网站建设 2026/7/7 16:56:12

运动跟踪系统硬件选型与6DoF传感器应用实践

1. 从零构建运动跟踪系统的硬件选型思考 当我第一次接触运动跟踪项目时&#xff0c;面对市场上琳琅满目的传感器和微控制器&#xff0c;着实有些无从下手。经过多次迭代验证&#xff0c;ASM330LHH和PIC18F46K22的组合逐渐显现出独特优势。这个搭配不是偶然&#xff0c;而是基于…

作者头像 李华
网站建设 2026/7/7 16:55:46

BilibiliDown:3步解锁B站视频自由,建立你的个人数字图书馆

BilibiliDown&#xff1a;3步解锁B站视频自由&#xff0c;建立你的个人数字图书馆 【免费下载链接】BilibiliDown (GUI-多平台支持) B站 哔哩哔哩 视频下载器。支持稍后再看、收藏夹、UP主视频批量下载|Bilibili Video Downloader &#x1f633; 项目地址: https://gitcode.c…

作者头像 李华
网站建设 2026/7/7 16:50:56

终极Windows和Office激活指南:KMS_VL_ALL_AIO一站式解决方案

终极Windows和Office激活指南&#xff1a;KMS_VL_ALL_AIO一站式解决方案 【免费下载链接】KMS_VL_ALL_AIO Smart Activation Script 项目地址: https://gitcode.com/gh_mirrors/km/KMS_VL_ALL_AIO KMS_VL_ALL_AIO是一款功能强大的智能激活脚本&#xff0c;专为Windows和…

作者头像 李华