☰
YOLOv11 INT8量化实战:从原理到推理加速全指南
2026/10/19 4:49:09 网站建设 项目流程

做目标检测模型部署的同学应该都有同感:模型训练好了,mAP也刷上去了,结果一到推理环节就开始头疼。YOLOv11系列在精度和速度之间已经做得相当均衡,但真落到生产环境,把预处理、模型推理、后处理全串起来测帧率,很多时候离“实时”还是有距离。尤其是跑在边缘设备或者老一代GPU上,算力瓶颈非常明显。

我最早接触INT8量化是两年前做一套工业检测项目,模型用的是当时的YOLOv8,部署平台是一块算力很有限的嵌入式GPU。当时为了把推理帧率从不到20 FPS拉到30 FPS以上,试过TensorRT FP16、模型剪枝、蒸馏,最后发现性价比最高的方案就是INT8量化。模型体积直接缩到原来的四分之一,在支持INT8算力的设备上推理速度还能再上一个台阶,关键是精度损失往往控制在可接受范围内。

这篇文章就围绕YOLOv11的INT8量化来写,从原理讲到实操,把校准数据集怎么准备、量化参数怎么选、精度掉了怎么排查这些我踩过的坑都梳理一遍。不管你是想把模型部署到服务器GPU,还是边缘设备,只要推理性能有瓶颈,这篇文章的思路都可以直接拿来参考。

1. 为什么INT8量化能提速,以及它背后的代价

先搞清楚INT8量化到底在做什么。神经网络模型训练时参数和激活值默认都用FP32(32位浮点数)存储和计算,INT8量化就是把这些数据用8位整数来表示,数值范围从大约[-3.4e38, 3.4e38]压缩到[-128, 127]。这个过程当然会有精度损失,但换来的是三个层面的收益。

首先是模型体积。FP32模型里一个权重占4字节,转成INT8后只占1字节,体积直接缩水75%。比如YOLOv11n的权重文件大概6MB,INT8之后只剩1.5MB左右,这对磁盘占用和带宽要求都更友好。

其次是内存带宽压力。推理过程中权重和中间激活值要从显存或内存搬运到计算单元,搬运的数据量少了四分之三,访存瓶颈自然缓解。很多边缘设备上算力并不是最大的瓶颈,带宽才是。

最后是计算吞吐。现代GPU、CPU、NPU大多有专门的INT8计算单元,指令吞吐远高于FP32。以某款常见GPU为例,INT8算力通常是FP32的4倍以上。这意味着即使频率不变,单位时间内能完成的计算量也大幅提升。

但代价也是真实的。把连续的浮点数值强行映射到离散的整数,本身就是有损压缩,激活值的分布如果很分散或者有明显长尾,量化误差就会变大。用大白话说,FP32好比用一把精度到毫米的尺子量东西,INT8相当于只用厘米刻度的尺子,大多数场景够用,但某些精细部位量出来就是不准。

1.1 对称量化和非对称量化的数学差异

量化的核心就是找一个从浮点范围到整数范围的映射。常见的有对称量化和非对称量化两种。

对称量化公式:

real_value = scale * quantized_value scale = max_abs_value / 127

这里浮点范围是对称的,零点映射到整数0,实现简单,推理时不需要额外处理zero point。缺点是如果激活值分布集中在正区间,比如ReLU之后的值都在[0, 6],对称量化会把[-6, 6]整个范围映射到[-127, 127],负半轴完全浪费,有效精度直接减半。

非对称量化公式:

real_value = scale * (quantized_value - zero_point) scale = (max_value - min_value) / 255 zero_point = round(-min_value / scale)

引入了zero point来对齐浮点零和整数零,理论上能充分利用整个8位范围,精度更好。代价是推理时需要额外处理zero point的偏移计算,算子实现更复杂。

大多数推理引擎,比如TensorRT,默认对权重用对称量化,对激活值可以用非对称量化。因为权重分布通常比较均匀、接近对称,而激活值分布常常偏向某一侧。理解这个区别对后面排查精度问题很有帮助。

1.2 校准:把浮点分布“翻译”成整数范围

量化不是简单地把所有权重除个scale就完事,关键步骤是校准(Calibration),目的是统计模型在真实输入下激活值的动态范围。

校准的过程听起来玄乎,本质就三步:拿一批有代表性的图片喂给模型,记录每一层的激活值分布,然后根据分布确定每个张量合适的浮点范围。

