当前位置: 首页 > article >正文

Sophon边缘盒数据校验及量化

Sophon边缘盒


1 问题定位

1.1 数据校验

在使用Sophon盒子推理时遇到问题:关于识别等模型,使用bmodel和onnx的推理结果差距较大,此时需要确定是否是bmodel推理本身有问题,所以需要数据校验。🎯需要使用tpu-mlir工具

  1. 将程序读取的图像数据保存到txt中:

    bm_device_mem_t input_dev_mem;
    //从多个内存连续的image中得到连续内存的device memory信息
    bm_image_get_contiguous_device_mem(image_n, m_converto_imgs.data(), &input_dev_mem);
    std::vector<cv::Mat> convert_img_vec;
    for(auto convertto_img : m_converto_imgs)
    {
        float *buffer = new float[convertto_img.width * convertto_img.height *3];
        // 将bm_image类型的convertto_img从NPU拷贝至CPU,然后遍历保存
        // 为什么不直接读取convertto_img进行保存,因为其数值在NPU中的,所以其存储方式为bbbbbbbbbgggggggggggrrrrrrrrrrrrrr的形式
        bm_image_copy_device_to_host(convertto_img, (void**)&buffer);
        int64_t start = (int64_t)(std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch()).count());
        std::ofstream outfile(std::to_string(start)+ "_ng.txt");
    
        outfile << convertto_img.height << " " << convertto_img.width << " " << 3 << std::endl;
        // 其数据维度为(height, width*3),且由于是从NPU上拷贝的,所以其数据格式为
        for (int i = 0; i < convertto_img.height; ++i)
        {
            for (int j = 0; j < convertto_img.width; ++j)
            {
                for (int c = 0; c < 3; ++c)
                {
                    // 按照121*channel为一行的像素排列方式,遍历换行时需要考虑channel
                    // 虽然每次写入三个数据,但实际上的存储是全存b,然后全存g,最后全存r的方式,并不是交叉
                    outfile << (float)(*(buffer + i * convertto_img.width * 3 + j * 3 + c))<< " ";
                }
            }
            outfile << std::endl;
        }
        outfile.close();
        delete[] buffer;
    
        // bm_image_get_data(convertto_img, buffer);
        // cv::Mat resized_img(convertto_img.height, convertto_img.width, CV_32FC3, buffer);
        // convert_img_vec.push_back(resized_img);
    }
    
  2. 将txt转换为npz:

    import numpy as np
    
    # 读取txt文件中的数据
    data = np.loadtxt('./txt_file/1713921805509691_ng.txt')
    # 将数据保存为npz格式
    np.savez('./txt_file/1713921805509691_ng.npz', data=data)
    
  3. 分别调用onnx和bmodel加载图像数据进行推理,校验bmodel是否有问题:

    # 样例
    python model_runner.py --input input.npz --model xxx.bmodel --output bmodelout.npz
    python model_runner.py --input input.npz --model xxx.onnx --output onnx.npz
    python npz_tool.py compare onnxout.npz bmodelout.npz
    

    4.由于刚才保存图像数据时是二维的形式,而模型的输入要求4维,所以可能会报错onnxruntime.capi.onnxruntime_pybind11_state.InvalidArgument: [ONNXRuntimeError] : 2 : INVALID_ARGUMENT : Invalid rank for input: images Got: 2 Expected: 4 Please fix either the inputs or the model.则需要在model_runner.py中将输入的数据拉伸为4维。(由于图像数据保存的形式是bbbbbbbbgggggggggrrrrrrrr,所以可以直接拉伸为3通道的h*w图像)

    data[name] = data[name].flatten()
    data[name] = data[name].reshape(1, 3, 32, 128)  # 根据onnx模型的实际输入进行拉伸
    

    5.分别执行推理:

    # 实际(model_runner.py在./tpu-mlir_v1.7.beta.103-g4d1b1430b-20240507/python/tools路径下)
    python model_runner.py --input 1713923372730797_ng.npz --model asset_tag_rec_int_20240415.onnx --output onnx_tag_int_20240415.npz
    python model_runner.py --input 1713923372730797_ng.npz --model asset_tag_rec_int_20240415_BM1684.bmodel --output bmodel_tag_int_20240415.npz
    
    # 直接打开生成的两个推理npz格式的推理结果进行比对即可。
    

2 模型量化

Tpu-mlir参考文档:Tpu-Mlir参考文档

