news 2026/4/3 6:26:55

YOLO26如何导出模型?onnx转换部署实战教程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
YOLO26如何导出模型?onnx转换部署实战教程

YOLO26如何导出模型?ONNX转换部署实战教程

YOLO26作为Ultralytics最新发布的高性能目标检测与姿态估计统一架构,凭借其轻量化设计、多任务协同能力和开箱即用的工程友好性,正快速成为工业落地新选择。但很多用户在完成训练后卡在关键一步:怎么把训练好的.pt模型转成ONNX,再部署到边缘设备或推理引擎上?本文不讲理论、不堆参数,只聚焦一个动作——手把手带你从YOLO26训练镜像出发,完成模型导出、格式验证、推理测试全流程,所有命令可直接复制粘贴运行,连路径都帮你写好了。

1. 为什么必须导出ONNX?不是直接用.pt就行吗?

先说结论:.pt是PyTorch训练专用格式,不能直接部署;ONNX才是跨平台推理的“通用语言”。

你可能已经用model.predict()跑通了推理,但那只是在GPU服务器上“玩得转”。一旦要部署到Jetson、RK3588、树莓派,或者集成进C++/Java生产系统,甚至上云做API服务,就必须把模型变成ONNX——它不依赖Python环境,能被TensorRT、ONNX Runtime、OpenVINO等主流推理引擎直接加载。

更重要的是,YOLO26的官方代码(ultralytics v8.4.2)对ONNX导出做了深度适配:支持动态batch、动态输入尺寸、带NMS后处理的端到端导出。这意味着你导出的ONNX文件,不用自己写NMS逻辑,推理时直接输出框坐标+类别+置信度,省去90%的后处理开发工作。

所以,导出不是可选项,而是工程落地的必经关卡。

2. 准备工作:确认环境与模型路径

本教程基于你已启动的「YOLO26官方训练与推理镜像」,我们跳过环境安装,直奔核心。请按顺序执行以下三步,确保基础就绪:

2.1 激活专属环境并进入工作目录

conda activate yolo cd /root/workspace/ultralytics-8.4.2

验证:执行python -c "import torch; print(torch.__version__)"应输出1.10.0;执行which python应指向/root/miniconda3/envs/yolo/bin/python

2.2 确认待导出模型位置

镜像中已预置多个权重文件,路径统一为:

  • yolo26n.pt—— 检测主干(YOLOv8n级轻量)
  • yolo26n-pose.pt—— 检测+姿态估计双任务
  • yolo26s.pt—— 中等规模检测模型

你也可以用自己训练好的模型,比如runs/train/exp/weights/best.pt。只要路径正确,导出流程完全一致。

2.3 安装ONNX相关依赖(镜像已预装,仅需验证)

pip list | grep -i onnx

应看到onnx,onnxruntime,onnx-simplifier三个包。若缺失,执行:

pip install onnx onnxruntime onnx-simplifier

3. 核心操作:一行命令导出ONNX模型

Ultralytics官方提供了极简导出接口,无需修改源码、无需手写导出脚本。只需一条命令:

3.1 基础导出命令(推荐新手)

