Toybrick

标题: 使用C语言在RV1126部署in8模型的问题 [打印本页]

作者: hjh2008    时间: 2023-8-4 15:22
标题: 使用C语言在RV1126部署in8模型的问题
已经参考文档在RV1126上用C语言部署了uint8(asymmetric_quantized-u8量化)的模型,文档说对于有些量化模型而言,dynamic_fixed_point-i8 量化的精度比 asymmetric_quantized-u8 高。所以我用rknn-toolkit 1.7.3 转换了int8版本的模型,该int8模型用python测试推理结果是正确的。于是我参考uint8的C语言部署代码(RK没有给出int8的代码只给出了uint8的代码)编写了int8的推理代码,部署到板子上进行推理,结果是错误的(找到很多框框,没有一个框框是正确的)。


我感觉int8和uint8的推理代码差别主要是在量化和反量化上,以下是我们的量化和反量化的代码:
  1. static int8_t qnt_f32_to_i8(float f32, int8_t fl)
  2. {
  3.     float dst_val = f32 * pow(2, fl);
  4.     int8_t res = (int8_t)__clip(dst_val, -128, 127);
  5.     return res;
  6. }

  7. static float deqnt_i8_affine_to_f32(int8_t qnt, int8_t fl)
  8. {
  9.     return (float)qnt / pow(2, fl);
  10. }

  11. static int process_i8(int8_t *input, int *anchor, int anchor_per_branch, int grid_h, int grid_w, int height, int width, int stride,
  12.                    std::vector<float> &boxes, std::vector<float> &boxScores, std::vector<int> &classId,
  13.                    float threshold, int8_t fl, MODEL_TYPE yolo)
  14. {
  15.     int validCount = 0;
  16.     int grid_len = grid_h * grid_w;
  17.     float thres = threshold;
  18.     int8_t thres_i8 = qnt_f32_to_i8(thres, fl);
  19.     // printf("threash %f\n", thres);
  20.     // printf("thres_u8 %u\n", thres_u8);
  21.     // printf("scale %f\n", scale);
  22.     // printf("zp %u\n", zp);

  23.     for (int a = 0; a < anchor_per_branch; a++)
  24.     {
  25.         for (int i = 0; i < grid_h; i++)
  26.         {
  27.             for (int j = 0; j < grid_w; j++)
  28.             {
  29.                 int8_t box_confidence = input[(PROP_BOX_SIZE * a + 4) * grid_len + i * grid_w + j];
  30.                 if (box_confidence >= thres_i8)
  31.                 {
  32.                     // printf("box_conf %u, thres_u8 %u\n", box_confidence, thres_u8);
  33.                     int offset = (PROP_BOX_SIZE * a) * grid_len + i * grid_w + j;
  34.                     int8_t *in_ptr = input + offset;

  35.                     int8_t maxClassProbs = in_ptr[5 * grid_len];
  36.                     int maxClassId = 0;
  37.                     for (int k = 1; k < OBJ_CLASS_NUM; ++k)
  38.                     {
  39.                         int8_t prob = in_ptr[(5 + k) * grid_len];
  40.                         if (prob > maxClassProbs)
  41.                         {
  42.                             maxClassId = k;
  43.                             maxClassProbs = prob;
  44.                         }
  45.                     }

  46.                     float box_conf_f32 = deqnt_i8_affine_to_f32(box_confidence, fl);
  47.                     float class_prob_f32 = deqnt_i8_affine_to_f32(maxClassProbs, fl);
  48.                     float limit_score = 0;
  49.                     limit_score = box_conf_f32* class_prob_f32;

  50.                     // printf("limit score: %f\n", limit_score);
  51.                     if (limit_score > threshold){
  52.                         float box_x, box_y, box_w, box_h;
  53.                         if(yolo == YOLOX){
  54.                             box_x = deqnt_i8_affine_to_f32(*in_ptr, fl);
  55.                             box_y = deqnt_i8_affine_to_f32(in_ptr[grid_len], fl);
  56.                             box_w = deqnt_i8_affine_to_f32(in_ptr[2 * grid_len], fl);
  57.                             box_h = deqnt_i8_affine_to_f32(in_ptr[3 * grid_len], fl);
  58.                             box_w = exp(box_w)* stride;
  59.                             box_h = exp(box_h)* stride;
  60.                         }   
  61.                         else{
  62.                             box_x = deqnt_i8_affine_to_f32(*in_ptr, fl) * 2.0 - 0.5;
  63.                             box_y = deqnt_i8_affine_to_f32(in_ptr[grid_len], fl) * 2.0 - 0.5;
  64.                             box_w = deqnt_i8_affine_to_f32(in_ptr[2 * grid_len], fl) * 2.0;
  65.                             box_h = deqnt_i8_affine_to_f32(in_ptr[3 * grid_len], fl) * 2.0;
  66.                             box_w = box_w * box_w;
  67.                             box_h = box_h * box_h;
  68.                         }
  69.                         box_x = (box_x + j) * (float)stride;
  70.                         box_y = (box_y + i) * (float)stride;
  71.                         box_w *= (float)anchor[a * 2];
  72.                         box_h *= (float)anchor[a * 2 + 1];
  73.                         box_x -= (box_w / 2.0);
  74.                         box_y -= (box_h / 2.0);

  75.                         boxes.push_back(box_x);
  76.                         boxes.push_back(box_y);
  77.                         boxes.push_back(box_w);
  78.                         boxes.push_back(box_h);
  79.                         boxScores.push_back(box_conf_f32* class_prob_f32);
  80.                         classId.push_back(maxClassId);
  81.                         validCount++;
  82.                     }
  83.                 }
  84.             }
  85.         }
  86.     }
  87.     return validCount;
  88. }
复制代码

请问问题出在哪里? 或者要怎么在RV1126板子上实现int8模型的C语言部署?  谢谢!





欢迎光临 Toybrick (https://t.rock-chips.com/) Powered by Discuz! X3.3