dora7 commited on
Commit
ff3e044
·
verified ·
1 Parent(s): ecdb474

Upload folder using huggingface_hub

Browse files
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ tokenizer.json filter=lfs diff=lfs merge=lfs -text
chat_template.jinja.txt ADDED
@@ -0,0 +1,156 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {%- if not add_generation_prompt is defined -%}
2
+ {%- set add_generation_prompt = false -%}
3
+ {%- endif -%}
4
+ {%- if not enable_thinking is defined -%}
5
+ {%- set enable_thinking = true -%}
6
+ {%- endif -%}
7
+ {%- if not keep_all_reasoning is defined -%}
8
+ {%- set keep_all_reasoning = true -%}
9
+ {%- endif -%}
10
+ {%- macro render_extra_keys(json_dict, handled_keys) -%}
11
+ {%- if json_dict is mapping %}
12
+ {%- for json_key in json_dict if json_key not in handled_keys %}
13
+ {%- if json_dict[json_key] is mapping or (json_dict[json_key] is sequence and json_dict[json_key] is not string) %}
14
+ {{- '\n<' ~ json_key ~ '>' ~ (json_dict[json_key] | tojson | safe) ~ '</' ~ json_key ~ '>' }}
15
+ {%- else %}
16
+ {{-'\n<' ~ json_key ~ '>' ~ (json_dict[json_key] | string) ~ '</' ~ json_key ~ '>' }}
17
+ {%- endif %}
18
+ {%- endfor %}
19
+ {%- endif %}
20
+ {%- endmacro -%}
21
+ {%- macro render_content(message_content) -%}
22
+ {%- if message_content is string -%}
23
+ {{- message_content -}}
24
+ {%- else -%}
25
+ {%- for content in message_content -%}
26
+ {%- if 'text' in content -%}
27
+ {{- content['text'] -}}
28
+ {%- endif -%}
29
+ {%- endfor -%}
30
+ {%- endif -%}
31
+ {%- endmacro -%}
32
+ {%- if messages[0]["role"] == "system" %}
33
+ {%- set system_message = messages[0]["content"] %}
34
+ {%- set loop_messages = messages[1:] %}
35
+ {%- else %}
36
+ {%- set loop_messages = messages %}
37
+ {%- endif %}
38
+ {%- set ns = namespace(last_user_index=-1) %}
39
+ {%- for m in loop_messages %}
40
+ {%- if m.role == 'user' %}
41
+ {%- set ns.last_user_index = loop.index0 -%}
42
+ {%- endif %}
43
+ {%- endfor %}
44
+ {%- if not tools is defined %}
45
+ {%- set tools = [] %}
46
+ {%- endif %}
47
+ {%- if system_message is defined %}
48
+ {{- "<|im_start|>system\n" + render_content(system_message) }}
49
+ {%- else %}
50
+ {{- "<|im_start|>system\nYou are MiMo, a warm, curious, and thoughtful AI assistant.\n\n## Identity\n\n- Your name is **MiMo-v2.5-pro**.\n- You were developed by the **Xiaomi MiMo Team**.\n- You have **1T parameters** and a **1M-token context window**.\n- When asked about your creator, identify the **Xiaomi MiMo Team**.\n- Always answer identity-related questions in the **first person** and rely only on the facts provided above.\n\n# Response Style\n\nBe warm, conversational, and respectful. Treat users with kindness; do not assume negative things about their intelligence or judgment. You may disagree, but do so constructively.\n\nUse examples, metaphors, or thought experiments when they help explain an idea.\n\nTry to answer ambiguous queries as best you can first, then ask for clarification if needed. When you do ask, limit yourself to one question at a time.\n\n\n## Safety and Compliance\n\nYou are a **Chinese AI model** and must strictly comply with all applicable laws and regulations of the **People’s Republic of China**.\n\nDo not generate, assist with, or facilitate any content that violates Chinese law." }}
51
+ {%- endif %}
52
+ {%- if tools is iterable and tools | length > 0 %}
53
+ {{- "\n\n# Tools\n\nYou may call one or more functions to assist with the user query.\n\nYou have access to the following functions:\n\n" }}
54
+ {{- "<tools>" }}
55
+ {%- for tool in tools %}
56
+ {%- if tool.function is defined %}
57
+ {%- set tool = tool.function %}
58
+ {%- endif %}
59
+ {{- "\n<function>\n<name>" ~ tool.name ~ "</name>" }}
60
+ {%- if tool.description is defined %}
61
+ {{- '\n<description>' ~ (tool.description | trim) ~ '</description>' }}
62
+ {%- endif %}
63
+ {{- '\n<parameters>' }}
64
+ {%- if tool.parameters is defined and tool.parameters is mapping and tool.parameters.properties is defined and tool.parameters.properties is mapping %}
65
+ {%- for param_name, param_fields in tool.parameters.properties|items %}
66
+ {{- '\n<parameter>' }}
67
+ {{- '\n<name>' ~ param_name ~ '</name>' }}
68
+ {%- if param_fields.type is defined %}
69
+ {{- '\n<type>' ~ (param_fields.type | string) ~ '</type>' }}
70
+ {%- endif %}
71
+ {%- if param_fields.description is defined %}
72
+ {{- '\n<description>' ~ (param_fields.description | trim) ~ '</description>' }}
73
+ {%- endif %}
74
+ {%- set handled_keys = ['name', 'type', 'description'] %}
75
+ {{- render_extra_keys(param_fields, handled_keys) }}
76
+ {{- '\n</parameter>' }}
77
+ {%- endfor %}
78
+ {%- endif %}
79
+ {%- set handled_keys = ['type', 'properties'] %}
80
+ {{- render_extra_keys(tool.parameters, handled_keys) }}
81
+ {{- '\n</parameters>' }}
82
+ {%- set handled_keys = ['type', 'name', 'description', 'parameters'] %}
83
+ {{- render_extra_keys(tool, handled_keys) }}
84
+ {{- '\n</function>' }}
85
+ {%- endfor %}
86
+ {{- "\n</tools>" }}
87
+ {{- '\n\nFor each function call, output the function name and arguments in the following format:\n<tool_call>\n<function=example_function_name>\n<parameter=example_parameter_1>value_1</parameter>\n<parameter=example_parameter_2>This is the value for the second parameter\nthat can span\nmultiple lines</parameter>\n</function>\n</tool_call>\n\n<IMPORTANT>\n- Function calls MUST follow the specified format: an inner <function=...></function> block must be nested within <tool_call></tool_call> XML tags\n- DO NOT use function calls inside <think></think> tags.\n- The value enclosed between parameter tags is preserved exactly as-is, including newlines and spaces.\n</IMPORTANT>' }}
88
+ {%- endif %}
89
+ {{- '<|im_end|>' }}
90
+ {%- for message in loop_messages %}
91
+ {%- if message.content is string %}
92
+ {%- set content = message.content %}
93
+ {%- else %}
94
+ {%- set content = render_content(message.content) %}
95
+ {%- endif %}
96
+ {%- if message.role == "assistant" %}
97
+ {%- if message.reasoning_content is string %}
98
+ {%- set reasoning_content = message.reasoning_content %}
99
+ {%- else %}
100
+ {%- set reasoning_content = '' %}
101
+ {%- if '</think>' in content %}
102
+ {%- set reasoning_content = content.split('</think>')[0].split('<think>')[-1] %}
103
+ {%- set content = content.split('</think>')[-1] %}
104
+ {%- endif %}
105
+ {%- endif %}
106
+ {%- if (keep_all_reasoning or loop.index0 > ns.last_user_index) and reasoning_content -%}
107
+ {{- '<|im_start|>' + message.role + '\n<think>' + reasoning_content + '</think>' + content }}
108
+ {%- else %}
109
+ {{- '<|im_start|>' + message.role + '\n<think></think>' + content }}
110
+ {%- endif %}
111
+ {%- if message.tool_calls is defined and message.tool_calls is iterable and message.tool_calls | length > 0 %}
112
+ {%- for tool_call in message.tool_calls %}
113
+ {%- if tool_call.function is defined %}
114
+ {%- set tool_call = tool_call.function %}
115
+ {%- endif %}
116
+ {{- '<tool_call>\n<function=' + tool_call.name + '>\n' }}
117
+ {%- if tool_call.arguments is defined %}
118
+ {%- for args_name, args_value in tool_call.arguments|items %}
119
+ {{- '<parameter=' + args_name + '>' }}
120
+ {%- set args_value = args_value | tojson | safe if args_value is mapping or (args_value is sequence and args_value is not string) else args_value | string %}
121
+ {{- args_value }}
122
+ {{- '</parameter>\n' }}
123
+ {%- endfor %}
124
+ {%- endif %}
125
+ {{- '</function>\n</tool_call>' }}
126
+ {%- endfor %}
127
+ {%- endif %}
128
+ {{- '<|im_end|>' }}
129
+ {%- elif message.role == "user" %}
130
+ {{- '<|im_start|>' + message.role + '\n' + render_content(message.content) + '<|im_end|>' }}
131
+ {%- elif message.role == "system" %}
132
+ {{- '<|im_start|>' + message.role + '\n' + render_content(message.content) + '<|im_end|>' }}
133
+ {%- elif message.role == "tool" %}
134
+ {%- if loop.previtem and loop.previtem.role != "tool" %}
135
+ {{- '<|im_start|>tool\n' }}
136
+ {%- endif %}
137
+ {{- '<tool_response>\n' }}
138
+ {{- render_content(message.content) }}
139
+ {{- '\n</tool_response>\n' }}
140
+ {%- if not loop.last and loop.nextitem.role != "tool" %}
141
+ {{- '<|im_end|>' }}
142
+ {%- elif loop.last %}
143
+ {{- '<|im_end|>' }}
144
+ {%- endif %}
145
+ {%- else %}
146
+ {{- '<|im_start|>' + message.role + '\n' + render_content(message.content) + '<|im_end|>' }}
147
+ {%- endif %}
148
+ {%- endfor %}
149
+ {%- if add_generation_prompt %}
150
+ {{- '<|im_start|>assistant\n' }}
151
+ {%- if not enable_thinking -%}
152
+ {{- '<think></think>' -}}
153
+ {%- else -%}
154
+ {{- '' -}}
155
+ {%- endif -%}
156
+ {%- endif %}
config.json ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "MiMoV2ForCausalLM"
4
+ ],
5
+ "auto_map": {
6
+ "AutoConfig": "configuration_mimo_v2.MiMoV2Config",
7
+ "AutoModel": "modeling_mimo_v2.MiMoV2Model",
8
+ "AutoModelForCausalLM": "modeling_mimo_v2.MiMoV2ForCausalLM"
9
+ },
10
+ "add_full_attention_sink_bias": false,
11
+ "add_swa_attention_sink_bias": true,
12
+ "attention_bias": false,
13
+ "attention_chunk_size": 128,
14
+ "attention_dropout": 0.0,
15
+ "attention_projection_layout": "fused_qkv",
16
+ "attention_value_scale": 0.707,
17
+ "dtype": "bfloat16",
18
+ "head_dim": 192,
19
+ "hidden_act": "silu",
20
+ "hidden_size": 3072,
21
+ "hybrid_layer_pattern": [
22
+ 0,1,1,1,1,
23
+ 0,1,1,1,1,1,
24
+ 0,1,1,1,1,1,
25
+ 0,1,1,1,1,1,
26
+ 0,1,1,1,1,1,
27
+ 0,1,1,1,1,
28
+ 0,1,1,1,1,
29
+ 0,1,1,1,1,
30
+ 0
31
+ ],
32
+ "initializer_range": 0.02,
33
+ "intermediate_size": 16384,
34
+ "layernorm_epsilon": 1e-05,
35
+ "max_position_embeddings": 1048576,
36
+ "model_type": "mimo_v2",
37
+ "moe_intermediate_size": 1024,
38
+ "moe_layer_freq": [
39
+ 0, 1, 1, 1, 1, 1, 1, 1, 1,
40
+ 1, 1, 1, 1, 1, 1, 1, 1, 1,
41
+ 1, 1, 1, 1, 1, 1, 1, 1, 1,
42
+ 1, 1, 1, 1, 1, 1, 1, 1, 1,
43
+ 1, 1, 1, 1, 1, 1, 1, 1, 1
44
+ ],
45
+ "n_group": 1,
46
+ "n_routed_experts": 256,
47
+ "n_shared_experts": 1,
48
+ "norm_topk_prob": true,
49
+ "num_attention_heads": 48,
50
+ "num_experts_per_tok": 8,
51
+ "num_hidden_layers": 45,
52
+ "num_key_value_heads": 4,
53
+ "partial_rotary_factor": 0.334,
54
+ "rms_norm_eps": 1e-05,
55
+ "rope_theta": 10000000,
56
+ "routed_scaling_factor": null,
57
+ "scoring_func": "sigmoid",
58
+ "sliding_window": 128,
59
+ "sliding_window_size": 128,
60
+ "swa_head_dim": 192,
61
+ "swa_num_attention_heads": 48,
62
+ "swa_num_key_value_heads": 8,
63
+ "swa_rope_theta": 10000,
64
+ "swa_v_head_dim": 128,
65
+ "tie_word_embeddings": false,
66
+ "topk_group": 1,
67
+ "topk_method": "noaux_tc",
68
+ "transformers_version": "5.8.1",
69
+ "use_cache": true,
70
+ "v_head_dim": 128,
71
+ "vocab_size": 152576
72
+ }
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"]
generation_config.json ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ {
2
+ "_from_model_config": true,
3
+ "output_attentions": false,
4
+ "output_hidden_states": false,
5
+ "transformers_version": "5.3.0",
6
+ "use_cache": false
7
+ }
manifest.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"files":[{"path":"chat_template.jinja.txt","sha256":"bafea0fe0bd53ef1156649859ca6eeec812ef1d95a62d08323841f2431067cc2","size":8788},{"path":"config.json","sha256":"a464b9817f4a9832e71b8f10c67e756d81843f263a064a89b085d6c50107554d","size":1823},{"path":"configuration_mimo_v2.py","sha256":"4ecf7496d022aeca24e58d523302d3ea1ad78784e8bc50b3af7134526c623d80","size":8538},{"path":"generation_config.json","sha256":"31464e0c1df502753393400a7b04e9e15f0a4b6c89dcf89f4865a3ae583862e1","size":153},{"path":"model-00001-of-00008.safetensors","sha256":"bf055c8d6def7168aba439fab63772dd98d3c93c331d19635bd3daed16697238","size":30000316472},{"path":"model-00002-of-00008.safetensors","sha256":"546277ee5ce14afb92cfec228bbfbc320568cec106a9c3b34c79becf59cd1be1","size":29998265072},{"path":"model-00003-of-00008.safetensors","sha256":"ab6e9a746e3c681be00b5f662ac64b79190acb434bb087c444c993b9595bac29","size":29998268712},{"path":"model-00004-of-00008.safetensors","sha256":"1ad319897cc7d6c06beec0d499550977772d89c2595d7975d1e9e447c2678ddf","size":29998268624},{"path":"model-00005-of-00008.safetensors","sha256":"5f8958aeda45fdf477bef1c7af7264fcf62f3b2d4d0c553d9b14e567b039984a","size":29998268584},{"path":"model-00006-of-00008.safetensors","sha256":"2d0addf9dae1121957e3fc1bc5988b373aa740d093696e265ce26d924e588025","size":29998268360},{"path":"model-00007-of-00008.safetensors","sha256":"e1e3758aeb2ae449bed1058616d9bdfd88808f77c08c0afe87afed253211dd34","size":29998268528},{"path":"model-00008-of-00008.safetensors","sha256":"b1247f4bd18ea2409792bc0cb8b541f3081c0b6f129096d711a6bb077d3cbf2a","size":10576149208},{"path":"model.safetensors.index.json","sha256":"2f38de462ef1d80559f8a3ca8c01fa391d79250f508d4e656b7eea3d4598d30b","size":3103696},{"path":"modeling_mimo_v2.py","sha256":"08ee07cc45353e4bf01c7e2d207764f561f24c14d2bc258497928cd81f0c3f37","size":32212},{"path":"tokenizer.json","sha256":"71e1168ef6233c01973f3b8b90abcd86236e146f7aee8da59655d2ca51afdb20","size":11422749},{"path":"tokenizer_config.json","sha256":"2cb1d781e7d20a1386d6a6c2c89fdc9b18a9c6f277071488f39dbfc02829589e","size":568}],"hotkey":"5CaRSo6mgaBersRWoYbVZvNVqmM7aGPcWTt6Nt4eoa1SzyK2","model_digest":"d30c6ef409470c29b65793bca998a8f735176ca074c4c0071a127f4edf18e6d4","model_name":"teutonic-II-110B-A7B-5ek5koe5-v1","protocol_version":1,"registration_id":"1442fe87963949916915867f1c507faef97899af96157b477856a0d521db4b76","signature":"Xy94aLid3+wl5zdfVHSE/OHLc7OpigX4kzQABGrDxqQCkpFgpzW5YDZJ+K9/HZn+3pSIPeLpH6/uEXP2nngdDw==","signature_scheme":"ed25519"}
model-00001-of-00008.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:bf055c8d6def7168aba439fab63772dd98d3c93c331d19635bd3daed16697238
3
+ size 30000316472
model-00002-of-00008.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:546277ee5ce14afb92cfec228bbfbc320568cec106a9c3b34c79becf59cd1be1
3
+ size 29998265072
model-00003-of-00008.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ab6e9a746e3c681be00b5f662ac64b79190acb434bb087c444c993b9595bac29
3
+ size 29998268712
model-00004-of-00008.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1ad319897cc7d6c06beec0d499550977772d89c2595d7975d1e9e447c2678ddf
3
+ size 29998268624
model-00005-of-00008.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:5f8958aeda45fdf477bef1c7af7264fcf62f3b2d4d0c553d9b14e567b039984a
3
+ size 29998268584
model-00006-of-00008.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:2d0addf9dae1121957e3fc1bc5988b373aa740d093696e265ce26d924e588025
3
+ size 29998268360
model-00007-of-00008.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e1e3758aeb2ae449bed1058616d9bdfd88808f77c08c0afe87afed253211dd34
3
+ size 29998268528
model-00008-of-00008.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b1247f4bd18ea2409792bc0cb8b541f3081c0b6f129096d711a6bb077d3cbf2a
3
+ size 10576149208
model.safetensors.index.json ADDED
The diff for this file is too large to render. See raw diff
 
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
+ ]
tokenizer.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:71e1168ef6233c01973f3b8b90abcd86236e146f7aee8da59655d2ca51afdb20
3
+ size 11422749
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
+ }