yolov8n.pt 到 NCNN INT8 模型转换流程
graph LRF --> G[C++ ncnn 推理]
·
以下是 从 yolov8n.pt 到 NCNN INT8 模型的完整、可执行转换流程,专为你的环境(Windows 7 / C++ / 老旧 CPU)优化,包含所有工具下载、命令、代码和注意事项。
📦 一、准备工作
1. 确保你有以下文件
yolov8n.pt(Ultralytics YOLOv8n 权重)- 校准图像文件夹(如
D:\Datasets\quantization_pic,含 100~300 张.jpg)
2. 下载必要工具(Windows 兼容版)
| 工具 | 用途 | 下载链接 |
|---|---|---|
| Python + Ultralytics | 导出 ONNX | pip install ultralytics onnx onnxsim |
| NCNN 工具包 | ONNX → NCNN + 量化 | ncnn-20230309-windows-vs2019.zip |
💡 解压
ncnn-20230309-windows-vs2019.zip到D:\ncnn,你会得到:
D:\ncnn\tools\onnx\onnx2ncnn.exeD:\ncnn\tools\quantize\quantize.exe(已预编译)
🔧 二、完整转换流程(6 步)
✅ 步骤 1:从 .pt 导出干净的 FP32 ONNX
# export_onnx.py
from ultralytics import YOLO
model = YOLO("yolov8n.pt")
model.export(
format="onnx",
imgsz=320, # 或 160(推荐提速)
opset=13, # NCNN 兼容性最佳
simplify=True, # 合并冗余节点
dynamic=False, # 固定输入尺寸
device="cpu" # 避免 CUDA 依赖
)
print("✅ FP32 ONNX 已生成: yolov8n.onnx")
运行:
python export_onnx.py
📌 输出:
yolov8n.onnx(确保无int8=True)
✅ 步骤 2:简化 ONNX 模型(可选但推荐)
pip install onnxsim
python -m onnxsim yolov8n.onnx yolov8n-sim.onnx
💡 这能解决
onnx2ncnn的常见兼容性问题(如Unsqueeze节点)。
✅ 步骤 3:ONNX → NCNN(生成 .param + .bin)
# 在 D:\ncnn\tools\onnx 目录下运行
onnx2ncnn.exe yolov8n-sim.onnx yolov8n.param yolov8n.bin
✅ 成功标志:生成
yolov8n.param(文本)和yolov8n.bin(二进制权重)
❌ 如果报错Unsupported SiLU:升级 NCNN 到 2023+ 版本(你下载的 20230309 已支持 SiLU)
✅ 步骤 4:准备校准图像列表
创建 calibration.txt,每行一个图片路径(绝对路径):
# gen_calib_txt.py
import os
img_dir = r"D:\Datasets\quantization_pic"
with open("calibration.txt", "w") as f:
for file in os.listdir(img_dir):
if file.lower().endswith(('.jpg', '.jpeg', '.png')):
f.write(os.path.join(img_dir, file) + "\n")
print("✅ calibration.txt 已生成")
📌 建议:使用 100~300 张有代表性的图像。
✅ 步骤 5:NCNN INT8 量化
# 在 D:\ncnn\tools\quantize 目录下运行
quantize.exe yolov8n.param yolov8n.bin yolov8n-int8.param yolov8n-int8.bin calibration.txt
✅ 成功标志:生成
yolov8n-int8.param和yolov8n-int8.bin
📝 量化过程会自动计算 scale/zero_point 并内嵌到模型中。
✅ 步骤 6:C++ 推理代码(完整模板)
// yolov8_ncnn.cpp
#include <iostream>
#include <opencv2/opencv.hpp>
#include "net.h"
int main() {
// 1. 加载模型
ncnn::Net net;
net.load_param("yolov8n-int8.param");
net.load_model("yolov8n-int8.bin");
net.set_num_threads(2); // i5-7200U / i7-6500U 双核
// 2. 读取图像
cv::Mat img = cv::imread("test.jpg");
if (img.empty()) return -1;
// 3. 预处理: BGR -> RGB, resize, normalize [0,1]
ncnn::Mat in = ncnn::Mat::from_pixels_resize(
img.data, ncnn::Mat::PIXEL_BGR2RGB, img.cols, img.rows, 320, 320
);
const float mean_vals[3] = {0.f, 0.f, 0.f};
const float norm_vals[3] = {1/255.f, 1/255.f, 1/255.f};
in.substract_mean_normalize(mean_vals, norm_vals);
// 4. 推理
ncnn::Extractor ex = net.create_extractor();
ex.input("images", in); // 输入 blob 名(从 .param 确认)
ncnn::Mat out;
ex.extract("output0", out); // 输出 blob 名(YOLOv8 通常是 output0)
// 5. 解析检测结果 (out: [N, 84])
for (int i = 0; i < out.h; i++) {
const float* values = out.row(i);
float x = values[0];
float y = values[1];
float w = values[2];
float h = values[3];
float conf = values[4];
if (conf > 0.25f) {
std::cout << "Box: (" << x << "," << y << ") conf=" << conf << std::endl;
}
}
return 0;
}
🔧 编译说明(Windows + VS2019):
- 下载 OpenCV 4.5.5 Windows 版
- 将
ncnn/include和ncnn/lib加入项目 - 链接库:
ncnn.lib,opencv_world455.lib - 运行时需
ncnn.dll(或静态链接)
💡 blob 名确认:用文本编辑器打开
yolov8n.param,查找:Input images 0 1 images ... Split splitncnn_0 1 2 output output0 output1→ 输入名:
images,输出名:output0
⚠️ 三、关键注意事项
1. 输入/输出 blob 名必须匹配
- 用记事本打开
.param文件确认Input和Output层的名字; - YOLOv8 通常输出为
output0(检测头)。
2. 预处理必须与训练一致
- 归一化:
/255.0(Ultralytics 默认) - 通道顺序:
BGR2RGB(OpenCV 默认 BGR)
3. Windows 7 部署建议
- 使用 静态链接 避免 DLL 依赖:
set(NCNN_STATIC ON) - 或将
ncnn.dll、opencv_world455.dll放在 exe 同目录。
4. 性能预期(i5-7200U)
| 模型 | 输入尺寸 | 推理时间 | 内存占用 |
|---|---|---|---|
| ONNX FP32 | 320×320 | ~100 ms | ~200 MB |
| NCNN INT8 | 320×320 | 6080 ms | ~100 MB |
✅ 提速 1.3~1.8x,内存减半 —— 这是在无 VNNI CPU 上的最佳结果。
📝 四、验证量化是否成功
-
检查文件大小:
yolov8n.bin(FP32):约 6MByolov8n-int8.bin(INT8):约 3MB(减半)
-
运行 C++ 程序:
- 如果能正常输出检测框,说明 INT8 推理成功;
- 对比 FP32 和 INT8 的输出差异(应 < 1e-2)。
✅ 五、总结流程图
graph LR
A[yolov8n.pt] --> B[export_onnx.py → yolov8n.onnx]
B --> C[onnxsim → yolov8n-sim.onnx]
C --> D[onnx2ncnn.exe → .param/.bin]
D --> E[gen_calib_txt.py → calibration.txt]
E --> F[quantize.exe → INT8 .param/.bin]
F --> G[C++ ncnn 推理]
更多推荐
所有评论(0)