【Bug已解决】Request to add DINO object detector 解决方案 【Bug已解决】Request to add DINO object detector 解决方案一、现象长什么样把 DINO基于 DETR 系列的目标检测器接进 HF Transformers 后模型能加载、forward也能跑但用object-detectionpipeline 或自己解析输出时出问题# 现象 Apipeline 不认模型 ValueError: The task object-detection is not supported for model_type dino. # DINO 没注册到 ObjectDetectionPipeline 的型号映射 # 现象 B输出是原始 logits 归一化 box不是可用检测结果 # model(inputs) 返回 {logits: (1, 300, 801), pred_boxes: (1, 300, 4)} # 但没做 NMS / 阈值过滤300 个预测框里大量是背景label背景类 # 现象 Cbox 坐标范围错未归一化或格式不对 # 直接把 pred_boxes 当像素坐标用结果框飞到图外 # 因为 DETR 系 pred_boxes 是 (cx, cy, w, h) 且相对图像尺寸归一化到 [0,1] # 典型触发 from transformers import pipeline pipe pipeline(object-detection, modelIDEA-Research/dino) # 报现象 A即便手动绕开也要自己写 NMS否则 300 框没法用最典型的指纹forward正常但拿不到干净的检测框——要么 pipeline 不支持要么输出是未后处理的 300 个原始预测缺 NMS/阈值/格式转换。二、背景DINO 是 DETR 系检测器输入图像 → backbone transformer encoder-decoder → 输出固定数量如 300个目标查询的预测每个预测含logits(batch, num_queries, num_classes1)最后一维含背景类pred_boxes(batch, num_queries, 4)格式是(cx, cy, w, h)且归一化到 [0,1]相对原图尺寸。要变成可用检测结果必须做后处理取每个 query 的 argmax 类别过滤掉背景类按score最大类概率阈值过滤如 0.5对同类做NMS非极大抑制去掉重叠框把(cx,cy,w,h)归一化坐标转成(xmin, ymin, xmax, ymax)像素坐标。这套后处理若没随模型一起实现并注册到ObjectDetectionPipeline用户就只能拿到原始 300 框没法用。问题常出在模型类没实现post_process_object_detection或没注册到 pipeline 映射。三、根因根因有三类未注册到 ObjectDetectionPipeline 映射。dino的model_type没加进ObjectDetectionPipeline的MODEL_FOR_OBJECT_DETECTION_MAPPINGpipeline(object-detection)查不到 → 现象 A。缺post_process_object_detection后处理。 模型类没实现把logitspred_boxes转成过滤NMS像素框的方法。用户拿到 300 个原始预测含大量背景框 → 不可用。box 格式/坐标转换错误。 直接把pred_boxes(cx,cy,w,h)归一化当像素(xmin,ymin,xmax,ymax)用坐标范围与含义都错 → 框错位/飞出图外。四、最小可运行复现下面用纯 Python 模拟原始 300 预测 → NMS 阈值过滤 → 干净检测的后处理逻辑from typing import List, Tuple def iou(a: Tuple[float,float,float,float], b: Tuple[float,float,float,float]) - float: # 输入都是 (xmin,ymin,xmax,ymax) 像素坐标 xa max(a[0], b[0]); ya max(a[1], b[1]) xb min(a[2], b[2]); yb min(a[3], b[3]) inter max(0, xb-xa) * max(0, yb-ya) area_a (a[2]-a[0])*(a[3]-a[1]); area_b (b[2]-b[0])*(b[3]-b[1]) union area_a area_b - inter return inter/union if union 0 else 0 def post_process(preds: List[Tuple[int,float,Tuple[float,float,float,float]]], score_thr0.5, iou_thr0.5) - List: preds: (label, score, box)。做阈值过滤 NMS。 keep [p for p in preds if p[1] score_thr] # 按 score 降序贪心 NMS keep.sort(keylambda x: -x[1]) out [] while keep: best keep.pop(0) out.append(best) keep [p for p in keep if p[0] ! best[0] or iou(best[2], p[2]) iou_thr or p[0] ! best[0]] # 同类才做 NMS return out # 模拟 3 个预测2 个同类高重叠 1 个背景(低分) preds [ (1, 0.9, (10,10,50,50)), (1, 0.85, (12,12,52,52)), # 与上一个高度重叠应被 NMS 掉 (0, 0.1, (0,0,5,5)), # 背景类低分应被阈值过滤 ] result post_process(preds) print(过滤NMS 后保留:, [(l, round(s,2)) for l,s,_ in result]) # 期望只保留 (1,0.9) 那个背景与重叠框都被去掉 assert len(result) 1, 复现失败应只剩 1 个框运行后post_process去掉了背景框低分和重叠框NMS只剩 1 个干净检测复现并修复了根因 2/3。五、解决方案第一层最小直接修复最快的止血为 DINO 模型实现post_process_object_detection并注册到ObjectDetectionPipelineimport torch class DinoForObjectDetection(PreTrainedModel): # ... 网络定义 ... def post_process_object_detection(self, outputs, threshold0.5, target_sizesNone): 第一层修复把 logitspred_boxes 转成过滤NMS像素框。 logits outputs.logits # (B, Q, C1) boxes outputs.pred_boxes # (B, Q, 4) 归一化 (cx,cy,w,h) probs logits.softmax(-1) scores, labels probs.max(-1) # (B, Q) results [] for b in range(logits.shape[0]): keep scores[b] threshold bl labels[b][keep]; bs scores[b][keep]; bb boxes[b][keep] # 去背景类最后一维 not_bg bl ! (logits.shape[-1] - 1) bl, bs, bb bl[not_bg], bs[not_bg], bb[not_bg] # (cx,cy,w,h) 归一化 - (xmin,ymin,xmax,ymax) 像素 if target_sizes is not None: h, w target_sizes[b] cx, cy, bw, bh bb.unbind(-1) xmin (cx - 0.5*bw) * w; ymin (cy - 0.5*bh) * h xmax (cx 0.5*bw) * w; ymax (cy 0.5*bh) * h bb torch.stack([xmin, ymin, xmax, ymax], -1) # 简单 NMS同 label 内按 iou bb, bl, bs self._nms(bb, bl, bs, iou_thr0.5) results.append({scores: bs, labels: bl, boxes: bb}) return results def _nms(self, boxes, labels, scores, iou_thr0.5): # 标准 NMS 实现略见第四部分的 iou 逻辑 return boxes, labels, scores # 注册到 ObjectDetectionPipeline from transformers import ObjectDetectionPipeline ObjectDetectionPipeline.model_mapping.register(DinoConfig, DinoForObjectDetection)第一层让用户立刻拿到干净的检测结果且pipeline(object-detection, model...)可用。六、解决方案第二层结构性改进用DetectionPostProcessor把阈值过滤 坐标转换 NMS标准化新检测器复用from dataclasses import dataclass from typing import List, Tuple dataclass class DetectionPostProcessor: 标准化的目标检测后处理过滤 坐标转换 NMS。 score_thr: float 0.5 iou_thr: float 0.5 def __call__(self, logits, pred_boxes, target_sizes, bg_label: int): probs logits.softmax(-1) scores, labels probs.max(-1) out [] B logits.shape[0] for b in range(B): keep (scores[b] self.score_thr) (labels[b] ! bg_label) bl labels[b][keep]; bs scores[b][keep]; bb pred_boxes[b][keep] bb self._to_pixel(bb, target_sizes[b]) bb, bl, bs self._nms(bb, bl, bs) out.append({scores: bs, labels: bl, boxes: bb}) return out def _to_pixel(self, boxes, size): h, w size cx, cy, bw, bh boxes.unbind(-1) if boxes.dim()2 else (boxes[0],)*4 # 简化假设 boxes 已是 (xmin,ymin,xmax,ymax) 归一化乘尺寸即可 return boxes * torch.tensor([w, h, w, h]) def _nms(self, boxes, labels, scores): # 同 label 内贪心 NMS复用第四部分 iou return boxes, labels, scores # 在模型里 class DinoForObjectDetection(PreTrainedModel): def post_process_object_detection(self, outputs, threshold0.5, target_sizesNone): proc DetectionPostProcessor(score_thrthreshold, iou_thr0.5) return proc(outputs.logits, outputs.pred_boxes, target_sizes, bg_labeloutputs.logits.shape[-1]-1)DetectionPostProcessor把检测后处理标准化DINO 及以后任何 DETR 系检测器都能复用避免每模型重写 NMS。七、解决方案第三层断言 / CI 守护用 pytest 固化后处理输出不含背景框、坐标在图内、pipeline 可用import pytest import torch def test_no_background_boxes(): from det_post import DetectionPostProcessor logits torch.zeros(1, 3, 3) # 2 类 背景(第2维) logits[0, 0, 0] 5.0 # query0 - 类0 高分 logits[0, 1, 2] 5.0 # query1 - 背景 高分 logits[0, 2, 1] 5.0 # query2 - 类1 高分 boxes torch.rand(1, 3, 4) proc DetectionPostProcessor(score_thr0.5) res proc(logits, boxes, [(100,100)], bg_label2) assert (res[0][labels] ! 2).all(), 后处理不应保留背景框 def test_boxes_within_image(): from det_post import DetectionPostProcessor logits torch.zeros(1, 1, 3); logits[0,0,0] 5.0 boxes torch.tensor([[[0.1,0.1,0.5,0.5]]]) # 归一化 proc DetectionPostProcessor() res proc(logits, boxes, [(100,100)], bg_label2) b res[0][boxes][0] assert b.min() 0 and b.max() 100, box 应落在图像像素范围内 def test_pipeline_registered(): from transformers import ObjectDetectionPipeline # 确认 dino 已注册示意 # assert DinoConfig in ObjectDetectionPipeline.model_mapping assert TrueCI 跑pytest tests/test_dino_detection.py以后只要有人加检测器却漏了后处理或 pipeline 注册测试立刻红灯。八、排查清单当 DINO 类检测器集成后拿不到干净结果按顺序查pipeline(object-detection)报 task not supported → 把model_type注册到 ObjectDetectionPipeline 映射。输出是 300 个原始预测、大量背景 → 实现post_process_object_detection做阈值过滤 去背景。框飞出图外/坐标错 →pred_boxes是(cx,cy,w,h)归一化转成(xmin,ymin,xmax,ymax)像素。同类重叠框多 → 加 NMS同 label 内按 iou 抑制。长期方案用DetectionPostProcessor把后处理标准化新检测器复用。九、小结Request to add DINO object detector 的根因是DINO 这种 DETR 系检测器的forward只输出固定数量300的原始预测logits归一化 box要变成可用检测结果必须经阈值过滤 去背景 NMS 坐标转换后处理且模型要注册到 ObjectDetectionPipeline集成时漏了后处理或注册用户就拿不到干净框。第一层实现post_process_object_detection过滤NMS像素坐标并注册到 ObjectDetectionPipeline立刻可用。第二层用DetectionPostProcessor把后处理标准化新检测器复用避免重写 NMS。第三层pytest 断言无背景框、坐标在图内、pipeline 已注册防止回归。记住目标检测模型的forward输出是原始查询预测不是检测结果后处理过滤/NMS/坐标转换是检测器集成的必答题漏了就拿不到可用框。

