YOLO 模型从 PyTorch 转换为 ONNX 并优化

在深度学习部署中,ONNX(Open Neural Network Exchange) 已成为跨框架与跨平台的标准格式。我们经常需要将 YOLOv8 在 PyTorch 中训练好的模型转换为 ONNX,并进行优化,以便在 CPU、GPU 或边缘设备 上高效推理。

本文将详细介绍:

  1. 如何从 PyTorch 导出 YOLOv8 为 ONNX
  2. 如何用 onnxruntime 优化模型(包含新旧版本对比)
  3. 每个操作的意义
  4. 优化选项与参数说明

1. 为什么要优化 ONNX 模型?

导出的原始 ONNX 文件里,可能包含很多“冗余算子”或“不适合推理加速的计算方式”。
比如:

  • 多余的 TransposeIdentity 节点。
  • 可合并的 Conv → BatchNorm → Relu
  • 未展开的常量。

优化的目的就是:减少节点数、合并算子、提升推理速度,同时不改变模型的计算逻辑。


2. onnxruntime 的优化机制

onnxruntime 里,优化是在 InferenceSession 初始化 时完成的,控制参数就是:

options = ort.SessionOptions()
options.graph_optimization_level = ort.GraphOptimizationLevel.ORT_ENABLE_ALL

2.1 优化级别(GraphOptimizationLevel)

onnxruntime 提供 4 种优化级别:

选项作用典型场景
ORT_DISABLE_ALL完全不做优化调试/测试
ORT_ENABLE_BASIC基础优化:常量折叠、消除无用节点保守优化,结果最安全
ORT_ENABLE_EXTENDED扩展优化:算子融合(Conv+BN+Relu),节点重排序性能更好,常用
ORT_ENABLE_ALL启用所有可用优化,包括 layout 优化、内存重用生产环境推荐

默认是 ORT_ENABLE_ALL,你可以按需求调节。

2.2 其他常用参数(SessionOptions)

options.intra_op_num_threads = 4   							# 单个算子内部使用的线程数
options.inter_op_num_threads = 2   							# 不同算子之间的并行线程数
options.execution_mode = ort.ExecutionMode.ORT_PARALLEL  	# 启用并行执行
options.enable_mem_pattern = True  							# 内存复用模式
options.enable_cpu_mem_arena = True  						# CPU 内存分配优化

📌 意义

  • 线程数控制可以充分利用 CPU 多核。
  • 内存优化选项可以减少内存占用,适合边缘设备。

3. 优化的保存方式

旧版本(≤1.16):

  • 优化只存在于内存,不会保存到 .onnx 文件。
  • 即使你 onnx.save(),保存的还是原始模型

新版本(≥1.17):

  • 可以用:

    options.optimized_model_filepath = "yolov8n_optimized.onnx"
    

    这样在 Session 初始化时,会把优化后的图写入文件。

👉 这就是新版和旧版最大的区别。


4. 环境准备

安装必要依赖:

pip install ultralytics onnx onnxruntime

如果需要高级优化(算子融合、量化),还可以安装:

pip install onnxruntime-tools

确认版本(非常关键,因为 API 有变化):

pip show onnxruntime
  • 旧版 onnxruntime:≤ 1.16.x
  • 新版 onnxruntime:≥ 1.17.0

5. 从 PyTorch 导出 YOLOv8 为 ONNX

from ultralytics import YOLO
from pathlib import PathMODELS_DIR = Path("models")# 加载 YOLOv8 模型
model = YOLO(str(MODELS_DIR / "yolov8n.pt"))# 导出为 ONNX 格式
model.export(format="onnx")
  • 输入:PyTorch 的 .pt 模型
  • 输出yolov8n.onnx
  • 意义:ONNX 模型是跨平台的,可以在不同推理引擎(onnxruntime、TensorRT、OpenVINO)中运行。

👉 导出后,你可以用 Netron 查看模型结构,检查输入/输出 shape 是否正确。

在这里插入图片描述

5.1 什么是 Netron?

Netron 是一个 神经网络模型可视化工具,用来查看 .onnx.pt.h5.tflite 等模型的网络结构。

  • 你可以 直观查看每一层的算子(Conv、Relu、FC 等)。
  • 支持 模型输入输出 shape、权重信息
  • 非常适合在导出 ONNX 后,检查网络结构是否符合预期。

