当前位置: 首页 > news >正文

PNNX + TorchScript + 手动修改后处理逻辑,最终输出适配 NCNN官方 yolov8.cpp

根据说明https://github.com/Tencent/ncnn/blob/master/examples/yolov8.cpp
请根据以下说明,给出yolov8n.pt模型转换为ncnn模型,详细步骤与脚本代码:
// Copyright 2024 Tencent
// SPDX-License-Identifier: BSD-3-Clause

// 1. install
// pip3 install -U ultralytics pnnx ncnn
// 2. export yolov8 torchscript
// yolo export model=yolov8n.pt format=torchscript
// 3. convert torchscript with static shape
// pnnx yolov8n.torchscript
// 4. modify yolov8n_pnnx.py for dynamic shape inference
// A. modify reshape to support dynamic image sizes
// B. permute tensor before concat and adjust concat axis
// C. drop post-process part
// before:
// v_165 = v_142.view(1, 144, 6400)
// v_166 = v_153.view(1, 144, 1600)
// v_167 = v_164.view(1, 144, 400)
// v_168 = torch.cat((v_165, v_166, v_167), dim=2)
// …
// after:
// v_165 = v_142.view(1, 144, -1).transpose(1, 2)
// v_166 = v_153.view(1, 144, -1).transpose(1, 2)
// v_167 = v_164.view(1, 144, -1).transpose(1, 2)
// v_168 = torch.cat((v_165, v_166, v_167), dim=1)
// return v_168
// 5. re-export yolov8 torchscript
// python3 -c ‘import yolov8n_pnnx; yolov8n_pnnx.export_torchscript()’
// 6. convert new torchscript with dynamic shape
// pnnx yolov8n_pnnx.py.pt inputshape=[1,3,640,640] inputshape2=[1,3,320,320]
// 7. now you get ncnn model files
// mv yolov8n_pnnx.py.ncnn.param yolov8n.ncnn.param
// mv yolov8n_pnnx.py.ncnn.bin yolov8n.ncnn.bin

// the out blob would be a 2-dim tensor with w=144 h=8400
//
// | bbox-reg 16 x 4 | per-class scores(80) |
// ±----±----±----±----±---------------------+
// | dx0 | dy0 | dx1 | dy1 |0.1 0.0 0.0 0.5 …|
// all /| | | | | . |
// boxes | … | … | … | … |0.0 0.9 0.0 0.0 …|
// (8400)| | | | | . |
// | | | | | . |
// ±----±----±----±----±---------------------+
//
根据你提供的详细说明,以下是将 yolov8n.pt 模型转换为 支持动态输入尺寸NCNN 模型 的完整步骤与脚本代码。整个流程基于 PNNX + TorchScript + 手动修改后处理逻辑,最终输出适配 NCNN 官方 yolov8.cpp 推理格式的模型。


✅ 前提条件

确保已安装必要依赖:

pip3 install -U ultralytics pnnx ncnn

