RK3588-TVM-GPU推理模型

1.前言

        之前的博客已经在RK3588上安装了tvm的mali-gpu的版本,我们整理一下思路,本文将从模型的转换和调用两个方面进行讲解,tvm使用的是0.10版本,模型和代码也都是tvm官方的案例。

2.onnx模型转换

        将ONNX格式的ResNet50-v2模型转换为TVM Runtime支持的形式,并将其编译为一个共享库文件。以下是对代码的解释:

1. 导入库和模块

import onnx
import tvm
import tvm.relay as relay

2. 指定ONNX模型路径和加载模型

model_path = "resnet50-v2-7.onnx"

onnx_model = onnx.load(model_path)

        指定了ONNX模型的路径,并使用onnx.load加载模型。

3. 设置TVM的目标和目标主机

target = tvm.target.mali(model='rk3588')

target_host = tvm.target.arm_cpu(model='rk3588')

        设置TVM的目标设备和目标主机:
        (1)目标设备为Mali GPU(mali(model='rk3588'))
        (2)目标主机为ARM CPU(arm_cpu(model='rk3588'))

4. 获取输入名称和形状

input_name = "data"

input_shape = (1, 3, 224, 224)

shape_dict = {input_name: input_shape}

        定义了输入张量的名称(input_name)和形状(input_shape

        使用netron查看onnx模型的输入名和shape。

5. TVM Relay从ONNX创建模块和参数

mod, params = relay.frontend.from_onnx(onnx_model, shape_dict)

        使用relay.frontend.from_onnx函数将ONNX模型转换为TVM Relay模块和参数。

6. 构建TVM Relay模块

with tvm.transform.PassContext(opt_level=3):
   graph, lib, params = relay.build(mod, 
   target=tvm.target.Target(target, host=target_host), params=params)

        使用TVM Relay的relay.build函数将模块编译为图(graph)、库文件(lib),并使用指定的目标设备和目标主机。

7. 导出编译后的共享库文件

libpath = "./resnet.so"

lib.export_library(libpath)

        将编译后的库文件保存为resnet.so

8. 导出神经网络结构到JSON文件

graph_json_path = "./resnet.json"

with open(graph_json_path, 'w') as fo:

    fo.write(graph)

        将神经网络结构保存为JSON文件(resnet.json)。

9. 导出神经网络模型的权重参数到二进制文件

param_path = "./resnet.params"

with open(param_path, 'wb') as fo:

    fo.write(relay.save_param_dict(params))

        将神经网络模型的权重参数保存为二进制文件(resnet.params)。

10.完整代码

import onnx
import tvm
import tvm.relay as relay

#ONNX model path
model_path = "resnet50-v2-7.onnx"
onnx_model = onnx.load(model_path)


target = tvm.target.mali(model='rk3588')
target_host = tvm.target.arm_cpu(model='rk3588')
# 使用netron查看onnx模型的输入名和shape
input_name = "data"
input_shape = (1, 3, 224, 224)
shape_dict = {input_name: input_shape}
mod, params = relay.frontend.from_onnx(onnx_model, shape_dict)

with tvm.transform.PassContext(opt_level=3):
   graph, lib, params = relay.build(mod,
                                    target=tvm.target.Target(target, host=target_host),
                                    params=params)

libpath = "./resnet.so"
lib.export_library(libpath)

# 下面的函数导出我们神经网络的结构,使用json文件保存
graph_json_path = "./resnet.json"
with open(graph_json_path, 'w') as fo:
   fo.write(graph)

# 下面的函数中我们导出神经网络模型的权重参数
param_path = "./resnet.params"
with open(param_path, 'wb') as fo:
   fo.write(relay.save_param_dict(params))
   

3. 模型推理

1.导入所需的库和模块

import onnx

import numpy as np

from scipy.special import softmax

from PIL import Image

import tvm

import tvm.relay as relay

from tvm.contrib import graph_executor

import timeit

        导入了ONNX、NumPy、SciPy、PIL、TVM等相关库和模块。

2.准备输入图像

img_path = "kitten.jpg"

resized_image = Image.open(img_path).resize((224, 224))

img_data = np.asarray(resized_image).astype("float32")

        从文件加载图像,并将其调整为224x224像素大小。

3. 图像预处理

img_data = np.transpose(img_data, (2, 0, 1))

imagenet_mean = np.array([0.485, 0.456, 0.406]).reshape((3, 1, 1)) imagenet_stddev = np.array([0.229, 0.224, 0.225]).reshape((3, 1, 1))

norm_img_data = (img_data / 255 - imagenet_mean) / imagenet_stddev img_data = np.expand_dims(norm_img_data, axis=0)

        调整图像的格式和进行归一化,以符合ResNet50模型的输入要求。

4. 设置TVM的目标和目标主机

target = tvm.target.mali(model='rk3588')

target_host = tvm.target.arm_cpu(model='rk3588')

        这里设置了TVM的目标设备和目标主机,与上一个代码片段中相同。

5. 加载模型结构、权重和参数

libpath = "./resnet.so"

graph_json_path = "./resnet.json"

param_path = "./resnet.params"

loaded_json = open(graph_json_path).read()

loaded_lib = tvm.runtime.load_module(libpath)

loaded_params = bytearray(open(param_path, "rb").read())

        从之前保存的文件中加载神经网络的结构(graph_json_path)、库文件(libpath)、权重参数(param_path)。

6.创建TVM图执行器

dev = tvm.device(str(target), 0)

ctx = dev

module = graph_executor.create(loaded_json, loaded_lib, ctx) module.load_params(loaded_params) module.set_input(input_name, img_data)

        创建一个TVM图执行器,加载模型结构和权重,并设置输入数据。

7. 运行模型

ftimer = module.module.time_evaluator("run", dev, number=1, repeat=30)

prof_res = np.array(ftimer().results) * 1

        使用TVM的时间评估器运行模型,并记录执行时间。

8. 输出模型推理结果

module.run()
output_shape = (1, 1000)
tvm_output = module.get_output(0, tvm.nd.empty(output_shape)).numpy()

        获取模型输出。

9. 加载标签文件

labels_path = "synset.txt"

with open(labels_path, "r") as f:

    labels = [l.rstrip() for l in f]

        从文件加载标签。

10. 后处理和输出预测结果

scores = softmax(tvm_output)

scores = np.squeeze(scores)

ranks = np.argsort(scores)[::-1]

for rank in ranks[0:5]:

    print("class='%s' with probability=%f" % (labels[rank], scores[rank]))

        使用Softmax进行后处理,并输出前五个类别的预测结果及其概率。

11.完整代码

import onnx
import numpy as np
from scipy.special import softmax
from PIL import Image
import tvm
import tvm.relay as relay
from tvm.contrib import graph_executor
import timeit

img_path  = "kitten.jpg"
# Resize it to 224x224
resized_image = Image.open(img_path).resize((224, 224))
img_data = np.asarray(resized_image).astype("float32")

# Our input image is in HWC layout while ONNX expects CHW input, so convert the array
img_data = np.transpose(img_data, (2, 0, 1))

# Normalize according to the ImageNet input specification
imagenet_mean = np.array([0.485, 0.456, 0.406]).reshape((3, 1, 1))
imagenet_stddev = np.array([0.229, 0.224, 0.225]).reshape((3, 1, 1))
norm_img_data = (img_data / 255 - imagenet_mean) / imagenet_stddev

# Add the batch dimension, as we are expecting 4-dimensional input: NCHW.
img_data = np.expand_dims(norm_img_data, axis=0)

target = tvm.target.mali(model='rk3588')
target_host = tvm.target.arm_cpu(model='rk3588')

input_name = "data"
shape_dict = {input_name: img_data.shape}

libpath = "./resnet.so"
# 下面的函数导出我们神经网络的结构,使用json文件保存
graph_json_path = "./resnet.json"
# 下面的函数中我们导出神经网络模型的权重参数
param_path = "./resnet.params"
    
loaded_json = open(graph_json_path).read()
loaded_lib = tvm.runtime.load_module(libpath)
loaded_params = bytearray(open(param_path, "rb").read())

dev = tvm.device(str(target), 0)
ctx = dev
module = graph_executor.create(loaded_json, loaded_lib, ctx)
module.load_params(loaded_params)
module.set_input(input_name, img_data)



ftimer = module.module.time_evaluator("run", dev, number=1, repeat=30)
prof_res = np.array(ftimer().results) * 1  # multiply 1000 for converting to millisecond
print(
    "%-20s %-19s (%s)" % ("resnet50", "%.2f ms" % np.mean(prof_res), "%.2f ms" % np.std(prof_res))
)
module.run()
output_shape = (1, 1000)
tvm_output = module.get_output(0, tvm.nd.empty(output_shape)).numpy()


labels_path = "synset.txt"

with open(labels_path, "r") as f:
    labels = [l.rstrip() for l in f]

# Open the output and read the output tensor
scores = softmax(tvm_output)
scores = np.squeeze(scores)
ranks = np.argsort(scores)[::-1]
for rank in ranks[0:5]:
    print("class='%s' with probability=%f" % (labels[rank], scores[rank]))

12.推理结果

4.完整的代码和模型下载

完整代码icon-default.png?t=N7T8https://download.csdn.net/download/weixin_43999691/88652823?spm=1001.2014.3001.5503

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/267026.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于协同过滤的电影评论数据分析与推荐系统

温馨提示:文末有 CSDN 平台官方提供的学长 QQ 名片 :) 1. 项目介绍 随着社会的发展,人们生活水平的提高,欣赏电影逐渐成为人们闲暇时的主要娱乐方式之一。本文电影推荐系统是为了给顾客提供方便快捷的热门电影推荐以及查询电影资讯而建立的&…

