miceworks commited on
Commit
a890846
·
verified ·
1 Parent(s): 4d72a51

feat: upload MODELING_PY weights (modeling_mark_engineer_v2_8b.py)

Browse files
Files changed (1) hide show
  1. modeling_mark_engineer_v2_8b.py +302 -0
modeling_mark_engineer_v2_8b.py ADDED
@@ -0,0 +1,302 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Hugging Face Transformers Compatible Modeling Implementation for Mark-Engineer-V2-8B
3
+ Self-contained causal language model architecture with Multi-Head Latent Attention (MLA),
4
+ DeepSeekMoE (1 Shared + 24 Routed Experts, Top-2 active), and Multi-Token Prediction (MTP).
5
+ """
6
+
7
+ import math
8
+ from typing import List, Optional, Tuple, Union
9
+
10
+ import torch
11
+ import torch.nn as nn
12
+ import torch.nn.functional as F
13
+ from transformers.modeling_outputs import CausalLMOutputWithPast
14
+ from transformers.modeling_utils import PreTrainedModel
15
+
16
+ try:
17
+ from .configuration_mark_engineer_v2_8b import MarkEngineerV2_8BConfig
18
+ except (ImportError, ValueError):
19
+ from configuration_mark_engineer_v2_8b import MarkEngineerV2_8BConfig
20
+
21
+
22
+ class MarkRMSNorm(nn.Module):
23
+ def __init__(self, dim: int, eps: float = 1e-5):
24
+ super().__init__()
25
+ self.eps = eps
26
+ self.weight = nn.Parameter(torch.ones(dim))
27
+
28
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
29
+ variance = x.pow(2).mean(-1, keepdim=True)
30
+ return x * torch.rsqrt(variance + self.eps) * self.weight
31
+
32
+
33
+ def precompute_rope_freqs(head_dim: int, max_seq_len: int, theta: float = 500000.0) -> Tuple[torch.Tensor, torch.Tensor]:
34
+ freqs = 1.0 / (theta ** (torch.arange(0, head_dim, 2).float() / head_dim))
35
+ t = torch.arange(max_seq_len, dtype=torch.float)
36
+ freqs = torch.outer(t, freqs)
37
+ cos = freqs.cos()
38
+ sin = freqs.sin()
39
+ return cos, sin
40
+
41
+
42
+ def apply_rotary_emb(x: torch.Tensor, cos: torch.Tensor, sin: torch.Tensor) -> torch.Tensor:
43
+ d = x.shape[-1]
44
+ x1 = x[..., : d // 2]
45
+ x2 = x[..., d // 2 :]
46
+ rotated = torch.cat((-x2, x1), dim=-1)
47
+ cos = cos.unsqueeze(0).unsqueeze(2)
48
+ sin = sin.unsqueeze(0).unsqueeze(2)
49
+ cos = torch.cat([cos, cos], dim=-1)
50
+ sin = torch.cat([sin, sin], dim=-1)
51
+ return (x * cos) + (rotated * sin)
52
+
53
+
54
+ class MarkSwiGLUFFN(nn.Module):
55
+ def __init__(self, dim: int, intermediate_size: int):
56
+ super().__init__()
57
+ self.w_gate = nn.Linear(dim, intermediate_size, bias=False)
58
+ self.w_up = nn.Linear(dim, intermediate_size, bias=False)
59
+ self.w_down = nn.Linear(intermediate_size, dim, bias=False)
60
+
61
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
62
+ return self.w_down(F.silu(self.w_gate(x)) * self.w_up(x))
63
+
64
+
65
+ class MarkMLAAttention(nn.Module):
66
+ def __init__(self, config: MarkEngineerV2_8BConfig, layer_idx: int):
67
+ super().__init__()
68
+ self.layer_idx = layer_idx
69
+ self.dim = config.hidden_size
70
+ self.n_heads = config.num_attention_heads
71
+ self.q_lora_rank = config.q_lora_rank
72
+ self.kv_lora_rank = config.kv_lora_rank
73
+ self.qk_nope_head_dim = config.qk_nope_head_dim
74
+ self.qk_rope_head_dim = config.qk_rope_head_dim
75
+ self.v_head_dim = config.v_head_dim
76
+ self.qk_head_dim = self.qk_nope_head_dim + self.qk_rope_head_dim
77
+
78
+ self.wq_a = nn.Linear(self.dim, self.q_lora_rank, bias=False)
79
+ self.q_norm = MarkRMSNorm(self.q_lora_rank, eps=config.rms_norm_eps)
80
+ self.wq_b = nn.Linear(self.q_lora_rank, self.n_heads * self.qk_head_dim, bias=False)
81
+
82
+ self.wkv_a = nn.Linear(self.dim, self.kv_lora_rank + self.qk_rope_head_dim, bias=False)
83
+ self.kv_norm = MarkRMSNorm(self.kv_lora_rank, eps=config.rms_norm_eps)
84
+ self.wkv_b = nn.Linear(
85
+ self.kv_lora_rank,
86
+ self.n_heads * (self.qk_nope_head_dim + self.v_head_dim),
87
+ bias=False,
88
+ )
89
+
90
+ self.wo = nn.Linear(self.n_heads * self.v_head_dim, self.dim, bias=False)
91
+
92
+ def forward(
93
+ self,
94
+ x: torch.Tensor,
95
+ cos: torch.Tensor,
96
+ sin: torch.Tensor,
97
+ attention_mask: Optional[torch.Tensor] = None,
98
+ ) -> torch.Tensor:
99
+ bsz, seqlen, _ = x.shape
100
+
101
+ q_latent = self.q_norm(self.wq_a(x))
102
+ q = self.wq_b(q_latent).view(bsz, seqlen, self.n_heads, self.qk_head_dim)
103
+ q_nope = q[..., : self.qk_nope_head_dim]
104
+ q_pe = q[..., self.qk_nope_head_dim :]
105
+
106
+ kv_combined = self.wkv_a(x)
107
+ kv_latent = self.kv_norm(kv_combined[..., : self.kv_lora_rank])
108
+ k_pe = kv_combined[..., self.kv_lora_rank :].view(bsz, seqlen, 1, self.qk_rope_head_dim)
109
+
110
+ kv = self.wkv_b(kv_latent).view(bsz, seqlen, self.n_heads, self.qk_nope_head_dim + self.v_head_dim)
111
+ k_nope = kv[..., : self.qk_nope_head_dim]
112
+ v = kv[..., self.qk_nope_head_dim :]
113
+
114
+ q_pe = apply_rotary_emb(q_pe, cos[:seqlen], sin[:seqlen])
115
+ k_pe = apply_rotary_emb(k_pe.expand(-1, -1, self.n_heads, -1), cos[:seqlen], sin[:seqlen])
116
+
117
+ k = torch.cat([k_nope, k_pe], dim=-1)
118
+ q = torch.cat([q_nope, q_pe], dim=-1)
119
+
120
+ q = q.transpose(1, 2)
121
+ k = k.transpose(1, 2)
122
+ v = v.transpose(1, 2)
123
+
124
+ scores = torch.matmul(q, k.transpose(-2, -1)) / math.sqrt(self.qk_head_dim)
125
+ if attention_mask is not None:
126
+ scores = scores + attention_mask
127
+
128
+ attn_weights = F.softmax(scores, dim=-1)
129
+ output = torch.matmul(attn_weights, v)
130
+ output = output.transpose(1, 2).contiguous().view(bsz, seqlen, -1)
131
+ return self.wo(output)
132
+
133
+
134
+ class MarkMoELayer(nn.Module):
135
+ def __init__(self, config: MarkEngineerV2_8BConfig):
136
+ super().__init__()
137
+ self.n_routed = config.n_routed_experts
138
+ self.n_shared = config.n_shared_experts
139
+ self.top_k = config.num_experts_per_tok
140
+ self.dim = config.hidden_size
141
+ self.moe_intermediate = config.moe_intermediate_size
142
+
143
+ self.gate = nn.Linear(self.dim, self.n_routed, bias=False)
144
+ self.register_buffer("router_bias", torch.zeros(self.n_routed))
145
+ self.router_bias_rate = config.router_bias_update_rate
146
+
147
+ self.routed_experts = nn.ModuleList([
148
+ MarkSwiGLUFFN(self.dim, self.moe_intermediate) for _ in range(self.n_routed)
149
+ ])
150
+ if self.n_shared > 0:
151
+ self.shared_experts = MarkSwiGLUFFN(self.dim, self.moe_intermediate * self.n_shared)
152
+ else:
153
+ self.shared_experts = None
154
+
155
+ self.last_router_z_loss = None
156
+
157
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
158
+ bsz, seqlen, dim = x.shape
159
+ flat_x = x.view(-1, dim)
160
+
161
+ logits = self.gate(flat_x)
162
+ if self.training:
163
+ self.last_router_z_loss = torch.logsumexp(logits, dim=-1).pow(2).mean()
164
+
165
+ biased_logits = logits + self.router_bias
166
+ topk_weights, topk_indices = torch.topk(F.softmax(biased_logits, dim=-1), self.top_k, dim=-1)
167
+ topk_weights = topk_weights / topk_weights.sum(dim=-1, keepdim=True)
168
+
169
+ out = torch.zeros_like(flat_x)
170
+ for i, expert in enumerate(self.routed_experts):
171
+ mask = (topk_indices == i).any(dim=-1)
172
+ if mask.any():
173
+ idx_in_topk = (topk_indices[mask] == i).nonzero(as_tuple=True)[1]
174
+ w = topk_weights[mask, idx_in_topk].unsqueeze(-1)
175
+ out[mask] += w * expert(flat_x[mask])
176
+
177
+ if self.shared_experts is not None:
178
+ out += self.shared_experts(flat_x)
179
+
180
+ return out.view(bsz, seqlen, dim)
181
+
182
+
183
+ class MarkEngineerV2Block(nn.Module):
184
+ def __init__(self, config: MarkEngineerV2_8BConfig, layer_idx: int):
185
+ super().__init__()
186
+ self.attn_norm = MarkRMSNorm(config.hidden_size, eps=config.rms_norm_eps)
187
+ self.attn = MarkMLAAttention(config, layer_idx)
188
+ self.ffn_norm = MarkRMSNorm(config.hidden_size, eps=config.rms_norm_eps)
189
+
190
+ if layer_idx < config.n_dense_layers:
191
+ self.ffn = MarkSwiGLUFFN(config.hidden_size, config.intermediate_size)
192
+ self.is_moe = False
193
+ else:
194
+ self.ffn = MarkMoELayer(config)
195
+ self.is_moe = True
196
+
197
+ def forward(
198
+ self,
199
+ x: torch.Tensor,
200
+ cos: torch.Tensor,
201
+ sin: torch.Tensor,
202
+ attention_mask: Optional[torch.Tensor] = None,
203
+ ) -> torch.Tensor:
204
+ h = x + self.attn(self.attn_norm(x), cos, sin, attention_mask)
205
+ out = h + self.ffn(self.ffn_norm(h))
206
+ return out
207
+
208
+
209
+ class MarkEngineerV2ForCausalLM(PreTrainedModel):
210
+ config_class = MarkEngineerV2_8BConfig
211
+ base_model_prefix = "model"
212
+ _supports_flash_attn_2 = False
213
+
214
+ def __init__(self, config: MarkEngineerV2_8BConfig):
215
+ super().__init__(config)
216
+ self.config = config
217
+ self.embed_tokens = nn.Embedding(config.vocab_size, config.hidden_size)
218
+ self.layers = nn.ModuleList([
219
+ MarkEngineerV2Block(config, i) for i in range(config.num_hidden_layers)
220
+ ])
221
+ self.norm = MarkRMSNorm(config.hidden_size, eps=config.rms_norm_eps)
222
+ self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=False)
223
+
224
+ if config.mtp_depth > 0:
225
+ self.mtp_proj = nn.Linear(config.hidden_size * 2, config.hidden_size, bias=False)
226
+ self.mtp_norm = MarkRMSNorm(config.hidden_size, eps=config.rms_norm_eps)
227
+ self.mtp_head = nn.Linear(config.hidden_size, config.vocab_size, bias=False)
228
+ else:
229
+ self.mtp_proj = None
230
+
231
+ if config.tie_word_embeddings:
232
+ self.lm_head.weight = self.embed_tokens.weight
233
+
234
+ cos, sin = precompute_rope_freqs(
235
+ config.qk_rope_head_dim,
236
+ config.max_position_embeddings,
237
+ theta=config.rope_theta,
238
+ )
239
+ self.register_buffer("rope_cos", cos, persistent=False)
240
+ self.register_buffer("rope_sin", sin, persistent=False)
241
+
242
+ self.post_init()
243
+
244
+ def get_input_embeddings(self):
245
+ return self.embed_tokens
246
+
247
+ def set_input_embeddings(self, value):
248
+ self.embed_tokens = value
249
+
250
+ def get_output_embeddings(self):
251
+ return self.lm_head
252
+
253
+ def forward(
254
+ self,
255
+ input_ids: Optional[torch.LongTensor] = None,
256
+ attention_mask: Optional[torch.Tensor] = None,
257
+ labels: Optional[torch.LongTensor] = None,
258
+ return_mtp: bool = False,
259
+ **kwargs,
260
+ ) -> Union[Tuple, CausalLMOutputWithPast]:
261
+ bsz, seqlen = input_ids.shape
262
+ x = self.embed_tokens(input_ids)
263
+
264
+ if attention_mask is None:
265
+ causal_mask = torch.triu(
266
+ torch.full((seqlen, seqlen), float("-inf"), device=input_ids.device),
267
+ diagonal=1,
268
+ ).unsqueeze(0).unsqueeze(0)
269
+ else:
270
+ causal_mask = attention_mask
271
+
272
+ for layer in self.layers:
273
+ x = layer(x, self.rope_cos, self.rope_sin, causal_mask)
274
+
275
+ h = self.norm(x)
276
+ logits = self.lm_head(h)
277
+
278
+ mtp_logits = None
279
+ if return_mtp and self.mtp_proj is not None and seqlen > 1:
280
+ next_emb = self.embed_tokens(input_ids[:, 1:])
281
+ h_prev = h[:, :-1]
282
+ cat_h = torch.cat([h_prev, next_emb], dim=-1)
283
+ h_mtp = self.mtp_norm(self.mtp_proj(cat_h))
284
+ mtp_logits = self.mtp_head(h_mtp)
285
+
286
+ loss = None
287
+ if labels is not None:
288
+ shift_logits = logits[..., :-1, :].contiguous()
289
+ shift_labels = labels[..., 1:].contiguous()
290
+ loss_fct = nn.CrossEntropyLoss()
291
+ loss = loss_fct(shift_logits.view(-1, self.config.vocab_size), shift_labels.view(-1))
292
+
293
+ if mtp_logits is not None and seqlen > 2:
294
+ shift_mtp_logits = mtp_logits[..., :-1, :].contiguous()
295
+ shift_mtp_labels = labels[..., 2:].contiguous()
296
+ loss_mtp = loss_fct(shift_mtp_logits.view(-1, self.config.vocab_size), shift_mtp_labels.view(-1))
297
+ loss = loss + (self.config.mtp_loss_weight * loss_mtp)
298
+
299
+ return CausalLMOutputWithPast(
300
+ loss=loss,
301
+ logits=logits,
302
+ )