4. 边缘推理框架与模型部署
在边缘推理与PLC控制联动系统中,模型训练通常在服务器或工作站完成,而真正执行推理的往往是工控机、ARM网关、带NPU的视觉控制器或Jetson类设备。不同硬件平台的算力、内存、指令集差异很大,因此“选对推理框架”与“选对模型格式”几乎决定了系统能否稳定运行。本节围绕TensorFlow Lite、ONNX Runtime、OpenVINO、TensorRT四个主流边缘推理框架,说明它们的推理流程、模型转换方式与性能调优要点。
一、四个框架的定位与适用边界
TensorFlow Lite(TFLite)主要面向移动端和低功耗ARM设备,模型以.tflite为容器,支持整型量化,适合PLC网关上的轻量分类、异常检测。ONNX Runtime(ORT)以ONNX为中间表示,跨平台能力最强,可在Windows工控机、Linux ARM、甚至部分PLC的Linux运行时上执行,是“一次转换、多端部署”的首选。OpenVINO针对Intel CPU、集成GPU和VPU优化,在x86工控机上延迟低、部署简单。TensorRT是NVIDIA GPU专用推理编译器,对卷积、矩阵乘等算子做层融合与内核自动调优,适合Jetson或带独显的视觉工位,但模型必须转换为.engine且与GPU型号、TensorRT版本绑定。
二、推理流程的共性结构
四个框架的推理流程在结构上高度一致,可分为五个阶段:加载模型 → 预处理输入 → 执行推理 → 后处理输出 → 与PLC交互。差异主要体现在模型加载方式和执行后端上。以ONNX Runtime为例,典型流程如下:
import onnxruntime as ort
import numpy as np
# 1. 加载模型,指定执行提供器
sess = ort.InferenceSession(
"defect_det.onnx",
providers=["CPUExecutionProvider"] # Jetson 上可换 CUDAExecutionProvider
)
# 2. 查看输入输出名称与形状
for i in sess.get_inputs():
print(i.name, i.shape, i.type) # 例如 images [1,3,224,224] tensor(float)
# 3. 预处理:BGR→RGB、归一化、NCHW
img = preprocess(frame) # 输出 float32, shape (1,3,224,224)
# 4. 推理
outputs = sess.run(None, {"images": img})
cls_id = int(np.argmax(outputs[0]))
conf = float(np.max(outputs[0]))
# 5. 结果写入 PLC 寄存器(示例:置信度 > 0.85 判为缺陷)
if conf > 0.85:
write_plc_register(40001, 1) # 1 = 缺陷
else:
write_plc_register(40001, 0)
TensorFlow Lite使用Interpreter加载.tflite,通过allocate_tensors()分配张量,再用set_tensor与invoke完成推理。OpenVINO通过Core().compile_model()加载IR模型,TensorRT则先反序列化.engine再执行execute_v2。无论哪种框架,预处理与后处理通常占端到端延迟的30%以上,是调优的重点。
三、模型转换的关键操作
模型转换不是简单换格式,而是要在目标硬件上保持精度并提升速度。以下给出四个框架的典型转换命令与注意事项。
| 框架 | 转换入口 | 关键参数 | 注意事项 |
|---|---|---|---|
| TFLite | tf.lite.TFLiteConverter | optimizations=[DEFAULT]、representative_dataset | INT8量化需校准集,算子不支持时需自定义 |
| ONNX Runtime | torch.onnx.export / onnxsim | opset=13、dynamic_axes | 动态轴会增加推理开销,边缘端建议固定形状 |
| OpenVINO | mo --input_model | --data_type=FP16、--input_shape | FP16在iGPU上收益明显,CPU上需确认指令集 |
| TensorRT | trtexec / builder | --fp16、--int8、--workspace | engine与GPU型号、TRT版本强绑定,需在目标机编译 |
以TensorRT为例,在Jetson Orin上编译FP16引擎的示例命令:
trtexec --onnx=defect_det.onnx \
--saveEngine=defect_det_fp16.engine \
--fp16 \
--workspace=2048 \
--minShapes=images:1x3x224x224 \
--optShapes=images:4x3x224x224 \
--maxShapes=images:8x3x224x224
其中--optShapes是性能最优的批大小,--minShapes与--maxShapes定义动态范围。若实际推理批大小偏离optShapes,延迟会明显上升,因此边缘端通常固定批大小为1或2。
四、性能调优的四个抓手
第一,量化。FP32转INT8通常可带来2~4倍加速,但需用代表性校准集。TFLite的representative_dataset、TensorRT的--int8校准、OpenVINO的NNCF量化都遵循这一思路。量化后必须用验证集复核精度,若mAP下降超过2个百分点,应回退到FP16。
第二,算子融合与图优化。TensorRT会自动融合Conv+BN+ReLU,OpenVINO的MO也会做类似优化。ONNX Runtime可通过graph_optimization_level=ORT_ENABLE_ALL开启图优化。若模型中存在大量小算子,融合收益最明显。
第三,输入尺寸与批大小。将输入从640×640降到320×320,计算量约降为1/4,但小目标检测精度会下降。边缘端建议先用trtexec或ORT的benchmark扫描不同尺寸,找到精度与延迟的平衡点。
第四,线程与执行提供器。ORT的intra_op_num_threads、OpenVINO的CPU_THROUGHPUT_STREAMS、TFLite的num_threads都影响CPU利用率。在PLC联动场景中,推理线程不宜占满所有核心,应给通信与PLC扫描留出余量,否则会出现控制周期抖动。
五、与PLC联动的延迟预算
假设PLC控制周期为50 ms,则端到端预算可拆分为:图像采集5 ms、预处理8 ms、推理20 ms、后处理5 ms、通信与PLC写入7 ms,合计45 ms,留有5 ms余量。若推理超过25 ms,应优先降低输入尺寸或启用量化,而不是压缩通信时间。推理结果写入PLC时,建议使用保持寄存器并附加时间戳,PLC侧判断数据是否新鲜,避免使用过期结果触发动作。
.engine放到Jetson上可能反序列化失败,必须在目标设备上重新编译,或将ONNX作为交付物、在部署时现场生成引擎。综上,四个框架并非互斥:可以在训练侧统一导出ONNX,再按目标硬件分别转换为TFLite、OpenVINO IR或TensorRT引擎。选择时优先看硬件与延迟约束,其次看团队对工具链的熟悉程度。把模型转换、量化校准、延迟测量和PLC写入验证纳入同一套部署流程,才能让边缘推理真正服务于产线控制。