CSB文件上传漏洞 -->Day4(图片挂马)

22二号,冬至啦,深圳这边只有5(尊嘟好冷啊),写这篇文章的时候都已经是凌晨一点了,相信大部分的人都在温暖的被窝里面了吧!!(可怜的我,还得写writeup&#xff0…

JSP打印直角三角形

代码&#xff1a; <%page language"java" contentType"text/html;charsetutf-8"%> <html> <head><title>expressionDemo</title> </head> <body> <h1>以直角三角形的形式输出数字</h1> <table&…

Hadoop入门学习笔记——二、在虚拟机里部署HDFS集群

视频课程地址&#xff1a;https://www.bilibili.com/video/BV1WY4y197g7 课程资料链接&#xff1a;https://pan.baidu.com/s/15KpnWeKpvExpKmOC8xjmtQ?pwd5ay8 Hadoop入门学习笔记&#xff08;汇总&#xff09; 目录 二、在虚拟机里部署HDFS集群2.1. 部署node1虚拟机2.2. 部…

如何在更新 Windows 11 后恢复误删除的文件

在本分步指南中&#xff0c;您将找到在 Windows 11 更新后恢复已删除文件的有用提示和方法。了解数据丢失的原因&#xff1a; 最新版本的 Windows 11 一直是热门话题之一&#xff0c;微软以突破性的方式重新推出了他们的操作系统。 从优雅的界面到严格的安全管理&#xff0c;…

敏捷时代的架构

在敏捷时代&#xff0c;架构如何适应敏捷原则&#xff0c;架构师如何以敏捷的方式与各个团队合作&#xff0c;本文希望能够给出这些问题的答案。原文: Architecture in the Age of Agile 前言 在快节奏的软件开发领域&#xff0c;架构和敏捷这两个看似截然不同的概念碰撞在一起…

Java设计模式-适配器模式

目录 一、生活中的适配器例子 二、基本介绍 三、工作原理 四、类适配器模式 &#xff08;一&#xff09;类适配器模式介绍 &#xff08;二&#xff09;应用实例 &#xff08;三&#xff09;类适配器模式注意事项和细节 五、对象适配器模式 &#xff08;一&#xff09…

【架构】ServerLess

文章目录 概述什么是serverless无服务与传统模式架构区别serverless优缺点使用serverless的应用场景有哪些“无服务器”搭建网站Serverless的落地案例来源 概述 架构 单体&#xff08;三层架构&#xff09;微服务分布式ServerLess 什么是serverless无服务 serverless中文的…

鸿蒙开发语言介绍--ArkTS

1.编程语言介绍 ArkTS是HarmonyOS主力应用开发语言。它在TypeScript (简称TS)的基础上&#xff0c;匹配ArkUI框架&#xff0c;扩展了声明式UI、状态管理等相应的能力&#xff0c;让开发者以更简洁、更自然的方式开发跨端应用。 2.TypeScript简介 自行补充TypeScript知识吧。h…

深入理解Python的logging模块:从基础到高级

在Python编程中&#xff0c;日志记录是一种重要的调试和错误追踪工具。Python的logging模块提供了一种灵活的框架&#xff0c;用于发出日志消息&#xff0c;这些消息可以被发送到各种输出源&#xff0c;如控制台、文件、HTTP GET/POST位置等。本文将深入探讨Python的logging模块…

冒泡排序之C++实现

描述 冒泡排序算法是一种简单的排序算法&#xff0c;它通过将相邻的元素进行比较并交换位置来实现排序。冒泡排序的基本思想是&#xff0c;每一轮将未排序部分的最大元素逐个向右移动到已排序部分的最右边&#xff0c;直到所有元素都按照从小到大的顺序排列。 冒泡排序的算法…

前端工程注入版本号

文章目录 一、前言二、webpack三、vite四、最后 一、前言 容器化时代&#xff0c;当页面出现问题时&#xff0c;如果你的新版本有可能已经修复了&#xff0c;那样你再排查它就没有意义了。为什么不一定是最新版本呢&#xff1f;一是可能是缓存作祟&#xff0c;二是可能运维成员…

每日一题——LeetCode860

个人方法&#xff1a; 用change数组保存我们拥有的零钱的数量&#xff0c;change数组只有change[5]、change[10]、change[20]是有效的&#xff0c;其值代表了不同面值的零钱拥有多少张 顾客付了多少钱&#xff0c;先把钱存入零钱数组&#xff0c;然后计算需要找零的金额&…

HarmonyOS - 鸿蒙开发入门

文章目录 HarmonyOS核心资源特性&#xff1a;全场景终端HarmonyOS 版本 HarmonyOS 和 OpenHarmony教程资源开发环境开发工具 - DevEco开发语言 - ArkTS核心框架 - ArkUI 考证 HarmonyOS 开发交流秋秋群&#xff1a;23458659&#xff0c;V : ez-code&#xff0c;期待交流和合作 …

vue 实验报告8 基于Nuxt.js开发一个Vue程序,实现登录和注册切换

一、步骤&#xff1a; 保证node.js版本在14以上 1. 全局安装create-nuxt-app: npm install -g create-nuxt-app2.9.x 2. 创建项目: create-nuxt-app my-nuxt-demo 选项这么选&#xff1a; 然后输入&#xff1a; cd my-nuxt-demo 3. 创建登录和注册页面: 在/pages目录下创建logi…

Docker知识总结

Docker 学习目标&#xff1a; 掌握Docker基础知识&#xff0c;能够理解Docker镜像与容器的概念 完成Docker安装与启动 掌握Docker镜像与容器相关命令 掌握Tomcat Nginx 等软件的常用应用的安装 掌握docker迁移与备份相关命令 能够运用Dockerfile编写创建容器的脚本 能够…

【小沐学写作】Docsify制作在线电子书、技术文档(Docsify + Markdown + node)

文章目录 1、简介2、安装2.1 node2.2 docsify-cli 3、配置3.1 初始化3.2 预览效果3.3 加载对话框3.4 更多页面3.5 侧 栏3.6 自定义导航栏 结语 1、简介 https://docsify.js.org/#/?iddocsify 一个神奇的文档网站生成器。 简单轻巧没有静态构建的 html 文件多个主题 Docsify…

跨平台Markdown编辑软件Typora mac功能介绍

Typora mac是一款跨平台的Markdown编辑器&#xff0c;支持Windows、MacOS和Linux操作系统。它具有实时预览功能&#xff0c;能够自动将Markdown文本转换为漂亮的排版效果&#xff0c;让用户专注于写作内容而不必关心格式调整。Typora Mac版除了支持常见的Markdown语法外&#x…

【测试开发】测试用例讲解

文章目录 目录 文章目录 前言 一、测试用例的基本要素 二、测试用例的设计方法 1.基于需求的设计方法 对日历根据web界面的功能布局分析出的功能框图如下&#xff1a; 继续举一个例子百度云盘非功能测试的案例&#xff1a; 2.等价类 3.边界值 5.正交表 6.场景设计法 7…