5.2 怎么使用 Netron?

  1. 安装(桌面应用 / 浏览器版):

    • 桌面版下载地址:https://github.com/lutzroeder/netron
    • 浏览器版直接打开:https://netron.app
  2. 打开模型:

    • 在桌面应用里,直接拖拽 yolov8n.onnx 文件进去。
    • 在网页端,点击 Open Model 上传模型。
  3. 查看结构:

    • 你会看到类似一张「流程图」,每一层算子(Conv、BN、Relu、Concat 等)都展示出来。
    • 可以点选层节点,查看 输入/输出 shape权重参数

在这里插入图片描述

5.3 为什么要用 Netron?

  • 确认 ONNX 导出是否成功(有时候导出会缺少算子或层)。
  • 检查 输入输出 shape 是否正确(例如 YOLO 输入是否是 1x3x640x640)。
  • 验证 模型优化前后层结构是否保持一致

它就像模型的「显微镜」,帮我们把黑盒的 .onnx 文件拆开看清楚。


6. 优化 ONNX 模型(onnxruntime)

6.1 新旧版本对比

对比项旧版 onnxruntime (≤1.16.x)新版 onnxruntime (≥1.17.0)
导入方式from onnxruntime import GraphOptimizationLevel, SessionOptionsimport onnxruntime as ort
设置优化级别options.graph_optimization_level = GraphOptimizationLevel.ORT_ENABLE_ALLoptions.graph_optimization_level = ort.GraphOptimizationLevel.ORT_ENABLE_ALL
创建 Sessionsession = ort.InferenceSession("model.onnx", options)session = ort.InferenceSession("model.onnx", sess_options=options)
保存优化模型❌ 不支持,优化仅存在内存options.optimized_model_filepath = "optimized.onnx"
是否推荐⚠️ 已过时✅ 官方推荐

6.2 新版写法(推荐,onnxruntime ≥ 1.17)

import onnxruntime as ort
from pathlib import PathMODELS_DIR = Path("models")
onnx_path = str(MODELS_DIR / "yolov8n.onnx")
optimized_path = str(MODELS_DIR / "yolov8n_optimized.onnx")# 设置优化选项
options = ort.SessionOptions()
options.graph_optimization_level = ort.GraphOptimizationLevel.ORT_ENABLE_ALL
options.optimized_model_filepath = optimized_path# 创建 Session(会触发优化并保存)
session = ort.InferenceSession(onnx_path, sess_options=options)print(f"优化后的模型已保存到: {optimized_path}")

📌 意义

  • 优化发生在 Session 初始化 阶段。
  • 优化图会被写入文件,避免每次加载时重复优化。
  • 部署时直接加载优化好的 .onnx,加快推理启动速度。

在这里插入图片描述

6.3 旧版写法(已过时,onnxruntime ≤ 1.16.x)

from onnxruntime import GraphOptimizationLevel, SessionOptions
import onnxruntime as ortoptions = SessionOptions()
options.graph_optimization_level = GraphOptimizationLevel.ORT_ENABLE_ALLsession = ort.InferenceSession("yolov8n.onnx", options)

⚠️ 问题

  • 优化仅存在内存,不会保存到 .onnx 文件。
  • 部署时需要每次重新优化,影响启动性能。

7. 高级优化(可选,onnxruntime-tools)

如果需要进一步优化(算子融合、Transformer 专用优化、量化),可以用:

from onnxruntime_tools import optimizer
from pathlib import PathMODELS_DIR = Path("models")
onnx_path = str(MODELS_DIR / "yolov8n.onnx")
optimized_path = str(MODELS_DIR / "yolov8n_tools_optimized.onnx")# YOLO 没有专用类型,"transformer" 或 "bert" 都能工作
optimized_model = optimizer.optimize_model(onnx_path,model_type="bert",opt_level=99
)optimized_model.save_model_to_file(optimized_path)
print(f"进一步优化后的模型已保存到: {optimized_path}")

在这里插入图片描述


8. InferenceSession 和 onnxruntime-tools 对比

方法优点缺点
onnxruntime-tools支持更多优化策略(图融合、量化),可控性强需要额外安装
options.optimized_model_filepath依赖少,直接在 onnxruntime 里完成只做 onnxruntime 的图级优化,不包含高级策略