注意:pnnx 包仅提供 Python 接口,实际转换依赖系统 PATH 中的 pnnx 可执行文件(需从 https://github.com/pnnx/pnnx 编译或下载预编译版)。


🔧 步骤详解与脚本

步骤 1:导出原始 TorchScript 模型

yolo export model=yolov8n.pt format=torchscript

输出:yolov8n.torchscript


步骤 2:用 PNNX 初步转换(用于生成 Python 模型代码)

pnnx yolov8n.torchscript

此步骤会生成:

  • yolov8n_pnnx.py
  • yolov8n_pnnx.bin
  • 其他中间文件

我们只关心 yolov8n_pnnx.py,用于手动修改。


步骤 3:修改 yolov8n_pnnx.py 支持动态尺寸并移除后处理

打开 yolov8n_pnnx.py,定位到类似以下代码段(通常在 forward 函数末尾):

v_165 = v_142.view(1, 144, 6400)
v_166 = v_153.view(1, 144, 1600)
v_167 = v_164.view(1, 144, 400)
v_168 = torch.cat((v_165, v_166, v_167), dim=2)
...
return v_final  # 包含 NMS 或后处理

替换为(支持动态尺寸 + 仅输出原始检测头):

# 动态 reshape + transpose
v_165 = v_142.view(1, 144, -1).transpose(1, 2)  # [1, 6400, 144]
v_166 = v_153.view(1, 144, -1).transpose(1, 2)  # [1, 1600, 144]
v_167 = v_164.view(1, 144, -1).transpose(1, 2)  # [1,  400, 144]# 沿检测框数量维度拼接(dim=1)
v_168 = torch.cat((v_165, v_166, v_167), dim=1)  # [1, 8400, 144]# 直接返回原始输出,不进行 sigmoid/NMS
return v_168

✅ 这样输出张量形状为 [1, 8400, 144],对应 NCNN 中的 w=144, h=8400(NCNN 是 HWC 布局,但 blob 维度为 w=channel)。


步骤 4:添加导出函数(便于重新生成 TorchScript)

yolov8n_pnnx.py 末尾添加以下代码:

def export_torchscript():import torchmodel = Model()  # 确保类名为 Model,若不是请替换model.eval()dummy_input = torch.randn(1, 3, 640, 640)traced = torch.jit.trace(model, dummy_input)traced.save("yolov8n_pnnx.py.pt")print("✅ TorchScript saved as yolov8n_pnnx.py.pt")

⚠️ 如果你的模型类名不是 Model,请根据 yolov8n_pnnx.py 中的实际类名修改(如 class yolov8n_pnnx(torch.nn.Module),则应实例化 yolov8n_pnnx())。

例如,若类名为 yolov8n_pnnx,则改为:

def export_torchscript():import torchmodel = yolov8n_pnnx()model.eval()dummy_input = torch.randn(1, 3, 640, 640)traced = torch.jit.trace(model, dummy_input)traced.save("yolov8n_pnnx.py.pt")print("✅ TorchScript saved as yolov8n_pnnx.py.pt")

步骤 5:重新导出修改后的 TorchScript

python3 -c "import yolov8n_pnnx; yolov8n_pnnx.export_torchscript()"

输出:yolov8n_pnnx.py.pt


步骤 6:用 PNNX 转换为 NCNN(支持动态尺寸)

pnnx yolov8n_pnnx.py.pt inputshape=[1,3,640,640] inputshape2=[1,3,320,320]

inputshape2 用于指定第二个测试尺寸,使 PNNX 生成动态兼容的 NCNN 模型。

输出:

  • yolov8n_pnnx.py.ncnn.param
  • yolov8n_pnnx.py.ncnn.bin

步骤 7:重命名模型文件

mv yolov8n_pnnx.py.ncnn.param yolov8n.ncnn.param
mv yolov8n_pnnx.py.ncnn.bin yolov8n.ncnn.bin

✅ 现在你已获得可用于 ncnn/examples/yolov8.cpp 的模型!


📌 最终输出说明

  • 模型输出 blob:形状为 (w=144, h=8400)
    • 前 4 列:dx, dy, dw, dh(需转换为 xywh 或 xyxy)
    • 后 80 列:未经过 sigmoid 的类别 logits
  • 后处理需在 C++ 中完成
    • 对 80 类别分值应用 sigmoid
    • 计算置信度 = obj_conf(隐含在 bbox 回归中) × cls_conf
    • NMS

这与官方 yolov8.cpp 完全一致。


📝 补充建议

  • 若你后续需要 INT8 量化,请先确保 FP32 模型推理正确,再使用 ncnn2int8
  • 若 PNNX 报错找不到算子,可尝试升级 PNNX 到最新版(YOLOv8 支持在 2023 年后逐步完善)。

如需自动化脚本,我也可以为你打包成 .sh.py 文件。是否需要?

http://www.dtcms.com/a/490120.html

相关文章:

  • 记录小程序真机bug,而模拟器无法复现
  • 【iOS取证篇】浅谈iPhone手机的失窃设备保护功能
  • Qoder 全栈Ai工具
  • 数据库—数据库设计 多表查询 事务
  • php网站开发如何赚钱新发地网站建设
  • 多合一建网站数码电子产品网站建设策划书
  • Spring Boot + Kafka 全面实战案例
  • MATLAB基于GWO-BP神经网络对某拨叉件锻造金属流动性的参数分析
  • 建网站教学视频wordpress外汇
  • Ubuntu-8卡H20服务器升级nvidia驱动+cuda版本
  • 2.6 代码注释与编码规
  • html css js网页制作成品——饮料官网html+css+js 4页网页设计(4页)附源码
  • Langchain流式自定义生成器函数
  • 基于单片机的智能收银机模拟系统设计
  • ssh连接本地虚拟机
  • PyInstaller多模块项目打包指南
  • access 网站后台汕头自助建站
  • 从图纸到三维模型:智能装配指导的突破之路
  • 「JMM+Java锁+AQS」 知识图谱
  • 【广州公共资源交易-注册安全分析报告-无验证方式导致安全隐患】
  • C++ 学习日记
  • 晶晨S905L3SB芯片_安卓9.0_高安版_支持外置WIFI_线刷固件包
  • 4G5G 移动代理实战:什么时候必须用移动 IP?
  • 【OpenHarmony】传感器轻量级服务模块架构
  • 面向服务架构(SOA)模式全解析:设计、实践与价值
  • HTML 零基础入门到实战:从骨架到页面的完整指南
  • 【Java EE进阶 --- SpringBoot】Mybatis操作数据库(进阶)
  • 成都海鸥手表网站crm系统的销售管理功能包括
  • 『 QT 』QT信号机制深度解析
  • stp,rstp,mstp的区别