Skip to content

Commit a1ee7bf

Browse files
committed
fix(models): repair Transformers 5.15 compatibility
Signed-off-by: yaoyu-33 <yaoyu.094@gmail.com>
1 parent 181b9e4 commit a1ee7bf

4 files changed

Lines changed: 66 additions & 14 deletions

File tree

‎src/megatron/bridge/models/gemma/gemma4_bridge.py‎

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,14 @@ def _infer_attn_pattern(layer_types: list[str]) -> tuple[int, int] | list[str]:
9898
return (len(layer_types), 0)
9999

100100

101-
def _attention_config_value(hf_config: Any, layer_type: str, field_name: str, default: Any) -> Any:
101+
def _attention_config_value(
102+
hf_config: Any,
103+
layer_type: str,
104+
field_name: str,
105+
default: Any,
106+
*,
107+
legacy_field_name: str | None = None,
108+
) -> Any:
102109
"""Read an attention field from a concrete HF layer config when available."""
103110
layer_types = getattr(hf_config, "layer_types", None)
104111
per_layer_config = getattr(hf_config, "per_layer_config", None)
@@ -110,9 +117,10 @@ def _attention_config_value(hf_config: Any, layer_type: str, field_name: str, de
110117
else:
111118
return getattr(per_layer_config[layer_index], field_name, default)
112119

113-
# Transformers 5.15 rejects direct reads of fields that vary by layer. The
114-
# global value is still the correct fallback for the local-attention config.
115-
return getattr(hf_config, "__dict__", {}).get(field_name, default)
120+
# Transformers 5.15 rejects direct reads of fields that vary by layer.
121+
# Older configs instead serialize separate flat local/global field names.
122+
fallback_name = legacy_field_name or field_name
123+
return getattr(hf_config, "__dict__", {}).get(fallback_name, default)
116124

117125

118126
def _layer_types_from_provider(provider: Gemma4ModelProvider | Gemma4DenseProvider) -> list[str]:
@@ -245,7 +253,8 @@ def _build_dense_provider(self, hf_config) -> Gemma4DenseProvider:
245253
hf_config,
246254
"full_attention",
247255
"num_key_value_heads",
248-
getattr(hf_config, "num_global_key_value_heads", num_query_groups),
256+
num_query_groups,
257+
legacy_field_name="num_global_key_value_heads",
249258
)
250259

251260
self._dense_num_attention_heads = num_attention_heads
@@ -265,7 +274,13 @@ def _build_dense_provider(self, hf_config) -> Gemma4DenseProvider:
265274
num_attention_heads=num_attention_heads,
266275
num_query_groups=num_query_groups,
267276
kv_channels=_attention_config_value(hf_config, "sliding_attention", "head_dim", 256),
268-
global_kv_channels=_attention_config_value(hf_config, "full_attention", "head_dim", 512),
277+
global_kv_channels=_attention_config_value(
278+
hf_config,
279+
"full_attention",
280+
"head_dim",
281+
512,
282+
legacy_field_name="global_head_dim",
283+
),
269284
num_global_query_groups=num_global_query_groups,
270285
seq_length=hf_config.max_position_embeddings,
271286
vocab_size=hf_config.vocab_size,
@@ -307,12 +322,19 @@ def _build_moe_provider(self, hf_config) -> Gemma4ModelProvider:
307322
provider.kv_channels = head_dim
308323
provider.qk_layernorm = True
309324

310-
provider.global_head_dim = _attention_config_value(hf_config, "full_attention", "head_dim", 512)
325+
provider.global_head_dim = _attention_config_value(
326+
hf_config,
327+
"full_attention",
328+
"head_dim",
329+
512,
330+
legacy_field_name="global_head_dim",
331+
)
311332
provider.num_global_key_value_heads = _attention_config_value(
312333
hf_config,
313334
"full_attention",
314335
"num_key_value_heads",
315-
getattr(hf_config, "num_global_key_value_heads", 2),
336+
2,
337+
legacy_field_name="num_global_key_value_heads",
316338
)
317339
provider.attention_k_eq_v = getattr(hf_config, "attention_k_eq_v", False)
318340

