Detectron2导出ONNX模型做边界框推理报错AliasWithName如何解决
完全可以基于ONNX格式的Detectron2模型实现边界框推理,你遇到的报错和推理失败问题,根源是导出方式和适配流程不对,不是能力不支持。
你触发的AliasWithName is not a registered function/op报错,是因为用官方默认Caffe2Tracer导出的ONNX模型,绑定了多个Caffe2专属的自定义算子,这些算子不在ONNX标准算子集里,ONNX Runtime、TensorRT这类通用推理引擎没有对应实现,自然加载运行失败。这类算子本身大多是Caffe2框架用来做张量标记、流程调度的占位符,没有实际数值计算逻辑。
- 导出路径选错:默认导出接口是专门给Caffe2运行时做的,本身就不兼容其他推理引擎,官方文档里已经明确说明这点
- 推理流程缺失预处理:你直接把cv2读取的原始BGR图像喂给模型,没有做尺寸对齐、归一化、维度转换,就算算子问题解决了,也会因为输入格式不匹配得到错误结果
1. 替换导出方式,剔除Caffe2专属算子
不要用默认的Caffe2Tracer导出流程,换用面向通用推理场景的导出逻辑:
- 导出时关闭Caffe2专属算子生成开关,选择opset 11及以上版本的ONNX标准算子集
- 导出过程中直接移除
AliasWithName这类无计算逻辑的Caffe2专属占位算子 - 检测头的边界框解码、NMS逻辑如果用了自定义Caffe2算子,要么替换成ONNX标准算子实现,要么直接把这部分后处理逻辑拆到模型外,导出时只保留主干网络+检测头的张量计算部分
- 嫌手动改导出逻辑麻烦的,可以先走Detectron2官方的TorchScript导出流程,再从TorchScript模型转ONNX,这个路径生成的模型默认不会带Caffe2专属算子,适配成本低很多
2. 简化并校验模型结构
导出得到初始ONNX模型后,用onnx-simplifier工具做结构简化,自动裁剪冗余算子、折叠常量,执行命令如下:
pip install onnx-simplifier python -m onnxsim test.onnx test_sim.onnx
简化完成后再用onnx.checker.check_model()做结构校验,确认模型里没有未注册的自定义算子。
3. 补全推理前处理逻辑
cv2读取的图像默认是BGR通道顺序、HWC维度排列、0-255取值范围的uint8格式,和模型要求的输入格式不匹配,喂入模型前必须做和训练阶段一致的预处理:
import cv2 import numpy as np # 以下参数替换成你自己模型训练时使用的配置 INPUT_HEIGHT = 800 INPUT_WIDTH = 1216 PIXEL_MEAN = np.array([103.53, 116.28, 123.675], dtype=np.float32).reshape(1, 1, 3) PIXEL_STD = np.array([57.375, 57.12, 58.395], dtype=np.float32).reshape(1, 1, 3) img = cv2.imread("img.png") origin_h, origin_w = img.shape[:2] # resize到模型要求的输入尺寸 img_resized = cv2.resize(img, (INPUT_WIDTH, INPUT_HEIGHT)) # 按训练配置做归一化 img_normalized = (img_resized.astype(np.float32) - PIXEL_MEAN) / PIXEL_STD # 转为CHW维度排列,增加batch维度 input_tensor = np.transpose(img_normalized, (2, 0, 1))[np.newaxis, ...]
4. 对接后处理逻辑
如果你导出时把边界框解码、置信度过滤、NMS逻辑拆到了模型外,拿到模型输出的原始预测结果后,手动完成这部分计算,再把预测框坐标从模型输入尺寸映射回原图尺寸,就能得到最终的边界框推理结果。
注意:如果是用新版本Detectron2,官方已经提供了面向通用ONNX推理的导出API,不需要手动改算子逻辑,只要导出时指定运行时为ONNX Runtime即可,不用再走老的Caffe2Tracer路径。
内容的提问来源于stack exchange,提问作者Vitor Bento

