alibaba / MNN

MNN is a blazing fast, lightweight deep learning framework, battle-tested by business-critical use cases in Alibaba
http://www.mnn.zone/
8.76k stars 1.67k forks source link

语义分割模型在AMD处理器上opencl推理结果错误,cpu推理正常 #3047

Open youngestuser opened 1 month ago

youngestuser commented 1 month ago

1、windows系统下,cpu推理正常,AMD核显opencl推理结果错误,使用MNN版本为2.8.1 cpu推理结果: image opencl推理结果: image

2、模型文件 res.zip 3、输入张量名“src”,大小[1,3,144,256],预处理对输入图片执行一个resize操作到模型输入大小,然后像素值标准化到0~1之间,means为0.f, norm为1.f/255.f,转换为nchw输入

youngestuser commented 1 month ago

MNN 1.2.0版本和2.9.0版本同样也能复现这样的结果

hebangwen commented 1 month ago

你好,我最近也发现了一个类似的问题。使用你当前提供的模型,用 backendTest.out 测试正确性如下:

-> % ./backendTest.out res.mnn 3 0.05 0
Test forward type: 3
Tolerance Rate: 0.050000
Open Model res.mnn
The device supports: i8sdot:0, fp16:0, i8mm: 0, sve2: 0
Input: 128,72,8,1
precision=0 in main, 280
modeNum=1 in main, 285
stopOp.c_str()=s  in main, 290
238: 0.232422 != 0.275364
input.335_raster_1 - 0 is error

发现是 335 的 Pooling3D 算子出错。

经过一路排查,发现原因是一路计算下来的误差累计,最后在这一个算子误差超过限制而报错,而不是这个算子实现有误。因为 MNN 对非 MALI 和 INTEL GPU 使用 IMAGE 数据结构,对精度有影响。解决方案是,不要使用 IMAGE 而是使用 BUFFER。如下,

if (config.type == MNN_FORWARD_OPENCL) {
  // 这样会将内部的 memory type 设为 buffer 而不是默认的 image
  config.mode = 1 << 6;
} else {
  config.numThread = 4;
}

测试如下。

-> % ./backendTest.out res.mnn 3 0.05 0 64
Test forward type: 3
Tolerance Rate: 0.050000
Open Model res.mnn
The device supports: i8sdot:0, fp16:0, i8mm: 0, sve2: 0
Input: 128,72,8,1
precision=0 in main, 280
modeNum=64 in main, 285
stopOp.c_str()=s  in main, 290
set multi tuning mode is not permitted, please check cl_mode:40!
Correct ! Run second pass
Correct !