Skip to content

Commit 9e7f5cd

Browse files
sergereview[bot]serge[bot]zucchini-nlptarekziadeclaude
authored
[serge] Fix 8 integration tests for model grounding_dino failing with output_mismatch (tensor values differ (6), oth (#49886)
* [serge] Fix 8 integration tests for model `grounding_dino` failing with `output_mismatch` (tensor values differ (6), oth * what pablo asked * fix repo * and the pos id thing seems valid * trf * Address review: required special_tokens, regression tests, new expectations - `generate_masks_with_special_tokens_and_transfer_map` now requires `special_tokens` - drop the buffer comment - add fast tests for phrase masks / position ids and for float text position embeddings - update detection-head expectations for the position-id fix (grounding_dino + mm_grounding_dino) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * no more flaky asserts and update loss * add expectations from runner here --------- Co-authored-by: serge[bot] <serge[bot]@users.noreply.github.com> Co-authored-by: raushan <raushan@huggingface.co> Co-authored-by: Tarek Ziade <tarek@ziade.org> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 78a4daf commit 9e7f5cd

5 files changed

Lines changed: 267 additions & 132 deletions

File tree

‎src/transformers/models/grounding_dino/modeling_grounding_dino.py‎

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1049,20 +1049,16 @@ def get_text_position_embeddings(
10491049
text_position_embedding: torch.Tensor | None,
10501050
text_position_ids: torch.Tensor | None,
10511051
) -> Tensor:
1052-
batch_size, seq_length, _ = text_features.shape
1053-
if text_position_embedding is None and text_position_ids is None:
1054-
text_position_embedding = torch.arange(seq_length, device=text_features.device)
1055-
text_position_embedding = text_position_embedding.float()
1056-
text_position_embedding = text_position_embedding.unsqueeze(0).unsqueeze(-1)
1057-
text_position_embedding = text_position_embedding.repeat(batch_size, 1, 1)
1058-
text_position_embedding = encode_sinusoidal_position_embedding(
1059-
text_position_embedding, num_pos_feats=self.d_model
1060-
)
1061-
if text_position_ids is not None:
1062-
text_position_embedding = encode_sinusoidal_position_embedding(
1063-
text_position_ids[..., None], num_pos_feats=self.d_model
1064-
)
1065-
1052+
if text_position_embedding is not None:
1053+
return text_position_embedding
1054+
1055+
if text_position_ids is None:
1056+
batch_size, seq_length, _ = text_features.shape
1057+
text_position_ids = torch.arange(seq_length, device=text_features.device)
1058+
text_position_ids = text_position_ids.expand(batch_size, -1)
1059+
text_position_embedding = encode_sinusoidal_position_embedding(
1060+
text_position_ids[..., None].to(text_features.dtype), num_pos_feats=self.d_model
1061+
)
10661062
return text_position_embedding
10671063

10681064
def forward(
@@ -1337,6 +1333,8 @@ def _init_weights(self, module):
13371333
if isinstance(module, GroundingDinoLearnedPositionEmbedding):
13381334
init.uniform_(module.row_embeddings.weight)
13391335
init.uniform_(module.column_embeddings.weight)
1336+
elif isinstance(module, GroundingDinoModel):
1337+
init.copy_(module.special_tokens, torch.tensor(SPECIAL_TOKENS))
13401338
elif isinstance(module, GroundingDinoMultiscaleDeformableAttention):
13411339
init.constant_(module.sampling_offsets.weight, 0.0)
13421340
default_dtype = torch.get_default_dtype()
@@ -1809,11 +1807,15 @@ def custom_forward(*inputs):
18091807
SPECIAL_TOKENS = [101, 102, 1012, 1029]
18101808

18111809

1812-
def generate_masks_with_special_tokens_and_transfer_map(input_ids: torch.LongTensor) -> tuple[Tensor, Tensor]:
1810+
def generate_masks_with_special_tokens_and_transfer_map(
1811+
input_ids: torch.LongTensor, special_tokens: torch.LongTensor
1812+
) -> tuple[Tensor, Tensor]:
18131813
"""Generate attention mask between each pair of special tokens and positional ids.
18141814
Args:
18151815
input_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`):
18161816
Indices of input sequence tokens in the vocabulary.
1817+
special_tokens (`torch.LongTensor` of shape `(num_special_tokens,)`):
1818+
Ids of the delimiter tokens that split the text into phrases.
18171819
Returns:
18181820
`tuple(torch.Tensor)` comprising attention mask between each special tokens and position_ids:
18191821
- **attention_mask** (`torch.BoolTensor` of shape `(batch_size, sequence_length, sequence_length)`)
@@ -1823,14 +1825,15 @@ def generate_masks_with_special_tokens_and_transfer_map(input_ids: torch.LongTen
18231825
device = input_ids.device
18241826

18251827
# Identify special token positions
1826-
special_mask = torch.isin(input_ids, torch.tensor(SPECIAL_TOKENS, device=device))
1828+
special_mask = torch.isin(input_ids, special_tokens)
18271829

18281830
# For each position, find the previous and next special token indices
18291831
indices = torch.arange(seq_len, device=device).unsqueeze(0).expand(batch_size, -1)
18301832

18311833
# Previous special token: cummax of special token indices
18321834
prev_special = torch.where(special_mask, indices, torch.full((), -1, device=device))
18331835
prev_special = torch.cummax(prev_special, dim=1)[0]
1836+
prev_special = torch.cat([prev_special.new_full((batch_size, 1), -1), prev_special[:, :-1]], dim=1)
18341837

18351838
# Next special token: flip, cummin, flip back
18361839
next_special = torch.where(special_mask, indices, torch.tensor(seq_len, device=device))
@@ -1933,6 +1936,10 @@ def __init__(self, config: GroundingDinoConfig):
19331936
else:
19341937
self.reference_points = nn.Embedding(config.num_queries, 4)
19351938

1939+
self.special_tokens = nn.Buffer(
1940+
torch.tensor(SPECIAL_TOKENS, dtype=torch.long),
1941+
persistent=False,
1942+
)
19361943
self.post_init()
19371944

19381945
def freeze_backbone(self):
@@ -2060,7 +2067,9 @@ def forward(
20602067
)
20612068
return_dict = return_dict if return_dict is not None else self.config.return_dict
20622069

2063-
text_self_attention_masks, position_ids = generate_masks_with_special_tokens_and_transfer_map(input_ids)
2070+
text_self_attention_masks, position_ids = generate_masks_with_special_tokens_and_transfer_map(
2071+
input_ids, special_tokens=self.special_tokens
2072+
)
20642073

20652074
if attention_mask is None:
20662075
attention_mask = torch.ones_like(input_ids)

‎src/transformers/models/mm_grounding_dino/modeling_mm_grounding_dino.py‎

Lines changed: 30 additions & 21 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎src/transformers/models/mm_grounding_dino/modular_mm_grounding_dino.py‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
from ..auto import AutoConfig
2525
from ..auto.modeling_auto import AutoModel
2626
from ..grounding_dino.modeling_grounding_dino import (
27+
SPECIAL_TOKENS,
2728
GroundingDinoContrastiveEmbedding,
2829
GroundingDinoConvEncoder,
2930
GroundingDinoConvModel,
@@ -247,6 +248,10 @@ def __init__(self, config: MMGroundingDinoConfig):
247248
)
248249
self.encoder_output_class_embed = MMGroundingDinoContrastiveEmbedding(config)
249250

251+
self.special_tokens = nn.Buffer(
252+
torch.tensor(SPECIAL_TOKENS, dtype=torch.long),
253+
persistent=False,
254+
)
250255
self.post_init()
251256

252257

0 commit comments

Comments
 (0)