• 【SOPHON】算能盒子SE-16的C++模型转换



    本文以 arcface 为例, 介绍如何编译迁移一个onnx模型至TPU平台运行。
    有疑问具体可参考 TPU-MLIR

    ONNX转MLIR

    如果模型是图片输入, 在转模型之前我们需要了解模型的预处理。如果模型用预处理后的npz文件做输入, 则不需要考虑预处理。 预处理过程用公式表达如下:
    在这里插入图片描述
    官网yolov5的图片是rgb, 每个值会乘以 1/255 , 转换成mean和scale对应为 0.0,0.0,0.0 和 0.0039216,0.0039216,0.0039216 。
    基本操作过程是用 model_transform.py 将模型转成mlir文件, 然后用 model_deploy.py 将mlir转成对应的model。
    模型转换示例命令如下:

    #!/bin/bash
    source /workspace/tpu-mlir_v1.2.8-g32d7b3ec-20230802/envsetup.sh
    /workspace/tpu-mlir_v1.2.8-g32d7b3ec-20230802/python/tools/model_transform.py \
        --model_name arcface1 \
        --model_def /workspace/sdk/myarcface/model/arcface1.onnx \
        --input_shapes [[1,3,112,112]] \
        --mean 125.0,125.0,125.0 \
        --scale 0.008,0.008,0.008 \
        --keep_aspect_ratio \
        --pixel_format rgb \
        --output_names prob \
        --pad_type center \
        --pad_value 114 \
        --mlir arcface1.mlir
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    参数表:
    在这里插入图片描述
    注意,所有上述参数,不会附加在模型上直接生效,是提供给算能的程序在int8量化时用的,转换后的模型,还是裸模型。在量化过程中使用平均值(mean)和标准差(std)是为了将浮点数转换为整数表示时,确保量化后的数据可以在整个数据集上保持足够的动态范围和信息表达能力。标准化是通过减去均值并除以标准差的方式,将数据映射到以0为中心的分布,进而将数据转换为一个新的分布,使得量化后的数据在整个范围内都可以保留较高的精度。
    这部分参数是量化参数,应该与后续stream中的预处理参数保持一致,并与训练时的参数保持一致。

    指定模型的预处理过程

        imagenet_mean = [0.5, 0.5, 0.5]
        imagenet_std = [0.5, 0.5, 0.5]
        image = cv2.imread(image, cv2.IMREAD_COLOR)
        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        image = image / 255.0
        image = (image - imagenet_mean) / imagenet_std
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    模型的输入是:1, 3, 112, 112
    由上可知,模型接收的是rgb图片

    image = (image / 255.0 - imagenet_mean) / imagenet_std
    =(image - imagenet_mean*255.0) / (imagenet_std*255.0)
    =(image - imagenet_mean*255.0) *(1/(imagenet_std*255.0))
    
    • 1
    • 2
    • 3

    对应有:

    #!/bin/bash
    #!/bin/bash
    source /workspace/tpu-mlir_v1.2.8-g32d7b3ec-20230802/envsetup.sh
    /workspace/tpu-mlir_v1.2.8-g32d7b3ec-20230802/python/tools/model_transform.py \
        --model_name arcface1 \
        --model_def /workspace/sdk/myarcface/model/arcface1.onnx \
        --input_shapes [[1,3,112,112]] \
        --mean 125.0,125.0,125.0 \
        --scale 0.008,0.008,0.008 \
        --keep_aspect_ratio \
        --pixel_format rgb \
        --output_names prob \
        --pad_type center \
        --pad_value 114 \
        --mlir arcface1.mlir
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    注:算能不推荐使用动态batch,会损失性能
    –keep_aspect_ratio出现即生效

    注:opencv的内存排布

    实际上,在OpenCV中,图像的维度顺序是(height, width, channels),其中height表示图像的高度,width表示图像的宽度,channels表示图像的通道数。这个顺序是按照常见的习惯和约定来定义的,使得在处理图像时能更加直观和方便地使用。所以,正确的顺序是先高度再宽度,

    转换结果

    2023/10/27 17:50:57 - INFO : 
             _____________________________________________________ 
            | preprocess:                                           |
            |   (x - mean) * scale                                  |
            '-------------------------------------------------------'
      config Preprocess args : 
            resize_dims           : same to net input dims
            keep_aspect_ratio     : True
            keep_ratio_mode       : letterbox
            pad_value             : 114
            pad_type              : center
            --------------------------
            mean                  : [125.0, 125.0, 125.0]
            scale                 : [0.008, 0.008, 0.008]
            --------------------------
            pixel_format          : rgb
            channel_format        : nchw
    
    --------------------------------
    Before assigning input_shape:
    True
    True
    Run onnxsim 1 times, model simplified: True
    --------------------------------
    After assigning input_shape:
    True
    True
    Run onnxsim 1 times, model simplified: True
    --------------------------------
    Save mlir file: arcface512_origin.mlir
    [Running]: tpuc-opt arcface512_origin.mlir --shape-infer --canonicalize --extra-optimize -o arcface512.mlir 
    [Success]: tpuc-opt arcface512_origin.mlir --shape-infer --canonicalize --extra-optimize -o arcface512.mlir 
    Mlir file generated:arcface512.mlir
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    接着将mlir文件转为16fp的半精度文件

    同目录下新建文件,写入:

    #!/bin/bash
    source /workspace/tpu-mlir_v1.2.8-g32d7b3ec-20230802/envsetup.sh
    /workspace/tpu-mlir_v1.2.8-g32d7b3ec-20230802/python/tools/model_deploy.py \
        --mlir /workspace/sdk/myarcface/model/arcface1.mlir \
        --chip bm1684x \
        --quantize F16 \
        --model arcface1.model
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    运行即得到最终的fp16模型。

  • 相关阅读:
    【电场】基于模拟电荷法计算输电线路铁塔周围电场分布附matlab代码
    大语言模型架构---Transformer 模型
    面试题 01.04. 回文排列
    【JAVA设计模式】适配器模式
    前端技能树,面试复习第 54 天—— 手写代码:情景题
    多级缓存之缓存同步
    FFmpeg -r 放在 -i 前后的区别
    “华为杯”第十三届中国研究生 数学建模竞赛-B题:具有遗传性疾病和性状的遗传位点分析(续)(附SAS代码实现)
    C语言 位操作
    关于KMP模式匹配的一些思考
  • 原文地址:https://blog.csdn.net/hh1357102/article/details/134077679