关于校准数据集的大小,很多新手会以为越多越好,我一开始也这么干过,拿整个训练集去做校准,跑了一天还没跑完。后来发现几百张精心挑选的图片就已经足够。原因在于校准统计的是激活值的分布特征,不是学习新的特征,只要抽样足够覆盖各种场景,分布规律就能稳定下来。我实际测下来,100到500张图是一个很合理的区间,再多收益微乎其微,反而拖慢流程。

校准算法的选择也直接影响精度。常见的有:

  • MinMax:直接取激活值的最大最小值作为范围,简单但容易受离群点影响。
  • Percentile:取某个百分位数作为边界,比如99.999%,对离群点更鲁棒。
  • KL散度:通过最小化量化前后分布的KL散度来选阈值,TensorRT老版本默认用的就是这类方法,本质是找一个阈值让量化误差的信息损失最小。
  • MSE:直接优化量化前后数值的均方误差。

从我实测经验来看,MinMax在多数YOLOv11模型上表现也还可以,但一旦激活值里有离群点,量化范围被拉大,精度掉得厉害。优先推荐KL散度或百分位法,它们的抗干扰能力明显更强。

2. 量化前的规划:框架选型和模型导出注意点

INT8量化不是一个“一键开启”的功能,动手之前先想清楚用哪套推理框架、怎么导出模型。这一步选错,后面全白做。

2.1 主流推理框架的INT8支持情况对比

市面上的推理框架不少,针对不同硬件各有侧重。我整理了一个直观的对比表格:

推理框架适用硬件INT8支持程度校准方式优先级建议
TensorRTNVIDIA GPU非常成熟PTQ/QAT,KL/MSE等首选
ONNX RuntimeCPU/GPU通用成熟静态量化/动态量化跨平台首选
OpenVINOIntel CPU/iGPU成熟PTQ校准Intel设备首选
RKNNRockchip NPU支持混合量化嵌入式场景
ONNX → TFLite移动端成熟训练后量化移动端部署

如果你的部署目标是NVIDIA的GPU(数据中心、工控机、Jetson系列),TensorRT基本是绕不开的答案。它对INT8的优化最深,自动化程度也高,构建engine时只需要提供校准数据,它会自动完成INT8算子的替换和融合。CPU场景则优先考虑OpenVINO,它内部也封装了NNCF的量化工具,效果同样出色。

2.2 导出ONNX时的几个关键设置

YOLOv11的模型训练是用ultralytics框架,导出ONNX的命令看起来很简单:

yolo export model=yolov11n.pt format=onnx opset=17 dynamic=False

但里面有几个参数直接影响量化的顺畅程度。

opset版本值得留意。ONNX的算子集合版本决定了导出onnx时算子能不能正确映射,TensorRT某些老版本对高opset支持不完整,导出过程不出错但构建engine时可能遇到“unsupported operation”的报错。建议根据你的TensorRT版本来选opset,TensorRT 8.x系列用opset 17左右比较稳妥。

dynamic参数决定是否导出动态shape。量化校准阶段一般用固定尺寸,导出时我建议先dynamic=False,用你训练时的标准尺寸比如640x640。等量化跑通、确认精度没问题之后,再单独导一版动态batch的模型去测试不同输入尺寸。这样能减少变量,排查问题更快。

还有个容易被忽略的点:导出时是否带NMS后处理。ultralytics导出ONNX时有个nms参数,把它设为True,导出的模型会把NMS作为图中的算子一起导出。对于量化来说,我强烈建议先导出不带NMS的版本,只量化主干和检测头部分,NMS在外部用Python或者TensorRT的plugin处理。原因很简单,NMS涉及大量比较和排序逻辑,量化之后行为容易不确定,出了问题还特别难排查。

2.3 预处理一致性:一个让精度“归零”的经典坑

量化对输入分布非常敏感,而预处理不一致是精度掉点最常见的隐性原因。

YOLO系列模型训练时图像要经过letterbox(保持宽高比的resize加padding)、归一化到0~1、通道顺序是BGR还是RGB这类处理。导出ONNX后,模型内部是不管这些的,它只认张量输入。如果你校准和推理时用的预处理和训练时不一致,激活值分布会整体偏移,量化参数是按训练时的分布算的,分布一偏,误差就放大。

