pt->onnx->rknn(量化) step by step & FAQ

发布于:2025-02-15 ⋅ 阅读:(30) ⋅ 点赞:(0)

文档修订中...

1.pt->onnx

这个转换是在yolov11的docker环境做的转换。非常简单。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# 获取当前脚本文件所在目录的父目录,并构建相对路径
import os
import sys
current_dir = os.path.dirname(os.path.abspath(__file__))
project_path = os.path.join(current_dir, '..')
sys.path.append(project_path)
sys.path.append(current_dir)
#based: https://docs.ultralytics.com/modes/export/#key-features-of-export-mode
from ultralytics import YOLO

# Load a model
#model = YOLO("yolo11n.pt")  # load an official model
model = YOLO(r"./best.pt")  # load a custom trained model
# Export the model
model.export(format="onnx")

2.onnx->rknn

 这个转换需要在rknn-toolkit2所在docker环境转换。这个过程中,注意事项有几个:

  • 需要引入一个校验图片,一个或者一组。
  • 图片的索引文件是:dataset.txt,内容是一个或者多个图片文件。
  • 命令行参数中可以指定最终的量化级别:
python onnx2rknn.py ./yolo11n.onnx rk3588 i8
#onnx2rknn.py
import cv2
import numpy as np

from rknn.api import RKNN
import os

if __name__ == '__main__':

    platform = 'rk3588'
    exp = 'yolov11'
    Width = 640
    Height = 640
    # Model from https://github.com/airockchip/rknn_model_zoo
    MODEL_PATH = './best.onnx' 
    NEED_BUILD_MODEL = True
    # NEED_BUILD_MODEL = False
    im_file = './frame_0127.png'

    # Create RKNN object
    rknn = RKNN()

    OUT_DIR = "rknn_models"
    RKNN_MODEL_PATH = './{}/{}_{}.rknn'.format(
        OUT_DIR, exp+'-'+str(Width)+'-'+str(Height), platform)
    if NEED_BUILD_MODEL:
        DATASET = './dataset.txt'
        rknn.config(mean_values=[[0, 0, 0]], std_values=[
                    [255, 255, 255]], target_platform=platform)
        # Load model
        print('--> Loading model')
        ret = rknn.load_onnx(MODEL_PATH)
        if ret != 0:
            print('load model failed!')
            exit(ret)
        print('done')

        # Build model
        print('--> Building model')
        ret = rknn.build(do_quantization=True, dataset=DATASET)
        if ret != 0:
            print('build model failed.')
            exit(ret)
        print('done')

        # Export rknn model
        if not os.path.exists(OUT_DIR):
            os.mkdir(OUT_DIR)
        print('--> Export RKNN model: {}'.format(RKNN_MODEL_PATH))
        ret = rknn.export_rknn(RKNN_MODEL_PATH)
        if ret != 0:
            print('Export rknn model failed.')
            exit(ret)
        print('done')
    else:
        ret = rknn.load_rknn(RKNN_MODEL_PATH)

    rknn.release()

上面的转换代码是从rknn_model_zoo中的yolov5部分的模型转化代码修改过的。瑞芯微rknn至少从2024年,推理和模型转换分离成了两个独立的git工程。

3.FAQ

3.1 pt->onnx的核心文档在哪里?

主页 -Ultralytics YOLO 文档

3.2 onnx->rknn的核心文档在哪里? 

https://gitcode.com/Coco_cool/rknn-toolkit2
doc文件夹

可以通读,特别关注一下:01_Rockchip_RKNPU_Quick_Start_RKNN_SDK_V2.3.0_CN.pdf

3.3 整体参考

可以参考野火开发板的在线帮助,它一直在维护更新

14. YOLO11 — [野火]嵌入式AI应用开发实战指南—基于LubanCat-RK系列板卡 文档

另一家:firefly的,NPU参考资料:

1. NPU使用 — Firefly Wiki

4.扩展问题

4.1 早期1.6版的rknn模型转换过程中rknn.config中的mean_value,std_value阈值,以及color_channel在2.3版仍然需要手工指定吗? 

参见:【rknn】onnx转rknn脚本解读以及函数解读(版本V1.7.3)_rknn.config-CSDN博客 

pytorch模型转onnx-量化rknn(bisenet)_onnx转rknn-CSDN博客

4.2 模型转换中如果选择量化需要用到的验证用数据集只有图片,没有label,是这样的?2.3版仍然有保留吗?

答案:确实如此,2.3版仍然是只有img list,不含lable.

