瑞芯微RKNN开发·yolov7

本文详细描述了使用PyTorch将yolov7预训练模型转换为ONNX格式,包括权重加载、简化优化,并在RKNN开发板上进行NPU推理的步骤。

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

官方预训练模型转换

  1. 下载yolov7源码解压到本地,并配置基础运行环境。
  2. 下载官方预训练模型
  1. 进入yolov7-main目录下,新建文件夹weights,并将步骤2中下载的权重文件放进去。
  2. 修改models/yolo.py文件
    def forward(self, x):
        # x = x.copy()  # for profiling
        z = []  # inference output
        self.training |= self.export
        for i in range(self.nl):
            x[i] = self.m[i](x[i]).sigmoid()  # conv
        return x[0], x[1], x[2]
  1. 新建export_nnie.py文件
import os
import torch
import onnx
from onnxsim import simplify
import onnxoptimizer
import argparse
from models.yolo import Detect, Model

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--weights', type=str, default='./weights/yolov7.pt', help='initial weights path') 
    parser.add_argument('--cfg', type=str, default='./cfg/deploy/yolov7.yaml', help='initial weights path') 
    #================================================================
    opt = parser.parse_args()
    print(opt)

    #Save Only weights
    ckpt = torch.load(opt.weights, map_location=torch.device('cpu'))
    torch.save(ckpt['model'].state_dict(), opt.weights.replace(".pt", "-model.pt"))

    #Load model without postprocessing
    new_model = Model(opt.cfg)
    new_model.load_state_dict(torch.load(opt.weights.replace(".pt", "-model.pt"), map_location=torch.device('cpu')), False)
    new_model.eval()

    #save to JIT script
    example = torch.rand(1, 3, 640, 640)
    traced_script_module = torch.jit.trace(new_model, example)
    traced_script_module.save(opt.weights.replace(".pt", "-jit.pt"))

    #save to onnx
    f = opt.weights.replace(".pt", ".onnx")
    torch.onnx.export(new_model, example, f, verbose=False, opset_version=12,
                            training=torch.onnx.TrainingMode.EVAL,
                            do_constant_folding=True,
                            input_names=['data'],
                            output_names=['out0','out1','out2'])

    #onnxsim
    model_simp, check = simplify(f)
    assert check, "Simplified ONNX model could not be validated"
    onnx.save(model_simp, opt.weights.replace(".pt", "-sim.onnx"))

    #optimize onnx
    passes = ["extract_constant_to_initializer", "eliminate_unused_initializer"]
    optimized_model = onnxoptimizer.optimize(model_simp, passes)
    onnx.checker.check_model(optimized_model)
    onnx.save(optimized_model, opt.weights.replace(".pt", "-op.onnx"))
    print('finished exporting onnx')
  1. 命令行执行python3 export_nnie.py脚本(默认为yolov7.pt, 加–weights参数可指定权重,–cfg指定模型配置文件),转换成功会输出一下信息, 转换后的模型存于权重同级目录(*-op.onnx后缀模型)
Namespace(cfg='./cfg/deploy/yolov7.yaml', weights='./weights/yolov7.pt')
finished exporting onnx

请添加图片描述

RKNN开发板植入-模型转换篇

前期准备
  • RKNN开发环境(python)
  • rknn-toolkit2
详细流程
  1. 进入rknn-toolkits2/examples/onnx/yolov5示例目录下
  2. 修改test.py内容(按需修改ONNX_MODEL、RKNN_MODEL、IMG_PATH、DATASET等等超参数)
def sigmoid(x):
    # return 1 / (1 + np.exp(-x))
    return x
  1. 命令行执行python3 test.py即可获取推理结果
    请添加图片描述
    请添加图片描述

RKNN开发板植入-NPU加载推理篇(C++)

后续放出代码

### YOLOv8 模型转换与部署至瑞芯微 RKNN 平台教程 #### 准备工作 为了成功将YOLOv8模型转换并部署到瑞芯微RKNN平台上,需准备必要的开发环境和工具链。确保安装了Python、PyTorch以及ONNX等相关库。 #### 将 PyTorch 模型导出为 ONNX 格式 首先需要把原始的YOLOv8 PyTorch模型保存成通用中间表示形式——ONNX文件。此过程涉及定义输入张量形状,并调用`torch.onnx.export()`函数完成转换操作[^3]。 ```python import torch from ultralytics import YOLO model = YOLO('yolov8n.pt') # 加载预训练好的YOLOv8 nano版本模型 dummy_input = torch.randn(1, 3, 640, 640) # 创建虚拟输入数据用于导出 output_onnx = 'yolov8n.onnx' input_names = ["image"] output_names = ['boxes', 'labels'] torch.onnx.export(model, dummy_input, output_onnx, input_names=input_names, output_names=output_names, opset_version=12) ``` #### 使用 RKNN Toolkit 进行模型优化与编译 一旦获得了`.onnx`格式的目标检测网络结构描述文档,则可以利用官方提供的[RKNN Toolkit](https://github.com/rockchip-linux/rknn-toolkit),将其进一步转化为适用于特定硬件架构下的可执行二进制码(即`.rknn`文件)。具体命令如下所示: ```bash pip install rknn-toolkit==1.7.0 # 安装对应版本的RKNN toolkit包 ``` 接着编写一段简单的脚本来处理后续步骤: ```python from rknn.api import RKNN if __name__ == '__main__': # Create RKNN object rknn = RKNN() # Pre-process config print('--> Config model') rknn.config(mean_values=[[0, 0, 0]], std_values=[[255, 255, 255]], target_platform='rv1126') # Load ONNX model print('--> Loading model') ret = rknn.load_onnx(model='./yolov8n.onnx') if ret != 0: print('Load ONNX model failed!') exit(ret) # Build model print('--> Building model') ret = rknn.build(do_quantization=True, dataset='./dataset.txt') if ret != 0: print('Build model failed!') exit(ret) # Export RKNN model print('--> Exporting RKNN model') ret = rknn.export_rknn('./yolov8n.rknn') if ret != 0: print('Export RKNN model failed!') exit(ret) print('done') ``` 上述代码片段展示了如何通过设置量化参数来减小最终生成的应用程序体积大小的同时保持较高的精度水平;同时也指定了目标平台为RV1126系列处理器作为运行载体之一[^1]。 #### C++ 接口实现推理功能 最后,在嵌入式设备端可通过C++ API接口加载之前构建出来的`.rknn`文件来进行实时图像识别任务。下面给出了一段简化版的例子说明怎样初始化会话对象、配置输入输出缓冲区尺寸规格等细节事项[^2]: ```cpp #include "rknn_api.h" int main() { const char* model_path = "./yolov8n.rknn"; int ret; /* 初始化 */ rknn_context ctx; ret = rknn_init(&ctx, model_path, 0, 0, NULL); if (ret < 0){ printf("rknn_init fail! ret=%d\n", ret); return -1; } /* 获取输入输出属性信息 */ rknn_tensor_attr *input_attrs = new rknn_tensor_attr[input_num]; memset(input_attrs, 0, sizeof(rknn_tensor_attr)*input_num); for(int i=0; i<input_num; ++i){ input_attrs[i].index=i; ret=rknn_query(ctx,RKNN_QUERY_INPUT_ATTR,&input_attrs[i],sizeof(rknn_tensor_attr)); ... } } ``` 这段源码实现了基本的功能框架搭建,实际应用中还需要补充更多逻辑控制语句以满足不同场景需求。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值