陈蓝度
发布于 2026-01-19 / 81 阅读
0
0

将模型转换为全志NPU所支持的格式

模型转换前的准备工作

  1. 创建属于待转换模型的目录,避免后续转换其他模型会带来的混乱。

    比如 ${模型目录} 为 ~/workspace/vivante-acuity-toolkit/yolov5nu

    执行下列命令

     mkdir -p ${模型目录}
    
  2. 获取yolo学习笔记

     git clone https://github.com/hexchip/ultralytics-nootbook.git
    
  3. 启动 jupyter nootbook 容器并挂载学习笔记目录

    比如 ${学习笔记目录} 为 ~/workspace/yolov8-nootbook

    docker run 
    -it \
    --rm \
    -p 8888:8888 \
    --mount type=bind,source=${学习笔记目录},target=/workspace \
    --gpus=all \
    --ipc=host \
    cld1994/ultralytics:8.1.26-jupyter
    

    在浏览器中打开jupyter nootbook:http://127.0.0.1:8888/lab

  4. 获取待转换模型的onnx格式

    我们以获取yolov5nu模型的onnx格式为例

    在浏览器的jupyter nootbook页面中打开 export-onnx.ipynb

    执行!

    执行完成后可以在左侧导航栏的根目录中发现新增的 yolov5nu.onnx

    在主机命令行中执行下列命令放入${模型目录}

     cp ${学习笔记目录}/yolov5nu.onnx ${模型目录}
    
  5. 准备量化所需的数据集和对应的声明文件

    在浏览器的jupyter nootbook页面中打开 download_coco_dataset.ipynb

    逐步执行!

    执行完成后可以在左侧导航栏的根目录中的coco目录下发现新增的 preprocessed 目录
    量化所需的数据集就存放在此目录
    此时,你可以在你的主机中找到它,路径为 ${学习笔记目录}/coco/preprocessed

    同时在左侧导航栏的根目录中发现新增的dataset.txt文件,该文件即量化所需的数据集声明文件。 此时,你可以在你的主机中找到它,路径为 ${学习笔记目录}/dataset.txt

    在主机命令行中执行下列命令放入量化所需的数据集和对应的声明文件

     cp ${学习笔记目录}/dataset.txt ${模型目录}
     mkdir -p ${模型目录}/coco/train2017
     cp ${学习笔记目录}/coco/preprocessed/* ${模型目录}/coco/train2017/
    
  6. 启动 acuity-toolkit 容器并挂载该模型的目录

     docker run \
     -it \
     --rm \
     --mount type=bind,source=${模型目录},target=/workspace \
     cld1994/vivante-acuity-toolkit:6.6.1-ide5.7.0
    

模型转换

进入 acuity-toolkit 容器后执行下列命令

  1. 导入模型

     cd /usr/local/VeriSilicon/acuity-toolkit-binary-6.6.1/bin/
     pegasus import onnx --model ${模型目录}/yolov5nu.onnx
    

    该操作在${模型目录}生成了 yolov5nu.jsonyolov5nu.data

  2. 为模型生成输入元数据文件

     cd ${模型目录}
     pegasus generate inputmeta --model yolov5nu.json
     
    

    该操作在${模型目录}生成了 yolov5nu_inputmeta.yml

  3. 修改yolov5nu_inputmeta.yml 的 scale 参数 为 0.0039216

  4. 先推导一次,目的是与量化后的模型进行精度对比

    pegasus inference \
        --model yolov5nu.json \
        --model-data yolov5nu.data \
        --with-input-meta yolov5nu_inputmeta.yml
    

    该操作生成了两个文件, 分别代表模型的输入张量和输出张量:

    1. iter_0_images_267_out0_1_3_320_320.tensor
    2. iter_0_attach_Concat__model.24_Concat_5_out0_0_out0_1_84_2100.tensor
  5. 将模型进行量化

    其中 --iterations 的值为 dataset.txt 的有效行数

    pegasus quantize \
        --model yolov5nu.json \
        --model-data yolov5nu.data \
        --with-input-meta yolov5nu_inputmeta.yml \
        --algorithm kl_divergence \
        --divergence-first-quantize-bits 11 \
        --quantizer perchannel_symmetric_affine \
        --qtype int8 \
        --iterations 796 \
        --rebuild
    

    该操作生成了量化表⽂件 yolov5nu.quantize

  6. 将模型进行混合量化

    因yolov5nu模型包含了对特征图进行结果处理的算子(比如计算坐标,置信度等),int8量化后误差较大,还需要对这些算子进行混合量化。

    打开量化表⽂件 yolov5nu.quantize,在底部的 customized_quantize_layers: 下增加这些层:

    customized_quantize_layers:
      attach_Concat_/model.24/Concat_5/out0_0: dynamic_fixed_point-i16
      Concat_/model.24/Concat_5_1: dynamic_fixed_point-i16
      Mul_/model.24/Mul_2_2: dynamic_fixed_point-i16
      Sigmoid_/model.24/Sigmoid_3: dynamic_fixed_point-i16
      Concat_/model.24/Concat_4_4: dynamic_fixed_point-i16
      Initializer_/model.24/Constant_12_output_0_5: dynamic_fixed_point-i16
      Div_/model.24/Div_1_6: dynamic_fixed_point-i16
      Sub_/model.24/Sub_1_7: dynamic_fixed_point-i16
      Add_/model.24/Add_2_8: dynamic_fixed_point-i16
      Initializer_/model.24/Constant_11_output_0_9: dynamic_fixed_point-i16
      Add_/model.24/Add_1_10: dynamic_fixed_point-i16
      Sub_/model.24/Sub_11: dynamic_fixed_point-i16
      Slice_/model.24/Slice_12: dynamic_fixed_point-i16
      Reshape_/model.24/dfl/Reshape_1_13: dynamic_fixed_point-i16
      Initializer_/model.24/Constant_9_output_0_14: dynamic_fixed_point-i16
      Slice_/model.24/Slice_1_15: dynamic_fixed_point-i16
      Conv_/model.24/dfl/conv/Conv_17: dynamic_fixed_point-i16
      Softmax_/model.24/dfl/Softmax_18: dynamic_fixed_point-i16
      Reshape_/model.24/dfl/Reshape_20: dynamic_fixed_point-i16
      Split_/model.24/Split_21: dynamic_fixed_point-i16
      Reshape_/model.24/dfl/Reshape_1_13_acuity_mark_perm_268: dynamic_fixed_point-i16
      Softmax_/model.24/dfl/Softmax_18_acuity_mark_perm_269: dynamic_fixed_point-i16
    

    然后执行下列命令进行混合量化

    pegasus quantize \
        --model yolov5nu.json \
        --model-data yolov5nu.data \
        --with-input-meta yolov5nu_inputmeta.yml \
        --algorithm kl_divergence \
        --divergence-first-quantize-bits 11 \
        --quantizer perchannel_symmetric_affine \
        --qtype int8 \
        --iterations 796 \
        --model-quantize yolov5nu.quantize \
        --hybrid
    

    该操作生成了 yolov5nu.quantize.json文件,后续都将使用它来代替 yolov5nu.json

  7. 进行推理,目的是与浮点精度的推理结果作对比。

    先将浮点精度下的推理结果移动到 ${学习笔记目录},在主机终端中执行下列命令:

     mv ${模型目录}/iter_0_images_267_out0_1_3_320_320.tensor ${学习笔记目录}/float_input_1_3_320_320.tensor
     mv ${模型目录}/iter_0_attach_Concat__model.24_Concat_5_out0_0_out0_1_84_2100.tensor ${学习笔记目录}/float_result_84_2100.tensor
    

    然后在容器中执行下列代码进行推理

    pegasus inference \
        --model yolov5nu.quantize.json \
        --model-data yolov5nu.data \
        --with-input-meta yolov5nu_inputmeta.yml \
        --dtype quantized \
        --model-quantize yolov5nu.quantize
    

    该操作生成了两个文件, 分别代表模型的输入张量和输出张量:

    1. iter_0_images_267_out0_1_3_320_320.tensor
    2. iter_0_attach_Concat__model.24_Concat_5_out0_0_out0_1_84_2100.tensor

    最后,将量化精度的推理结果移动到 ${学习笔记目录},在主机终端中执行下列命令:

     mv ${模型目录}/iter_0_images_267_out0_1_3_320_320.tensor ${学习笔记目录}/input_1_3_320_320.tensor
     mv ${模型目录}/iter_0_attach_Concat__model.24_Concat_5_out0_0_out0_1_84_2100.tensor ${学习笔记目录}/result_84_2100.tensor
    
  8. jupyter nootbook 容器中验证量化精度是否可用

    在浏览器的jupyter nootbook页面中打开 see-result.ipynb

    逐行执行!可以看到浮点进度的推理结果在图片上的展示。

    接着修改第二个单元格中的imgTensorPath,resultTensorPath变量

    imgTensorPath = 'input_1_3_320_320.tensor'
    resultTensorPath = 'result_84_2100.tensor'
    

    点击如图所示图标,重新运行该笔记本。可以看到量化精度的推理结果在图片上的展示。

  9. 导出模型

    acuity-toolkit 容器执行下列命令

     cd /usr/local/VeriSilicon/acuity-toolkit-binary-6.6.1/bin/
    
        pegasus export ovxlib \
        --model ${模型目录}/yolov5nu.quantize.json \
        --model-data ${模型目录}/yolov5nu.data \
        --with-input-meta ${模型目录}/yolov5nu_inputmeta.yml \
        --dtype quantized \
        --model-quantize ${模型目录}/yolov5nu.quantize \
        --output-path ${模型目录}/ovxilb/yolov5nu \
        --save-fused-graph \
        --pack-nbg-unify \
        --optimize "VIP9000PICO_PID0XEE" \
        --viv-sdk ${VIV_SDK}
    
     cd ${模型目录}
    

    该步骤生成了ovxilb,ovxilb_nbg_unify 两个目录。

    我们需要的模型文件路径为 ovxilb_nbg_unify/network_binary.nb

    其他文件可以忽略。

  10. 查看模型内存占用信息

    acuity-toolkit 容器执行下列命令

    nbinfo -a ${模型目录}/ovxilb_nbg_unify/network_binary.nb
    

yolov5nu的迁移训练

Ultralytics官方推荐使用 Roboflow 作为数据标注平台与数据集管理平台。

注:需要科学上网

这里不详细展开说明,我们假设已经在该平台上准备好了数据集。

在浏览器的jupyter nootbook页面中打开 train.ipynb

参考修改并执行。

注:大部分迁移训练相关的知识请看Ultralytics官方文档


评论