4.3 似乎存在直接从.pt到.rknn的转换吗(darknet)?可能的优势和劣势是什么?

答案:存在,但是不要尝试。详见4.5

4.4 onnx有一个专门的嵌入式子集,.rknn模型对.onnx的格式有要求吗?

答案:目前.rknn模型转换时,几乎不调.onnx,但是,我前段时间处理的一个工业环境的识别.pt在RKNN模拟环境无法识别目标对象,我再试试另一个模型。 

4.5 rknn量化过程2.1版的那个预量化的概念,现在还存在吗?

答案:存在,但不好用。

rknn的预量化之前似乎是直接加载PyTorch的预量化模型;rknn-toolkit2.3doc里提到:

 支持量化感知训练(QAT)模型,但需要将torch版本更新至1.9.0以 上。 

当前的rknn-toollite2.3中,默认的torch版本是:torch                        1.10.1

直接加载.py模型,会报错。模型之间的转换,多一个接口就需要多一组任务量。我怀疑它要精确地匹配,版本号高,低都不行。在训练时就要把pytorch的版本始终保持一致。

所以,目前如果没有特别的原因,还是建议走.pt->.onnx->.rknn的转换路线。pytorch主版本已经升级至2.6. 瑞芯微理论上没有这么多精力维持这类可做可不做的版本迭代。

4.6 量化时的那个非对称量化,动态定点量化的配置,现在还有吗?默认值是什么?

1. NPU使用 — Firefly Wiki

我的开发板:量化功能: 支持将浮点模型量化为定点模型,目前支持的量化方法为非对称量化 ( asymmetric_quantized-8 及 asymmetric_quantized-16 ),并支持混合量化功能 。 asymmetric_quantized-16 目前版本暂不支持 

4.7 板卡部署的pre_compile加速仍然是有效的,对吧?

答案:2.3版已经取消。pre_compile 是1.6版,build的一个参数,现在已经消失。但是现在有一个针对rk3588这里NPU multi-core的NPU平台。这个函数实际上用于onnx->rknn阶段。注意:

rknn_batch_size类似yolo训练时的batch设置,是一个优化选项。

4.8 未pre_compile的量化模型是可以在主机系统上运行的,对吧?无需部署到板卡就可测试。

答案:始终记得,交叉环境不可以直接加载.rknn。

  • RKNN-Toolkit2 自带了一个模拟器,直接在 PC 上运行 Demo 即是将转换后的模型部署到仿真 NPU 上运行

    这个信息出现在firefly里,指向的是这个东西
    rknn的模拟功能似乎和mobilenet没有关系,mobienet是tensorflow lite,是一个模型的终端执行方案,适用于手机的arm环境,是与rknn,onnx同级的一款模型形式。

然后:在主机环境,现在是无法直接加载.rknn模型的,如果你在主机环境调用.rknn,会得到一个运行时异常(rknn-toolkit2.3):

E init_runtime: RKNN model that loaded by 'load_rknn' not support inference on the simulator, please set 'target' first!
                If you really want to inference on the simulator, use 'load_xxx' & 'build' instead of 'load_rknn'!

 另外在rknn-lite帮助里也提到这个:

4.9  如何查看.onnx和.rknn的各层参数?

.rknn的参数在rknn-toolkits 转换的过程中就会出现,你可以非常清晰地看到使用量化,和不使用量化的不同的打印调试信息。

sudo snap install netron

/snap/bin/netron ./best.onnx

 

附录A 重要知识点索引

  • 4.5提到的一个npu加速 batch...

附录B RKNN-Toolkit2.3 笔记

 1.文档来源[2024/11/04版]

GitCode - 全球开发者的开源社区,开源代码托管平台

/doc/03_Rockchip_RKNPU_API_Reference_RKNN_Toolkit2_V2.3.0_CN.pdf

2.关键参数

  1. mean_value
    这是为了确认原始原始数据是无符号的还是有符号的,三通道。后级继续使用无符号为默认:[0,0,0],使用[128,128,128]可以把一个U8数据通道转为S8
  2. std_value
    这是对原始数据的量化,也是三通道格式,默认[1,1,1],表示不量化。[2,2,2]会把U8的数据空间从[0,255],缩减到[0,127]
  3. op_target
    指定执行目标,默认为None,可指定为auto
  4. dynamic_input
    可以指定模型使用的图片幅面,并且可能会同时支持多种幅面。比如640*640,1920*1080.
    page8


网站公告

今日签到

点亮在社区的每一天
去签到