YOLO 模型從 PyTorch 轉換為 ONNX 并優化

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 年,他在工地上再次聽人提起區塊鏈,…