ncnn icon indicating copy to clipboard operation
ncnn copied to clipboard

Yolov11-n 模型int8量化误差过大

Open WYL-Projects opened this issue 1 year ago • 4 comments

问题描述

在我对自己训练的yolov11-n ncnn模型进行int8量化后,int8模型推理图像出现了目标框不准的问题,我执行了以下命令进行模型量化:

../ncnnoptimize yolov11n.param yolov11n.bin yolov11n_opt.param yolov11n_opt.bin 0
../quantize/ncnn2table yolov11_opt.param yolov11_opt.bin data.txt yolov11n.table mean=[104,117,123] norm=[0.017,0.017,0.017] shape=[640,640,3] pixel=BGR thread=8 method=kl
../quantize/ncnn2int8 yolov11n_opt.param yolov11n_opt.bin yolov11n-int8.param yolov11n-int8.bin yolov11n.table

为了对比yolov11n和yolov11n-int8 ncnn模型的检测效果,我执行了以下代码:


import numpy as np
import ncnn
import torch

from ultralytics.data.augment import LetterBox
from ultralytics.engine.results import Results
from ultralytics.utils import ops
from PIL import Image
import cv2


def test_inference(image_path):
    im = cv2.imread(image_path)
    ori_img_shape = im.shape[:2]
    new_shape = (640, 640)
    pre_tranform = LetterBox(new_shape=(640,640), auto=False, stride=32)
    resized_image = pre_tranform(image=im)
    resized_image = resized_image[..., ::-1].transpose((2, 0, 1))  # BGR to RGB, BHWC to BCHW, (n, 3, h, w)
    resized_image = np.ascontiguousarray(resized_image)
    image_normalized  = resized_image / 255.0
    image_normalized = image_normalized.astype(np.float32) 
 
    outs = []
    with ncnn.Net() as net:
        net.load_param("runs/detect/vstd_yolov11/v1.1/weights/best_ncnn_model/yolov11n-int8.param")
        net.load_model("runs/detect/vstd_yolov11/v1.1/weights/best_ncnn_model/yolov11n-int8.bin")
        net.opt.use_int8_inference = True

        with net.create_extractor() as ex:
            ex.input("in0", ncnn.Mat(image_normalized).clone())
            # ex.input("in0", ncnn.Mat(image_normalized).clone())

            _, out0 = ex.extract("out0")
            outs.append(torch.from_numpy(np.array(out0)).unsqueeze(0))
    out = outs[0]
    out_mean = torch.mean(out)
    out_max = torch.max(out)
    out_min = torch.min(out)
    print(out.shape, out_mean, out_max, out_min)

    # 后处理
    classes_name = ["person", "biycle", "car", "motorcycle", "bus", "truck"]
    pred = ops.non_max_suppression(
        out,
        0.5,
        0.5,
        agnostic=False,
        max_det=300
    )[0]
    pred[:, :4] = ops.scale_boxes(new_shape, pred[:, :4], ori_img_shape)
    r = Results(im, path=image_path, names=classes_name, boxes=pred)
    r.save(filename=f"datasets/000000001532_int8.jpg", line_width=2)
    print(pred)
    

    

if __name__ == "__main__":
    image_path = "/data/object_detection/coco2017/000000001532.jpg"
    test_inference(image_path)

以下是模型的推理结果,上图是float32的效果,下图是int8的效果:

Image

Image

请问这种量化误差过大的问题如何解决?我目前没啥头绪,期待回复!

WYL-Projects avatar Feb 20 '25 09:02 WYL-Projects

你这个是mean norm参数传错了吧,yolo的mean=0, norm=1/255=0.0039

ohLAHai avatar Mar 10 '25 09:03 ohLAHai

我用methd=kl 一个框结果成了六个框还不对,改成method=aciq,结果正确了

ohLAHai avatar Mar 11 '25 03:03 ohLAHai

hi, ncnn yolo11 examples are on board https://github.com/Tencent/ncnn/tree/master/examples https://github.com/nihui/ncnn-android-yolo11

model conversion guide (zh) https://zhuanlan.zhihu.com/p/1903414797195781701

nihui avatar May 07 '25 03:05 nihui

为啥我yolov8量化完,模型bin大小是变成原来1/4了,但是推理速度变慢了,精度也不行了,是不是哪里量化的不对呀,能分享一下你的量化后模型吗

dimension1234 avatar May 11 '25 13:05 dimension1234

标题: ncnn2int8量化时出现“Floating point exception (core dumped)”求助

内容: 大家好, 我在使用ncnn对YOLO模型进行量化时,执行以下命令:

./ncnn2int8 yolo11n.ncnn-opt.param yolo11n.ncnn-opt.bin yolo11n-int8.param yolo11n-int8.bin yolo11n.ncnn.table

运行到某些卷积层时,出现报错:

quantize_convolution conv_80 quantize_convolutiondepthwise convdw_174 ... Floating point exception (core dumped)

我已经检查过table文件和param/bin文件都是有效的。 不清楚为什么会出现floating point错误。 请问有谁对ncnn2int8量化有经验,能帮我分析原因并给出解决方法吗?

非常感谢!

viethung2002 avatar Sep 01 '25 12:09 viethung2002