Grounding DINO: phrase delimiters get text position id 0 since v5.0 (the remaining divergence of #47674)

该报错/偏差出现在使用 Transformers v5.x 的 Grounding DINO 做图文目标检测时,文本 position_ids 对短语结尾的分隔符( . 、 ? )被算成 0 ,导致文本特征整体偏移、logits 和分数与旧版不一致。优先排查并修正 generate_masks_wi

快速结论:该报错/偏差出现在使用 Transformers v5.x 的 Grounding DINO 做图文目标检测时,文本 position_ids 对短语结尾的分隔符(.、?)被算成 0,导致文本特征整体偏移、logits 和分数与旧版不一致。优先排查并修正 generate_masks_with_special_tokens_and_transfer_map 中 prev_special 的取值方式。

适用环境:Issue 已确认环境为 transformers 5.18.0(main 上代码未变)、torch 2.14.1、Python 3.12.13、macOS 27.2 arm64、CPU。模型为 IDEA-Research/grounding-dino-tiny。

最快修复方案:暂无确认的一步修复方案;Issue 中作者提出并已在讨论中获得跟进的可优先尝试方案,是在 prev_special 的 cummax 结果上整体右移一位,使每个位置只取“严格位于它之前”的特殊 token,从而让结尾分隔符得到所在短语的长度。

注意事项:该修复只解决 position_ids 偏差,Issue 指出还需配合 #47675/#49886 的 dtype 修复才能让测试进入容差范围;默认图像处理器与 PIL 路径仍存在约 0.0126 的预期差异。修改位于模型代码,需同时同步 mm_grounding_dino 中的同一段代码,并注意 CUDA graph 场景下不得引入 host sync。

问题场景

用户在 Transformers v5.x 中运行 Grounding DINO 目标检测推理(如 test_inference_object_detection_head),或对比 Transformers 与原始 GroundingDINO / mmdetection 实现时触发问题。表现是检测结果整体偏差:logits 与参考值不一致,置信度分数发生漂移。Issue 给出的示例中,test_inference_object_detection_head 仍然失败(0.3003 → 0.1401),分数从期望的 0.4526、0.4082 变为 0.4474、0.4361。含多个短语的 prompt 在每个分隔符处都会受影响。

报错原文

Grounding DINO: phrase delimiters get text position id 0 since v5.0 (the remaining divergence of #47674)

原因分析

自 v5.0.0 起,generate_masks_with_special_tokens_and_transfer_map 被向量化。attention mask 未变,但 position_ids 的计算变了:一个 token 的位置从前一个特殊 token 开始计数,并且包含该 token 自身,因此每个结束短语的分隔符(. 或 ?)会得到 -1,再被 clamp 成 0。v4 的循环实现(以及原始 GroundingDINO 和 mmdetection)给分隔符赋的是它所在短语的长度。

例如:

ids = processor(text="a cat.", return_tensors="pt").input_ids   # [101, 1037, 4937, 1012, 102]
# v5.x:  position_ids = [0, 0, 1, 0, 0]
# v4.x:  position_ids = [0, 0, 1, 2, 0]

position_ids 会输入 BERT 的 position embeddings 和编码器的 text sine embedding,因此每个文本特征都会改变。问题代码位于 src/transformers/models/grounding_dino/modeling_grounding_dino.py,同一段代码也复制到了 mm_grounding_dino:

prev_special = torch.where(special_mask, indices, torch.full((), -1, device=device))
prev_special = torch.cummax(prev_special, dim=1)[0]   # includes the current position
...
position_ids = indices - prev_special - 1              # -1 for every special token

此外,Issue 表明仅修 position_ids 还不够,单靠 #47675/#49886 的 dtype 修复也只能把 logits 最大绝对差从 0.3004 降到 0.1400;两项修复同时应用才降到 0.0126,再配合 GroundingDinoImageProcessorPil 处理像素后降到 0.0010,测试才在容差内通过。

环境排查

  • 确认 transformers 版本是否为 5.x(Issue 复现为 5.18.0,main 上代码未变)。
  • 确认 torch 版本(Issue 为 2.14.1)。
  • 确认 Python 版本(Issue 为 3.12.13)。
  • 确认运行设备与平台(Issue 为 macOS 27.2 arm64、CPU)。
  • 确认是否已包含 #47675 / #49886 的 position ids 转 float 的修复。
  • 确认是否存在 mm_grounding_dino 中重复的同一段代码需要一并检查。
  • 确认图像处理器使用的是默认 fast 处理器还是 GroundingDinoImageProcessorPil,以便区分预期的像素级差异与真正的精度偏差。

解决步骤

  1. 定位 generate_masks_with_special_tokens_and_transfer_map(modeling_grounding_dino.py,以及 mm_grounding_dino 中的复制版本)。
  2. 找到 prev_special = torch.cummax(prev_special, dim=1)[0] 这一行。
  3. 可优先尝试在下一行加入右移,使 prev_special 表示严格位于当前位置之前的特殊 token:
    +    # previous special token strictly before each position, so a closing delimiter
    +    # gets the length of its phrase (as in v4 and the original implementation)
    +    prev_special = torch.cat([torch.full_like(prev_special[:, :1], -1), prev_special[:, :-1]], dim=1)

    该写法保持向量化,不产生 host sync,因此保留了重写时面向 CUDA graph 的动机。

  4. 确认 #47675 / #49886 的 dtype 修复已在当前代码中,即 position ids 以 float 参与后续计算。
  5. 用 IDEA-Research/grounding-dino-tiny 重新运行 test_inference_object_detection_head;若需要对齐到最紧容差,改用 GroundingDinoImageProcessorPil 处理像素。
  6. 如果项目中存在 mm_grounding_dino,同步应用相同修改,避免两个实现再次分叉。

验证方法

在同一权重和输入下,检查 a cat. 这类输入的 position_ids:结尾 . 应得到其短语长度(v4 为 [0, 0, 1, 2, 0]),而不是 0。运行 test_inference_object_detection_head,确认在 (None, None) 期望值与容差内通过。也可对比 GroundingDinoForObjectDetection 编码器输出与 mmdetection 实现:Issue 中两项修复同时应用后两者相差约 5e-6,而未修复时编码器 text memory 最大相差 0.25。

参考来源

huggingface/transformers #50465

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 33950

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注