快速结论:该报错/偏差出现在使用 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,以便区分预期的像素级差异与真正的精度偏差。
解决步骤
- 定位
generate_masks_with_special_tokens_and_transfer_map(modeling_grounding_dino.py,以及mm_grounding_dino中的复制版本)。 - 找到
prev_special = torch.cummax(prev_special, dim=1)[0]这一行。 - 可优先尝试在下一行加入右移,使
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 的动机。
- 确认 #47675 / #49886 的 dtype 修复已在当前代码中,即 position ids 以 float 参与后续计算。
- 用
IDEA-Research/grounding-dino-tiny重新运行test_inference_object_detection_head;若需要对齐到最紧容差,改用GroundingDinoImageProcessorPil处理像素。 - 如果项目中存在
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
AI 工具推荐
想把多个 AI 模型放在一个入口?
GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。
推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。
这个方案解决了吗?
可以继续搜索完整报错,或查看同一工具的其他排查指南。


![[BUG]: division by zero panic in lance-encoding during RAG queries](https://www.chat-gpts.plus/wp-content/uploads/2026/11/7039-b52d5c4f-768x403.jpg)