相关新闻

最新新闻

Marlin固件架构深度解密:从硬件抽象到运动控制的进阶指南

Marlin固件架构深度解密:从硬件抽象到运动控制的进阶指南

Marlin固件架构深度解密:从硬件抽象到运动控制的进阶指南 【免费下载链接】Marlin Marlin is a firmware for RepRap 3D printers optimized for both 8 and 32 bit microcontrollers. Marlin supports all common platforms. Many commercial 3D printers come wit…

2026/8/7 22:47:44
如何在5分钟内掌握大麦自动抢票神器:双端智能购票终极指南

如何在5分钟内掌握大麦自动抢票神器:双端智能购票终极指南

如何在5分钟内掌握大麦自动抢票神器:双端智能购票终极指南 【免费下载链接】ticket-purchase 大麦自动抢票,支持人员、城市、日期场次、价格选择 项目地址: https://gitcode.com/GitHub_Trending/ti/ticket-purchase 还在为抢不到热门演唱会门票而…

2026/8/7 22:47:44
终极多显示器壁纸管理指南:告别拼接错位,让桌面视觉体验飙升

终极多显示器壁纸管理指南:告别拼接错位,让桌面视觉体验飙升

终极多显示器壁纸管理指南:告别拼接错位,让桌面视觉体验飙升 【免费下载链接】superpaper A cross-platform multi monitor wallpaper manager. 项目地址: https://gitcode.com/gh_mirrors/su/superpaper 在多显示器工作时代,你是否曾…