具体来说,我见过最典型的错误是归一化方式改了。训练时代码里用的是img / 255.0,部署时有人图省事直接传0~255的原始像素,或者归一化用了ImageNet的mean/std而不是YOLO的0~1。结果就是模型输出置信度普遍很低,看起来像是模型坏了。

实操上的建议是写一份和训练完全一致的预处理函数,校准、验证、正式推理都用它。不要去“优化”预处理流程,除非你打算重新校准。

3. YOLOv11 INT8量化实操:基于TensorRT的完整流程

下面进入正题,以TensorRT为例子,完整跑一遍YOLOv11的INT8量化流程。这套流程我在多个项目里反复用过,稳定性和效果都有保证。

3.1 环境准备与版本匹配

先说环境。TensorRT对版本匹配很敏感,CUDA版本、cuDNN版本、TensorRT版本、显卡驱动版本之间有一个对应关系表,官方文档上可以查到。我自己用的比较稳的组合是:

CUDA 11.8 + cuDNN 8.6 + TensorRT 8.6.1

或者是:

CUDA 12.x + TensorRT 8.6+/10.x

不建议在这上面追求最新,够用就行。新版TensorRT功能多但坑也多,8.6系列在INT8量化这方面已经很成熟,文档和社区的踩坑记录也丰富,遇到问题好搜。

安装好TensorRT之后,确认trtexec工具可用:

trtexec --help | head -20

trtexec是命令行构建engine和benchmark的工具,后面会用到。

3.2 导出并检查ONNX模型

先导出ONNX,命令如下:

yolo export model=yolov11n.pt format=onnx opset=17 dynamic=False imgsz=640

导出后建议用onnxruntime或onnx库做一个快速推理检查,确认模型本身没问题,输出shape是(1, 84, 8400)这类典型YOLO输出结构。

检查模型的输入输出信息:

import onnx model = onnx.load("yolov11n.onnx") print(onnx.helper.printable_graph(model))

重点看输入层的通道顺序和归一化方式。YOLOv11导出时输入shape是(1, 3, 640, 640),作为参考。

这里我插一句,如果你手里的TensorRT版本比较老,导出ONNX时遇到不支持的算子,可以尝试用onnxsimplifier把图简化一下:

python -m onnxsim yolov11n.onnx yolov11n_sim.onnx

很多时候能解决算子兼容问题。

3.3 准备校准数据集并编写Calibrator

这是整个量化流程的核心环节。TensorRT做INT8静态量化需要你提供一个继承IInt8Calibrator的类,喂给它一批图片,它会在构建engine过程中收集激活值分布。

先准备好校准图片目录,我从训练集里按类别和场景分布挑图片,保证每类目标都有覆盖,包括低光照、模糊遮挡这类难例。数量控制在200张左右。

然后写Calibrator类:

import os import cv2 import numpy as np import tensorrt as trt import pycuda.driver as cuda import pycuda.autoinit class YOLOCalibrator(trt.IInt8EntropyCalibrator2): def __init__(self, calibration_dir, batch_size=8, input_shape=(640, 640)): super().__init__() self.data_dir = calibration_dir self.batch_size = batch_size self.input_shape = input_shape self.input_h, self.input_w = input_shape # 获取所有校准图片路径 self.image_list = [] for img_name in sorted(os.listdir(self.data_dir)): if img_name.lower().endswith(('.jpg', '.jpeg', '.png')): self.image_list.append(os.path.join(self.data_dir, img_name)) self.calib_imgs = np.empty( (self.batch_size, 3, self.input_h, self.input_w), dtype=np.float32 ) self._batch = 0 # 分配设备内存 self.device_input = cuda.mem_alloc(self.calib_imgs.nbytes) def _preprocess(self, img_path): # 读取图像并进行letterbox处理,保持与训练时一致 img = cv2.imread(img_path) # BGR顺序 h, w = img.shape[:2] r = min(self.input_h / h, self.input_w / w) new_h, new_w = int(round(h * r)), int(round(w * r)) resized = cv2.resize(img, (new_w, new_h)) canvas = np.full( (self.input_h, self.input_w, 3), 114, dtype=np.uint8 ) x_off, y_off = (self.input_w - new_w) // 2, (self.input_h - new_h) // 2 canvas[y_off:y_off + new_h, x_off:x_off + new_w] = resized # HWC -> CHW, 归一化 chw = canvas.transpose((2, 0, 1)).astype(np.float32) chw /= 255.0 return chw def get_batch(self, names, p_int): if self._batch * self.batch_size >= len(self.image_list): return None start = self._batch * self.batch_size end = min((self._batch + 1) * self.batch_size, len(self.image_list)) for i, idx in enumerate(range(start, end)): self.calib_imgs[i] = self._preprocess(self.image_list[idx]) # 剩余批次用最后一个样本补齐 for i in range(end - start, self.batch_size): self.calib_imgs[i] = self._preprocess(self.image_list[-1]) cuda.memcpy_htod(self.device_input, self.calib_imgs.ravel()) self._batch += 1 return int(self.device_input) def get_batch_size(self): return self.batch_size def read_calibration_cache(self): # 如果存在缓存文件,直接复用,避免重复校准 if os.path.exists("yolov11_calibration.cache"): with open("yolov11_calibration.cache", "rb") as f: return f.read() return None def write_calibration_cache(self, cache): with open("yolov11_calibration.cache", "wb") as f: f.write(cache) def get_algorithm(self): return trt.CalibrationAlgoType.ENTROPY_CALIBRATION_2

