hanswalt commited on
Commit
8cee404
·
verified ·
1 Parent(s): 8d44097

Upload folder using huggingface_hub

Browse files
.gitattributes CHANGED
@@ -35,3 +35,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
  epoch_0_step_499/model/tokenizer.json filter=lfs diff=lfs merge=lfs -text
37
  epoch_0_step_999/model/tokenizer.json filter=lfs diff=lfs merge=lfs -text
 
 
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
  epoch_0_step_499/model/tokenizer.json filter=lfs diff=lfs merge=lfs -text
37
  epoch_0_step_999/model/tokenizer.json filter=lfs diff=lfs merge=lfs -text
38
+ epoch_0_step_1499/model/tokenizer.json filter=lfs diff=lfs merge=lfs -text
epoch_0_step_1499/config.yaml ADDED
@@ -0,0 +1,118 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ recipe: TrainFinetuneRecipeForNextTokenPrediction
2
+ seed: 1368
3
+ step_scheduler:
4
+ global_batch_size: 96
5
+ local_batch_size: 12
6
+ ckpt_every_steps: 500
7
+ val_every_steps: 100
8
+ num_epochs: 1
9
+ max_steps: 5000
10
+ save_checkpoint_every_epoch: false
11
+ validate_on_checkpoint: false
12
+ log_remote_every_steps: 1
13
+ gc_every_steps: 100
14
+ distributed:
15
+ strategy: fsdp2
16
+ tp_size: 1
17
+ cp_size: 1
18
+ pp_size: 1
19
+ ep_size: 8
20
+ defer_fsdp_grad_sync: true
21
+ sequence_parallel: false
22
+ activation_checkpointing: true
23
+ pipeline:
24
+ pp_schedule: interleaved1f1b
25
+ pp_microbatch_size: 1
26
+ layers_per_stage: 1
27
+ round_virtual_stages_to_pp_multiple: down
28
+ scale_grads_in_schedule: false
29
+ patch_inner_model: false
30
+ patch_causal_lm_model: false
31
+ moe:
32
+ reshard_after_forward: false
33
+ wrap_outer_model: false
34
+ dist_env:
35
+ backend: nccl
36
+ timeout_minutes: 300
37
+ peft:
38
+ _target_: nemo_automodel.components._peft.lora.PeftConfig
39
+ target_modules:
40
+ - '*'
41
+ dim: 256
42
+ alpha: 2560
43
+ use_triton: true
44
+ model:
45
+ _target_: nemo_automodel.NeMoAutoModelForCausalLM.from_config
46
+ config:
47
+ _target_: nemo_automodel.components.models.mimo_v25.config.MiMoV2Config.from_pretrained
48
+ pretrained_model_name_or_path: /home/silver/teutonic_mining/models/merged-1625
49
+ name_or_path: /home/silver/teutonic_mining/models/merged-1625
50
+ architectures:
51
+ - MiMoV25ForCausalLM
52
+ trust_remote_code: false
53
+ load_base_model: true
54
+ backend:
55
+ _target_: nemo_automodel.components.models.common.BackendConfig
56
+ attn: tilelang
57
+ linear: torch
58
+ rms_norm: te
59
+ experts: torch_mm
60
+ dispatcher: torch
61
+ gate_precision: float32
62
+ rope_fusion: false
63
+ fake_balanced_gate: false
64
+ enable_hf_state_dict_adapter: true
65
+ enable_fsdp_optimizations: true
66
+ freeze_config:
67
+ unfreeze_modules:
68
+ - glob: '*input_layernorm*'
69
+ - glob: '*post_attention_layernorm*'
70
+ checkpoint:
71
+ enabled: true
72
+ checkpoint_dir: checkpoint-main45-medium-only-2nd
73
+ model_save_format: safetensors
74
+ save_consolidated: false
75
+ dequantize_base_checkpoint: true
76
+ loss_fn:
77
+ _target_: nemo_automodel.components.loss.masked_ce.MaskedCrossEntropy
78
+ dataset:
79
+ _target_: nemo_automodel.components.datasets.llm.jsonl_token_dataset.PlainTextCompletionDataset
80
+ file_path: /home/silver/teutonic_mining/dataset-jullian/train/teutonic_medium_350k_v1.jsonl
81
+ dataloader:
82
+ _target_: torchdata.stateful_dataloader.StatefulDataLoader
83
+ shuffle: false
84
+ collate_fn:
85
+ _target_: nemo_automodel.components.datasets.utils.default_collater
86
+ pad_seq_len_divisible: 64
87
+ validation_dataset:
88
+ _target_: nemo_automodel.components.datasets.llm.jsonl_token_dataset.PlainTextCompletionDataset
89
+ file_path: /home/silver/teutonic_mining/dataset-jullian/train/teutonic_medium_1k_v1_eval.jsonl
90
+ validation_dataloader:
91
+ _target_: torchdata.stateful_dataloader.StatefulDataLoader
92
+ shuffle: false
93
+ collate_fn:
94
+ _target_: nemo_automodel.components.datasets.utils.default_collater
95
+ pad_seq_len_divisible: 64
96
+ packed_sequence:
97
+ packed_sequence_size: 0
98
+ optimizer:
99
+ _target_: torch.optim.AdamW
100
+ betas:
101
+ - 0.9
102
+ - 0.95
103
+ eps: 1.0e-08
104
+ lr: 3.0e-07
105
+ weight_decay: 0.001
106
+ foreach: false
107
+ lr_scheduler:
108
+ lr_decay_style: cosine
109
+ lr_warmup_steps: 100
110
+ min_lr: 1.0e-07
111
+ wandb:
112
+ project: Teutonic
113
+ name: 1014_merge1625_medium_350k_3e7_1e7_lora256_2560
114
+ mode: online
115
+ ci:
116
+ recipe_owner: Simar-malhotra09
117
+ nodes: 18
118
+ time: 02:00:00
epoch_0_step_1499/dataloader/dataloader_dp_rank_0.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ad5a8c0af1e9ae9fd349b68665f56d57f7411feff62643b8c5fdff3f14dcc272
3
+ size 1659
epoch_0_step_1499/dataloader/dataloader_dp_rank_1.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ffa8dcad0c6a4e78611f1fb67c9d99bf3700a9fbf6751c18bf65da2688dc401b
3
+ size 1659
epoch_0_step_1499/dataloader/dataloader_dp_rank_2.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:86ca0d1f1581989be3416d38dc6e8ececf9543e5d2ba744b84b4cba92c2ded6b
3
+ size 1659
epoch_0_step_1499/dataloader/dataloader_dp_rank_3.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c94318f978cbcf5884b41114387421a83b2e083ac44fd7d705de04c441a3de8d
3
+ size 1659
epoch_0_step_1499/dataloader/dataloader_dp_rank_4.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1b8148b6abc9cd2571f5f31c43914c909dcffdb8d25d4798d9f88fb21f654bc6
3
+ size 1659
epoch_0_step_1499/dataloader/dataloader_dp_rank_5.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7ba95c749cc7b39d2faaaf803a0bb746da4b8ee9782dfb73249cb1f2ec954ca4
3
+ size 1659
epoch_0_step_1499/dataloader/dataloader_dp_rank_6.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c5c0eabf2cd116cc2d39e7ec52935eb2bb96f80882c99b3b27c8aa426bb97371
3
+ size 1659
epoch_0_step_1499/dataloader/dataloader_dp_rank_7.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:11a256cf7fa141efc01e680050179ac1b4e1ac681f65c7505923578ea8b33115
3
+ size 1659
epoch_0_step_1499/losses.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"train_loss": 1.9494314193725586, "val_loss": 2.0442943572998047}
epoch_0_step_1499/model/adapter_config.json ADDED
The diff for this file is too large to render. See raw diff
 