2.1 Tpu-Mlir量化流程

  1. 生成mlir文件:

    python3 ./tpu-mlir_v1.7.beta.103-g4d1b1430b-20240507/python/tools/model_transform.py \
        --model_name plate_rec_20230406 \
        --model_def ./plate_rec_20230406.onnx \
        --input_shapes [[1,3,96,288]] \
        --mean 123.675,116.28,103.53 \
        --scale 0.017125,0.017507,0.017429 \
        --keep_aspect_ratio \
        --pixel_format rgb \
        --mlir ./plate_rec_20230406.mlir
    

    2.使用部分训练集构建量化校验表cali_table(100-200张即可):

    python ./tpu-mlir_v1.7.beta.103-g4d1b1430b-20240507/python/tools/run_calibration.py plate_rec_20230406.mlir \
        --dataset ./workspace/sophon_model_quality/calibration_npz/plate_rec_npz/ \
        --input_num 200 \
        --tune_num 5 \
        -o ./plate_rec_20230406_cali_table
    

    3.挑选敏感层(挑选出(F32->INT8)中影响较大的层,不进行量化,避免过大的精度损失)生成qtable:

    • 自动挑选(调用run_sensitive_layer.py生成qtable):

      python ./workspace/tpu-mlir_v1.7.beta.103-g4d1b1430b-20240507/python/tools/run_sensitive_layer.py face_fea_20230406.mlir --dataset train_img/ --max_float_layers 10 --calibration_table face_fea_cali --chip bm1684x --fp_type F32 -o face_fea_qtable
      
    • 手动挑选:

      • 首先在onnx中搜索Concat,然后找到最后一个Concat节点。
      • 找到此节点前的Conv层,然后将这些Conv层的完整"name",注意不是"outputs"在mlir中进行搜索,记录匹配的层,然后当做参数运行fp_forward.py脚本生成qtable。
      • 若找到的层在mlir中没有被匹配到,则可以直接查看第一步中生成的mlir文件,由后向前查找Conv层。`⚠️指定的层之后的层不会参与量化,仍保持FP32精度。所以高精度就指定稍微偏前面的Conv层,高速度就执行最后的Conv。
 # 指定的层使用","隔开
  python ./workspace/tpu-mlir_v1.7.beta.103-g4d1b1430b-20240507/python/tools/fp_forward.py ./fire_extinguisher_dete_20240222.mlir --fpfwd_outputs onnx::Concat_350_Conv,onnx::Concat_357_Conv,onnx::Concat_335_Conv --fp_type F32 -o ./fire_ext_v8_qtable --chip bm1684x

​ 4.利用处理后的量化表生成模型:

python ./workspace/tpu-mlir_v1.7.beta.103-g4d1b1430b-20240507/python/tools/model_deploy.py \
    --mlir ./wl_light_flash_dete_v24.10.22.mlir \
    --quantize INT8 \
    --calibration_table ./wl_light_flash_dete_v24.10.22_cali_table \
    --chip bm1684x \
    --quantize_table wl_light_flash_dete_v24.10.22_qtable \
    --tolerance 0.99,0.99 \
    --model ./wl_light_flash_dete_v24.10.22_BM1684X.bmodel

http://www.kler.cn/a/516136.html

相关文章:

  • 单调栈详解
  • 计算机视觉算法实战——无人机检测
  • Flutter鸿蒙化中的Plugin
  • 什么是稀疏 MoE?Doubao-1.5-pro 如何以少胜多?
  • 【Vim Masterclass 笔记21】S09L39:Vim 设置与 vimrc 文件的用法示例(二)
  • 循环队列(C语言版)
  • Java拓展学习——Process类的学习和使用
  • mysql 计算2个时间段之间的间距
  • 差分轮算法-两个轮子计算速度的方法-阿克曼四轮小车计算方法
  • 从新手到高手的蜕变:MySQL 视图进阶全攻略
  • 不使用 JS 纯 CSS 获取屏幕宽高
  • 单片机内存管理剖析
  • 【Python模块】使用sys.path查看当前的模块搜索路径
  • Spring AOT
  • 2025-1-20-sklearn学习(42) 使用scikit-learn计算 钿车罗帕,相逢处,自有暗尘随马。
  • Linux网络之TCP
  • GOAT‘S AI早鸟报Part10
  • MFC程序设计(三)MFC程序启动
  • 动态路由协议基础知识
  • JavaScript系列(42)--路由系统实现详解
  • 2025.1.20——二、buuctf BUU UPLOAD COURSE 1 1 文件上传
  • 详解单片机学的是什么?(电子硬件)
  • Redis面试题每日20道【其一】
  • AI智慧社区--生成验证码
  • 【CPH系列】RFID标签读取模块,开发说明文档(包含重要内容和BUG)
  • K8S 启动探测、就绪探测、存活探测