瑞芯微 Rockchip 系列 RK3588 主流深度学习框架模型转成 rknn 模型教程

前言

在瑞芯微 Rockchip 芯片上进行 NPU 推理,需要先将模型文件转换成 rknn 模型文件,才能执行各种推理任务。本文将介绍如何安装各种工具,并最终实现将各种深度学习框架的模型文件转换成 rknn 文件。

本教程不仅适合 RK3588 平台,也适合其他 RK 系列平台,例如 RK3566、RK3568、RK3562 等。具体平台请参考 RKNN-Toolkit2 文档。

RKNNToolkit2__7">安装 RKNN-Toolkit2 环境

RKNN-Toolkit2 是瑞芯微官方提供的工具包,用于将各种深度学习框架的模型文件转换成 rknn 文件。

安装 Conda

RKNN-Toolkit2 转换依赖于 Python 3.8(建议版本),而一般我们使用 Conda 来管理 python 环境,所以需要先安装 Conda。

下面的命令会下载 Anaconda 的安装包,并执行安装。

wget https://repo.anaconda.com/archive/Anaconda3-2024.10-1-Linux-x86_64.sh
bash Anaconda3-2024.10-1-Linux-x86_64.sh

安装完成后,运行下面命令,查看是否安装成功。

conda --version

使用 Conda 创建 Python 3.8 环境

通过以下命令创建名称为 toolkit2 的 Python 3.8 环境:

conda create -n toolkit2 python=3.8

激活 toolkit2 环境,后续将在此环境中安装 RKNN-Toolkit2:

conda activate toolkit2
# 成功后,命令行提示符会变成以下形式:
# (toolkit2) xxx@xxx:~$

RKNNToolkit2_44">安装 RKNN-Toolkit2

在终端运行如下命令:

pip install rknn-toolkit2 -i https://pypi.org/simple

运行下面命令验证是否安装成功:

# 进入 Python 交互模式
python

# 导入 RKNN
from rknn.api import RKNN

如果没有输出错误,则表示 RKNN-Toolkit2 安装成功。

模型转换

模型转换流程

RKNN-Toolkit2 的转换流程如下:

image.png

可以看到,整个流程非常简单,初始化 -> 配置 -> 加载 -> 构建 -> 导出模型 -> 释放资源

目前RKNN-Toolkit2支持多个主流深度学习框架的模型转换,包括:

  • Caffe(推荐版本为1.0)
  • TensorFlow(推荐版本为1.12.0~2.8.0)
  • TensorFlow Lite(推荐版本为Schema version = 3)
  • ONNX(推荐版本为1.7.0~1.10.0)
  • PyTorch(推荐版本为1.6.0~1.13.1)
  • Darknet(推荐版本为Commit ID = 810d7f7)

RKNN 模型转换过程中,可以选择是否要进行模型量化量化的作用是减少模型的大小,提高推理速度,但可能会牺牲一定的精度。如果要量化,需要传入量化校准的数据集,这是为了确保量化后的模型在推理时,能够达到相对较好的精度。

编写模型转换示例

下面我以转换 yolo11 的 ONNX 模型为例,手把手带大家编写一个简单的模型转换示例,请确保上面的 Conda 已经安装并且 toolkit2 激活环境。

在最下面我也会提供整个示例的完整代码仓库,大家可以直接下载使用。

首先,在 Linux 终端运行如下命令:

mkdir rknn_trans_test
cd rknn_trans_test

# 下载 yolo11 的 ONNX 模型
wget -O ./yolo11n.onnx https://ftrg.zbox.filez.com/v2/delivery/data/95f00b0fc900458ba134f8b180b3f7a1/examples/yolo11/yolo11n.onnx

接着下载量化的数据集

# 下载 yolo11 的量化数据集
wget https://github.com/qaz624824554/rknn_trans_test/raw/refs/heads/master/COCO.tar.gz
tar -xzvf COCO.tar.gz

创建 convert.py 文件

touch convert.py

将下面的代码复制到 convert.py 文件中:

import sys
from rknn.api import RKNN

DATASET_PATH = './COCO/coco_subset_20.txt'  # 量化数据集路径
DEFAULT_RKNN_PATH = './yolo11n.rknn'        # 默认输出RKNN模型路径
DEFAULT_QUANT = True                         # 默认是否量化

def parse_arg():
    """
    解析命令行参数
    Returns:
        model_path: ONNX模型路径
        platform: 目标平台
        do_quant: 是否进行量化
        output_path: RKNN模型输出路径
    """
    if len(sys.argv) < 3:
        print("Usage: python3 {} onnx_model_path [platform] [dtype(optional)] [output_rknn_path(optional)]".format(sys.argv[0]))
        print("       platform choose from [rk3562,rk3566,rk3568,rk3588,rk3576,rk1808,rv1109,rv1126]")
        print("       dtype choose from [i8, fp] for [rk3562,rk3566,rk3568,rk3588,rk3576]")
        print("       dtype choose from [u8, fp] for [rk1808,rv1109,rv1126]")
        exit(1)

    model_path = sys.argv[1]
    platform = sys.argv[2]

    # 根据输入参数确定是否量化
    do_quant = DEFAULT_QUANT
    if len(sys.argv) > 3:
        model_type = sys.argv[3]
        if model_type not in ['i8', 'u8', 'fp']:
            print("ERROR: Invalid model type: {}".format(model_type))
            exit(1)
        elif model_type in ['i8', 'u8']:
            do_quant = True
        else:
            do_quant = False

    # 确定输出路径
    if len(sys.argv) > 4:
        output_path = sys.argv[4]
    else:
        output_path = DEFAULT_RKNN_PATH

    return model_path, platform, do_quant, output_path

