|
13 | 13 | # limitations under the License. |
14 | 14 |
|
15 | 15 | from collections.abc import Mapping |
16 | | -from typing import Dict, Optional |
| 16 | +from typing import Any, Dict, Optional |
17 | 17 |
|
18 | 18 | import torch |
19 | 19 | import torch.nn as nn |
20 | 20 | from megatron.core.models.gpt.gpt_model import GPTModel |
| 21 | +from transformers import PretrainedConfig |
21 | 22 |
|
22 | 23 | from megatron.bridge.models.conversion import quantization_utils |
23 | 24 | from megatron.bridge.models.conversion.mapping_registry import MegatronMappingRegistry |
@@ -128,46 +129,52 @@ class MiniMaxM2Bridge(MegatronModelBridge): |
128 | 129 | Example: |
129 | 130 | >>> from megatron.bridge import AutoBridge |
130 | 131 | >>> bridge = AutoBridge.from_hf_pretrained("MiniMaxAI/MiniMax-M2") |
131 | | - >>> provider = bridge.to_megatron_provider() |
| 132 | + >>> model_config = bridge.get_model_config() |
132 | 133 | """ |
133 | 134 |
|
134 | | - def provider_bridge(self, hf_pretrained): |
135 | | - """Convert HuggingFace MiniMax-M2 config to GPTModelProvider.""" |
136 | | - provider = super().provider_bridge(hf_pretrained) |
137 | | - |
138 | | - hf_config = hf_pretrained.config |
139 | | - |
140 | | - provider.normalization = "RMSNorm" |
141 | | - provider.gated_linear_unit = True |
142 | | - provider.position_embedding_type = "rope" |
143 | | - provider.add_bias_linear = False |
144 | | - provider.add_qkv_bias = False |
145 | | - provider.hidden_dropout = 0.0 |
146 | | - provider.autocast_dtype = torch.bfloat16 |
| 135 | + USE_MODEL_CONFIG_FOR_CONVERSION = True |
| 136 | + |
| 137 | + def hf_config_to_model_config_kwargs(self, hf_config: PretrainedConfig) -> dict[str, Any]: |
| 138 | + """Convert a Hugging Face MiniMax-M2 config to builder config kwargs.""" |
| 139 | + config_kwargs = super().hf_config_to_model_config_kwargs(hf_config) |
| 140 | + config_kwargs.update( |
| 141 | + normalization="RMSNorm", |
| 142 | + gated_linear_unit=True, |
| 143 | + position_embedding_type="rope", |
| 144 | + add_bias_linear=False, |
| 145 | + add_qkv_bias=False, |
| 146 | + hidden_dropout=0.0, |
| 147 | + autocast_dtype=torch.bfloat16, |
| 148 | + masked_softmax_fusion=True, |
| 149 | + rope_scaling=False, |
| 150 | + rope_scaling_factor=1.0, |
| 151 | + # Full-dimension QK norm via custom layer spec (see minimax_m2_provider.py). |
| 152 | + # qk_layernorm=True so mcore creates QK norms; the spec overrides the default |
| 153 | + # TENorm with FullDimQNorm/FullDimKNorm for full-dimension normalization. |
| 154 | + qk_layernorm=True, |
| 155 | + transformer_layer_spec=minimax_m2_layer_spec, |
| 156 | + # MoE settings — sigmoid routing with expert bias (same pattern as DeepSeek V3) |
| 157 | + moe_grouped_gemm=True, |
| 158 | + moe_router_pre_softmax=False, |
| 159 | + moe_router_load_balancing_type="aux_loss", |
| 160 | + moe_aux_loss_coeff=getattr(hf_config, "router_aux_loss_coef", 1e-3), |
| 161 | + moe_token_dispatcher_type="alltoall", |
| 162 | + moe_permute_fusion=True, |
| 163 | + moe_router_score_function="sigmoid", |
| 164 | + moe_router_enable_expert_bias=True, |
| 165 | + ) |
147 | 166 |
|
148 | 167 | # MiniMax-M2 uses rotary_dim instead of partial_rotary_factor |
149 | 168 | rotary_dim = getattr(hf_config, "rotary_dim", None) |
150 | 169 | head_dim = getattr(hf_config, "head_dim", None) |
151 | 170 | if rotary_dim is not None and head_dim is not None: |
152 | | - provider.rotary_percent = rotary_dim / head_dim |
153 | | - |
154 | | - # Full-dimension QK norm via custom layer spec (see minimax_m2_provider.py). |
155 | | - # qk_layernorm=True so mcore creates QK norms; the spec overrides the default |
156 | | - # TENorm with FullDimQNorm/FullDimKNorm for full-dimension normalization. |
157 | | - provider.qk_layernorm = True |
158 | | - provider.transformer_layer_spec = minimax_m2_layer_spec |
159 | | - |
160 | | - # MoE settings — sigmoid routing with expert bias (same pattern as DeepSeek V3) |
161 | | - provider.moe_grouped_gemm = True |
162 | | - provider.moe_router_pre_softmax = False |
163 | | - provider.moe_router_load_balancing_type = "aux_loss" |
164 | | - provider.moe_aux_loss_coeff = getattr(hf_config, "router_aux_loss_coef", 1e-3) |
165 | | - provider.moe_token_dispatcher_type = "alltoall" |
166 | | - provider.moe_permute_fusion = True |
167 | | - provider.moe_router_score_function = "sigmoid" |
168 | | - provider.moe_router_enable_expert_bias = True |
169 | | - |
170 | | - return provider |
| 171 | + config_kwargs["rotary_percent"] = rotary_dim / head_dim |
| 172 | + |
| 173 | + return config_kwargs |
| 174 | + |
| 175 | + def hf_config_to_provider_kwargs(self, hf_config: PretrainedConfig) -> dict[str, Any]: |
| 176 | + """Adapt the canonical builder mapping to the deprecated provider path.""" |
| 177 | + return self.hf_config_to_model_config_kwargs(hf_config) |
171 | 178 |
|
172 | 179 | def maybe_modify_loaded_hf_weight( |
173 | 180 | self, hf_param: str | dict[str, str], hf_state_dict: Mapping[str, torch.Tensor] |
|
0 commit comments