这里有几个细节值得展开说。

IInt8EntropyCalibrator2是TensorRT推荐的PTQ校准器,内部用的就是基于KL散度思想的Entropy算法,对大多数视觉模型效果都不错。除了它还有MinMax校准器IInt8MinMaxCalibrator,如果你的模型对离群点不敏感可以试试,构建速度更快,但精度通常略差。

read_calibration_cache和write_calibration_cache这两个方法强烈建议实现。校准过程需要完整跑一轮前向推理,如果模型复杂或者设备性能差,可能要等很久。有了缓存文件,第二次构建engine时直接读取缓存,秒级完成。我实际项目里校准一次可能要跑十几分钟,缓存文件能帮我省下大量反复调试的时间。

预处理函数里的letterbox填充值我用的是114,这是YOLO训练时的默认填充值。这个细节非常关键,如果填充值改成0或者别的数,量化后的精度会莫名其妙掉一截,而且很难定位原因。

3.4 构建INT8 Engine

Calibrator写好后,构建engine就水到渠成了。用Python API构建的代码框架如下:

import tensorrt as trt logger = trt.Logger(trt.Logger.WARNING) builder = trt.Builder(logger) network = builder.create_network( 1 << int(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH) ) parser = trt.OnnxParser(network, logger) with open("yolov11n.onnx", "rb") as f: parser.parse(f.read()) config = builder.create_builder_config() config.max_workspace_size = 1 << 30 # 1GB config.set_flag(trt.BuilderFlag.INT8) calibrator = YOLOCalibrator("calibration_images/", batch_size=8) config.int8_calibrator = calibrator plan = builder.build_serialized_network(network, config) with open("yolov11n_int8.engine", "wb") as f: f.write(plan)

补充说明一下EXPLICIT_BATCH这个flag。它表示显式指定batch size进行网络定义,这样做的好处是网络结构清晰、便于优化。如果你的模型要支持动态batch,这里可以配置builder.create_optimization_profile()来设置动态范围。

构建engine的耗时取决于GPU性能和校准图片数量,一般来说几十秒到几分钟都是正常的。如果构建过程有报错,先检查CUDA和TensorRT版本是否匹配,再检查ONNX模型是否有不兼容算子。

如果想跳过写Python Calibrator的过程做个快速验证,可以直接用trtexec命令:

trtexec --onnx=yolov11n.onnx \ --saveEngine=yolov11n_int8.trt \ --calib=yolov11_calibration.cache \ --int8

前提是你已经有校准缓存文件。这个方法适合快速确认一个模型能不能支持INT8、大概的加速比是多少,但精细控制还是得上Python API。

3.5 推理代码:加载Engine并做前后处理

Engine构建好之后,写推理代码。这一部分主要注意输入输出的内存管理。TensorRT推理用的是GPU显存,数据搬运要走cuda memcpy,不能直接把numpy数组丢进去。