9. 验证优化后的模型

优化后需要验证模型是否能正确推理:

import numpy as np# 加载优化模型
session = ort.InferenceSession(str(MODELS_DIR / "yolov8n_optimized.onnx"))# 构造随机输入 (1, 3, 640, 640)
input_data = np.random.randn(1, 3, 640, 640).astype(np.float32)# 获取输入/输出名称
input_name = session.get_inputs()[0].name
output_name = session.get_outputs()[0].name# 运行推理
outputs = session.run([output_name], {input_name: input_data})print(outputs)

📌 意义

  • 确保优化后的模型依然输出正确结果。
  • 可以进一步对比 PyTorch 原始输出和 ONNX 输出,确保差异在数值误差范围内(1e-4 ~ 1e-6)。

在这里插入图片描述


10. 总结

  • 转换:使用 Ultralytics 将 YOLOv8 .pt 导出为 .onnx
  • 优化:用 onnxruntime 的 SessionOptions,推荐设置 graph_optimization_level = ORT_ENABLE_ALL,并保存为新文件。
  • 版本差异:onnxruntime ≥ 1.17 才能保存优化模型;旧版仅内存优化。
  • 参数调整:可以通过线程数和内存选项进一步提升性能。
  • 验证:运行推理,确认优化模型与原始模型一致。
  • 高级优化:onnxruntime-tools 可做更激进的算子融合与量化。

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

推进新型信息基础设施建设发展:蜂窝模组行业迎来结构性机遇

工信部副部长张云明在2025年9月9日国新办新闻发布会上明确表示,将"扎实推进新型信息基础设施建设发展",并重点强调"打造新型工业网络,推进蜂窝车联网部署" 。这一政策表态对蜂窝模组行业产生深远影响,将推动行…

返利app排行榜的缓存更新策略:基于过期时间与主动更新的混合方案

返利app排行榜的缓存更新策略:基于过期时间与主动更新的混合方案 大家好,我是阿可,微赚淘客系统及省赚客APP创始人,是个冬天不穿秋裤,天冷也要风度的程序猿! 在返利APP中,“热门商品排行榜”“用…

科技信息差(9.12)

AI量子计算重塑药物研发:技术融合路径与产业革命一、引言:技术融合的颠覆性机遇2025年9月,AI药物研发公共服务平台正式上线,宣称可将新药上市时间缩短近半1。与此同时,量子计算与AI的跨界合作在KRAS抑制剂开发中取得突…

Java 分布式缓存实现:结合 RMI 与本地文件缓存

目录 一、核心思路 二、项目结构说明 2.1 服务端项目结构(IDEA) 2.2 客户端项目结构(Eclipse) 三、服务端实现(IDEA) 3.1 数据库访问层 3.2 远程接口定义 3.3 远程服务实现 3.4 服务端启动类 四、…

Electron第一个应用

1、安装node nodeJS下载 2、下载完成,需要配置环境。 写道path路径 、 3、安装完成,查看版本 npm -v4、 配置cnpm npm install -g cnpm --registryhttps://registry.npmmirror.com5、参考Electron 写: Electron第一个程序hello 6、安装…

React 原理篇 - React 新架构深度解析

使用过 React v16 之前版本的开发者或许都经历过这样的场景:当页面包含复杂组件或大量列表时,输入框打字会卡顿,滚动会不流畅。这些体验问题的背后,往往与 React 的渲染机制密切相关。2017 年 React v16 推出的 Fiber 架构&#x…

【JavaSE五天速通|第三篇】常用API与日期类篇

适合有其他语言基础想快速入门JavaSE的。用的资料是 Java入门基础视频教程 ,从中摘取了笔者认为与其他语言不同或需要重点学习的内容 常用API与日期类只需要有印象即可,用到了再来这查 day04 常用API 一、StringBuilder类 StringBuilder代表可变字符…

K8s学习笔记(二) Pod入门与实战

1 K8s核心资源Pod 1.1 Pod是什么? 官方文档:Pod | Kubernetes Pod 是 Kubernetes(k8s)中最小的部署与调度单元,并非直接运行容器,而是对一个或多个 “紧密关联” 容器的封装。 核心特点可简单总结为 3 …

