4. 推理框架与运行时

在自动驾驶异构算力平台上,模型训练完成并不等于可以直接高效推理。真正决定“模型能否跑起来、跑得多快、能否跨芯片复用”的,是推理框架与运行时这一层。它承担模型解析、图优化、算子调度、内存规划、内核选择与设备绑定等职责。同一份 ONNX 模型,交给不同运行时,可能得到数倍性能差异,甚至出现部分算子无法执行、精度漂移或回退到 CPU 的情况。因此,理解主流推理框架的部署流程与异构支持边界,是调度工程的基础能力。

核心原理:运行时如何把模型变成异构内核

推理运行时通常遵循“前端解析—中间表示—图优化—内核选择—执行调度”的链路。前端负责把 ONNX、PyTorch、TensorFlow 等格式转换为内部图;中间表示用于统一算子语义;图优化包括常量折叠、算子融合、布局转换、量化插入;内核选择则根据目标设备能力,从预编译内核库或即时编译中挑选实现;执行调度负责流、事件、内存池与设备间同步。

异构支持的关键在于“设备抽象层”和“内核后端”。TensorRT 面向 NVIDIA GPU,通过 builder 生成序列化 engine,内核由 cuDNN、cuBLAS 及自研融合内核提供;ONNX Runtime 采用 Execution Provider 机制,CPU、CUDA、TensorRT、OpenVINO、ROCm 等以 EP 形式挂载;TVM 通过 Relay 图与 TE 张量表达式,借助 AutoTVM/Ansor 为不同目标生成代码;OpenVINO 面向 Intel CPU、iGPU、NPU,使用 IR 中间表示与插件式设备管理;厂商 SDK 如地平线、黑芝麻、寒武纪则提供私有图编译器与量化工具链,通常只支持自家芯片。

推理框架部署流程与异构支持全景 训练模型 ONNX / PyTorch / TF TensorRT Builder→Engine INT8/FP16 校准 ONNX Runtime Execution Provider 图分割与回退 TVM Relay + TE AutoTVM/Ansor OpenVINO IR + 插件设备 CPU/iGPU/NPU 厂商 SDK 私有编译器 量化工具链 中间表示与图优化:常量折叠 · 算子融合 · 布局转换 · 量化插入 · 内存复用 各框架在此层差异最大,决定跨芯片迁移成本 异构硬件与设备抽象层 NVIDIA GPU Intel CPU/iGPU/NPU ARM / 车载 SoC 地平线 / 黑芝麻 寒武纪 / 其他 NPU 推理调度运行时:流 / 事件 / 内存池 / 设备绑定 / 多模型并发 CUDA Stream / Graph OpenVINO Async Infer TVM Graph Executor 厂商 Runtime API 部署流程 异构支持

方法流程:从模型到可执行引擎

以 TensorRT 为例,典型流程为:导出 ONNX → 解析网络 → 设置 builder 配置(精度、workspace、DLA)→ 选择校准集做 INT8 校准 → 生成并序列化 engine → 运行时反序列化并绑定输入输出。ONNX Runtime 则更轻量:加载模型 → 创建 SessionOptions → 按优先级注册 Execution Provider → 运行 Session。TVM 需要先 Relay 导入,再 target 指定设备,最后 build 出模块。OpenVINO 使用 Model Optimizer 或直接读取 ONNX,转换为 IR 后由 Core 加载到指定设备。厂商 SDK 通常要求先做量化校准,再用私有编译器生成离线模型。

# ONNX Runtime 注册多 EP 的典型顺序
sess_options = ort.SessionOptions()
sess_options.graph_optimization_level = ort.GraphOptimizationLevel.ORT_ENABLE_ALL
session = ort.InferenceSession(
    "model.onnx",
    sess_options,
    providers=["TensorrtExecutionProvider",
               "CUDAExecutionProvider",
               "CPUExecutionProvider"])

案例场景:同一模型跨三平台部署

某 BEV 感知模型需同时部署到 NVIDIA Orin、Intel 车载 CPU 与地平线 J5。在 Orin 上使用 TensorRT,FP16 下延迟约 18ms;在 Intel 平台上使用 OpenVINO,通过 iGPU 加速后约 35ms;在地平线 J5 上必须使用厂商 SDK,经过 INT8 量化后约 22ms。三者的共同点是都从 ONNX 出发,但图优化策略、量化方式和内存布局完全不同。若直接复用 TensorRT engine 到其他平台,必然失败。因此调度工程需要维护“模型—框架—芯片”三元映射表,并在编译期完成设备绑定。

框架 输入格式 异构支持 量化能力 典型部署方式
TensorRT ONNX / Caffe NVIDIA GPU、DLA FP16、INT8 校准 序列化 engine 离线加载
ONNX Runtime ONNX CPU、CUDA、TRT、OpenVINO 等 EP 动态量化、静态量化 Session + Provider 注册
TVM ONNX / Relay CPU、GPU、NPU、FPGA Relay 量化 + 自动调优 编译为 so / 离线模块
OpenVINO ONNX / IR Intel CPU、iGPU、NPU NNCF 量化感知训练 Core 加载 IR 到设备
厂商 SDK ONNX / 私有格式 仅自家芯片 私有量化工具链 离线编译 + Runtime API

误区与复盘

误区一:认为 ONNX 是“万能中间格式”。ONNX 只保证算子语义,不保证每个运行时都支持全部算子。遇到不支持算子时,ONNX Runtime 会回退到 CPU,TensorRT 可能直接报错,厂商 SDK 则可能要求替换算子。

误区二:忽略量化校准集分布。INT8 校准若使用与真实场景差异大的数据,精度会显著下降。校准集应覆盖夜间、雨天、逆光等自动驾驶长尾场景。

误区三:把框架选择当成纯性能问题。实际上还要考虑芯片锁定、工具链成熟度、团队维护成本和 OTA 升级路径。多平台项目应优先选择 EP 机制灵活的 ONNX Runtime 作为统一入口,再按设备下沉到专用运行时。

复盘建议:建立“模型—框架—芯片—精度—延迟”五维台账,每次新增车型或芯片时,先做算子支持性扫描,再做量化精度回归,最后做端到端延迟压测。只有把运行时差异显式管理起来,异构算力调度才不会在集成阶段失控。