epoch_0_step_1499/model/adapter_model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:62c1fb636a07d896e83e73098ce4638b772555e459f49634a174925838b64ffa
3
+ size 71812129008
epoch_0_step_1499/model/automodel_peft_config.json ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "dropout": 0.0,
3
+ "dropout_position": "post",
4
+ "exclude_modules": [],
5
+ "expert_weight_format": "unquantized",
6
+ "lora_A_init": "xavier",
7
+ "lora_dtype": null,
8
+ "match_all_linear": false,
9
+ "moe_rank_scaling": false,
10
+ "target_modules": [
11
+ "*"
12
+ ],
13
+ "use_dora": false,
14
+ "use_memory_efficient_lora": true,
15
+ "use_triton": true
16
+ }
epoch_0_step_1499/model/configuration_mimo_v2.py ADDED
@@ -0,0 +1,209 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # coding=utf-8
2
+ #
3
+ # Copyright 2026 Xiaomi Corporation.
4
+ # Copyright 2026 The HuggingFace Inc. team.
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+
18
+ from transformers.configuration_utils import PretrainedConfig
19
+ from transformers.modeling_rope_utils import rope_config_validation
20
+ from transformers.utils import logging
21
+
22
+
23
+ logger = logging.get_logger(__name__)
24
+
25
+
26
+ _MIMOV2_ATTENTION_PROJECTION_LAYOUTS = {"split", "fused_qkv"}
27
+
28
+ _MIMOV2_SPLIT_TP_PLAN = {
29
+ "layers.*.self_attn.q_proj": "colwise",
30
+ "layers.*.self_attn.k_proj": "colwise",
31
+ "layers.*.self_attn.v_proj": "colwise",
32
+ "layers.*.self_attn.o_proj": "rowwise",
33
+ "layers.*.mlp.gate_proj": "colwise",
34
+ "layers.*.mlp.up_proj": "colwise",
35
+ "layers.*.mlp.down_proj": "rowwise",
36
+ }
37
+
38
+ _MIMOV2_FUSED_QKV_TP_PLAN = {
39
+ "layers.*.self_attn.qkv_proj": "colwise",
40
+ "layers.*.self_attn.o_proj": "rowwise",
41
+ "layers.*.mlp.gate_proj": "colwise",
42
+ "layers.*.mlp.up_proj": "colwise",
43
+ "layers.*.mlp.down_proj": "rowwise",
44
+ }
45
+
46
+ _MIMOV2_PP_PLAN = {
47
+ "embed_tokens": (["input_ids"], ["inputs_embeds"]),
48
+ "layers": (["hidden_states", "attention_mask"], ["hidden_states"]),
49
+ "norm": (["hidden_states"], ["hidden_states"]),
50
+ }
51
+
52
+
53
+ class MiMoV2Config(PretrainedConfig):
54
+
55
+ model_type = "mimo_v2"
56
+ keys_to_ignore_at_inference = ["past_key_values"]
57
+
58
+ base_model_tp_plan = _MIMOV2_SPLIT_TP_PLAN
59
+ base_model_pp_plan = _MIMOV2_PP_PLAN
60
+
61
+ attribute_map = {
62
+ "num_local_experts": "n_routed_experts",
63
+ }
64
+
65
+ def __init__(
66
+ self,
67
+ vocab_size=151936,
68
+ hidden_size=4096,
69
+ intermediate_size=22016,
70
+ num_hidden_layers=32,
71
+ num_attention_heads=32,
72
+ num_key_value_heads=32,
73
+ hidden_act="silu",
74
+ max_position_embeddings=32768,
75
+ initializer_range=0.02,
76
+ layernorm_epsilon=1e-6,
77
+ use_cache=True,
78
+ tie_word_embeddings=False,
79
+ rope_theta=10000.0,
80
+ rope_scaling=None,
81
+ attention_dropout=0.0,
82
+ attention_bias=False,
83
+ attention_value_scale=None,
84
+ head_dim=None,
85
+ v_head_dim=None,
86
+ swa_num_attention_heads=None,
87
+ swa_num_key_value_heads=None,
88
+ swa_head_dim=None,
89
+ swa_v_head_dim=None,
90
+ swa_rope_theta=None,
91
+ sliding_window=None,
92
+ sliding_window_size=None,
93
+ add_full_attention_sink_bias=False,
94
+ add_swa_attention_sink_bias=False,
95
+ hybrid_block_size=None,
96
+ hybrid_layer_pattern=None,
97
+ partial_rotary_factor=1.0,
98
+ n_routed_experts=None,
99
+ moe_intermediate_size=None,
100
+ num_experts_per_tok=None,
101
+ routed_scaling_factor=None,
102
+ scoring_func="sigmoid",
103
+ topk_method="noaux_tc",
104
+ n_group=None,
105
+ topk_group=None,
106
+ norm_topk_prob=True,
107
+ moe_layer_freq=None,
108
+ attention_projection_layout="split",
109
+ **kwargs,
110
+ ):
111
+ rope_parameters = kwargs.pop("rope_parameters", None)
112
+ if rope_scaling is None and rope_parameters is not None:
113
+ rope_scaling = rope_parameters
114
+
115
+ if attention_projection_layout is None:
116
+ attention_projection_layout = "split"
117
+ if attention_projection_layout not in _MIMOV2_ATTENTION_PROJECTION_LAYOUTS:
118
+ raise ValueError(f"Unsupported MiMoV2 attention projection layout: {attention_projection_layout}")
119
+
120
+ self.attention_projection_layout = attention_projection_layout
121
+ self.base_model_tp_plan = (
122
+ _MIMOV2_FUSED_QKV_TP_PLAN.copy()
123
+ if attention_projection_layout == "fused_qkv"
124
+ else _MIMOV2_SPLIT_TP_PLAN.copy()
125
+ )
126
+ self.base_model_pp_plan = _MIMOV2_PP_PLAN.copy()
127
+
128
+ self.vocab_size = vocab_size
129
+ self.max_position_embeddings = max_position_embeddings
130
+ self.hidden_size = hidden_size
131
+ self.intermediate_size = intermediate_size
132
+ self.num_hidden_layers = num_hidden_layers
133
+ self.num_attention_heads = num_attention_heads
134
+
135
+ if num_key_value_heads is None:
136
+ num_key_value_heads = num_attention_heads
137
+ if num_attention_heads % num_key_value_heads != 0:
138
+ raise ValueError("num_attention_heads must be divisible by num_key_value_heads")
139
+
140
+ self.num_key_value_heads = num_key_value_heads
141
+ self.hidden_act = hidden_act
142
+ self.initializer_range = initializer_range
143
+ self.layernorm_epsilon = layernorm_epsilon
144
+ self.use_cache = use_cache
145
+ self.rope_theta = rope_theta
146
+ self.rope_scaling = rope_scaling
147
+ self.attention_dropout = attention_dropout
148
+ self.attention_bias = attention_bias
149
+ self.attention_value_scale = attention_value_scale
150
+
151
+ self.head_dim = head_dim if head_dim is not None else hidden_size // num_attention_heads
152
+ self.v_head_dim = v_head_dim if v_head_dim is not None else self.head_dim
153
+ self.swa_num_attention_heads = (
154
+ swa_num_attention_heads if swa_num_attention_heads is not None else num_attention_heads
155
+ )
156
+ self.swa_num_key_value_heads = (
157
+ swa_num_key_value_heads if swa_num_key_value_heads is not None else num_key_value_heads
158
+ )
159
+ if self.swa_num_attention_heads % self.swa_num_key_value_heads != 0:
160
+ raise ValueError("swa_num_attention_heads must be divisible by swa_num_key_value_heads")
161
+ self.swa_head_dim = swa_head_dim if swa_head_dim is not None else self.head_dim
162
+ self.swa_v_head_dim = swa_v_head_dim if swa_v_head_dim is not None else self.swa_head_dim
163
+ self.swa_rope_theta = swa_rope_theta if swa_rope_theta is not None else rope_theta
164
+
165
+ if sliding_window is None:
166
+ sliding_window = sliding_window_size
167
+ self.sliding_window = sliding_window
168
+ self.sliding_window_size = sliding_window_size if sliding_window_size is not None else sliding_window
169
+ self.add_full_attention_sink_bias = add_full_attention_sink_bias
170
+ self.add_swa_attention_sink_bias = add_swa_attention_sink_bias
171
+
172
+ if hybrid_block_size is not None and hybrid_layer_pattern is None:
173
+ hybrid_layer_pattern = [0 if ((i + 1) % hybrid_block_size == 0) else 1 for i in range(num_hidden_layers)]
174
+ elif hybrid_layer_pattern is None:
175
+ hybrid_layer_pattern = [0] * num_hidden_layers
176
+ if len(hybrid_layer_pattern) != num_hidden_layers:
177
+ raise ValueError("hybrid_layer_pattern length must match num_hidden_layers")
178
+ self.hybrid_block_size = hybrid_block_size
179
+ self.hybrid_layer_pattern = hybrid_layer_pattern
180
+
181
+ self.partial_rotary_factor = partial_rotary_factor
182
+
183
+ self.n_routed_experts = n_routed_experts
184
+ self.moe_intermediate_size = moe_intermediate_size if moe_intermediate_size is not None else intermediate_size
185
+ self.num_experts_per_tok = num_experts_per_tok
186
+ self.routed_scaling_factor = routed_scaling_factor
187
+ self.scoring_func = scoring_func
188
+ self.topk_method = topk_method
189
+ self.n_group = n_group
190
+ self.topk_group = topk_group
191
+ self.norm_topk_prob = norm_topk_prob
192
+ if isinstance(moe_layer_freq, int):
193
+ moe_layer_freq = [moe_layer_freq > 0 and i % moe_layer_freq == 0 for i in range(num_hidden_layers)]
194
+ elif moe_layer_freq is None:
195
+ moe_layer_freq = [False] * num_hidden_layers
196
+ if len(moe_layer_freq) != num_hidden_layers:
197
+ raise ValueError("moe_layer_freq length must match num_hidden_layers")
198
+ self.moe_layer_freq = moe_layer_freq
199
+
200
+ if self.rope_scaling is not None and "type" in self.rope_scaling:
201
+ self.rope_scaling["rope_type"] = self.rope_scaling["type"]
202
+ rope_config_validation(self)
203
+
204
+ super().__init__(
205
+ tie_word_embeddings=tie_word_embeddings,
206
+ **kwargs,
207
+ )
208
+
209
+ __all__ = ["MiMoV2Config"]
epoch_0_step_1499/model/modeling_mimo_v2.py ADDED
@@ -0,0 +1,710 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # coding=utf-8
2
+ #
3
+ # Copyright 2026 Xiaomi Corporation.
4
+ # Copyright 2026 The HuggingFace Inc. team.
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+
18
+ from copy import copy
19
+ from typing import Callable, Optional, Union
20
+
21
+ import torch
22
+ import torch.nn as nn
23
+ import torch.nn.functional as F
24
+
25
+ from transformers.activations import ACT2FN
26
+ from transformers.cache_utils import Cache, DynamicCache
27
+ from transformers.generation import GenerationMixin
28
+ from transformers.integrations import use_kernel_forward_from_hub
29
+ from transformers.masking_utils import create_causal_mask, create_sliding_window_causal_mask
30
+ from transformers.modeling_outputs import BaseModelOutputWithPast, CausalLMOutputWithPast
31
+ from transformers.modeling_rope_utils import ROPE_INIT_FUNCTIONS, dynamic_rope_update
32
+ from transformers.modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel
33
+ from transformers.processing_utils import Unpack
34
+ from transformers.utils import TransformersKwargs, can_return_tuple, logging
35
+
36
+ from .configuration_mimo_v2 import MiMoV2Config
37
+
38
+
39
+ logger = logging.get_logger(__name__)
40
+
41
+
42
+ def rotate_half(x):
43
+ """Rotates half the hidden dims of the input."""
44
+ x1 = x[..., : x.shape[-1] // 2]
45
+ x2 = x[..., x.shape[-1] // 2 :]
46
+ return torch.cat((-x2, x1), dim=-1)
47
+
48
+
49
+ def apply_rotary_pos_emb(q, k, cos, sin, position_ids=None, unsqueeze_dim=1):
50
+ """Applies rotary position embedding to query and key tensors."""
51
+ cos = cos.unsqueeze(unsqueeze_dim)
52
+ sin = sin.unsqueeze(unsqueeze_dim)
53
+ q_embed = (q * cos) + (rotate_half(q) * sin)
54
+ k_embed = (k * cos) + (rotate_half(k) * sin)
55
+ return q_embed, k_embed
56
+
57
+
58
+ def repeat_kv(hidden_states: torch.Tensor, n_rep: int) -> torch.Tensor:
59
+ batch, num_key_value_heads, slen, head_dim = hidden_states.shape
60
+ if n_rep == 1:
61
+ return hidden_states
62
+ hidden_states = hidden_states[:, :, None, :, :].expand(batch, num_key_value_heads, n_rep, slen, head_dim)
63
+ return hidden_states.reshape(batch, num_key_value_heads * n_rep, slen, head_dim)
64
+
65
+
66
+ def eager_attention_forward(
67
+ module: nn.Module,
68
+ query: torch.Tensor,
69
+ key: torch.Tensor,
70
+ value: torch.Tensor,
71
+ attention_mask: Optional[torch.Tensor],
72
+ scaling: float,
73
+ dropout: float = 0.0,
74
+ sinks: Optional[torch.Tensor] = None,
75
+ **kwargs,
76
+ ):
77
+ key_states = repeat_kv(key, module.num_key_value_groups)
78
+ value_states = repeat_kv(value, module.num_key_value_groups)
79
+ attn_weights = torch.matmul(query, key_states.transpose(2, 3)) * scaling
80
+ if attention_mask is not None:
81
+ causal_mask = attention_mask[:, :, :, : key_states.shape[-2]]
82
+ attn_weights = attn_weights + causal_mask
83
+
84
+ if sinks is not None:
85
+ sinks = module.attention_sink_bias.reshape(1, -1, 1, 1).expand(query.shape[0], -1, query.shape[-2], -1)
86
+ attn_weights = torch.cat([attn_weights, sinks], dim=-1)
87
+
88
+ attn_weights = attn_weights - attn_weights.max(dim=-1, keepdim=True).values
89
+ probs = F.softmax(attn_weights, dim=-1, dtype=torch.float32).to(query.dtype)
90
+
91
+ if sinks is not None:
92
+ probs = probs[..., :-1]
93
+
94
+ attn_weights = nn.functional.dropout(probs, p=dropout, training=module.training)
95
+ attn_output = torch.matmul(attn_weights, value_states)
96
+ attn_output = attn_output.transpose(1, 2).contiguous()
97
+ return attn_output, attn_weights
98
+
99
+
100
+ @use_kernel_forward_from_hub("RMSNorm")
101
+ class MiMoV2RMSNorm(nn.Module):
102
+ def __init__(self, hidden_size, eps=1e-6):
103
+ super().__init__()
104
+ self.weight = nn.Parameter(torch.ones(hidden_size))
105
+ self.variance_epsilon = eps
106
+
107
+ def forward(self, hidden_states):
108
+ input_dtype = hidden_states.dtype
109
+ hidden_states = hidden_states.to(torch.float32)
110
+ variance = hidden_states.pow(2).mean(-1, keepdim=True)
111
+ hidden_states = hidden_states * torch.rsqrt(variance + self.variance_epsilon)
112
+ return self.weight * hidden_states.to(input_dtype)
113
+
114
+
115
+ class MiMoV2MLP(nn.Module):
116
+ def __init__(self, config, intermediate_size=None):
117
+ super().__init__()
118
+ self.config = config
119
+ self.hidden_size = config.hidden_size
120
+ self.intermediate_size = config.intermediate_size if intermediate_size is None else intermediate_size
121
+ self.gate_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)
122
+ self.up_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)
123
+ self.down_proj = nn.Linear(self.intermediate_size, self.hidden_size, bias=False)
124
+ self.act_fn = ACT2FN[config.hidden_act]
125
+
126
+ def forward(self, hidden_states):
127
+ return self.down_proj(self.act_fn(self.gate_proj(hidden_states)) * self.up_proj(hidden_states))
128
+
129
+
130
+ class MiMoV2MoEGate(nn.Module):
131
+ def __init__(self, config):
132
+ super().__init__()
133
+ self.config = config
134
+ self.top_k = config.num_experts_per_tok
135
+ self.n_routed_experts = config.n_routed_experts
136
+ self.routed_scaling_factor = config.routed_scaling_factor if config.routed_scaling_factor is not None else 1.0
137
+ self.scoring_func = config.scoring_func
138
+ self.topk_method = config.topk_method
139
+ self.n_group = config.n_group
140
+ self.topk_group = config.topk_group
141
+ self.norm_topk_prob = config.norm_topk_prob
142
+ self.gating_dim = config.hidden_size
143
+ self.weight = nn.Parameter(torch.empty((self.n_routed_experts, self.gating_dim)))
144
+ if self.topk_method == "noaux_tc":
145
+ self.e_score_correction_bias = nn.Parameter(torch.empty((self.n_routed_experts)))
146
+
147
+ def forward(self, hidden_states):
148
+ bsz, seq_len, h = hidden_states.shape
149
+ hidden_states = hidden_states.view(-1, h)
150
+ logits = F.linear(hidden_states.type(torch.float32), self.weight.type(torch.float32), None)
151
+ if self.scoring_func == "sigmoid":
152
+ scores = logits.sigmoid()
153
+ else:
154
+ raise NotImplementedError(f"Unsupported scoring function for MoE gating: {self.scoring_func}")
155
+
156
+ if self.topk_method == "noaux_tc":
157
+ if self.training:
158
+ raise ValueError("MiMoV2 noaux_tc routing is only implemented for inference.")
159
+ scores_for_choice = scores.view(bsz * seq_len, -1) + self.e_score_correction_bias.unsqueeze(0)
160
+ group_scores = scores_for_choice.view(bsz * seq_len, self.n_group, -1).topk(2, dim=-1)[0].sum(dim=-1)
161
+ group_idx = torch.topk(group_scores, k=self.topk_group, dim=-1, sorted=False)[1]
162
+ group_mask = torch.zeros_like(group_scores)
163
+ group_mask.scatter_(1, group_idx, 1)
164
+ score_mask = (
165
+ group_mask.unsqueeze(-1)
166
+ .expand(bsz * seq_len, self.n_group, self.n_routed_experts // self.n_group)
167
+ .reshape(bsz * seq_len, -1)
168
+ )
169
+ tmp_scores = scores_for_choice.masked_fill(~score_mask.bool(), float("-inf"))
170
+ _, topk_idx = torch.topk(tmp_scores, k=self.top_k, dim=-1, sorted=False)
171
+ topk_weight = scores.gather(1, topk_idx)
172
+ else:
173
+ raise NotImplementedError(f"Unsupported TopK function for MoE gating: {self.topk_method}")
174
+
175
+ if self.top_k > 1 and self.norm_topk_prob:
176
+ denominator = topk_weight.sum(dim=-1, keepdim=True) + 1e-20
177
+ topk_weight = topk_weight / denominator
178
+ topk_weight = topk_weight * self.routed_scaling_factor
179
+ return topk_idx, topk_weight
180
+
181
+
182
+ class MiMoV2MoE(nn.Module):
183
+ def __init__(self, config):
184
+ super().__init__()
185
+ self.config = config
186
+ self.experts = nn.ModuleList(
187
+ [MiMoV2MLP(config, intermediate_size=config.moe_intermediate_size) for _ in range(config.n_routed_experts)]
188
+ )
189
+ self.gate = MiMoV2MoEGate(config)
190
+
191
+ n_shared_experts = getattr(config, "n_shared_experts", None) or 0
192
+ if n_shared_experts > 0:
193
+ shared_expert_inter_dim = getattr(config, "shared_expert_inter_dim", None) or config.moe_intermediate_size
194
+ self.shared_experts = MiMoV2MLP(
195
+ config, intermediate_size=n_shared_experts * shared_expert_inter_dim
196
+ )
197
+ else:
198
+ self.shared_experts = None
199
+
200
+ def moe(self, hidden_states: torch.Tensor, topk_indices: torch.Tensor, topk_weights: torch.Tensor):
201
+ final_hidden_states = torch.zeros_like(hidden_states, dtype=topk_weights.dtype)
202
+ expert_mask = torch.nn.functional.one_hot(topk_indices, num_classes=len(self.experts))
203
+ expert_mask = expert_mask.permute(2, 0, 1)
204
+
205
+ for expert_idx, expert in enumerate(self.experts):
206
+ mask = expert_mask[expert_idx]
207
+ token_indices, weight_indices = torch.where(mask)
208
+ if token_indices.numel() > 0:
209
+ expert_weights = topk_weights[token_indices, weight_indices]
210
+ expert_input = hidden_states[token_indices]
211
+ expert_output = expert(expert_input)
212
+ final_hidden_states.index_add_(0, token_indices, expert_output * expert_weights.unsqueeze(-1))
213
+
214
+ return final_hidden_states.type(hidden_states.dtype)
215
+
216
+ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
217
+ orig_shape = hidden_states.shape
218
+ topk_indices, topk_weights = self.gate(hidden_states)
219
+ flat_hidden_states = hidden_states.view(-1, hidden_states.shape[-1])
220
+ routed_output = self.moe(flat_hidden_states, topk_indices, topk_weights)
221
+ if self.shared_experts is not None:
222
+ # Shared experts run on every token unconditionally (no routing/gating),
223
+ # matching the training-time MoE layer's `y = y + z` combination.
224
+ routed_output = routed_output + self.shared_experts(flat_hidden_states)
225
+ return routed_output.view(*orig_shape)
226
+
227
+
228
+ class MiMoV2Attention(nn.Module):
229
+ """MiMoV2 attention.
230
+
231
+ `projection_layout` only controls how checkpoint weights are named and
232
+ stored: Flash uses separate q/k/v projections, while Pro uses fused qkv.
233
+ The attention computation after projection is shared.
234
+ """
235
+
236
+ def __init__(self, config, is_swa: bool, layer_idx: int, projection_layout: str = "split"):
237
+ super().__init__()
238
+ if projection_layout not in {"split", "fused_qkv"}:
239
+ raise ValueError(f"Unsupported MiMoV2 attention projection layout: {projection_layout}")
240
+
241
+ self.config = config
242
+ self.layer_idx = layer_idx
243
+ self.is_swa = is_swa
244
+ self.is_causal = True
245
+ self.projection_layout = projection_layout
246
+
247
+ default_head_dim = config.hidden_size // config.num_attention_heads
248
+ default_v_head_dim = getattr(config, "v_head_dim", default_head_dim)
249
+
250
+ if is_swa:
251
+ self.head_dim = getattr(config, "swa_head_dim", getattr(config, "head_dim", default_head_dim))
252
+ self.v_head_dim = getattr(config, "swa_v_head_dim", default_v_head_dim)
253
+ self.num_attention_heads = getattr(config, "swa_num_attention_heads", config.num_attention_heads)
254
+ self.num_key_value_heads = getattr(config, "swa_num_key_value_heads", config.num_key_value_heads)
255
+ else:
256
+ self.head_dim = getattr(config, "head_dim", default_head_dim)
257
+ self.v_head_dim = getattr(config, "v_head_dim", self.head_dim)
258
+ self.num_attention_heads = config.num_attention_heads
259
+ self.num_key_value_heads = config.num_key_value_heads
260
+
261
+ self.rope_dim = int(self.head_dim * getattr(config, "partial_rotary_factor", 1.0))
262
+ if self.rope_dim % 2 != 0:
263
+ raise ValueError(
264
+ f"MiMoV2 rotary dimension must be even, got {self.rope_dim} from "
265
+ f"head_dim={self.head_dim} and partial_rotary_factor={getattr(config, 'partial_rotary_factor', 1.0)}"
266
+ )
267
+ self.num_key_value_groups = self.num_attention_heads // self.num_key_value_heads
268
+ self.attention_dropout = getattr(config, "attention_dropout", 0.0)
269
+ self.scaling = self.head_dim**-0.5
270
+ self.sliding_window = getattr(config, "sliding_window", None) if is_swa else None
271
+ self.q_size = self.num_attention_heads * self.head_dim
272
+ self.k_size = self.num_key_value_heads * self.head_dim
273
+ self.v_size = self.num_key_value_heads * self.v_head_dim
274
+ self.o_hidden_size = self.num_attention_heads * self.v_head_dim
275
+ self.v_scale = getattr(config, "attention_value_scale", None)
276
+ self.attention_sink_bias = (
277
+ nn.Parameter(torch.empty(self.num_attention_heads), requires_grad=False)
278
+ if (
279
+ (getattr(config, "add_full_attention_sink_bias", False) and not is_swa)
280
+ or (getattr(config, "add_swa_attention_sink_bias", False) and is_swa)
281
+ )
282
+ else None
283
+ )
284
+
285
+ attention_bias = getattr(config, "attention_bias", False)
286
+ if self.projection_layout == "fused_qkv":
287
+ self.qkv_proj = nn.Linear(
288
+ config.hidden_size,
289
+ self.q_size + self.k_size + self.v_size,
290
+ bias=attention_bias,
291
+ )
292
+ else:
293
+ self.q_proj = nn.Linear(config.hidden_size, self.q_size, bias=attention_bias)
294
+ self.k_proj = nn.Linear(config.hidden_size, self.k_size, bias=attention_bias)
295
+ self.v_proj = nn.Linear(config.hidden_size, self.v_size, bias=attention_bias)
296
+ self.o_proj = nn.Linear(self.o_hidden_size, config.hidden_size, bias=False)
297
+
298
+ def _forward_attention(
299
+ self,
300
+ query_states: torch.Tensor,
301
+ key_states: torch.Tensor,
302
+ value_states: torch.Tensor,
303
+ input_shape: torch.Size,
304
+ position_embeddings: tuple[torch.Tensor, torch.Tensor],
305
+ attention_mask: Optional[torch.Tensor],
306
+ past_key_values: Optional[Cache] = None,
307
+ cache_position: Optional[torch.LongTensor] = None,
308
+ position_ids: Optional[torch.LongTensor] = None,
309
+ ) -> tuple[torch.Tensor, torch.Tensor]:
310
+ if self.v_scale is not None:
311
+ value_states = value_states * self.v_scale
312
+
313
+ cos, sin = position_embeddings
314
+ query_rope, query_nope = query_states.split([self.rope_dim, self.head_dim - self.rope_dim], dim=-1)
315
+ key_rope, key_nope = key_states.split([self.rope_dim, self.head_dim - self.rope_dim], dim=-1)
316
+ query_rope, key_rope = apply_rotary_pos_emb(query_rope, key_rope, cos, sin)
317
+ query_states = torch.cat([query_rope, query_nope], dim=-1)
318
+ key_states = torch.cat([key_rope, key_nope], dim=-1)
319
+
320
+ if past_key_values is not None:
321
+ cache_kwargs = {"sin": sin, "cos": cos, "cache_position": cache_position}
322
+ key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx, cache_kwargs)
323
+
324
+ attn_implementation = self.config._attn_implementation
325
+ if attn_implementation is not None and attn_implementation.startswith("paged|"):
326
+ raise ValueError(
327
+ "MiMoV2 remote code does not support paged attention cache. "
328
+ "Please use eager, sdpa, flex_attention, or flash_attention_2."
329
+ )
330
+
331
+ attention_interface: Callable = ALL_ATTENTION_FUNCTIONS.get_interface(
332
+ attn_implementation, eager_attention_forward
333
+ )
334
+ if self.attention_sink_bias is not None and attn_implementation == "sdpa":
335
+ logger.warning_once(
336
+ "MiMoV2 attention sink bias is not supported by SDPA; falling back to eager attention for correctness."
337
+ )
338
+ attention_interface = eager_attention_forward
339
+
340
+ attention_kwargs = {
341
+ "dropout": 0.0 if not self.training else self.attention_dropout,
342
+ "scaling": self.scaling,
343
+ "position_ids": position_ids,
344
+ "is_causal": self.is_causal,
345
+ }
346
+ if attention_interface is eager_attention_forward:
347
+ attention_kwargs["sinks"] = self.attention_sink_bias
348
+ else:
349
+ if self.attention_sink_bias is not None:
350
+ attention_kwargs["s_aux"] = self.attention_sink_bias
351
+ if self.sliding_window is not None:
352
+ attention_kwargs["sliding_window"] = self.sliding_window
353
+
354
+ attn_output, attn_weights = attention_interface(
355
+ self,
356
+ query_states,
357
+ key_states,
358
+ value_states,
359
+ attention_mask,
360
+ **attention_kwargs,
361
+ )
362
+ attn_output = attn_output.reshape(*input_shape, -1).contiguous()
363
+ attn_output = self.o_proj(attn_output)
364
+ return attn_output, attn_weights
365
+
366
+ def forward(
367
+ self,
368
+ hidden_states: torch.Tensor,
369
+ position_embeddings: tuple[torch.Tensor, torch.Tensor],
370
+ attention_mask: Optional[torch.Tensor],
371
+ past_key_values: Optional[Cache] = None,
372
+ cache_position: Optional[torch.LongTensor] = None,
373
+ position_ids: Optional[torch.LongTensor] = None,
374
+ **kwargs: Unpack[TransformersKwargs],
375
+ ) -> tuple[torch.Tensor, torch.Tensor]:
376
+ input_shape = hidden_states.shape[:-1]
377
+
378
+ if self.projection_layout == "fused_qkv":
379
+ qkv_states = self.qkv_proj(hidden_states)
380
+ query_states, key_states, value_states = qkv_states.split([self.q_size, self.k_size, self.v_size], dim=-1)
381
+ else:
382
+ query_states = self.q_proj(hidden_states)
383
+ key_states = self.k_proj(hidden_states)
384
+ value_states = self.v_proj(hidden_states)
385
+
386
+ query_states = query_states.view(*input_shape, self.num_attention_heads, self.head_dim).transpose(1, 2)
387
+ key_states = key_states.view(*input_shape, self.num_key_value_heads, self.head_dim).transpose(1, 2)
388
+ value_states = value_states.view(*input_shape, self.num_key_value_heads, self.v_head_dim).transpose(1, 2)
389
+ return self._forward_attention(
390
+ query_states,
391
+ key_states,
392
+ value_states,
393
+ input_shape,
394
+ position_embeddings,
395
+ attention_mask,
396
+ past_key_values=past_key_values,
397
+ cache_position=cache_position,
398
+ position_ids=position_ids,
399
+ )
400
+
401
+
402
+ class MiMoV2DecoderLayer(nn.Module):
403
+ attention_projection_layout = "split"
404
+
405
+ def __init__(self, config, layer_idx: int, attention_projection_layout: Optional[str] = None):
406
+ super().__init__()
407
+ attention_projection_layout = attention_projection_layout or self.attention_projection_layout
408
+ is_swa_layer = config.hybrid_layer_pattern[layer_idx] == 1
409
+ self.attention_type = "sliding_window_attention" if is_swa_layer else "full_attention"
410
+ self.self_attn = MiMoV2Attention(
411
+ config, is_swa_layer, layer_idx, projection_layout=attention_projection_layout
412
+ )
413
+ self.mlp = (
414
+ MiMoV2MoE(config)
415
+ if getattr(config, "n_routed_experts", None) is not None and config.moe_layer_freq[layer_idx]
416
+ else MiMoV2MLP(config)
417
+ )
418
+ self.input_layernorm = MiMoV2RMSNorm(config.hidden_size, eps=config.layernorm_epsilon)
419
+ self.post_attention_layernorm = MiMoV2RMSNorm(config.hidden_size, eps=config.layernorm_epsilon)
420
+
421
+ def forward(
422
+ self,
423
+ hidden_states: torch.Tensor,
424
+ attention_mask: Optional[torch.Tensor] = None,
425
+ position_ids: Optional[torch.LongTensor] = None,
426
+ past_key_values: Optional[Cache] = None,
427
+ use_cache: Optional[bool] = False,
428
+ cache_position: Optional[torch.LongTensor] = None,
429
+ position_embeddings: Optional[tuple[torch.Tensor, torch.Tensor]] = None,
430
+ **kwargs: Unpack[TransformersKwargs],
431
+ ) -> torch.Tensor:
432
+ residual = hidden_states
433
+ hidden_states = self.input_layernorm(hidden_states)
434
+ hidden_states, _ = self.self_attn(
435
+ hidden_states=hidden_states,
436
+ attention_mask=attention_mask,
437
+ position_ids=position_ids,
438
+ past_key_values=past_key_values,
439
+ use_cache=use_cache,
440
+ cache_position=cache_position,
441
+ position_embeddings=position_embeddings,
442
+ **kwargs,
443
+ )
444
+ hidden_states = residual + hidden_states
445
+
446
+ residual = hidden_states
447
+ hidden_states = self.post_attention_layernorm(hidden_states)
448
+ hidden_states = self.mlp(hidden_states)
449
+ hidden_states = residual + hidden_states
450
+ return hidden_states
451
+
452
+
453
+ class MiMoV2RotaryEmbedding(nn.Module):
454
+ inv_freq: torch.Tensor
455
+
456
+ def __init__(self, config, is_swa: bool, device=None):
457
+ super().__init__()
458
+ if hasattr(config, "rope_scaling") and isinstance(config.rope_scaling, dict):
459
+ self.rope_type = config.rope_scaling.get("rope_type", config.rope_scaling.get("type", "default"))
460
+ else:
461
+ self.rope_type = "default"
462
+ self.max_seq_len_cached = config.max_position_embeddings
463
+ self.original_max_seq_len = config.max_position_embeddings
464
+
465
+ self.config = copy(config)
466
+ self.config.rope_parameters = copy(getattr(config, "rope_parameters", None) or {})
467
+ if is_swa:
468
+ self.config.rope_theta = getattr(config, "swa_rope_theta", config.rope_theta)
469
+ self.config.head_dim = getattr(config, "swa_head_dim", getattr(config, "head_dim", None))
470
+ if self.config.rope_parameters:
471
+ self.config.rope_parameters["rope_theta"] = self.config.rope_theta
472
+ self.rope_init_fn = (
473
+ self.compute_default_rope_parameters
474
+ if self.rope_type == "default"
475
+ else ROPE_INIT_FUNCTIONS[self.rope_type]
476
+ )
477
+
478
+ inv_freq, self.attention_scaling = self.rope_init_fn(self.config, device)
479
+ self.register_buffer("inv_freq", inv_freq, persistent=False)
480
+ self.original_inv_freq = self.inv_freq
481
+
482
+ @staticmethod
483
+ def compute_default_rope_parameters(config, device=None, seq_len=None, layer_type=None):
484
+ config.standardize_rope_params()
485
+ rope_parameters = config.rope_parameters[layer_type] if layer_type is not None else config.rope_parameters
486
+ base = rope_parameters["rope_theta"]
487
+ partial_rotary_factor = rope_parameters.get("partial_rotary_factor", 1.0)
488
+ head_dim = getattr(config, "head_dim", None) or config.hidden_size // config.num_attention_heads
489
+ dim = int(head_dim * partial_rotary_factor)
490
+ if dim % 2 != 0:
491
+ raise ValueError(
492
+ f"MiMoV2 rotary dimension must be even, got {dim} from "
493
+ f"head_dim={head_dim} and partial_rotary_factor={partial_rotary_factor}"
494
+ )
495
+ inv_freq = 1.0 / (
496
+ base ** (torch.arange(0, dim, 2, dtype=torch.int64).to(device=device, dtype=torch.float) / dim)
497
+ )
498
+ return inv_freq, 1.0
499
+
500
+ @torch.no_grad()
501
+ @dynamic_rope_update
502
+ def forward(self, x, position_ids):
503
+ inv_freq_expanded = self.inv_freq[None, :, None].float().expand(position_ids.shape[0], -1, 1).to(x.device)
504
+ position_ids_expanded = position_ids[:, None, :].float()
505
+
506
+ device_type = x.device.type if isinstance(x.device.type, str) and x.device.type != "mps" else "cpu"
507
+ with torch.autocast(device_type=device_type, enabled=False):
508
+ freqs = (inv_freq_expanded.float() @ position_ids_expanded.float()).transpose(1, 2)
509
+ emb = torch.cat((freqs, freqs), dim=-1)
510
+ cos = emb.cos() * self.attention_scaling
511
+ sin = emb.sin() * self.attention_scaling
512
+
513
+ return cos.to(dtype=x.dtype), sin.to(dtype=x.dtype)
514
+
515
+
516
+ class MiMoV2Model(PreTrainedModel):
517
+ config_class = MiMoV2Config
518
+ attention_projection_layout = "split"
519
+
520
+ def __init__(self, config):
521
+ super().__init__(config)
522
+ self.attention_projection_layout = getattr(
523
+ config, "attention_projection_layout", self.attention_projection_layout
524
+ )
525
+ self.vocab_size = config.vocab_size
526
+ self.embed_tokens = nn.Embedding(config.vocab_size, config.hidden_size)
527
+ self.layers = nn.ModuleList(
528
+ [
529
+ MiMoV2DecoderLayer(
530
+ config,
531
+ layer_idx,
532
+ attention_projection_layout=self.attention_projection_layout,
533
+ )
534
+ for layer_idx in range(config.num_hidden_layers)
535
+ ]
536
+ )
537
+ self.norm = MiMoV2RMSNorm(config.hidden_size, eps=config.layernorm_epsilon)
538
+ self.rotary_emb = MiMoV2RotaryEmbedding(config=config, is_swa=False)
539
+ self.swa_rotary_emb = MiMoV2RotaryEmbedding(config=config, is_swa=True)
540
+ self.has_sliding_layers = any(pattern == 1 for pattern in config.hybrid_layer_pattern)
541
+ self.config.layer_types = [
542
+ "sliding_attention" if config.hybrid_layer_pattern[i] == 1 else "full_attention"
543
+ for i in range(config.num_hidden_layers)
544
+ ]
545
+ self.post_init()
546
+
547
+ def get_input_embeddings(self):
548
+ return self.embed_tokens
549
+
550
+ def set_input_embeddings(self, value):
551
+ self.embed_tokens = value
552
+
553
+ def forward(
554
+ self,
555
+ input_ids: Optional[torch.LongTensor] = None,
556
+ attention_mask: Optional[torch.Tensor] = None,
557
+ position_ids: Optional[torch.LongTensor] = None,
558
+ past_key_values: Optional[Cache] = None,
559
+ inputs_embeds: Optional[torch.FloatTensor] = None,
560
+ use_cache: Optional[bool] = None,
561
+ cache_position: Optional[torch.LongTensor] = None,
562
+ **kwargs: Unpack[TransformersKwargs],
563
+ ) -> BaseModelOutputWithPast:
564
+ if (input_ids is None) ^ (inputs_embeds is not None):
565
+ raise ValueError("You must specify exactly one of input_ids or inputs_embeds")
566
+
567
+ use_cache = use_cache if use_cache is not None else self.config.use_cache
568
+
569
+ if inputs_embeds is None:
570
+ inputs_embeds = self.embed_tokens(input_ids)
571
+
572
+ if use_cache and past_key_values is None:
573
+ past_key_values = DynamicCache(config=self.config)
574
+
575
+ if cache_position is None:
576
+ past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0
577
+ cache_position = torch.arange(
578
+ past_seen_tokens, past_seen_tokens + inputs_embeds.shape[1], device=inputs_embeds.device
579
+ )
580
+
581
+ if position_ids is None:
582
+ position_ids = cache_position.unsqueeze(0)
583
+
584
+ if not isinstance(causal_mask_mapping := attention_mask, dict):
585
+ mask_kwargs = {
586
+ "config": self.config,
587
+ "inputs_embeds": inputs_embeds,
588
+ "attention_mask": attention_mask,
589
+ "cache_position": cache_position,
590
+ "past_key_values": past_key_values,
591
+ "position_ids": position_ids,
592
+ }
593
+ causal_mask_mapping = {
594
+ "full_attention": create_causal_mask(**mask_kwargs),
595
+ }
596
+ if self.has_sliding_layers:
597
+ if getattr(self.config, "sliding_window", None) is None:
598
+ raise ValueError("MiMoV2 config `sliding_window` must be set when hybrid_layer_pattern uses SWA.")
599
+ causal_mask_mapping["sliding_window_attention"] = create_sliding_window_causal_mask(**mask_kwargs)
600
+
601
+ hidden_states = inputs_embeds
602
+ position_embeddings = self.rotary_emb(hidden_states, position_ids)
603
+ swa_position_embeddings = self.swa_rotary_emb(hidden_states, position_ids)
604
+
605
+ for decoder_layer in self.layers[: self.config.num_hidden_layers]:
606
+ hidden_states = decoder_layer(
607
+ hidden_states,
608
+ attention_mask=causal_mask_mapping[decoder_layer.attention_type],
609
+ position_embeddings=position_embeddings
610
+ if decoder_layer.attention_type == "full_attention"
611
+ else swa_position_embeddings,
612
+ position_ids=position_ids,
613
+ past_key_values=past_key_values,
614
+ use_cache=use_cache,
615
+ cache_position=cache_position,
616
+ **kwargs,
617
+ )
618
+
619
+ hidden_states = self.norm(hidden_states)
620
+ return BaseModelOutputWithPast(
621
+ last_hidden_state=hidden_states,
622
+ past_key_values=past_key_values if use_cache else None,
623
+ )
624
+
625
+
626
+ class MiMoV2ForCausalLM(PreTrainedModel, GenerationMixin):
627
+ config_class = MiMoV2Config
628
+ model_class = MiMoV2Model
629
+ _tied_weights_keys = {"lm_head.weight": "model.embed_tokens.weight"}
630
+ _tp_plan = {"lm_head": "colwise_rep"}
631
+ _pp_plan = {"lm_head": (["hidden_states"], ["logits"])}
632
+ _keys_to_ignore_on_load_unexpected = [
633
+ r"model\.(swa_)?rotary_emb\.inv_freq",
634
+ r"model\.layers\.\d+\.self_attn\.rotary_emb\.inv_freq",
635
+ r"model\.layers\.\d+\.self_attn\.rotary_emb\.(cos_cached|sin_cached)",
636
+ r"model\.mtp\..*",
637
+ ]
638
+
639
+ def __init__(self, config):
640
+ super().__init__(config)
641
+ self.model = self.model_class(config)
642
+ self.vocab_size = config.vocab_size
643
+ self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=False)
644
+ self.post_init()
645
+
646
+ def get_input_embeddings(self):
647
+ return self.model.embed_tokens
648
+
649
+ def set_input_embeddings(self, value):
650
+ self.model.embed_tokens = value
651
+
652
+ def get_output_embeddings(self):
653
+ return self.lm_head
654
+
655
+ def set_output_embeddings(self, new_embeddings):
656
+ self.lm_head = new_embeddings
657
+
658
+ @can_return_tuple
659
+ def forward(
660
+ self,
661
+ input_ids: Optional[torch.LongTensor] = None,
662
+ attention_mask: Optional[torch.Tensor] = None,
663
+ position_ids: Optional[torch.LongTensor] = None,
664
+ past_key_values: Optional[Cache] = None,
665
+ inputs_embeds: Optional[torch.FloatTensor] = None,
666
+ labels: Optional[torch.LongTensor] = None,
667
+ use_cache: Optional[bool] = None,
668
+ cache_position: Optional[torch.LongTensor] = None,
669
+ logits_to_keep: Union[int, torch.Tensor] = 0,
670
+ **kwargs: Unpack[TransformersKwargs],
671
+ ) -> CausalLMOutputWithPast:
672
+ outputs: BaseModelOutputWithPast = self.model(
673
+ input_ids=input_ids,
674
+ attention_mask=attention_mask,
675
+ position_ids=position_ids,
676
+ past_key_values=past_key_values,
677
+ inputs_embeds=inputs_embeds,
678
+ use_cache=use_cache,
679
+ cache_position=cache_position,
680
+ **kwargs,
681
+ )
682
+
683
+ hidden_states = outputs.last_hidden_state
684
+ slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep
685
+ logits = self.lm_head(hidden_states[:, slice_indices, :])
686
+
687
+ loss = None
688
+ if labels is not None:
689
+ loss = self.loss_function(logits=logits, labels=labels, vocab_size=self.config.vocab_size, **kwargs)
690
+
691
+ return CausalLMOutputWithPast(
692
+ loss=loss,
693
+ logits=logits,
694
+ past_key_values=outputs.past_key_values,
695
+ hidden_states=outputs.hidden_states,
696
+ attentions=outputs.attentions,
697
+ )
698
+
699
+
700
+ __all__ = [
701
+ "MiMoV2Attention",
702
+ "MiMoV2DecoderLayer",
703
+ "MiMoV2ForCausalLM",
704
+ "MiMoV2MLP",
705
+ "MiMoV2MoE",
706
+ "MiMoV2MoEGate",
707
+ "MiMoV2Model",
708
+ "MiMoV2RMSNorm",
709
+ "MiMoV2RotaryEmbedding",
710
+ ]
epoch_0_step_1499/model/tokenizer.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:71e1168ef6233c01973f3b8b90abcd86236e146f7aee8da59655d2ca51afdb20
3
+ size 11422749
epoch_0_step_1499/model/tokenizer_config.json ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "add_prefix_space": false,
3
+ "backend": "tokenizers",
4
+ "bos_token": null,
5
+ "clean_up_tokenization_spaces": false,
6
+ "eos_token": "<|im_end|>",
7
+ "errors": "replace",
8
+ "is_local": true,
9
+ "local_files_only": false,
10
+ "max_length": 512,
11
+ "model_max_length": 131272,
12
+ "pad_to_multiple_of": null,
13
+ "pad_token": "<|endoftext|>",
14
+ "pad_token_type_id": 0,
15
+ "padding_side": "right",
16
+ "split_special_tokens": false,
17
+ "stride": 0,
18
+ "tokenizer_class": "Qwen2Tokenizer",
19
+ "truncation_side": "right",
20
+ "truncation_strategy": "longest_first",
21
+ "unk_token": null
22
+ }
epoch_0_step_1499/rng/rng_global_rank_0.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ff7a765f882dc14b615a2de2246a5b8c981cc91467595cdc6ee672d263dfd4ab
3
+ size 15461
epoch_0_step_1499/rng/rng_global_rank_1.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a8390936a4e97b9d4a4bf4d168e7e51aa490c99c41e76df551efb1e2071a1a74
3
+ size 15461
epoch_0_step_1499/rng/rng_global_rank_2.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:2bc00688437624145dceb90ad75c46a2047370feddc5212162a9bb387c406f01
3
+ size 15461
epoch_0_step_1499/rng/rng_global_rank_3.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:21155b5b95ec2ad1c731fb4cf78832e1c59b1e93556e88d2877e4c26d04049f7
3
+ size 15461
epoch_0_step_1499/rng/rng_global_rank_4.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:fb15535a3503e74246e9a23e25c23a51a5dc3f172d0a1c4b7050eae26f5e6577
3
+ size 15461
epoch_0_step_1499/rng/rng_global_rank_5.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:6ecdfd8b01446452f011b3df658a63c1c8aa461b71ac057535dbc43054ebfc36
3
+ size 15525
epoch_0_step_1499/rng/rng_global_rank_6.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:19e634e7f435177445844d4ff36b7331d0d1e9edc668fff7098a058521bbe7f0
3
+ size 15461
epoch_0_step_1499/rng/rng_global_rank_7.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:bd96108236dd567aa473b549ce896129bbb434c1f6960843b565d60f4986f380
3
+ size 15461
epoch_0_step_1499/step_scheduler.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b034b152e634ceb07f1f11bcb5aa00f805ccc3e9e0709f2a300aa91204fab5ee
3
+ size 1303
training.jsonl CHANGED
The diff for this file is too large to render. See raw diff