Toybrick

关于pass_through=1时,推理结果错误问题

NeonEcho

新手上路

积分
13
楼主
发表于 6 小时前    查看: 60|回复: 0 | [复制链接]    打印 | 只看该作者
本帖最后由 NeonEcho 于 2025-10-16 17:02 编辑

平台:RK3588  
NPU:2.2
driver:0.9.2

1. 起因是rknn_input_set接口耗时比较长(2ms),后面查到pass_through=0,也就是rknn内部帮助进行了预处理工作,于是我想自己进行预处理,将pass_through置为1;
2.查阅官方文档,发现rknn_input_set可能会做三个操作:类型转换,归一化,量化,按照这个思路进行预处理
3. 该模型在量化的时候,采用混合量化,rknn.config没有配置均值和方差,即没有归一化操作
  1. 量化代码:
  2. rknn.config(mean_values=None, std_values=None, target_platform="rk3588",
  3.                  quantized_algorithm="mmse",
  4.                  quantized_method='channel',
  5.                  optimization_level=3)
  6. ret = rknn.load_onnx(model=ONNX_MODEL,
  7.                          input_size_list=[[3, 127, 127], [3, 255, 255]])
  8. ret = rknn.build(do_quantization=QUANTIZE_ON, dataset=DATASET)
  9. ret = rknn.export_rknn(RKNN_MODEL)
复制代码
4. 该模型输入为FP16数据,输入数据分布为NHWC,但是没有进行量化
  1. <font color="#ff00ff">query输出:</font>
  2. index=0, name=input_z, n_dims=4, dims=[1, 127, 127, 3], n_elems=48387, size=96774, fmt=NHWC, type=FP16, qnt_type=AFFINE, zp=0, scale=1.000000
  3. index=1, name=input_x, n_dims=4, dims=[1, 255, 255, 3], n_elems=195075, size=390150, fmt=NHWC, type=FP16, qnt_type=AFFINE, zp=0, scale=1.000000
复制代码
5. 也就是说,我只需要将输入改为FP16即可,这里为了方便对比,我把pass_through=0时的代码也放出来
pass_through = 0:
  1. v3_input[i].index  = i;
  2.             v3_input[i].type = RKNN_TENSOR_UINT8;
  3.             v3_input[i].size = width_v3[i] * height_v3[i] * channel_v3[i] * sizeof(uint8_t);
  4.             v3_input[i].fmt = RKNN_TENSOR_NHWC;
  5.             v3_input[i].pass_through = 0;
  6. v3_input[1].buf = (void*)x_crop.data;     // x_crop和z_mat是imread读取的CV_8UC3数据,未作处理
  7. v3_input[0].buf = (void*)z_mat.data;
  8. rknn_inputs_set(v3_ctx, v3_io_num.n_input, v3_input);
复制代码
pass_through = 1:
  1. v3_input[i].index  = i;
  2. v3_input[i].type = RKNN_TENSOR_FLOAT16;
  3. v3_input[i].size = width_v3[i] * height_v3[i] * channel_v3[i] * sizeof(float16_t);
  4. v3_input[i].fmt = RKNN_TENSOR_NHWC;
  5. v3_input[i].pass_through = 1;
  6. x_crop.convertTo(x_crop, CV_16FC3, 1.0);   // 多了类型转换
  7. z_mat.convertTo(z_mat, CV_16FC3, 1.0);
  8. v3_input[1].buf = (void*)x_crop.data;     // x_crop和z_mat是imread读取的CV_8UC3数据,未作处理
  9. v3_input[0].buf = (void*)z_mat.data;
  10. rknn_inputs_set(v3_ctx, v3_io_num.n_input, v3_input);
复制代码

但是输出的数据却不一致,pass_through = 1输出的是错的
  1. 26.7188 31.6562 36.5 43.0312 50.7812 53.0312 43.1875 41.6875 43.6875   // pass_through = 0
  2. 27.6094 34.0312 39.625 44.3125 44.75 47.0625 47.7188 49.125 49.8125  // pass_through = 1
复制代码
虽然数值上差距不大,但是应用上的结果全是错的。
6. 我又进一步做了对比,这次将输入数据设为全0或全255,全0是两次结果一样,符合预期,因为所有的处理对全0都无效了;但是全255的结果就不一样了,这样可以暂时排除通道错误或者颜色错误这种问题,所以应该还是rknn_input_set内部做了什么数值修改的操作

希望版主能帮忙看一下,这个问题已经困扰好几天了,不胜感激。



回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

产品中心 购买渠道 开源社区 Wiki教程 资料下载 关于Toybrick


快速回复 返回顶部 返回列表