Fix Transformers 5 compatibility for generation and RoPE cache

#22
Files changed (2) hide show
  1. modeling_step_vl.py +10 -7
  2. vision_encoder.py +8 -0
modeling_step_vl.py CHANGED
@@ -345,7 +345,6 @@ class StepRoboticsModel(StepRoboticsPreTrainedModel, GenerationMixin):
345
  output_attentions: Optional[bool] = None,
346
  output_hidden_states: Optional[bool] = None,
347
  return_dict: Optional[bool] = None,
348
- cache_position: Optional[torch.LongTensor] = None,
349
  logits_to_keep: Union[int, torch.Tensor] = 0,
350
  images: Optional[list[Image.Image]] = None,
351
  **kwargs: Unpack[TransformersKwargs],
@@ -390,7 +389,6 @@ class StepRoboticsModel(StepRoboticsPreTrainedModel, GenerationMixin):
390
  output_attentions=output_attentions,
391
  output_hidden_states=output_hidden_states,
392
  return_dict=True,
393
- cache_position=cache_position,
394
  **kwargs,
395
  )
396
 
@@ -461,7 +459,6 @@ class Step3VL10BForCausalLM(StepRoboticsPreTrainedModel, GenerationMixin):
461
  output_attentions: Optional[bool] = None,
462
  output_hidden_states: Optional[bool] = None,
463
  return_dict: Optional[bool] = None,
464
- cache_position: Optional[torch.LongTensor] = None,
465
  **kwargs: Unpack[TransformersKwargs],
466
  ) -> Union[tuple, StepVLCausalLMOutputWithPast]:
467
  r"""
@@ -504,7 +501,6 @@ class Step3VL10BForCausalLM(StepRoboticsPreTrainedModel, GenerationMixin):
504
  output_attentions=output_attentions,
505
  output_hidden_states=output_hidden_states,
506
  return_dict=return_dict,
507
- cache_position=cache_position,
508
  **kwargs,
509
  )
510
 
@@ -532,17 +528,25 @@ class Step3VL10BForCausalLM(StepRoboticsPreTrainedModel, GenerationMixin):
532
  ):
533
  # Overwritten -- in specific circumstances we don't want to forward image inputs to the model
534
 
 
 
 
 
 
 
 
 
 
535
  model_inputs = super().prepare_inputs_for_generation(
536
  input_ids,
537
  past_key_values=past_key_values,
538
  inputs_embeds=inputs_embeds,
539
  attention_mask=attention_mask,
540
- cache_position=cache_position,
541
  logits_to_keep=logits_to_keep,
542
  **kwargs,
543
  )
544
 
545
- if cache_position[0] == 0:
546
  # If we're in cached decoding stage, pixel values should be None because input ids do not contain special image token anymore
547
  # Otherwise we need pixel values to be passed to model
548
  model_inputs["pixel_values"] = pixel_values
@@ -554,4 +558,3 @@ class Step3VL10BForCausalLM(StepRoboticsPreTrainedModel, GenerationMixin):
554
  return key[len("language_model."):], True
555
 
556
  return key, False
557
-
 
345
  output_attentions: Optional[bool] = None,
346
  output_hidden_states: Optional[bool] = None,
347
  return_dict: Optional[bool] = None,
 
348
  logits_to_keep: Union[int, torch.Tensor] = 0,
349
  images: Optional[list[Image.Image]] = None,
350
  **kwargs: Unpack[TransformersKwargs],
 
389
  output_attentions=output_attentions,
390
  output_hidden_states=output_hidden_states,
391
  return_dict=True,
 
392
  **kwargs,
393
  )
394
 
 
459
  output_attentions: Optional[bool] = None,
460
  output_hidden_states: Optional[bool] = None,
461
  return_dict: Optional[bool] = None,
 
462
  **kwargs: Unpack[TransformersKwargs],
463
  ) -> Union[tuple, StepVLCausalLMOutputWithPast]:
464
  r"""
 
501
  output_attentions=output_attentions,
502
  output_hidden_states=output_hidden_states,
503
  return_dict=return_dict,
 
504
  **kwargs,
505
  )
506
 
 
528
  ):
529
  # Overwritten -- in specific circumstances we don't want to forward image inputs to the model
530
 
531
+ is_first_iteration = kwargs.get("is_first_iteration")
532
+ if is_first_iteration is None:
533
+ is_first_iteration = cache_position is None or cache_position[0] == 0
534
+
535
+ # Transformers 4.x still supplies `cache_position`; keep forwarding it
536
+ # there without making Transformers 5 recreate this removed argument.
537
+ if cache_position is not None:
538
+ kwargs["cache_position"] = cache_position
539
+
540
  model_inputs = super().prepare_inputs_for_generation(
541
  input_ids,
542
  past_key_values=past_key_values,
543
  inputs_embeds=inputs_embeds,
544
  attention_mask=attention_mask,
 
545
  logits_to_keep=logits_to_keep,
546
  **kwargs,
547
  )
548
 
549
+ if is_first_iteration:
550
  # If we're in cached decoding stage, pixel values should be None because input ids do not contain special image token anymore
551
  # Otherwise we need pixel values to be passed to model
552
  model_inputs["pixel_values"] = pixel_values
 
558
  return key[len("language_model."):], True
559
 
560
  return key, False
 
vision_encoder.py CHANGED
@@ -67,6 +67,10 @@ class EncoderRope2D(nn.Module):
67
  self.max_freq = max_freq
68
  self.num_freqs = num_freqs
69
  cache = self._compute_2d_freqs()
 
 
 
 
70
  self.register_buffer("freqs_cache", cache, persistent=False)
71
 
72
  def _compute_inv_freq(self, base: Union[int, float],
@@ -102,6 +106,10 @@ class EncoderRope2D(nn.Module):
102
 
103
  def forward(self, q: torch.Tensor, k: torch.Tensor,
104
  grid_hw: tuple[int, int]):
 
 
 
 
105
  # If grid matches cached shape we reuse directly to avoid recomputation.
106
  if grid_hw[0] != self.max_grid_height or grid_hw[1] != self.max_grid_width:
107
  rows = torch.arange(grid_hw[0], device=q.device).view(-1, 1)
 
67
  self.max_freq = max_freq
68
  self.num_freqs = num_freqs
69
  cache = self._compute_2d_freqs()
70
+ # `from_pretrained` initializes remote-code models on the meta device in
71
+ # Transformers 5. Non-persistent buffers are absent from checkpoints, so
72
+ # the materialized cache has to be recomputed before it is first used.
73
+ self._freqs_cache_needs_rebuild = cache.device.type == "meta"
74
  self.register_buffer("freqs_cache", cache, persistent=False)
75
 
76
  def _compute_inv_freq(self, base: Union[int, float],
 
106
 
107
  def forward(self, q: torch.Tensor, k: torch.Tensor,
108
  grid_hw: tuple[int, int]):
109
+ if self._freqs_cache_needs_rebuild:
110
+ self.freqs_cache = self._compute_2d_freqs().to(q.device)
111
+ self._freqs_cache_needs_rebuild = False
112
+
113
  # If grid matches cached shape we reuse directly to avoid recomputation.
114
  if grid_hw[0] != self.max_grid_height or grid_hw[1] != self.max_grid_width:
115
  rows = torch.arange(grid_hw[0], device=q.device).view(-1, 1)