:邊緣部署目標檢測的完整指南)
簡介一份面向工業(yè)級目標檢測落地場景的YOLOv11實戰(zhàn)資料適合算法工程師、計算機視覺學習者與部署人員閱讀。內(nèi)容圍繞YOLOv11的網(wǎng)絡結構、工作原理以及模型蒸餾與量化兩大輕量化技術展開并給出從需求分析、數(shù)據(jù)準備、訓練評估到部署驗收的完整工業(yè)項目流程同時配有實驗環(huán)境、性能指標與結果分析便于讀者直接對照實踐。資源共1個PDF文件大小1.98MB共33頁支持目錄跳轉(zhuǎn)與大綱定位文字、圖表顯示完整。已有172人學習下載。除基礎理論外文檔還覆蓋傳統(tǒng)蒸餾、特征蒸餾、多教師蒸餾以及靜態(tài)量化、動態(tài)量化、訓練感知量化等多種方法并對量化誤差、硬件兼容性等落地難點給出解決方案可作為輕量化目標檢測選型與調(diào)優(yōu)的參考手冊。1. 工業(yè)級輕量化的兩座大山精度與算力把YOLOv11模型蒸餾與量化放到同一個工作流里本質(zhì)上是回答一個問題在一個只有幾瓦功耗、幾 GB 內(nèi)存的邊緣盒子上怎么把檢測模型壓到能實時跑同時不把精度賠光。很多團隊卡在同一個地方——換輕量模型掉點嚴重硬上大模型又跑不動最后只能砍分辨率、降幀率部署效果遠不如訓練時的演示。模型蒸餾負責把大模型的“判斷經(jīng)驗”遷移給小模型量化負責把浮點權重和激活壓縮成 INT8兩者合起來才是完整的工業(yè)級輕量化目標檢測落地路徑。這篇實戰(zhàn)筆記面向做產(chǎn)線質(zhì)檢、邊緣部署、移動端檢測的工程師講清每一步怎么做、參數(shù)怎么定、哪里最容易翻車。2. 為什么是“蒸餾 量化”而不是直接換小模型原理與選型2.1 蒸餾到底在遷移什么logits、特征圖與注意力模型蒸餾的核心假設是大模型學到的知識不只存在于最終分類/回歸結果還藏在中間層的特征表達里。最簡單的蒸餾只對齊 Teacher 和 Student 的 logits——讓 Student 的輸出概率分布盡量接近 Teacher 的分布這一步通常用 KL 散度作為損失函數(shù)。但目標檢測場景里 logits 還不夠因為檢測頭同時輸出類別、box 坐標和 objectness這三個分支的“分布形狀”各有各的語義單獨靠最后的 logits 蒸餾效果提升很有限。所以工業(yè)界更常用的做法是特征蒸餾從 Teacher 的 backbone 中間層抽出特征圖讓 Student 對應層的特征圖去逼近它再疊加檢測頭的蒸餾。你可以在 YOLOv11 的 neck 輸出位置各抽一層用 L2 或者注意力掩碼加權來算特征對齊損失。這里有個關鍵點特征圖尺寸不匹配時不能硬對齊通常用 1x1 卷積把 Student 特征圖投影到 Teacher 的通道數(shù)再算距離。注意力圖上的對齊也值得做——把特征圖按通道求均值得到空間注意力掩碼對遮擋、小目標密集場景比純 L2 更抗噪。一個常見誤區(qū)是“Teacher 越重越好”。實際上 Teacher 和 Student 的架構差距過大會導致蒸餾信號太稀疏Student 學不到有效信息。做工業(yè)項目時我一般建議 Teacher 選同系列大模型比如 YOLOv11x 或帶更強主干比如融合了注意力機制的改進版本的變體Student 選 YOLOv11s 或 YOLOv11n差距在一個量級以內(nèi)蒸餾效果最穩(wěn)。2.2 量化為什么省內(nèi)存省算力INT8 推理的本質(zhì)量化把 FP32 的權重和激活映射到 INT8 的整數(shù)范圍。浮點計算變成整數(shù)計算在 CPU、GPU、NPU 上都有硬件加速指令同時模型體積縮小到原來的四分之一左右。以 YOLOv11n 為例FP32 權重約 20MB轉(zhuǎn) INT8 后約 5MB這直接影響邊緣設備的存儲占用和加載時間。量化核心是確定縮放因子 scale 和零點 zero point映射公式是q round(r / scale) zero_point。訓練后的動態(tài)范圍圈得準不準決定了量化誤差的大小。這里有兩個思路PTQ訓練后量化直接拿一批校準數(shù)據(jù)統(tǒng)計激活的分布來定 scaleQAT量化感知訓練則是在訓練時就模擬量化帶來的精度損失讓模型權重適應量化后的數(shù)值表達。工業(yè)項目里我通常先試 PTQ掉點超過 2% 再切換 QAT。值得強調(diào)的是量化不是“把所有層都壓成 INT8”就完事了。不同層對量化的敏感度差異極大——檢測頭的回歸分支對數(shù)值精度極其敏感一個 scale 沒選好box 坐標能偏出好幾個像素。業(yè)內(nèi)常見做法是“混合精度”backbone 的前幾層做 INT8檢測頭和敏感層保留 FP16 或 FP32用算子敏感度分析來決定保留哪些層。這一步在熱詞里對應的就是“YOLOv11 INT8 量化”“TRT 部署”這類場景。2.3 先蒸餾還是先量化兩種流程的取舍流程編排直接決定了項目周期。常見兩種路線先蒸餾后量化或者先量化后蒸餾。前者是主流——先把精度訓上去再量化掉點兩步解耦哪一步出問題容易定位后者較少用因為量化后的模型在訓練時梯度噪聲大蒸餾收斂更不穩(wěn)定對調(diào)參經(jīng)驗要求很高。我的習慣是先做一次快速基準測試FP32 Teacher 直接部署在目標硬件上看吞吐量能否達到要求。如果差 2~3 倍說明必須引入量化如果差 5 倍以上說明連 Teacher 的骨架都跑不動應該直接選更小的 Student 結構而不是指望蒸餾救回來。做完這步再決定要不要上 QAT——如果你的目標設備是國產(chǎn) NPU 或 ARM CPUQAT 基本是必選項因為這些平臺的 INT8 算子實現(xiàn)不如 NVIDIA TensorRT 成熟PTQ 精度損失會被放大。另一個容易忽略的決策點是部署框架。同樣一個 INT8 模型在 TensorRT、ONNX Runtime、OpenVINO 上的表現(xiàn)差異很大不同框架支持的量化算子和校準方式不同。這會影響你抄作業(yè)時的具體參數(shù)——比如 TensorRT 的 PTQ 用 entropy 校準器效果好OpenVINO 則更適合用 min-max。后面第 4 章會展開講。3. 基于 YOLOv11 的模型蒸餾配置與訓練實操3.1 準備 Teacher 模型與數(shù)據(jù)集劃分蒸餾訓練的第一步不是寫代碼而是確認 Teacher 的“純度”。這個 Teacher 必須是經(jīng)過充分訓練、在驗證集上有穩(wěn)定表現(xiàn)的模型。如果你拿一個沒收斂的 Teacher 去蒸餾學生的上限就被鎖死了后面量化掉點會更嚴重。通常我會先跑滿 300 epoch 的 YOLOv11 訓練用 COCO 或自己的業(yè)務數(shù)據(jù)集等 mAP50 和 mAP50-95 都穩(wěn)定了再當作 Teacher。數(shù)據(jù)劃分上有個注意點蒸餾訓練時要保證 Teacher 完全沒有見過驗證集。很多團隊把同一個數(shù)據(jù)集又訓 Teacher 又做蒸餾驗證導致蒸餾出來的 Student 在驗證集上虛高。正確做法是單獨拿出 5%~10% 的數(shù)據(jù)作為蒸餾驗證集Teacher 訓練時就不碰它。對工業(yè)場景我還會單獨留一批“量化校準集”——從訓練集中按類別分布抽 500~1000 張圖放一邊備用后面量化標定要用。YOLOv11 的蒸餾踩坑點主要集中在訓練腳本的修改方式。常見的做法是基于 ultralytics 框架改訓練流程或者用第三方蒸餾倉庫像 mmyolo 的 distill 配置。我一般推薦后者因為 mmyolo 的蒸餾配置是聲明式的Teacher 路徑、蒸餾損失權重、特征對齊位置都寫在 config 里不用改框架源碼復現(xiàn)和交接都更方便。3.2 蒸餾訓練的核心參數(shù)與最小配置以 mmdetection / mmyolo 體系的蒸餾配置為例一個最小可跑的蒸餾配置包含四個部分Teacher 模型配置、Student 模型配置、蒸餾連接配置、損失權重配置。下面的 YAML 展示了 YOLOv11s 作為 Student、YOLOv11x 作為 Teacher 的典型配置結構distill: teacher_cfg: yolov11x.yaml teacher_ckpt: path/to/yolov11x_ckpt.pth student_cfg: yolov11s.yaml distill_cfg: - type: FeatureDistill student_features: [neck.layer2.output] teacher_features: [neck.layer2.output] loss_weight: 0.3 align: 1x1conv - type: LogitsDistill student_logits: cls_score teacher_logits: cls_score loss_weight: 0.7 temperature: 4.0 training: epochs: 150 batch_size: 32 base_lr: 0.005 lr_schedule: cosine warmup_epochs: 5這段配置的邏輯是Teacher 和 Student 各自前向FeatureDistill 強制 Student 的 neck 特征圖去逼近 Teacher 的特征表達LogitsDistill 讓類別得分分布更接近。align: 1x1conv表示通道不匹配時用 1x1 卷積投影對齊。temperature: 4.0控制 logits 分布的平滑程度溫度越高Teacher 輸出的軟標簽越平滑但溫度過高會丟失類別間的細節(jié)差異。訓練時要注意兩個參數(shù)第一個是loss_weight的比例特征蒸餾和 logits 蒸餾權重加起來不要超過檢測本身的 loss。權重太大會讓 Student 過度模仿 Teacher反而丟失了自己從真實標注里學到的信息。第二個是學習率蒸餾訓練比普通訓練更敏感base_lr 通常要比正常訓練低 30%~50%否則前期容易震蕩。3.3 特征蒸餾的 Loss 權重怎么定蒸餾損失的權重分配沒有萬能公式但有可循的經(jīng)驗路徑。如果你是第一次跑我建議用“逐步加碼”的策略先用純 logits 蒸餾跑 30 epoch 做 baseline記下 mAP50再加入特征蒸餾weight 從 0.1 開始逐步加到 0.5每加一次跑 20 epoch 看驗證集變化。這個過程的觀察重點不是單點 mAP而是小目標類別比如工業(yè)場景里的缺陷、劃痕的 AP 變化——特征蒸餾對大目標的增益通常不明顯但對小目標往往有 2~4 個點的提升。一個參數(shù)組合的建議表格如下參數(shù)推薦范圍說明特征蒸餾層數(shù)2~3 層選 neck 的不同尺度輸出覆蓋多尺度特征特征損失權重0.1~0.5從小往大調(diào)觀察 AP 變化趨勢logits 蒸餾溫度3~6溫度越高標簽越平滑4 附近是常見起點蒸餾開始 epoch0 或前 5 epoch 后前幾個 epoch 用 warmup 讓 Student 先穩(wěn)定Teacher 凍結始終凍結Teacher 一定不要參與梯度更新關于層數(shù)選擇一個常見錯誤是只對齊 backbone 最后一層。backbone 最后一層的特征語義最抽象但空間分辨率最低對小目標的位置信息保留最少。正確做法是在 neck 的不同尺度各抽一層——比如 P3、P4、P5 三個尺度輸出各對齊一次保證不同大小目標的蒸餾信號都覆蓋到。這與熱詞里“yolov11小目標優(yōu)化”直接相關小目標場景下把 P3 層高分辨率特征的特征蒸餾權重調(diào)高效果會比均勻分配好很多。4. 量化落地從 PTQ 到 QAT 的關鍵步驟4.1 用 ONNX 導出并驗證 FP32 基線進量化之前第一步永遠是導出 ONNX 并驗證 FP32 的推理精度和速度基線。這一步的意義是建立“量化后跟誰對比”的錨點。YOLOv11 在 ultralytics 框架下導出 ONNX 很簡單但有幾個參數(shù)必須注意。下面是一個典型導出和驗證命令yolo export modelyolov11s_distilled.pt formatonnx dynamicFalse simplifyTrue opset17這個命令最關鍵的參數(shù)是dynamicFalse。默認導出的是動態(tài) batch 和動態(tài)輸入尺寸的 ONNX 圖但在量化部署場景下動態(tài) shape 會帶來額外的算子兼容性問題。工業(yè)部署基本都是固定輸入尺寸比如 640x640所以這里鎖死輸入 shape。simplifyTrue用 onnxsim 做圖優(yōu)化能刪掉一部分冗余 reshape 和 Transpose減少后續(xù)量化工具處理的算子種類。opset17是新版本 ONNX 支持 INT8 量化算子的基線版本太老的操作集會導致轉(zhuǎn)換報錯。導出的 ONNX 不要直接拿去量化先做一次 FP32 的推理測試。驗證指標包括每張圖的推理耗時和 mAP 對比——ONNX 推理結果應該和 PyTorch 原模型幾乎一致。如果這一步就有明顯精度掉落說明導出環(huán)節(jié)出了問題需要回查是否有不支持的算子。常見做法是用 ONNX Runtime 的 Python API 跑一遍驗證代碼大致如下import onnxruntime as ort import numpy as np sess ort.InferenceSession(yolov11s_distilled.onnx, providers[CPUExecutionProvider]) input_name sess.get_inputs()[0].name input_shape sess.get_inputs()[0].shape # [1, 3, 640, 640] # 構造輸入注意預處理要和訓練時保持一致BGR、歸一化方式 dummy_input np.random.randint(0, 255, size(1, 3, 640, 640)).astype(np.float32) / 255.0 outputs sess.run(None, {input_name: dummy_input})這段代碼檢查兩件事模型能不能正確跑通、輸出張量的結構是否符合預期。很多量化翻車案例的根因都發(fā)生在更早的地方——FP32 ONNX 導歪了后面量化所有對比都失真白忙一場。4.2 PTQ 標定數(shù)據(jù)、校準器與算子敏感度PTQ 的核心是標定calibration——用一批有代表性的數(shù)據(jù)跑一遍模型統(tǒng)計每層激活值的分布然后據(jù)此確定 INT8 的 scale 和 zero point。標定數(shù)據(jù)的選擇是 PTQ 成敗的第一決定因素。500 張和 5000 張的差異不是數(shù)量問題是分布覆蓋問題——如果標定集里全是白天場景模型在夜間或逆光場景下量化誤差會暴漲。TensorRT 的 PTQ 用 Python 腳本進行操作核心是配置校準器。下面用 TensorRT 的 Python API 配合 PyTorch 數(shù)據(jù)加載展示標定流程import tensorrt as trt from calibration import Calibrator engine builder.build_engine(network, config) # 偽代碼示意 calibrator Calibrator( datasetcalib_images/, # 標定圖像目錄 batch_size8, cache_filecalib.cache, # 量化緩存文件下次構建直接復用 calib_algoentropy # entropy 或 min_max ) config.int8_calibrator calibrator這段配置里最值得關注的是calib_algo的選擇。TensorRT 默認的 entropy 校準器在大多數(shù)檢測模型上表現(xiàn)更好因為它不是機械地取激活值的最大最小值而是根據(jù)信息熵找到一個讓量化前后分布最接近的截斷點。min_max校準器簡單粗暴對分布跨度大的層容易讓 outlier 主導了 scale導致大多數(shù)激活值被壓縮到 INT8 的低區(qū)間精度損失大。標定時的 batch size 和迭代次數(shù)的經(jīng)驗值batch size 8~16跑 100~200 次迭代總共 800~2000 張圖。標定集不需要標注但需要覆蓋模型在實際場景中會遇到的分布。這里有個“量化泄露未來信息”的坑——標定數(shù)據(jù)不能用于最終精度驗證如果你拿標定集去評測量化模型的 mAP結果虛高部署后真實場景掉點會讓你措手不及。算子敏感度是 PTQ 的第二個關鍵環(huán)節(jié)。量化后哪些層掉點嚴重需要用工具逐個分析。TensorRT 支持逐層量化誤差對比ONNX Runtime 則可以用onnxruntime.transformers里的量化工具跑一遍輸出每層的量化后輸出誤差。經(jīng)驗規(guī)律是檢測頭的reg分支和最后的sigmoid激活層最敏感backbone 的Conv層次之Add和Concat層最不敏感。所以混合精度策略通常是把檢測頭后兩層的卷積保留 FP16其余全走 INT8。4.3 QAT 微調(diào)哪些層值得量化感知訓練當 PTQ 掉點超過能接受的范圍時QAT 是下一步。QAT 的原理是在訓練階段插入偽量化算子fake quant讓模型前向計算時模擬 INT8 量化的舍入誤差反向傳播時通過直通估計器繞過舍入函數(shù)傳梯度。這樣模型權重在訓練過程中會主動適應量化的數(shù)值擾動。YOLOv11 的 QAT 落地通常有兩個路徑一是基于 TensorRT 的 QAT 流程用 pytorch-quantization 庫二是基于 ONNX Runtime 的 QAT 工具鏈。我以 pytorch-quantization 為例說明常見做法from pytorch_quantization import nn as quant_nn from pytorch_quantization.tensor_quant import QuantDescriptor # 配置默認量化位寬和校準方式 quant_desc QuantDescriptor(num_bits8, calib_methodhistogram) quant_nn.QuantConv2d.set_default_quant_desc_input(quant_desc) # 將模型中的指定 Conv/Linear 替換為量化版本 def quantize_model(model): for name, module in model.named_modules(): if isinstance(module, torch.nn.Conv2d): quant_conv quant_nn.QuantConv2d( module.in_channels, module.out_channels, module.kernel_size, stridemodule.stride, paddingmodule.padding ) quant_conv.weight.data.copy_(module.weight.data) model._modules[name] quant_conv return model這段代碼的核心思路是只替換部分卷積層而不是全量替換。經(jīng)驗做法是只量化 backbone 和 neck 的卷積層檢測頭保留 FP32。原因是檢測頭直接輸出坐標和置信度量化誤差會被放大到最終結果上而 backbone 的特征提取有一定的冗余性量化后的噪聲可以被后續(xù)層吸收。另外BatchNorm 層不量化保持 FP32 推理即可。QAT 訓練的超參和普通微調(diào)差別不大但有兩個特殊注意點。第一學習率要更小——一般用正常訓練最后階段學習率的 1/10因為模型已經(jīng)收斂只需微調(diào)權重適應量化誤差。第二epoch 數(shù)不要太多10~20 個 epoch 就足夠訓練太久會過擬合到量化噪聲上導致校準集表現(xiàn)好、真實場景反而變差。訓練完成后導出的 INT8 模型要重新在驗證集上測一輪確保不僅“量化后不掉點”還要確認“和 FP32 相比沒有系統(tǒng)性偏移”。5. 避坑清單蒸餾與量化落地中的 5 個常見問題5.1 蒸餾后 Student 精度反而低于 Teacher 直接部署現(xiàn)象蒸餾訓練完成Student 的 mAP50 比 Teacher 直接部署低 3~5 個點甚至比不蒸餾直接訓練的 Student 還低。原因最常見的是蒸餾權重配比失衡。特征蒸餾的 loss_weight 設置過大Student 把大量容量花在模仿 Teacher 的特征上忽略了真實標簽另一個高發(fā)原因是 Teacher 和 Student 的預處理不一致——輸入 Resize 方式、歸一化參數(shù)不同導致 Teacher 給 Student 的“軟標簽”本身就是歪的。解決先把 logits 蒸餾和特征蒸餾的權重各降到 0.1 跑 30 epoch 做對照確認蒸餾機制確實生效再逐層檢查 Teacher 和 Student 的特征對齊層是否選錯比如用 Teacher 的 P5 特征去對齊 Student 的 P3 特征空間尺寸差太多1x1 卷積根本拉不回來。最后核對兩個模型的預處理參數(shù)務必一致。5.2 量化后檢測框“漂移”但分類不掉點現(xiàn)象INT8 量化后分類置信度變化不大但預測框位置偏移明顯尤其是小目標框偏移能達到 5~10 個像素。原因這是檢測頭回歸分支對量化誤差敏感導致的典型表現(xiàn)。box 回歸分支的輸出是相對偏移量數(shù)值范圍小但精度要求高。INT8 量化后量化步長scale過大幾個 LSB 的量化誤差就足以產(chǎn)生可見的像素偏移。分類分支的數(shù)值范圍寬量化相對誤差小所以看不出問題。解決對檢測頭的卷積層做混合精度處理——把 head 部分的卷積保留 FP16。具體做法是在量化配置中指定disable_quant的算子名單或者用敏感度分析工具逐層查看量化誤差排名然后手動調(diào)整。如果框架不支持按層跳過量化則改用 QAT 并重點對 head 部分做量化感知訓練。5.3 標定集與驗證集混用導致虛高現(xiàn)象量化模型在本地測試時 mAP 只掉了 0.5%部署到現(xiàn)場后掉點超過 3%。反復排查找不到原因。原因標定集和驗證集重疊或分布太接近。標定過程本質(zhì)上是讓模型“記住”標定數(shù)據(jù)的分布特征當驗證集和標定集同源時量化后的“記憶偏差”被驗證集掩蓋了實戰(zhàn)場上分布一變就現(xiàn)出原形。這是熱詞里“量化泄露未來信息”的直接體現(xiàn)。解決標定時用獨立的 500~1000 張圖驗證時用另一批完全沒有參與標定的圖。更進一步按業(yè)務場景分別建標定集——比如產(chǎn)線場景按光照條件、遮擋程度分層采樣確保標定集覆蓋到部署時的真實分布邊界。量化后先在一個與訓練集分布差異較大的“挑戰(zhàn)集”上驗證能過再上線。5.4 小目標在 INT8 下幾乎全丟現(xiàn)象FP32 模型能檢測出的小目標低于 32x32 像素INT8 量化后漏檢率上升 30% 以上。原因小目標特征圖的分辨率高、通道數(shù)多且本身響應值偏低。量化后低響應值的特征被 INT8 的量化噪聲淹沒檢測頭無法從噪聲中區(qū)分目標和背景。另外小目標標注本身就稀疏量化校準時這些特征分布占比小scale 的計算被大目標響應主導。解決量化前先用蒸餾把 Student 的小目標 AP 提到足夠高給量化留足余量。量化時單獨對小目標特征層P3做統(tǒng)計——把校準集按目標大小加權采樣增加小目標樣本的占比讓校準器看到更完整的小目標響應分布。如果再不行就用 QAT 加強對小目標層的量化感知訓練。這一套組合拳在“yolov11小目標優(yōu)化”這個方向上幾乎是標準解法。5.5 蒸餾時 Teacher 和 Student 的預處理不一致現(xiàn)象蒸餾訓練 loss 迅速下降但驗證集 mAP 始終上不去訓練曲線看著正常實際效果卻很差。原因Teacher 的輸入通道順序或歸一化方式與 Student 不同。典型情況是 Teacher 用 BGR 通道訓練Student 的預處理代碼寫了 RGB或者 Teacher 用 /255.0 歸一化Student 用 /127.5 - 1。特征對齊時輸入分布不一致Student 學到的是 Teacher 特征在“錯誤分布”下的表達推理時自然對不上。解決寫一個數(shù)據(jù)管線檢查腳本同一張圖分別走 Teacher 和 Student 的預處理打印輸入 tensor 的 mean/std 對比。在蒸餾配置文件里強制 Teacher 復用 Student 的預處理管線而不是讓 Teacher 走自己的預處理邏輯。這個檢查要放在項目開始的第一天而不是等訓練跑完再排查。6. 驗證最后一公里用推理速度與精度回落評估值不值得做當蒸餾和量化都跑通后我習慣用一張表格把整個鏈路的收益算清楚而不是只看 mAP 一個指標。這個“最后一公里”驗證的目標是回答這套輕量化方案真正省了什么、賠了什么、能不能上線。以 YOLOv11s 蒸餾到 YOLOv11n 并 INT8 量化為典型參考驗證表格大致如下指標FP32 StudentINT8 量化后變化模型體積~20 MB~5 MB減少 75%推理耗時CPU45 ms/幀18 ms/幀提升約 2.5 倍推理耗時NPU不支持8 ms/幀打開 NPU 部署可能mAP5052.3%50.8%掉點 1.5 個百分點小目標 AP32px31.2%27.6%掉點 3.6 個百分點顯存占用1.8 GB0.9 GB減半這張表的決定性判斷是如果 INT8 后的掉點在業(yè)務容忍范圍內(nèi)通常工業(yè)場景允許 1~2 個點的 mAP50 回落且推理速度提升能覆蓋實際節(jié)拍需求這個方向就值得投入。如果小目標 AP 掉點讓你猶豫先回去補第 3 章的蒸餾策略把小目標 AP 再往上拉 3~5 個點再量化而不是直接調(diào)量化參數(shù)——量化參數(shù)只能在有限范圍內(nèi)止損不能創(chuàng)造精度。驗證時有一個我踩過的坑只看 mAP50 不看 mAP50-95。mAP50 對框的定位精度要求寬松box 漂移幾個像素看不出來。工業(yè)質(zhì)檢場景往往需要精確框選缺陷區(qū)域mAP50-95 和定位誤差比如 IoU 下降比例更能反映量化后的真實代價。所以我每次做完 INT8 都會額外跑一遍“框偏移統(tǒng)計”——對同一組測試圖用 FP32 和 INT8 分別推理統(tǒng)計所有匹配到的檢測框的中心點偏移均值和面積變化。偏移均值超過 3 個像素就需要警覺超過 8 個像素基本得回到 QAT 路線。最后的習慣是在部署代碼里加一個預熱階段前 50 張圖不參與耗時統(tǒng)計讓推理引擎完成算子融合、內(nèi)存分配等初始化動作。很多團隊在評測時把初始化耗時算進單幀延遲里導致 INT8 模型“看起來”只比 FP32 快 1 倍實際上算子融合完成后能快 2~3 倍。這個細節(jié)直接影響你是否值得把量化推到生產(chǎn)環(huán)境。把前面幾步走完再回來算這筆賬你會發(fā)現(xiàn)輕量化部署的每一分收益都是有據(jù)可查的希望幫到你。本文還有配套的精品資源點擊獲取