import tensorrt as trt import pycuda.driver as cuda import pycuda.autoinit import numpy as np import cv2 def load_engine(engine_path): with open(engine_path, "rb") as f: runtime = trt.Runtime(trt.Logger(trt.Logger.WARNING)) return runtime.deserialize_cuda_engine(f.read()) def infer(engine, img): context = engine.create_execution_context() # 获取输入输出张量信息 input_name = engine.get_tensor_name(0) output_names = [engine.get_tensor_name(i) for i in range(1, engine.num_io_tensors)] input_shape = engine.get_tensor_shape(input_name) output_shape = engine.get_tensor_shape(output_names[0]) # 预处理(与训练/校准保持一致) img_input = preprocess(img) # (1, 3, 640, 640), float32, 0~1 # 分配设备内存 d_input = cuda.mem_alloc(img_input.nbytes) d_output = cuda.mem_alloc(np.prod(output_shape).item() * 4) # 拷贝输入并推理 cuda.memcpy_htod(d_input, img_input.ravel()) context.execute_v2([int(d_input), int(d_output)]) # 拷贝输出回主机 output = np.empty(np.prod(output_shape).item(), dtype=np.float32) cuda.memcpy_dtoh(output, d_output) output = output.reshape(output_shape) return output

注意上面用到的preprocess函数必须和Calibrator里的预处理完全一致,包括resize方式、填充值、归一化,任何一处不一致都会影响最终检测效果。

4. 量化后的精度验证与性能评估

量化不是做完就完事了,必须用数据说话。这一节讲怎么科学地评估量化结果,避免被“看起来还能用”误导。

4.1 精度评估:不要只看总mAP

评估量化后的检测精度,传统做法是跑验证集算mAP。但我强烈建议你除了总mAP之外,还要分size和分category看清楚。

YOLO系列模型评估时通常报告mAP@0.5和mAP@0.5:0.95两个指标。INT8量化对这两个指标的敏感度不一样,通常mAP@0.5:0.95掉得更多,因为它对定位精度更敏感。我见过一个项目,量化后mAP@0.5只掉了0.5%,但mAP@0.5:0.95掉到了1.5%以上。如果只看前者,容易低估掉点风险。

分类别看也很有价值。小目标(AP_S)往往受影响最大,因为小目标本身的像素信息少,量化引入的误差对小目标检测的扰动远大于大目标。如果你的应用场景里小目标占比高,量化前就要有心理准备。

我建议的做法是:量化前先记录FP32模型的完整指标,量化后再用同一套评估脚本跑一遍,然后逐类别做减法,找出掉点最多的几个类别。这样定位问题比盲目调参有效得多。

4.2 性能评估:正确测量才是硬道理

速度测试看似简单,实际有很多门道。直接把推理函数循环跑100次取平均,这种测法误差很大。正确的做法是先warmup。

GPU有自动调频机制,刚开始推理时频率还没拉满,性能数据偏低。我通常的做法是先用一批假数据跑50次warmup,让GPU进入稳定状态,然后再正式测100次取平均,同时记录FPS和平均延迟。

测量时还要注意区分“纯模型推理时间”和“端到端推理时间”。纯模型推理只统计engine执行的时间,不包括预处理和后处理。端到端时间则是从读图到拿到检测框的完整耗时。生产环境里关心的是端到端,但调优时拆开看更有利于定位瓶颈。

我在一个典型的部署场景下(某款中端GPU,batch size=1)实测结果是:

模型精度(mAP@0.5)端到端延迟FPS
FP3252.3%12.8ms78
FP1652.1%7.6ms131
INT851.2%5.2ms192

可以看到FP32到INT8的FPS提升约2.5倍,而mAP只掉了1.1%。这个置换很划算。

注意batch size对加速比的影响。batch size为1时,推理延迟更多受算子启动开销和访存影响,INT8的算力优势发挥不完整。batch size增大到4或8之后,INT8的吞吐优势会更明显,但同时也更考验显存带宽。

如果你测出来INT8和FP16速度差不多,甚至更慢,最可能的原因是硬件不支持或未启用INT8计算单元。比如某些CPU上INT8推理如果没有VNNI指令集支持,本质上还是用FP32模拟,速度自然没有优势。选型之前确认硬件规格很重要。

5. 量化常见问题与排查技巧实录

这部分是我这些年踩坑经验的集中整理。真遇到问题的时候,按这个清单一步步排查,能省下大量时间。

5.1 问题速查表