yolo export model=yolo26n.pt format=onnx imgsz=640 dynamic=True opset=17
  • model=:指定输入模型路径(支持.pt.yaml
  • format=onnx:明确导出目标格式
  • imgsz=640:设定默认输入分辨率(YOLO26支持动态尺寸,此处为基准值)
  • dynamic=True关键!开启动态轴,让batch、height、width均可变,适配不同场景
  • opset=17:ONNX算子集版本,兼容TensorRT 8.6+和ONNX Runtime 1.15+

执行后,终端会显示类似:

Export complete (12.4s) Saved as: /root/workspace/ultralytics-8.4.2/yolo26n.onnx

导出文件将生成在当前目录,同名.onnx后缀。

3.2 进阶导出:带姿态估计的端到端模型

如果你用的是yolo26n-pose.pt,导出命令完全一样,但输出模型会自动包含姿态关键点分支:

yolo export model=yolo26n-pose.pt format=onnx imgsz=640 dynamic=True opset=17

导出后的ONNX模型,输出节点包含:

  • output0:检测结果([batch, num_boxes, 5+nc],含xywh+conf+cls)
  • output1:姿态关键点([batch, num_boxes, 17, 3],含x,y,conf)

提示:17是COCO关键点数量,如需自定义,需在模型配置中修改kpt_shape参数。

3.3 自定义导出:控制输入输出行为

某些场景需要更精细控制,例如:

  • 固定batch为1(嵌入式设备常用)
  • 指定输入名称便于后续绑定
  • 禁用自动NMS(自己实现后处理)

使用Python脚本方式导出更灵活:

# export_onnx.py from ultralytics import YOLO if __name__ == '__main__': # 加载模型(不加载权重,仅结构) model = YOLO('yolo26n.yaml') # 或 'yolo26n.pt' # 导出ONNX,传入完整参数 model.export( format='onnx', imgsz=640, dynamic=True, opset=17, simplify=True, # 自动优化图结构(推荐) batch=1, # 强制固定batch=1 device='cpu', # CPU导出更稳定 half=False, # 不启用FP16(ONNX暂不支持FP16输入) nms=True, # 保留NMS后处理(默认True) verbose=True )

运行:python export_onnx.py

4. 验证导出结果:三步确认ONNX可用性

导出成功≠能用。必须验证模型结构、输入输出、推理逻辑是否符合预期。

4.1 查看模型基本信息

安装ONNX可视化工具:

pip install netron

然后在终端启动:

netron yolo26n.onnx

浏览器会自动打开Netron界面,你能清晰看到:

  • 输入节点:images(shape: [1,3,640,640],dtype: float32)
  • 输出节点:output0(检测)、output1(姿态,若存在)
  • 所有算子类型(Conv, Resize, NonMaxSuppression等)

正常状态:无红色报错,NMS节点存在,输入尺寸与你设置一致。

4.2 用ONNX Runtime做最小化推理测试

创建test_onnx.py验证前向推理是否正常:

import cv2 import numpy as np import onnxruntime as ort # 加载ONNX模型 session = ort.InferenceSession('yolo26n.onnx', providers=['CUDAExecutionProvider']) # 构造模拟输入(BGR格式,归一化到[0,1]) img = cv2.imread('./ultralytics/assets/zidane.jpg') img = cv2.resize(img, (640, 640)) img = img.astype(np.float32) / 255.0 img = np.transpose(img, (2, 0, 1)) # HWC → CHW img = np.expand_dims(img, 0) # 添加batch维度 # 推理 outputs = session.run(None, {'images': img}) print(f"检测输出形状: {outputs[0].shape}") print(f"前2个框的坐标: {outputs[0][0, :2, :4]}")

运行后应输出类似:

检测输出形状: (1, 8400, 84) 前2个框的坐标: [[0.421 0.512 0.123 0.098] [0.634 0.287 0.087 0.112]]

成功标志:无报错、输出形状符合预期(YOLO26默认8400个anchor)、数值在合理范围。

4.3 对比PyTorch与ONNX输出一致性

最关键的验证:ONNX结果是否和原生PyTorch一致?

# 对比脚本 compare_outputs.py import torch from ultralytics import YOLO import onnxruntime as ort import numpy as np # PyTorch推理 model_pt = YOLO('yolo26n.pt') results_pt = model_pt('./ultralytics/assets/zidane.jpg', verbose=False) boxes_pt = results_pt[0].boxes.xyxy.cpu().numpy() # [x1,y1,x2,y2] # ONNX推理(同上) session = ort.InferenceSession('yolo26n.onnx') # ...(输入预处理同上) outputs_onnx = session.run(None, {'images': img}) # 解析ONNX输出(需自行实现NMS或用onnxruntime自带后处理) # 粗略对比:取前5个框的中心点距离误差 # (实际项目中建议用IoU或mAP评估)

注意:ONNX Runtime默认不包含NMS,YOLO26导出时若设nms=True,则NMS已固化在图中,输出即最终框;若设nms=False,需自己调用cv2.dnn.NMSBoxes

5. 部署实战:ONNX模型在不同平台的加载方式

导出只是第一步,部署才是价值所在。以下是三种最常见场景的接入方式,代码精简可直接复用。

5.1 Python服务化部署(Flask API)

# api_server.py from flask import Flask, request, jsonify import onnxruntime as ort import numpy as np import cv2 app = Flask(__name__) session = ort.InferenceSession('yolo26n.onnx') @app.route('/detect', methods=['POST']) def detect(): file = request.files['image'] img = cv2.imdecode(np.frombuffer(file.read(), np.uint8), cv2.IMREAD_COLOR) # 预处理(同上) img = cv2.resize(img, (640, 640)) / 255.0 img = np.transpose(img, (2,0,1))[None] # 推理 outputs = session.run(None, {'images': img.astype(np.float32)}) boxes = outputs[0][0] # [N, 5+nc] # 返回JSON return jsonify({ 'boxes': boxes[:, :4].tolist(), 'scores': boxes[:, 4].tolist(), 'classes': boxes[:, 5:].argmax(1).tolist() }) if __name__ == '__main__': app.run(host='0.0.0.0', port=5000)

启动:python api_server.py,用Postman发送图片即可获得JSON结果。

5.2 C++部署(ONNX Runtime + OpenCV)

// detect.cpp #include <onnxruntime_cxx_api.h> #include <opencv2/opencv.hpp> #include <vector> int main() { Ort::Env env(ORT_LOGGING_LEVEL_WARNING, "YOLO26"); Ort::SessionOptions session_options; session_options.SetIntraOpNumThreads(1); session_options.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_EXTENDED); Ort::Session session(env, L"yolo26n.onnx", session_options); // 读图、预处理(OpenCV) cv::Mat img = cv::imread("zidane.jpg"); cv::resize(img, img, cv::Size(640, 640)); img.convertScaleAbs(img, img, 1.0/255.0); std::vector<float> input_data(3*640*640); // ...(HWC→CHW转换) // 推理 Ort::Value input_tensor = Ort::Value::CreateTensor<float>( memory_info, input_data.data(), input_data.size(), input_shape, 4); auto output_tensors = session.Run(Ort::RunOptions{nullptr}, &input_name, &input_tensor, 1, &output_name, 1); }

编译命令(Linux):

g++ -std=c++17 detect.cpp -I/usr/include/onnxruntime -L/usr/lib -lonnxruntime -lopencv_core -lopencv_imgproc -lopencv_highgui -o detect

5.3 边缘设备部署(Jetson Nano)

在Jetson上,优先使用TensorRT加速:

# 安装TensorRT(JetPack自带) # 将ONNX转为TRT引擎 trtexec --onnx=yolo26n.onnx \ --saveEngine=yolo26n.trt \ --fp16 \ --workspace=2048 \ --minShapes=images:1x3x640x640 \ --optShapes=images:4x3x640x640 \ --maxShapes=images:8x3x640x640

之后用Python加载TRT引擎,推理速度可达ONNX的3倍以上。

6. 常见问题与避坑指南

导出过程看似简单,但新手常踩以下五个坑,这里一次性说清:

6.1 “导出失败:Unsupported operator ‘Softmax’”怎么办?

这是ONNX Opset版本不匹配。YOLO26部分算子在低版本Opset中未定义。解决方案:强制指定opset=17或更高(如opset=18),并确保onnx库版本≥1.14:

pip install --upgrade onnx onnxruntime

6.2 “ONNX Runtime推理结果全是0”?

大概率是输入预处理不一致。PyTorch模型默认输入为RGB且均值方差归一化(如ImageNet),而YOLO26官方导出要求纯线性归一化(/255.0)且BGR顺序。务必检查:

  • cv2.imread()读取的是BGR,不要cv2.cvtColor
  • 不要减均值、除方差(YOLO26导出模型已内置)

6.3 “导出ONNX后体积暴涨2倍”?

这是dynamic=True导致的。动态轴会增加图复杂度。如确定部署环境输入尺寸固定,可关闭:

yolo export model=yolo26n.pt format=onnx imgsz=640 dynamic=False

6.4 “如何导出不带NMS的模型,自己写后处理?”

在导出命令中添加nms=False

yolo export model=yolo26n.pt format=onnx nms=False

此时输出为原始logits([1, 8400, 84]),需自行实现:

  • torch.nn.functional.softmax()分类
  • torchvision.ops.nms()去重

6.5 “导出的ONNX在OpenVINO中报错”?

OpenVINO对ONNX支持有限。推荐先用onnx-simplifier优化

python -m onnxsim yolo26n.onnx yolo26n_sim.onnx

再导入OpenVINO Model Optimizer。

7. 总结:从导出到部署,你真正需要掌握的三件事

回顾整个流程,YOLO26的ONNX导出不是黑盒操作,而是有清晰路径的工程动作。你只需牢牢记住这三点,就能应对90%的部署需求:

7.1 记住一个命令,解决80%场景

yolo export model=yolo26n.pt format=onnx imgsz=640 dynamic=True opset=17

这是最安全、最通用的导出命令,覆盖检测、姿态、分割等所有YOLO26变体。

7.2 验证必须做三件事

① 用Netron看图结构(确认NMS存在、输入尺寸正确)
② 用ONNX Runtime跑通前向(确认无崩溃、输出形状合理)
③ 与PyTorch结果粗略比对(中心点误差<5像素即合格)

7.3 部署选型看场景

  • 快速验证/小流量API → ONNX Runtime + Python
  • 高性能C++服务 → ONNX Runtime C++ API
  • 边缘设备(Jetson/RK)→ TensorRT加速
  • Intel CPU集群 → OpenVINO + IR模型

导出不是终点,而是你掌控模型的第一步。当ONNX文件生成的那一刻,你就从“模型使用者”变成了“模型掌控者”——它可以跑在任何地方,被任何语言调用,融入任何系统。这才是YOLO26真正释放生产力的方式。


获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/3 6:20:32

如何打造无缝跨平台体验:Gopeed技术架构全解析

如何打造无缝跨平台体验&#xff1a;Gopeed技术架构全解析 【免费下载链接】gopeed A modern download manager that supports all platforms. Built with Golang and Flutter. 项目地址: https://gitcode.com/GitHub_Trending/go/gopeed 跨平台开发如何平衡一致性与原生…

作者头像 李华
网站建设 2026/3/4 17:47:10

中文数字人瓶颈突破?Supertonic英文TTS镜像实测分析

中文数字人瓶颈突破&#xff1f;Supertonic英文TTS镜像实测分析 1. 开篇&#xff1a;当TTS不再是数字人的拖累 你有没有遇到过这样的场景——3D数字人刚开口说第一句话&#xff0c;用户已经等得开始刷手机&#xff1f;ASR识别完、LLM想好了回复、UE骨骼驱动也准备就绪&#x…

作者头像 李华
网站建设 2026/4/2 5:35:44

艺术风格创新可能:unet与GAN融合前景预测

艺术风格创新可能&#xff1a;unet与GAN融合前景预测 1. unet person image cartoon compound人像卡通化 构建by科哥 你有没有想过&#xff0c;一张普通的人像照片&#xff0c;只需要几秒钟&#xff0c;就能变成漫画杂志里的主角&#xff1f;这不是幻想&#xff0c;而是已经可…

作者头像 李华
网站建设 2026/3/28 2:53:08

MinerU如何精准提取PDF表格?结构识别参数详解实战

MinerU如何精准提取PDF表格&#xff1f;结构识别参数详解实战 1. 为什么PDF表格提取总让人头疼&#xff1f; 你有没有遇到过这样的场景&#xff1a;一份几十页的行业报告PDF&#xff0c;里面嵌着十几张结构复杂的财务表格&#xff0c;想把它们复制进Excel&#xff0c;结果文字…

作者头像 李华
网站建设 2026/4/1 21:34:28

IQuest-Coder-V1指令微调实战:定制化编码助手部署教程

IQuest-Coder-V1指令微调实战&#xff1a;定制化编码助手部署教程 IQuest-Coder-V1-40B-Instruct 是一款专为软件工程与竞技编程场景打造的大型语言模型&#xff0c;具备强大的代码生成、理解与推理能力。它不仅能在复杂任务中表现出色&#xff0c;还支持长上下文原生处理&…

作者头像 李华