起因
有学习我《深度学习课路线图》课程的学员给我反馈说:“训练了一个自定义的YOLO11模型,但是因为修改了输入,导致导出了ONNX格式模型部署一直不正确,调用PT模型可以正常工作”。于是我让他把模型发给我试试,然后我直接用他的代码运行,发现真的什么结果都没有,跟他遇到的问题完全一致,我晕倒。

右边是PT文件推理结果,左边是ORT推理结果
查找与测试
我发现它修改了模型的输入格式从640改为960了,于是我对着我的onnxruntime代码一通改以后,惊讶的发现,我的onnxruntime部署代码是可以推理的,运行结果如下:

对比一下格式发现源码发现,原因预处理方法不一致导致的推理不正确。
然后我就想用我的OpenVINO™2025 C++的代码试试是否可以运行,修改了输入格式,直接加载以后,运行发现什么都没有,只看到右下角有个框,,这个是什么鬼,难道是因为OpenVINO™推理不行吗?不太可能啊!ONNXRUNTIME可以,OpenVINO™肯定也可以,于是我走查一下OpenVINO™ C++代码,发现最近我只改过预处理部分,就是参考新预处理方式把之前的一堆代码改为两行了。之前的代码如下:
size_t image_size = input_w * input_h;cv::Mat blob_image;resize(image, blob_image, cv::Size(input_w, input_h));cv::cvtColor(blob_image, blob_image, cv::COLOR_BGR2RGB);blob_image.convertTo(blob_image, CV_32F);blob_image = blob_image / 255.0;// NCHW 设置输入图象数据float* data = input_tensor.data<float>();for (size_t row = 0; row < input_h; row++) {for (size_t col = 0; col < input_w; col++) {for (size_t ch = 0; ch < 3; ch++) {data[image_size * ch + row * input_w + col] = blob_image.at<cv::Vec3f>(row, col)[ch];}}}
我修改之后的代码如下:
cv::Mat blob = cv::dnn::blobFromImage(image, 1.0 / 255.0, cv::Size(input_w, input_h), cv::Scalar(), true, false);memcpy(input_tensor.data<float>(), blob.ptr<float>(), data_s);
我怀疑我修改的memcpy有问题,于是把恢复到以前的代码,奇迹出现了,模型推理可以正常工作了,然后我就知道了是因为我的memcpy使用问题,之前没有太注意内存copy的数据类型,于是我把之前的内存拷贝代码从:
memcpy(input_tensor.data<float>(), blob.ptr<float>(), data_s);
改为:
memcpy(input_tensor.data<float>(), blob.ptr<float>(), data_s*sizeof(float));
奇迹又出现,一切OK,BUG改好了。

总结
任何时候使用memcpy内存拷贝函数时,最后一个参数一定记得写成
n * sizeof(type_name)
拷贝的是浮点数,就写成:
n*sizeof(float)
拷贝的是整形,就写成:
n*sizeof(int)
C++内存拷贝使用不当致模型部署问题

被折叠的 条评论
为什么被折叠?