if __name__ == '__main__':
    # 解析命令行参数
    model_path, platform, do_quant, output_path = parse_arg()

    # 创建RKNN对象
    rknn = RKNN(verbose=False)

    # 配置预处理参数
    print('--> Config model')
    rknn.config(mean_values=[[0, 0, 0]], std_values=[[255, 255, 255]], target_platform=platform)
    print('done')

    # 加载ONNX模型
    print('--> Loading model')
    ret = rknn.load_onnx(model=model_path)
    if ret != 0:
        print('Load model failed!')
        exit(ret)
    print('done')

    # 构建RKNN模型
    print('--> Building model')
    ret = rknn.build(do_quantization=do_quant, dataset=DATASET_PATH)
    if ret != 0:
        print('Build model failed!')
        exit(ret)
    print('done')

    # 导出RKNN模型
    print('--> Export rknn model')
    ret = rknn.export_rknn(output_path)
    if ret != 0:
        print('Export rknn model failed!')
        exit(ret)
    print('done')

    # 释放资源
    rknn.release()

保存,运行如下命令

# 用法: python convert.py model_path [rk3566|rk3588|rk3562] [i8/u8/fp] [output_path]
python convert.py ./yolo11n.onnx rk3588 i8 ./yolo11n.rknn

看到下面的运行效果表示转换成功,并且可以看到当前目录下多了一个 yolo11n.rknn 文件。

image.png

关于转换过程中用到的具体函数参数,可以参考 RKNN-Toolkit2 文档,这里不再过多赘述。

示例代码仓库:https://github.com/qaz624824554/rknn_trans_test

总结

本文介绍了如何在 RK3588 平台上进行主流深度学习框架模型转换,并提供了完整的示例代码。希望对大家有所帮助。

如果大家有任何问题,欢迎在评论区留言,我会尽快回复。

如果觉得本文对你有帮助,欢迎点赞、收藏、转发。

谢谢大家!


http://www.niftyadmin.cn/n/5845817.html

相关文章

WebStorm设置Vue Component模板

下载vue.js插件 下面有模板样例 Composition API&#xff1a;这是 Vue 3 的一项新特性&#xff0c;允许通过 setup 函数来组织组件逻辑。Options API&#xff1a;这是 Vue 2 和 Vue 3 都支持的传统方式&#xff0c;通过定义组件的 data、methods、computed 等来组织逻辑。 Comp…

PM2 与 Docker 结合使用:Node.js 应用的高效管理与部署

在现代 Web 开发中&#xff0c;Node.js 应用的部署和管理至关重要。为了确保应用的高可用性和性能&#xff0c;开发者常常采用 PM2&#xff08;进程管理工具&#xff09;和 Docker&#xff08;容器化平台&#xff09;的结合方案。本文将详细介绍 PM2 的功能、Docker 的优势&…

IDEA编写SpringBoot项目时使用Lombok报错“找不到符号”的原因和解决

目录 概述|背景 报错解析 解决方法 IDEA配置解决 Pom配置插件解决 概述|背景 报错发生背景&#xff1a;在SpringBoot项目中引入Lombok依赖并使用后出现"找不到符号"的问题。 本文讨论在上述背景下发生的报错原因和解决办法&#xff0c;如果仅为了解决BUG不论原…

LIMO:少即是多的推理

25年2月来自上海交大、SII 和 GAIR 的论文“LIMO: Less is More for Reasoning”。 一个挑战是在大语言模型&#xff08;LLM&#xff09;中的复杂推理。虽然传统观点认为复杂的推理任务需要大量的训练数据&#xff08;通常超过 100,000 个示例&#xff09;&#xff0c;但本文展…

工业相机在工业生产制造过程中的视觉检测技术应用

随着技术不断发展以及工业4.0时代的到来&#xff0c;利用工业相机进行视觉检测技术已经成为制造业不可或缺的一部分。通过结合先进的计算机视觉、AI算法和自动化设备&#xff0c;工业视觉检测为生产线质量控制和效率提升提供了革命性的解决方案。 一、什么是工业视觉检测技术 …

Linux 安装 Ollama

1、下载地址 Download Ollama on Linux 2、有网络直接执行 curl -fsSL https://ollama.com/install.sh | sh 命令 3、下载慢的解决方法 1、curl -fsSL https://ollama.com/install.sh -o ollama_install.sh 2、sed -i s|https://ollama.com/download/ollama-linux|https://…

C++小等于的所有奇数和=最大奇数除2加1的平方。

缘由 三种思路解题&#xff1a;依据算术推导得到一个规律&#xff1a;小等于的所有奇数和等于最大奇数除以2加1的平方。将在后续发布&#xff0c;总计有十种推导出来的实现代码。 int a 0,aa 1,aaa 0;cin >> a; while (aa<a) aaa aa, aa 2;cout << aaa;i…

DeepSeek vs. ChatGPT:不同的诞生时间,对人工智能发展的不同影响

DeepSeek vs. ChatGPT&#xff1a;不同的诞生时间&#xff0c;对人工智能发展的不同影响 ChatGPT 和 DeepSeek 诞生于不同的时间节点&#xff0c;代表了人工智能不同阶段的发展方向。它们在技术、应用以及对AI发展趋势的影响方面各有侧重。 1. 诞生时间与背景 ChatGPT&#x…