【深度学习】快速部署ONNX模型【入门】

news2025/2/28 3:30:55

【深度学习】快速部署ONNX模型【入门】

提示:博主取舍了很多大佬的博文并亲测有效,分享笔记邀大家共同学习讨论

文章目录

  • 【深度学习】快速部署ONNX模型【入门】
  • 前言
  • 搭建打包环境
  • 打包exe文件
  • 总结


前言

之前的内容已经尽可能简单、详细的介绍CPU【Pytorch2ONNX】和GPU【Pytorch2ONNX】俩种模式下Pytorch模型转ONNX格式的流程,本博文根据自己的学习和需求进一步讲解ONNX模型的部署。onnx模型博主将使用PyInstaller进行打包部署,PyInstaller是一个用于将Python脚本打包成独立可执行文件的工具,在之前的python程序打包成可执行文件【入门篇】中已经进行了最基本的使用讲解。


搭建打包环境

读者可以创建一个纯净的、没有多余的第三方库和模块的小型Python环境,用尽可能的少的库和模块来打包exe可执行文件。博主在GPU模式下成功将Pytorch模型转化成了ONNX模型,因此不在对转化过程再做讲解,详细内容查看前言提供的访问链接。

# name 环境名、3.x Python的版本
conda create -n deploy python==3.10
# 激活环境
activate deploy 
# 安装onnx
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple onnx
# 安装GPU版
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple onnxruntime-gpu==1.15.0
# 下载安装Pyinstaller模块
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple Pyinstaller
# 根据个人情况安装包,博主这里需要安装piilow
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple Pillow

现在抛开任何pytorch相关的依赖,只使用onnx模型完成测试。


打包exe文件

打包run.py文件成可执行文件,以下是run.py的代码内容:

import onnxruntime as ort
import numpy as np
from PIL import Image
import time
import datetime
import sys
import os

def composed_transforms(image):
    mean = np.array([0.485, 0.456, 0.406])  # 均值
    std = np.array([0.229, 0.224, 0.225])  # 标准差
    # transforms.Resize是双线性插值
    resized_image = image.resize((args['scale'], args['scale']), resample=Image.BILINEAR)
    # onnx模型的输入必须是np,并且数据类型与onnx模型要求的数据类型保持一致
    resized_image = np.array(resized_image)
    normalized_image = (resized_image/255.0 - mean) / std
    return np.round(normalized_image.astype(np.float32), 4)

def check_mkdir(dir_name):
    if not os.path.exists(dir_name):
        os.makedirs(dir_name)

args = {
    'scale': 416,
    'save_results': True
}
def main():
    # 保存检测结果的地址
    input = sys.argv[1]
    providers = ["CUDAExecutionProvider"]
    # providers = ["CPUExecutionProvider"]
    ort_session = ort.InferenceSession("PFNet.onnx", providers=providers)  # 创建一个推理session
    input_name = ort_session.get_inputs()[0].name
    print('Load {} succeed!'.format('PFNet.onnx'))
    # 输出有四个
    output_names = [output.name for output in ort_session.get_outputs()]
    start = time.time()
    time_list = []
    # 图片保存位置
    image_path = os.path.join(input, 'images')
    # 掩码保存位置,博主这里因为是实例所以保存在同一目录下了
    mask_path = os.path.join(input, 'masks')
    if args['save_results']:
        check_mkdir(mask_path)
    img_list = [os.path.splitext(f)[0] for f in os.listdir(image_path) if f.endswith('jpg')]
    for idx, img_name in enumerate(img_list):
        img = Image.open(os.path.join(image_path, img_name + '.jpg')).convert('RGB')
        w, h = img.size
        #  对原始图像resize和归一化
        img_var = composed_transforms(img)
        # np的shape从[w,h,c]=>[c,w,h]
        img_var = np.transpose(img_var, (2, 0, 1))
        # 增加数据的维度[c,w,h]=>[bathsize,c,w,h]
        img_var = np.expand_dims(img_var, axis=0)
        start_each = time.time()
        prediction = ort_session.run(output_names, {input_name: img_var})
        time_each = time.time() - start_each
        time_list.append(time_each)
        # 除去多余的bathsize维度,NumPy变会PIL同样需要变换数据类型
        # *255替换pytorch的to_pil
        prediction = (np.squeeze(prediction[3])*255).astype(np.uint8)
        if args['save_results']:
           mask = Image.fromarray(prediction).resize((w, h))
           Image.fromarray(mask).save(os.path.join(mask_path, img_name + '.jpg'))
    end = time.time()
    print("Total Testing Time: {}".format(str(datetime.timedelta(seconds=int(end - start)))))