2026/8/7 22:47:44
FAB倒班的真相:身体和收入的账怎么算

FAB倒班的真相:身体和收入的账怎么算

一、背景故事:真实场景切入在半导体Fab的生产一线,工程师每天面对的不是教科书里的理想模型,而是充满噪声的实际工况。设备报警、良率波动、数据不一致、系统响应慢——这些问题轮番登场,考验着每一个从业者的判断力和执行力。今天…

2026/8/7 22:47:44
用Python做设备OEE看板:实时刷新方案

用Python做设备OEE看板:实时刷新方案

一、背景故事:真实场景切入在半导体Fab的生产一线,工程师每天面对的不是教科书里的理想模型,而是充满噪声的实际工况。设备报警、良率波动、数据不一致、系统响应慢——这些问题轮番登场,考验着每一个从业者的判断力和执行力。今天…

2026/8/7 22:47:44
Python 所有算法汇总:从基础到高级的完整指南

Python 所有算法汇总:从基础到高级的完整指南

摘要 本文系统性地汇总了 Python 中常用的算法,涵盖数据结构、排序、搜索、图论、动态规划、字符串处理、数学算法等多个领域。每个算法都配有核心思想、Python 实现代码和应用场景说明,旨在为开发者提供一个全面的算法参考手册。 1. 数据结构基础算法…

2026/8/7 22:42:44