DZER-Studios commited on
Commit
85bfe69
·
verified ·
1 Parent(s): 9b26d43

Delete model.py

Browse files
Files changed (1) hide show
  1. model.py +0 -350
model.py DELETED
@@ -1,350 +0,0 @@
1
- # Copyright 2026 Dmitry
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
-
16
- import torch
17
- import torch.nn as nn
18
- import torch.nn.functional as F
19
- import math
20
- import torch.utils.checkpoint as cp
21
-
22
- class GPTConfig:
23
- def __init__(self, vocab_size=40960, embed_dim=1024, n_layers=16, n_heads=16,
24
- n_kv_heads=None, intermediate_size=2560, max_seq_len=2048,
25
- dropout=0.0, use_lora=False, num_experts=4, top_k=2, tie_word_embeddings=False, window_size=1024, anchor_size=64):
26
- self.vocab_size = vocab_size
27
- self.embed_dim = embed_dim
28
- self.n_layers = n_layers
29
- self.n_heads = n_heads
30
- self.n_kv_heads = n_kv_heads if n_kv_heads is not None else n_heads
31
- self.intermediate_size = intermediate_size
32
- self.max_seq_len = max_seq_len
33
- self.dropout = dropout
34
- self.use_lora = use_lora
35
- self.num_experts = num_experts
36
- self.top_k = top_k
37
- self.tie_word_embeddings = tie_word_embeddings
38
- self.window_size = window_size
39
- self.anchor_size = anchor_size
40
-
41
- def precompute_freqs_cis(dim: int, end: int, anchor_size: int = 64, theta: float = 10000.0):
42
- freqs = 1.0 / (theta ** (torch.arange(0, dim, 2)[: (dim // 2)].float() / dim))
43
- t = torch.arange(end, device=freqs.device)
44
- freqs = torch.outer(t, freqs).float()
45
- return torch.polar(torch.ones_like(freqs), freqs)
46
-
47
- def apply_rotary_emb(xq, xk, freqs_cis):
48
- xq_ = torch.view_as_complex(xq.float().reshape(*xq.shape[:-1], -1, 2))
49
- xk_ = torch.view_as_complex(xk.float().reshape(*xk.shape[:-1], -1, 2))
50
- freqs_cis = freqs_cis.view(1, freqs_cis.shape[0], 1, freqs_cis.shape[1])
51
- xq_out = torch.view_as_real(xq_ * freqs_cis).flatten(3)
52
- xk_out = torch.view_as_real(xk_ * freqs_cis).flatten(3)
53
- return xq_out.type_as(xq), xk_out.type_as(xk)
54
-
55
- class VexNorm(nn.Module):
56
- def __init__(self, dim: int, eps: float = 1e-6):
57
- super().__init__()
58
- self.eps = eps
59
- self.weight = nn.Parameter(torch.ones(dim))
60
-
61
- def forward(self, x):
62
- abs_mean = x.to(torch.float32).abs().mean(dim=-1, keepdim=True).to(x.dtype)
63
- norm_x = x / (abs_mean + self.eps)
64
- return norm_x.type_as(x) * self.weight.type_as(x)
65
-
66
- class DoRALinear(nn.Module):
67
- def __init__(self, linear_layer, rank=32, alpha=32, dropout=0.05):
68
- super().__init__()
69
- self.linear = linear_layer
70
- in_features = linear_layer.weight.shape[1]
71
- out_features = linear_layer.weight.shape[0]
72
- self.lora_A = nn.Parameter(torch.zeros(in_features, rank))
73
- self.lora_B = nn.Parameter(torch.zeros(rank, out_features))
74
- self.scaling = alpha / rank
75
- self.dropout = nn.Dropout(dropout)
76
- nn.init.normal_(self.lora_A, std=1 / rank)
77
- nn.init.zeros_(self.lora_B)
78
- self.lora_m = nn.Parameter(self.linear.weight.data.norm(p=2, dim=1, keepdim=True))
79
-
80
- def forward(self, x):
81
- W = self.linear.weight
82
- lora_weight = (self.lora_A @ self.lora_B).T * self.scaling
83
- W_modified = W + lora_weight
84
- norm = W_modified.to(torch.float32).norm(p=2, dim=1, keepdim=True).to(W_modified.dtype)
85
- W_dora = self.lora_m * (W_modified / norm)
86
- return F.linear(self.dropout(x), W_dora, self.linear.bias)
87
-
88
- class DiffCausalSelfAttention(nn.Module):
89
- def __init__(self, config):
90
- super().__init__()
91
- self.n_heads = config.n_heads
92
- self.n_embd = config.embed_dim
93
- self.head_dim = self.n_embd // self.n_heads
94
-
95
- self.window_size = getattr(config, 'window_size', 512)
96
- self.anchor_size = getattr(config, 'anchor_size', 64)
97
-
98
- self.c_attn = nn.Linear(self.n_embd, 5 * self.n_embd, bias=False)
99
- self.c_proj = nn.Linear(self.n_embd, self.n_embd, bias=False)
100
- self.lambda_noise = nn.Parameter(torch.zeros(self.n_heads, 1, 1))
101
-
102
- self.diff_norm = VexNorm(self.n_embd)
103
-
104
- def forward(self, x, freqs_cis=None, use_cache=False, past_kv=None):
105
- B, T, C = x.size()
106
-
107
- qkv = self.c_attn(x)
108
- q1, q2, k1, k2, v = qkv.split(self.n_embd, dim=2)
109
-
110
- q1 = q1.view(B, T, self.n_heads, self.head_dim)
111
- q2 = q2.view(B, T, self.n_heads, self.head_dim)
112
- k1 = k1.view(B, T, self.n_heads, self.head_dim)
113
- k2 = k2.view(B, T, self.n_heads, self.head_dim)
114
- v = v.view(B, T, self.n_heads, self.head_dim)
115
-
116
- if freqs_cis is not None:
117
- q1, k1 = apply_rotary_emb(q1, k1, freqs_cis)
118
- q2, k2 = apply_rotary_emb(q2, k2, freqs_cis)
119
-
120
- q1, q2 = q1.transpose(1, 2), q2.transpose(1, 2)
121
- k1, k2 = k1.transpose(1, 2), k2.transpose(1, 2)
122
- v = v.transpose(1, 2)
123
-
124
- if use_cache:
125
- if past_kv is not None:
126
- past_k1, past_k2, past_v = past_kv
127
- k1 = torch.cat([past_k1, k1], dim=2)
128
- k2 = torch.cat([past_k2, k2], dim=2)
129
- v = torch.cat([past_v, v], dim=2)
130
- past_kv = (k1, k2, v)
131
- else:
132
- past_kv = None
133
-
134
- seq_len_kv = k1.size(2)
135
-
136
- att1 = (q1 @ k1.transpose(-2, -1)) * (1.0 / math.sqrt(self.head_dim))
137
- att2 = (q2 @ k2.transpose(-2, -1)) * (1.0 / math.sqrt(self.head_dim))
138
-
139
- if seq_len_kv > 1:
140
- q_pos = torch.arange(seq_len_kv - T, seq_len_kv, device=x.device).unsqueeze(1)
141
- k_pos = torch.arange(seq_len_kv, device=x.device).unsqueeze(0)
142
-
143
- window_mask = (k_pos >= q_pos - self.window_size) | (k_pos < self.anchor_size)
144
-
145
- causal_mask = torch.triu(torch.full((T, seq_len_kv), float("-inf"), device=x.device), diagonal=seq_len_kv - T + 1)
146
-
147
- final_mask = causal_mask.masked_fill(~window_mask, float("-inf"))
148
-
149
- att1 = att1 + final_mask
150
- att2 = att2 + final_mask
151
-
152
- att1 = F.softmax(att1, dim=-1)
153
- att2 = F.softmax(att2, dim=-1)
154
-
155
- noise_canceller = torch.exp(self.lambda_noise)
156
- diff_att = att1 - (noise_canceller * att2)
157
-
158
- y = diff_att @ v
159
- y = y.transpose(1, 2).contiguous().view(B, T, C)
160
-
161
- y = self.diff_norm(y)
162
- return self.c_proj(y), past_kv
163
-
164
- class SwiGLU(nn.Module):
165
- def __init__(self, config):
166
- super().__init__()
167
- self.w1 = nn.Linear(config.embed_dim, config.intermediate_size, bias=False)
168
- self.w2 = nn.Linear(config.embed_dim, config.intermediate_size, bias=False)
169
- self.w3 = nn.Linear(config.intermediate_size, config.embed_dim, bias=False)
170
- self.w3.GPT_SCALE_INIT = True
171
-
172
- if config.use_lora:
173
- self.w1 = DoRALinear(self.w1)
174
- self.w2 = DoRALinear(self.w2)
175
- self.w3 = DoRALinear(self.w3)
176
-
177
- def forward(self, x):
178
- return self.w3(F.silu(self.w1(x)) * self.w2(x))
179
-
180
- class VexionMoE(nn.Module):
181
- def __init__(self, config):
182
- super().__init__()
183
- self.num_experts = config.num_experts
184
- self.top_k = getattr(config, 'top_k', 2)
185
-
186
- self.experts = nn.ModuleList([SwiGLU(config) for _ in range(self.num_experts)])
187
- self.router = nn.Linear(config.embed_dim, self.num_experts, bias=False)
188
- self.register_buffer('expert_usage_tracker', torch.zeros(self.num_experts))
189
-
190
- def forward(self, x):
191
- B, T, C = x.shape
192
- x_flat = x.view(-1, C)
193
-
194
- router_logits = self.router(x_flat)
195
- routing_weights = F.softmax(router_logits, dim=-1)
196
-
197
- if self.training:
198
- with torch.no_grad():
199
- batch_usage = routing_weights.sum(dim=0)
200
- self.expert_usage_tracker += batch_usage
201
-
202
- topk_weights, selected_experts = torch.topk(routing_weights, self.top_k, dim=-1)
203
- topk_weights = topk_weights / topk_weights.sum(dim=-1, keepdim=True)
204
-
205
- tokens_per_expert = torch.bincount(selected_experts.flatten(), minlength=self.num_experts)
206
- route_fraction = tokens_per_expert.float() / selected_experts.numel()
207
- mean_probs = routing_weights.mean(dim=0)
208
- aux_loss = self.num_experts * torch.sum(mean_probs * route_fraction)
209
-
210
- final_output = torch.zeros_like(x_flat)
211
-
212
- for i, expert in enumerate(self.experts):
213
- expert_mask = (selected_experts == i).any(dim=-1)
214
- if not expert_mask.any():
215
- continue
216
-
217
- expert_tokens = x_flat[expert_mask]
218
- expert_out = expert(expert_tokens)
219
-
220
- idx_in_topk = (selected_experts[expert_mask] == i).nonzero(as_tuple=True)[1]
221
- token_weights = topk_weights[expert_mask, idx_in_topk].unsqueeze(-1)
222
-
223
- temp_output = torch.zeros_like(x_flat)
224
- temp_output[expert_mask] = expert_out * token_weights
225
- final_output = final_output + temp_output
226
-
227
- return final_output.view(B, T, C), aux_loss
228
-
229
- @torch.no_grad()
230
- def mutate_dead_experts(self, optimizer=None, threshold_ratio=0.01, noise_factor=0.05):
231
- total_tokens = self.expert_usage_tracker.sum().item()
232
- if total_tokens == 0: return 0
233
-
234
- best_expert_idx = torch.argmax(self.expert_usage_tracker).item()
235
- best_expert = self.experts[best_expert_idx]
236
- mutated_count = 0
237
-
238
- for i in range(self.num_experts):
239
- usage_ratio = self.expert_usage_tracker[i].item() / total_tokens
240
- if usage_ratio < threshold_ratio and i != best_expert_idx:
241
- dead_expert = self.experts[i]
242
- for dead_param, best_param in zip(dead_expert.parameters(), best_expert.parameters()):
243
- dead_param.data.copy_(best_param.data)
244
- if optimizer is not None and dead_param in optimizer.state:
245
- del optimizer.state[dead_param]
246
- noise = torch.randn_like(dead_param.data)
247
- scaled_noise = noise * noise_factor * best_param.data.std()
248
- dead_param.data.add_(scaled_noise)
249
- self.router.weight.data[i].zero_()
250
- mutated_count += 1
251
-
252
- self.expert_usage_tracker.zero_()
253
- return mutated_count
254
-
255
- class Block(nn.Module):
256
- def __init__(self, config):
257
- super().__init__()
258
- self.ln_1 = VexNorm(config.embed_dim)
259
- self.attn = DiffCausalSelfAttention(config)
260
- self.ln_2 = VexNorm(config.embed_dim)
261
- self.mlp = VexionMoE(config)
262
-
263
- def forward(self, x, freqs_cis, use_cache=False, past_kv=None):
264
- attn_out, past_kv_out = self.attn(self.ln_1(x), freqs_cis, use_cache, past_kv)
265
- x = x + attn_out
266
-
267
- mlp_out, aux_loss = self.mlp(self.ln_2(x))
268
- x = x + mlp_out
269
-
270
- return x, aux_loss, past_kv_out
271
-
272
- class GPT(nn.Module):
273
- def __init__(self, config):
274
- super().__init__()
275
- self.config = config
276
-
277
- self.transformer = nn.ModuleDict(dict(
278
- wte = nn.Embedding(config.vocab_size, config.embed_dim),
279
- drop = nn.Dropout(config.dropout),
280
- h = nn.ModuleList([Block(config) for _ in range(config.n_layers)]),
281
- ln_f = VexNorm(config.embed_dim),
282
- ))
283
- self.lm_head = nn.Linear(config.embed_dim, config.vocab_size, bias=False)
284
-
285
- if config.tie_word_embeddings:
286
- self.lm_head.weight = self.transformer.wte.weight
287
-
288
- self.register_buffer(
289
- "freqs_cis",
290
- precompute_freqs_cis(
291
- config.embed_dim // config.n_heads,
292
- config.max_seq_len * 2,
293
- anchor_size=config.anchor_size
294
- ),
295
- persistent=False
296
- )
297
- self.apply(self._init_weights)
298
-
299
- def _init_weights(self, module):
300
- if isinstance(module, nn.Linear):
301
- std = 0.02
302
- if hasattr(module, 'GPT_SCALE_INIT') and module.GPT_SCALE_INIT:
303
- std *= (2 * self.config.n_layers) ** -0.5
304
- torch.nn.init.normal_(module.weight, mean=0.0, std=std)
305
- if module.bias is not None:
306
- torch.nn.init.zeros_(module.bias)
307
- elif isinstance(module, nn.Embedding):
308
- torch.nn.init.normal_(module.weight, mean=0.0, std=0.02)
309
-
310
- def forward(self, idx, targets=None, use_cache=False, past_key_values=None):
311
- b, t = idx.size()
312
-
313
- start_pos = past_key_values[0][0].shape[2] if past_key_values is not None else 0
314
- freqs_cis = self.freqs_cis[start_pos : start_pos + t]
315
-
316
- tok_emb = self.transformer.wte(idx)
317
- x = self.transformer.drop(tok_emb)
318
-
319
- if self.training and not x.requires_grad:
320
- x.requires_grad_(True)
321
-
322
- total_aux_loss = 0.0
323
- new_past_key_values = () if use_cache else None
324
-
325
- for i, block in enumerate(self.transformer.h):
326
- past_kv = past_key_values[i] if past_key_values is not None else None
327
-
328
- if self.training:
329
- x, aux_loss, _ = cp.checkpoint(block, x, freqs_cis, False, None, use_reentrant=False)
330
- else:
331
- x, aux_loss, past_kv_out = block(x, freqs_cis, use_cache, past_kv)
332
- if use_cache:
333
- new_past_key_values += (past_kv_out,)
334
-
335
- total_aux_loss += aux_loss
336
-
337
- x = self.transformer.ln_f(x)
338
-
339
- if targets is not None:
340
- logits = self.lm_head(x)
341
- loss = F.cross_entropy(logits.view(-1, logits.size(-1)).float(), targets.view(-1))
342
- if self.training:
343
- loss = loss + 0.01 * total_aux_loss
344
- else:
345
- logits = self.lm_head(x[:, [-1], :])
346
- loss = None
347
-
348
- if use_cache:
349
- return logits, loss, new_past_key_values
350
- return logits, loss