如何将pt模型转为rknn模型?

本文介绍了如何将基于PyTorch训练的YOLOv5模型权重文件(pt)转换为ONNX模型,然后进一步转化为RKNN模型,以便在开发板上进行推理。转换过程包括使用特定代码将pt模型转为onnx,以及通过RKNNAPI加载onnx模型并构建为rknn模型。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

pt模型是pytorch深度学习模型训练出的权重文件,需要先将其转为onnx模型,再转为rknn模型,进而可以部署在开发板上进行模型推理。

1.pt_to_onnx

我用yolov5训练了模型,得到权重文件后,用以下代码即可转为onnx模型

#运行本代码将pt模型转为onnx模型


import argparse
import sys
import time

sys.path.append('./')  # to run '$ python *.py' files in subdirectories

import torch
import torch.nn as nn

import models
from models.experimental import attempt_load
from utils.activations import Hardswish, SiLU
from utils.general import set_logging, check_img_size
from utils.torch_utils import select_device

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--weights', type=str, default='weights/add_guizi12_new4/weights/last.pt', help='weights path')  # from yolov5/models/
    parser.add_argument('--img-size', nargs='+', type=int, default=[640, 640], help='image size')  # height, width
    parser.add_argument('--batch-size', type=int, default=32, help='batch size')
    parser.add_argument('--dynamic', action='store_true', help='dynamic ONNX axes')
    parser.add_argument('--grid', default='False',action='store_true', help='export Detect() layer grid')
    parser.add_argument('--device', default='cpu', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
    opt = parser.parse_args()
    opt.img_size *= 2 if len(opt.img_size) == 1 else 1  # expand
    print(opt)
    set_logging()
    t = time.time()

    # Load PyTorch model
    device = select_device(opt.device)
    model = attempt_load(opt.weights)  # load FP32 model
    labels = model.names

    # Checks
    gs = int(max(model.stride))  # grid size (max stride)
    opt.img_size = [check_img_size(x, gs) for x in opt.img_size]  # verify img_size are gs-multiples

    # Input
    img = torch.zeros(opt.batch_size, 3, *opt.img_size).to(device)  # image size(1,3,320,192) iDetection

    # Update model
    for k, m in model.named_modules():
        m._non_persistent_buffers_set = set()  # pytorch 1.6.0 compatibility
        if isinstance(m, models.common.Conv):  # assign export-friendly activations
            if isinstance(m.act, nn.Hardswish):
                m.act = Hardswish()
            elif isinstance(m.act, nn.SiLU):
                m.act = SiLU()
        # elif isinstance(m, models.yolo.Detect):
        #     m.forward = m.forward_export  # assign forward (optional)
    model.model[-1].export = not opt.grid  # set Detect() layer grid export
    y = model(img)  # dry run

    # TorchScript export
    try:
        print('\nStarting TorchScript export with torch %s...' % torch.__version__)
        f = opt.weights.replace('.pt', '.torchscript.pt')  # filename
        ts = torch.jit.trace(model, img)
        ts.save(f)
        print('TorchScript export success, saved as %s' % f)
    except Exception as e:
        print('TorchScript export failure: %s' % e)

    # ONNX export
    try:
        import onnx

        print('\nStarting ONNX export with onnx %s...' % onnx.__version__)
        f = opt.weights.replace('.pt', '.onnx')  # filename
        torch.onnx.export(model, img, f, verbose=False, opset_version=11, input_names=['images'],
                          output_names=['classes', 'boxes'] if y is None else ['output'],
                          dynamic_axes={'images': {0: 'batch', 2: 'height', 3: 'width'},  # size(1,3,640,640)
                                        'output': {0: 'batch', 2: 'y', 3: 'x'}} if opt.dynamic else None)

        # Checks
        onnx_model = onnx.load(f)  # load onnx model
        onnx.checker.check_model(onnx_model)  # check onnx model
        print(onnx.helper.printable_graph(onnx_model.graph))  # print a human readable model
        print('ONNX export success, saved as %s' % f)
    except Exception as e:
        print('ONNX export failure: %s' % e)


    # Finish
    print('\nExport complete (%.2fs). Visualize with https://github.com/lutzroeder/netron.' % (time.time() - t))

转为onnx之后,查看模型可以在可视化网站Netron

如下图:

 可以点左下角按钮,查看网络输入和输出的相关信息

2.onnx_to_rknn

运行以下代码

import os
from rknn.api import RKNN

ONNX_MODEL = r'F:\hml\yolov5-10-3box\weights\add_guizi12_new6\weights\best.onnx'
RKNN_MODEL = r'F:\hml\yolov5-10-3box\weights\add_guizi12_new6\weights\best.rknn'
DATASET = './dataset.txt'

QUANTIZE_ON = True
BOX_THRESH = 0.5
NMS_THRESH = 0.6
IMG_SIZE = 640

if __name__ == '__main__':

    # Create RKNN object
    rknn = RKNN()

    if not os.path.exists(ONNX_MODEL):
        print('model not exist')
        exit(-1)

    # pre-process config
    print('--> Config model')
    rknn.config(reorder_channel='0 1 2',
                mean_values=[[0, 0, 0]],
                std_values=[[255, 255, 255]],
                optimization_level=3,
                target_platform='rv1126',
                output_optimize=1,
                quantize_input_node=QUANTIZE_ON)
    print('done')

    # Load ONNX model

    print('--> Loading model')
    ret = rknn.load_onnx(model=ONNX_MODEL,outputs=['output','378','379'])
    if ret != 0:
        print('Load yolov5 failed!')
        exit(ret)
    print('done')

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

    # Export RKNN model
    print('--> Export RKNN model')
    ret = rknn.export_rknn(RKNN_MODEL)
    if ret != 0:
        print('Export yolov5rknn failed!')
        exit(ret)
    print('done')

    rknn.release()

可以修改路径,target_platform等。加载onnx模型时候可以参考可视化网站找到输出的名字,build model时量化可以选择True还是False。

有什么问题可以评论区问我。

### 将 PyTorch (PT) 模型换为 RKNN 格式的工具与方法 将 PyTorch 模型换为 RKNN 格式的过程可以分为几个主要阶段:环境准备、模型换以及验证部署。以下是详细的说明: #### 1. **环境准备** 为了确保换过程顺利进行,建议在一个全新的 Python 环境中安装所需的依赖项。这可以通过 Anaconda 或虚拟环境实现[^2]。 - 创建一个新的 Python 环境并激活它: ```bash conda create -n rknn_env python=3.8 conda activate rknn_env ``` - 安装 `rknn-toolkit` 及其他必要的库。对于版本的选择,推荐使用大于等于 1.3 的版本,因为这些版本支持直接从 PyTorch 换至 RKNN。 ```bash pip install rknn-api==1.7 ``` #### 2. **模型换流程** ##### a. **选择合适的换路径** 根据实际需求和硬件平台的支持情况,可以选择两种不同的换方式: - 如果目标设备支持直接从 PyTorch 到 RKNN换,则可以直接调用 `rknn-toolkit` 中的相关接口完成操作。 - 对于某些特定场景(如量化失败或硬件兼容性问题),可能需要先将 PyTorch 模型导出为 ONNX 格式,然后再通过 ONNX 换为 RKNN。 ##### b. **PyTorch 至 ONNX 导出** 如果采用两步法(即先 ONNX 后 RKNN),则需执行以下步骤: - 修改原始 PyTorch 模型代码以便支持静态输入尺寸; - 使用 `torch.onnx.export()` 函数导出模型[^3]。 示例代码如下: ```python import torch dummy_input = torch.randn(1, 3, 224, 224) # 输入张量形状应匹配训练数据集 model = YourModel() # 替换为您自己的模型定义 model.eval() output_path = 'your_model.onnx' torch.onnx.export(model, dummy_input, output_path, input_names=['input'], output_names=['output']) ``` ##### c. **ONNX 至 RKNN 换** 利用 `rknn-toolkit` 提供的功能加载已生成的 ONNX 文件,并设置相应的配置选项来优化性能。 示例脚本展示如何初始化 RKNN 构造器对象并应用预处理规则: ```python from rknn.api import RKNN # 初始化 RKNN 实例 rknn = RKNN(verbose=True) # 加载 ONNX 模型 print('--> Loading model') ret = rknn.load_onnx(model='your_model.onnx') # 替换为您的 .onnx 文件名 if ret != 0: print('Load failed!') exit(ret) print('done') # 配置模型参数 rknn.config(mean_values=[[127.5]], std_values=[[127.5]]) # 执行编译 print('--> Building model') ret = rknn.build(do_quantization=False) # 是否启用量化取决于具体应用场景 if ret != 0: print('Build failed!') exit(ret) print('done') # 保存最终结果 rknn.export_rknn(path='your_model.rknn') # 输出文件名称自定义 ``` #### 3. **注意事项** - 不同硬件平台对 RKNN 模型的要求可能存在差异,请参照官方文档确认所选芯片组的具体约束条件[^4]。 - 在调试期间遇到错误时,仔细检查日志输出以定位潜在问题所在位置。 --- ###
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值