if __name__ == '__main__':
    main()

打包可执行文件也分cpu和gpu模式,只需要修改providers变量内容即可,二者只能选其一。

# cpu模式
providers = ["CPUExecutionProvider"]
# gpu模式
providers = ["CUDAExecutionProvider"]
  • 在cpu模式下打包可执行文件:
    pyinstaller -F run.py
    
    原本是run_onnx.exe,这里博主是做了重命名,cpu模式下的占用空间比较小。
    执行exe文件:将onnx权重文件与run_cpu.exe放置在一起,打开cmd,并进入run_cpu.exe执行命令。这里博主通过传递参数可以指定执行的分割的图片路径。

    在指定目录下的mask文件夹内保存结果。
  • 在gpu模式下打包可执行文件:
    pyinstaller打包会报onnxruntime-gpu时缺少onnxruntime-cuda的动态库。使用y在打包时需要加上动态库。
    pyinstaller -F run.py --add-binary "D:/ProgramData/Anaconda3_data/envs/deploy/Lib/site-packages/onnxruntime/capi/onnxruntime_providers_cuda.dll;./onnxruntime/capi" --add-binary "D:/ProgramData/Anaconda3_data/envs/deploy/Lib/site-packages/onnxruntime/capi/onnxruntime_providers_shared.dll;./onnxruntime/capi"
    
    –add-binar第一个是依赖库的位置,第二个是打包exe指定依赖库的位置。
    原本是run_onnx.exe,这里博主是做了重命名,gpu模式下的占用空间比较大。
    执行exe文件:

到这里整个onnx的打包过程已经结束了,补充一点,假如需要将exe迁移到其他主机,cpu版本的exe是不在需要其他额外的以来的,只需要与onnx权重文件一起使用,gpu版本的exe则需要添加额外的依赖,因为绝大部分迁移主机是不会安装cuda的,因此需要在你的cuda安装路径下拷贝出所需的依赖。
博主的cuda安装路径:C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.8。
在bin目录下拷贝出cudnn_ops_train64_8.dll和cudnn_cnn_infer64_8.dll文件到run_gpu.exe目录下。
在这里插入图片描述
到这里就可以放心的将exe迁移到其他显卡支持cuda运算的主机上了。


总结

尽可能简单、详细的介绍ONNX模型的部署过程。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

编译opencv-3.4.5 [交叉编译]

在unbuntu20.04环境下编译opencv3.4.5, cmake 版本:3.27.4 gcc 版本:11.4.0 g版本:11.4.0 在此环境下编译opencv4.5.4正常。 1. 编译时遇到的问题 (1) Built target libprotobuf make: *** [Makefile:163…

玩玩“小藤”开发者套件 Atlas 200I DK A2 之部署智能语音助手

玩玩“小藤”开发者套件 Atlas 200I DK A2 之部署智能语音助手 0. 背景1. 安装 flac2. 创建自签名证书3. 创建虚拟环境4. 安装PyTorch5. 安装 PyTorch 插件 torch_npu6. 安装APEX混合精度模块7. 安装依赖库8. 使用 gradio 启动智能语音助手9. 访问智能语音助手 0. 背景 总所周…

和逸云 RK3229 如何进入maskrom强刷模式

图中红圈两个点短接以后插usb,就可以进入maskrom模式强刷

【JavaEE】多线程(四)

多线程(四) 在开始讲之前,我们先来回顾回顾前三篇所讲过的内容~ 线程的概念 并发编程,多进程,比较重,频繁创建销毁,开销大 Thread的使用 创建线程 继承Thread实现Runnable继承Thread&#xff…

提交本地项目到GitHub

文章目录 1 下载git1.1 通过homebrew安装Git1.2 通过Xcode安装 2 创建ssh key、配置git3 提交本地项目到GitHub 说明:该博文参考这篇文章和这段视频 1 下载git 1.1 通过homebrew安装Git 1、未安装homebrew,需安装homebrew /usr/bin/ruby -e "$(…

踩坑:Invalid character found in method name. HTTP method names must be tokens

一、原因 在进行本地小程序与服务端请求时,由于加了签名认证,访问接口时报错 Spring boot端 小程序端 二、解决方案 2.1 更改访问路径 将https:更换成http: 示例:https://localhost:8080 改为 http://localhost:8080 2.2其他原因 ssl证书到期了Tomcat的header缓冲区大小不…

使用docker-compose 部署 MySQL8.0

目录 一、拉取MySQL镜像二、创建挂载目录三、添加配置文件my.cnf (没有特殊需求可以跳过)四、编写 docker-compose.yml 文件五、启动容器六、运行后查看启动容器的情况七、连接测试 一、拉取MySQL镜像 我这里使用的是MySQL8.0.18,可以自行选…

pycharm 中package, directory, sources root, resources root的区别

【遇到的问题】 导入yolov5中有utils文件,自己的代码中也有utils文件,使得yolov5中的这部分引用出错了。 【解决方案】 单独建立detection文件夹,把检测相关的都放在这里,yolov5是github上拉取的源码,发现yolov5中fr…

用于设计 CNN 的 7 种不同卷积

一 说明 最近对CNN架构的研究包括许多不同的卷积变体,这让我在阅读这些论文时感到困惑。我认为通过一些更流行的卷积变体的精确定义,效果和用例(在计算机视觉和深度学习中)是值得的。这些变体旨在保存参数计数、增强推理并利用目标…

scryptTS 新版本发布

scryptTS新版本发布,主要带来两个新特性。 您需要使用以下版本来体验: "dependencies": {"scrypt-ts": "0.1.5-beta.2" },1. scryptTS 中隐藏了交易原像 OP_PUSH_TX 技术 使用 OP_PUSH_TX 可以让合约代码访问整个 trans…

解决:Android Studio 中sdk tools 中库显示不全的问题

问题描述 如下图,打开配置后显示不全 解决方案 这是网络问题,由于Android Studio是goolge旗下的产品,多少需要向外访问 通过更改hosts文件即可,用记事本打开,末尾添加如下三行 203.208.43.97 dl.google.com 20…

1.3python基础语法——PyCharm

1)PyCharm的作用 python的集成开发环境,功能如下: Project管理 智能提示 语法高亮 代码跳转 调试代码 解释代码(解释器) 框架和库 2)下载与安装 下载地址:http://www.jetbrains.com/pycharm/download/#sectionwind…