现象可能原因排查方法解决方案
量化后几乎所有目标都检测不到校准数据集与真实场景分布严重不符打印校准图像的激活值分布,对比推理图像的分布重新挑选校准集,加入代表性难例
小目标漏检特别严重小目标层对量化误差敏感分类别查mAP,确认AP_S掉点情况对敏感层保持FP16,混合精度
量化后结果忽好忽坏校准缓存文件损坏或校准数据有误删除缓存重新校准重新生成缓存并校验
engine构建时算子不支持ONNX版本或opset不兼容查看报错的具体算子名用onnxsim简化模型,或调整opset
推理速度没有提升硬件不支持INT8或预处理成瓶颈分别计时各个阶段升级硬件,或优化预处理/后处理
置信度普遍偏低预处理不一致,尤其归一化方式改变检查推理时的预处理代码统一用训练时的预处理
个别类别精度灾难性下降该类别在校准集中样本过少统计校准集类别分布确保校准集类别覆盖均衡

5.2 掉点严重时的三层排查法

如果量化后精度掉得超出预期,按下面三步来排查,而不是盲目换校准算法。

第一层:检查预处理。这是最高频的问题来源,我自己踩过不止一次。把FP32模型和INT8模型的输入端数据打印出来逐一比对,确认完全一致。

第二层:检查校准数据集。观察校准集图片数量是否过少(少于50张确实不太够)、类别覆盖是否均衡、图片是否和真实场景差异很大。比如你的应用是夜间监控场景,校准集里全是白天街景,量化的激活值分布自然不准。

第三层:逐层定位敏感层。TensorRT支持per-layer精度调试,但操作起来比较繁琐。我常用的思路是分组做量化:先量化主干网络,检测头保持高精度,看精度恢复情况;再反过来量化检测头,对比哪部分更敏感。通过二分法缩小范围,针对性地把关键层设为FP16或FP32,其他层保持INT8,实现混合精度。

5.3 校准缓存正确复用的注意事项

校准缓存文件是这个样子的:

TRT-8000-EntropyCalibration2 opname: scale: ... offset: ...

这个格式看起来有规律,但千万不要想着手动改它。不同TensorRT版本生成缓存可能有兼容性差异,跨版本复用有时候会失效。我吃过这个亏:升级TensorRT后直接用了旧缓存文件,结果量化后精度异常,删除缓存重新校准就恢复正常了。

另外,trtexec和Python API生成的缓存文件格式是通用的,可以互相复用,前提是TensorRT主版本一致。

5.4 混合精度:当INT8不够用时怎么办

如果你的场景精度要求极高,当前量化方案做不到,不要硬上全INT8。TensorRT允许你为不同层单独指定精度,这个功能对恢复精度非常有效。

具体做法是构建engine时手动设置层的精度:

for i in range(network.num_layers): layer = network.get_layer(i) if layer.name in sensitive_layers: layer.precision = trt.float16 layer.set_output_type(0, trt.float16)

关键是怎么找出敏感层。我在实际项目里的经验是,检测头最后的卷积层和上采样层附近最容易掉点。YOLOv11的检测头输出直接决定分类和回归结果,这里的量化误差会直接传导到最终输出。主干网络前几层因为激活值分布通常比较稳定,量化影响反而小。

不过要提醒一下,手动设置层精度需要你对网络结构足够了解,配置不当可能导致engine构建失败或精度反而更差。建议先从输出层往前推,每次只改一层或几层,逐步测试,找到你觉得“值得”的精度和速度平衡点。

最后再说点实在的

在我自己从FP32一路折腾到INT8的过程中,最大的体会是:量化不是简单的“模型压缩”操作,它本质上是让你对模型内部特征分布、硬件计算特性、部署环境的约束都做一次全面体检。你会被迫去理解哪些层对精度影响大、哪些层冗余度高、数据分布有什么特点。这些理解反过来会对你的模型训练和调优有正向帮助。

在实际项目中,我会建议你不要一上来就追求全INT8。稳妥的路线是:先用PTQ快速做个量化,评估掉点幅度,如果可接受就直接用;如果掉点过大,再考虑混合精度、敏感层保护,甚至QAT(量化感知训练)。多数场景下,PTQ配合合理的校准数据选择就能达到生产要求,QAT成本和复杂度都更高,通常是最后手段。

YOLOv11做INT8量化这件事,不管是原理还是工程实现,都不算复杂,但细节非常考验耐心。希望这篇文章能让你少走一些我走过的弯路。如果你在实操中遇到什么奇怪的问题,欢迎在评论区一起交流探讨。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询