@@ -447,16 +469,23 @@ def maybe_modify_loaded_hf_weight(
447469
text_config, "num_attention_heads", getattr(self, "_dense_num_attention_heads", 8)
448470
)
449471
kv_head_dim = q_weight.shape[0] // num_q_heads
450-
num_kv_heads = getattr(text_config, "num_key_value_heads", getattr(self, "_dense_num_query_groups", 2))
472+
num_kv_heads = _attention_config_value(
473+
text_config,
474+
"sliding_attention",
475+
"num_key_value_heads",
476+
getattr(self, "_dense_num_query_groups", 2),
477+
)
451478
layer_match = re.search(r"layers\.(\d+)\.", q_name)
452479
layer_types = getattr(text_config, "layer_types", None)
453480
if layer_match and layer_types:
454481
layer_idx = int(layer_match.group(1))
455482
if layer_idx < len(layer_types) and layer_types[layer_idx] == "full_attention":
456-
num_global_kv_heads = getattr(
483+
num_global_kv_heads = _attention_config_value(
457484
text_config,
458-
"num_global_key_value_heads",
485+
"full_attention",
486+
"num_key_value_heads",
459487
getattr(self, "_dense_num_global_query_groups", None),
488+
legacy_field_name="num_global_key_value_heads",
460489
)
461490
if num_global_kv_heads is not None:
462491
num_kv_heads = num_global_kv_heads

‎src/megatron/bridge/models/gemma_vl/gemma4_vl_bridge.py‎

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
)
5050
from megatron.bridge.models.gemma.gemma4_bridge import (
5151
Gemma4Bridge,
52+
_attention_config_value,
5253
_Gemma4QKVMapping,
5354
_infer_attn_pattern,
5455
)
@@ -99,6 +100,12 @@ def provider_bridge(
99100
return self._build_moe_provider(text_config)
100101

101102
provider_kwargs = self.hf_config_to_provider_kwargs(text_config)
103+
provider_kwargs["num_query_groups"] = _attention_config_value(
104+
text_config,
105+
"sliding_attention",
106+
"num_key_value_heads",
107+
4,
108+
)
102109
provider = Gemma4VLModelProvider(**provider_kwargs)
103110

104111
provider.window_size = getattr(text_config, "sliding_window", 1024)
@@ -107,13 +114,25 @@ def provider_bridge(
107114
rope_theta_from_hf(text_config),
108115
)
109116

110-
head_dim = getattr(text_config, "head_dim", 256)
117+
head_dim = _attention_config_value(text_config, "sliding_attention", "head_dim", 256)
111118
provider.softmax_scale = 1.0
112119
provider.kv_channels = head_dim
113120
provider.qk_layernorm = True
114121

115-
provider.global_head_dim = getattr(text_config, "global_head_dim", 512)
116-
provider.num_global_key_value_heads = getattr(text_config, "num_global_key_value_heads", 2)
122+
provider.global_head_dim = _attention_config_value(
123+
text_config,
124+
"full_attention",
125+
"head_dim",
126+
512,
127+
legacy_field_name="global_head_dim",
128+
)
129+
provider.num_global_key_value_heads = _attention_config_value(
130+
text_config,
131+
"full_attention",
132+
"num_key_value_heads",
133+
2,
134+
legacy_field_name="num_global_key_value_heads",
135+
)
117136
provider.attention_k_eq_v = getattr(text_config, "attention_k_eq_v", False)
118137

119138
rope_params = getattr(text_config, "rope_parameters", {})

‎tests/unit_tests/models/gemma/test_gemma4_bridge.py‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,8 @@ def test_runtime_preserves_nonperiodic_attention_schedule(self, bridge):
221221
provider = bridge.provider_bridge(pretrained)
222222
assert provider.kv_channels == 256
223223
assert provider.global_head_dim == 512
224+
assert provider.num_query_groups == hf_config.per_layer_config[1].num_key_value_heads
225+
assert provider.num_global_key_value_heads == hf_config.per_layer_config[0].num_key_value_heads
224226
runtime_layer_types = [
225227
"sliding_attention"
226228
if _is_local_attn_layer(layer_number, provider.interleaved_attn_pattern)

‎tests/unit_tests/recipes/test_muse_glimmer_recipes.py‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,8 @@ def test_muse_glimmer_performance_recipe_is_dense_decoder_only() -> None:
149149
"CUDA_DEVICE_MAX_CONNECTIONS": 1,
150150
"NCCL_GRAPH_REGISTER": 0,
151151
"NCCL_NVLS_ENABLE": 0,
152+
"NVTE_BWD_LAYERNORM_SM_MARGIN": 0,
153+
"NVTE_FWD_LAYERNORM_SM_MARGIN": 0,
152154
"PYTORCH_CUDA_ALLOC_CONF": "expandable_segments:True",
153155
"TORCH_NCCL_AVOID_RECORD_STREAMS": 1,
154156
"TORCH_NCCL_HIGH_PRIORITY": 1,

0 commit comments

Comments
 (0)