flash attention的CUDA编程和二维线程块实现softmax

本文参考了链接添加链接描述 flash attention介绍 flash attention的介绍可以参考论文:FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness,具体的数学公式参考下面这个图片:其中注意关于矩阵S有两个维度,softmax的操作维度是dim=1,用pytorc…

python 全网最优雅命令行参数解析, 没有之一

背景 我们在编写python程序时,程序中经常会提供多种功能或者模式,在实际使用时根据不同的参数使用不同的功能。那么如何获取命令行传入进来的参数呢? 一般方法 一般情况下,我们会使用 sys 模块,如👇 im…

Python - 小玩意 - 请求网络地址获取网页链接

from bs4 import BeautifulSoup from urllib import request # 要请求的网络地址 url https://blog.csdn.net/qq_43116031/ # pip --default-timeout500000 install bs4 # 请求网络地址得到html网页代码 html request.urlopen(url)# 整理代码 soup BeautifulSoup(html, html…

深度学习论文: ISTDU-Net:Infrared Small-Target Detection U-Net及其PyTorch实现

深度学习论文: ISTDU-Net:Infrared Small-Target Detection U-Net及其PyTorch实现 ISTDU-Net:Infrared Small-Target Detection U-Net PDF: https://doi.org/10.1109/LGRS.2022.3141584 PyTorch代码: https://github.com/shanglianlm0525/CvPytorch PyTo…

GPT,GPT-2,GPT-3,InstructGPT的进化之路

ChatGPT 火遍圈内外,突然之间,好多人开始想要了解 NLP 这个领域,想知道 ChatGPT 到底是个什么?作为在这个行业奋斗5年的从业者,真的很开心让人们知道有一群人在干着这么样的一件事情。这也是我结合各位大佬的文章&…

MTK联发科MT6853和MT6873安卓核心板性能参数对比

联发科MTK6853芯片,又名天玑720,是一款具有先天的节能创新的5G芯片。天玑800(MTK6873)和天玑720二款处理器都是使用于中高端手机中,那么天玑720和天玑800处理器到底哪个更好呢? 1、处理器性能对比 天玑7…

系统架构设计师(第二版)学习笔记----系统分析与设计及测试

【原文链接】系统架构设计师(第二版)学习笔记----软件测试 文章目录 一、结构化方法1.1 结构化开发方法1.2 结构化分析使用的手段1.3 结构化分析的步骤1.4 数据流图(DFD)的基本元素1.5 数据流图(DFD)方法建…

【LeetCode-中等题】429. N 叉树的层序遍历

文章目录 题目方法一&#xff1a;二叉树的层序遍历的扩展 题目 方法一&#xff1a;二叉树的层序遍历的扩展 思路和二叉树的层序遍历一样&#xff0c;这一题的关键在于取出每个节点的孩子 for(int j 0;j<root.children.size();j)//取出所有当前节点的所有孩子节点放到队列…