Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions .github/workflows/test_openvino_slow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,6 @@ jobs:
path: ~/.cache/huggingface/hub
key: hf-models

- if: ${{ matrix.transformers-version != 'latest' && matrix.transformers-version != 'main' }}
name: Install specific dependencies and versions required for older transformers
run: |
uv pip install transformers==${{ matrix.transformers-version }} accelerate==0.* peft==0.13.* diffusers==0.32.* transformers_stream_generator

- if: ${{ matrix.transformers-version == 'main' }}
name: Install transformers from repository
run: |
Expand Down
8 changes: 6 additions & 2 deletions optimum/exporters/openvino/convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -1410,7 +1410,9 @@ def get_sd3_models_for_export(pipeline, exporter, int_dtype, float_dtype):
text_encoder = getattr(pipeline, "text_encoder", None)
if text_encoder is not None:
text_encoder.config.output_hidden_states = True
text_encoder.text_model.config.output_hidden_states = True
# `CLIPTextTransformer` removed since transformers v5.6
if hasattr(text_encoder, "text_model"):
text_encoder.text_model.config.output_hidden_states = True
text_encoder_config_constructor = TasksManager.get_exporter_config_constructor(
model=text_encoder,
exporter=exporter,
Expand Down Expand Up @@ -1472,7 +1474,9 @@ def get_sd3_models_for_export(pipeline, exporter, int_dtype, float_dtype):
text_encoder_2 = getattr(pipeline, "text_encoder_2", None)
if text_encoder_2 is not None:
text_encoder_2.config.output_hidden_states = True
text_encoder_2.text_model.config.output_hidden_states = True
# `CLIPTextTransformer` removed since transformers v5.6
if hasattr(text_encoder_2, "text_model"):
text_encoder_2.text_model.config.output_hidden_states = True
export_config_constructor = TasksManager.get_exporter_config_constructor(
model=text_encoder_2,
exporter=exporter,
Expand Down
56 changes: 34 additions & 22 deletions optimum/exporters/openvino/model_patcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -4881,12 +4881,6 @@ def forward_with_precomputed_mask(*args, **kwargs):

self.orig_forward = forward_with_precomputed_mask

def __enter__(self):
super().__enter__()

def __exit__(self, exc_type, exc_value, traceback):
super().__exit__(exc_type, exc_value, traceback)


# Forward method of the language model of Gemma3n, needs to be patched to pass 'per_layer_inputs',
# as original code fails to create per_layer_inputs without the providing of input_ids,
Expand Down Expand Up @@ -4969,7 +4963,7 @@ def gemma3n_language_model_forward(
return outputs


# Creates a dict of causal masks with bidirectional attention for vision tokens
# Creates a dict of causal masks with bidirectional attention for vision tokens,
# on sliding_attention layers, matching the behavior of transformers
# create_causal_mask_mapping when use_bidirectional_attention == "vision".
# Needs to be patched to pass proper 'sliding_mask' for prefill stage.
Expand Down Expand Up @@ -5021,7 +5015,9 @@ def _create_gemma4_bidirectional_mask_dict(attention_mask_2d, mm_token_type_ids,
same_group = (query_groups.unsqueeze(2) == key_groups.unsqueeze(1)) & (key_groups.unsqueeze(1) >= 0)
same_group = same_group.unsqueeze(1) # [batch, 1, seq_len, total_len]

# Undo masking for same-group vision tokens in sliding mask
# Un-mask same-group vision tokens in both masks (bidirectional attention within an image).
if is_transformers_version(">=", "5.9"):
full_mask = full_mask.masked_fill(same_group, 0.0)
sliding_mask = sliding_mask.masked_fill(same_group, 0.0)

return {
Expand Down Expand Up @@ -5229,6 +5225,10 @@ def gemma4_text_attention_forward(
) -> tuple:
from transformers.models.gemma4.modeling_gemma4 import apply_rotary_pos_emb as apply_rotary_pos_emb_gemma4

# since transformers >= v5.6 (PR #45788) `shared_kv_states` dict and is passed and `kv_shared_layer_index` removed
shared_kv_states = kwargs.pop("shared_kv_states", None)
legacy_shared_kv_states = hasattr(self, "kv_shared_layer_index")

input_shape = hidden_states.shape[:-1]
hidden_shape = (*input_shape, -1, self.head_dim)

Expand All @@ -5239,8 +5239,12 @@ def gemma4_text_attention_forward(
query_states = apply_rotary_pos_emb_gemma4(query_states, cos, sin, unsqueeze_dim=2)
query_states = query_states.transpose(1, 2)

if self.is_kv_shared_layer and past_key_values is not None:
key_states, value_states = past_key_values.shared_layers[self.kv_shared_layer_index]
if self.is_kv_shared_layer and (not legacy_shared_kv_states or past_key_values is not None):
if legacy_shared_kv_states:
key_states, value_states = past_key_values.shared_layers[self.kv_shared_layer_index]
else:
key_states, value_states = shared_kv_states[self.layer_type]

key_states = key_states.to(query_states.device)
value_states = value_states.to(query_states.device)
else:
Expand All @@ -5255,18 +5259,26 @@ def gemma4_text_attention_forward(
value_states = value_states.transpose(1, 2)

if past_key_values is not None:
cache_kwargs = {
"sin": sin,
"cos": cos,
"cache_position": cache_position,
"sliding_window": self.sliding_window,
}
if not self.is_kv_shared_layer:
key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx, cache_kwargs)
if self.store_full_length_kv:
if not hasattr(past_key_values, "shared_layers"):
past_key_values.shared_layers = {}
past_key_values.shared_layers[self.layer_idx] = key_states, value_states
if legacy_shared_kv_states:
cache_kwargs = {
"sin": sin,
"cos": cos,
"cache_position": cache_position,
"sliding_window": self.sliding_window,
}
if not self.is_kv_shared_layer:
key_states, value_states = past_key_values.update(
key_states, value_states, self.layer_idx, cache_kwargs
)
if self.store_full_length_kv:
if not hasattr(past_key_values, "shared_layers"):
past_key_values.shared_layers = {}
past_key_values.shared_layers[self.layer_idx] = key_states, value_states
else:
if not self.is_kv_shared_layer:
key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx)
if self.store_full_length_kv and shared_kv_states is not None:
shared_kv_states[self.layer_type] = key_states, value_states

attention_interface = gemma4_eager_attention_forward_patched

Expand Down
19 changes: 13 additions & 6 deletions optimum/intel/openvino/modeling_visual_language.py
Original file line number Diff line number Diff line change
Expand Up @@ -3160,9 +3160,12 @@ def rot_pos_emb(self, grid_thw):
wpos_ids = wpos_ids.flatten()
pos_ids.append(torch.stack([hpos_ids, wpos_ids], dim=-1).repeat(t, 1))
pos_ids = torch.cat(pos_ids, dim=0)
max_grid_size = grid_thw[:, 1:].max()
rotary_pos_emb_full = self._rotary_pos_emb(max_grid_size)
rotary_pos_emb = rotary_pos_emb_full[pos_ids].flatten(1)
if is_transformers_version(">=", "5.9"):

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rotary_pos_emb = self._rotary_pos_emb(pos_ids)
else:
max_grid_size = grid_thw[:, 1:].max()
rotary_pos_emb_full = self._rotary_pos_emb(max_grid_size)
rotary_pos_emb = rotary_pos_emb_full[pos_ids].flatten(1)
return rotary_pos_emb

def get_multimodal_embeddings(
Expand Down Expand Up @@ -4286,9 +4289,13 @@ def rot_pos_emb(self, grid_thw):
)
pos_ids.append(torch.stack([hpos_ids, wpos_ids], dim=-1).repeat(t, 1))
pos_ids = torch.cat(pos_ids, dim=0)
max_grid_size = grid_thw[:, 1:].max()
rotary_pos_emb_full = self.rotary_pos_emb(max_grid_size)
rotary_pos_emb = rotary_pos_emb_full[pos_ids].flatten(1)
if is_transformers_version(">=", "5.9"):
rotary_pos_emb = self.rotary_pos_emb(pos_ids)
else:
max_grid_size = grid_thw[:, 1:].max()
rotary_pos_emb_full = self.rotary_pos_emb(max_grid_size)
rotary_pos_emb = rotary_pos_emb_full[pos_ids].flatten(1)

return rotary_pos_emb

def get_vision_embeddings(self, pixel_values, grid_thw, **kwargs):
Expand Down
3 changes: 3 additions & 0 deletions optimum/intel/openvino/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@
TEXTUAL_INVERSION_EMBEDDING_KEYS = [
"self.text_model.embeddings.token_embedding.weight",
"self.model.text_model.embeddings.token_embedding.weight",
# `CLIPTextTransformer` was removed since transformers v5.6
"self.embeddings.token_embedding.weight",
"self.model.embeddings.token_embedding.weight",
]

OV_TO_NP_TYPE = {
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"torch>=2.1",
"safetensors<0.8.0",
"optimum~=2.3.0",
"transformers>=4.51,<5.6",
"transformers>=4.51,<5.11",
"setuptools",
"huggingface-hub>=0.23.2,<1.22",
"nncf>=2.19.0",
Expand Down
3 changes: 2 additions & 1 deletion tests/openvino/test_modeling.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
SEED,
TENSOR_ALIAS_TO_TYPE,
TEST_IMAGE_URL,
is_model_type_transformers_compatible,
)

from optimum.intel import (
Expand Down Expand Up @@ -1041,7 +1042,7 @@ class OVModelForFeatureExtractionIntegrationTest(unittest.TestCase):
"sentence-transformers-bert",
"qwen3",
)
if is_transformers_version("<", "5.4") or is_transformers_version(">=", "5.6"):
if is_model_type_transformers_compatible("qwen3_vl"):
SUPPORTED_ARCHITECTURES += ("qwen3_vl_embedding",)

@parameterized.expand(SUPPORTED_ARCHITECTURES)
Expand Down
6 changes: 5 additions & 1 deletion tests/openvino/test_quantization.py
Original file line number Diff line number Diff line change
Expand Up @@ -1295,7 +1295,11 @@ class OVWeightCompressionTest(unittest.TestCase):
{
"unet": {"names": ["__module.time_embedding.linear_1/aten::linear/MatMul"]},
"text_encoder": {
"names": ["__module.text_model.encoder.layers.0.self_attn.q_proj/aten::linear/MatMul"]
"names": [
"__module.text_model.encoder.layers.0.self_attn.q_proj/aten::linear/MatMul"
if is_transformers_version("<", "5.6")
else "__module.encoder.layers.0.self_attn.q_proj/aten::linear/MatMul"
]
},
},
),
Expand Down
4 changes: 2 additions & 2 deletions tests/openvino/utils_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -611,13 +611,13 @@ def _resolve_cached_model_paths(model_names: dict) -> dict:
"gemma4": {
"lm_model": 54,
"text_embeddings_model": 1,
"vision_embeddings_model": 10,
"vision_embeddings_model": 10 if is_transformers_version("<", "5.10") else 11,
"text_embeddings_per_layer_model": 1,
},
"gemma4_moe": {
"lm_model": 48,
"text_embeddings_model": 1,
"vision_embeddings_model": 10,
"vision_embeddings_model": 10 if is_transformers_version("<", "5.10") else 11,
"text_embeddings_per_layer_model": 0,
},
"smollm3": {"model": 30},
Expand Down
Loading