用 Python 调用 Bright Data MCP Server:在 VS Code 中实现实时网页数据抓取

用 Python 调用 Bright Data MCP Server:在 VS Code 中实现实时网页数据抓取,本文介绍了Bright Data的Web MCP Server,这是一款能实现实时、结构化网页数据访问的API,适用于AI应用等场景。其支持静态与动态网页,前3个月…

SPSS绘制ROC曲线并计算灵敏度、特异度

SPSS绘制ROC曲线并计算灵敏度、特异度。 (1)绘制ROC曲线: 输入:预测值、受试者标签。 在SPSS中点击“分析”-“分类”-“ROC曲线” 变量输入:检验变量输入预测值,状态变量输入受试者标签,如果标…

Modbus协议原理与Go语言实现详解

目录 Modbus协议概述协议架构与通信模式Modbus数据模型Modbus协议帧格式功能码详解Go Modbus库完整实现高级应用示例调试与故障排除 Modbus协议概述 Modbus是一种串行通信协议,由Modicon公司(现施耐德电气)于1979年开发,用于PL…

下载CentOS 7——从阿里云上下载不同版本的 CentOS 7

没有废话,直接上干货。跟着图片教程,一步一步来就行。 想下载其它版本的,自己可以再选择其它的就行。 想省事的朋友可以直接点击: 1、下载页面链接 2、CentOS-7-x86_64-DVD-2207-02(4.4GB).iso

SpringBoot -原理篇

文章目录配置优先级Bean管理获取beanbean作用域第三方beanSpringBoot原理起步依赖自动配置自动配置原理方案源码跟踪原理分析 Conditional案例(自定义starter)案例(自定义starter分析)案例(自定义starter实现&#xff…

JavaScript与jQuery:从入门到面试的完整指南

JavaScript与jQuery:从入门到面试的完整指南 第一部分:JavaScript基础 1.1 JavaScript简介 JavaScript是一种轻量级的解释型编程语言,主要用于Web开发,可以为网页添加交互功能。它是ECMAScript规范的一种实现。 // 第一个JavaScri…

解决:Ubuntu、Kylin、Rocky系统中root用户忘记密码

解决Linux系统中root用户忘记密码 Ubuntu2204 重启电脑,启动时,长按Shift键(对于 BIOS 系统)或 Esc 键(对于 UEFI 系统)进入GRUB菜单 步骤1:重启Ubuntu系统,长按Shift键进入Ubuntu…

ENVI系列教程(二)——自定义坐标系(北京 54、西安 80、2000 坐标系)

目录 1 概述 1.1 地理投影的基本原理 1.2 国内坐标系介绍 1.3 参数的获取 2 详细操作步骤 2.1 添加椭球体 2.2 添加基准面 2.3 定义坐标系 2.4 使用自定义坐标系 1 概述 1.1 地理投影的基本原理 常用到的地图坐标系有 2 种,即地理坐标系和投影坐标系。地理坐标系是…

一种基于因果干预的少样本学习的故障诊断模型

一、研究背景与问题 ​工业背景​:机械故障诊断对工业系统安全至关重要,但实际中故障样本稀少,难以训练传统深度学习模型。 ​现有问题​: 当前少样本学习(FSL)方法大多基于相关性而非因果关系建模,容易学习到伪相关特征,导致模型可解释性差、泛化能力弱。 跨组件故障诊…

机器视觉光源的尺寸该如何选型的方法

机器视觉光源的尺寸该如何选型的方法🎯机器视觉光源的尺寸选型的方法🎯一、选型案例🎯二、照射方式🎯三、镜头选择🎯四、光源架构光源的工作距离与视野大小🎯五、总结:光源选型 —— 机器视觉检…

HTML新属性

HTML5引入了许多新属性,旨在增强语义化、交互性和多媒体支持。以下是一些重要的新属性及其用途分类:语义化与结构属性data-*:自定义数据属性,允许开发者存储额外信息(如data-id"123")。hidden&am…

从工地到链上:一个土建人的 Web3 转行经历

Web3 的风,终究还是吹到了土建行业。2017 年,土建专业(给排水工程)的刘正源偶然看到一则关于比特币的新闻,被它背后的经济模型与技术架构深深震撼。到了 2021 年,他在工地上再次听人提起区块链,…