Johnblick187 commited on
Commit
f20d2af
·
verified ·
1 Parent(s): 1c5a4f4

Update modeling_mythos.py

Browse files
Files changed (1) hide show
  1. modeling_mythos.py +66 -72
modeling_mythos.py CHANGED
@@ -9,7 +9,7 @@ import torch.nn as nn
9
  import torch.nn.functional as F
10
  from dataclasses import dataclass
11
 
12
- from mamba_ssm.modules.mamba3 import Mamba3
13
  from gdn2 import GatedDeltaNet2
14
 
15
 
@@ -28,7 +28,6 @@ class MythosConfig:
28
  coda_attn_layers: int = 2
29
  max_loop_iters: int = 32
30
  act_threshold: float = 0.99
31
- hyper_n_streams: int = 4
32
  audio_vocab: int = 1024
33
  audio_n_codebooks: int = 8
34
  image_vocab: int = 8192
@@ -36,6 +35,14 @@ class MythosConfig:
36
  vision_encoder_dim: int = 1152
37
  rope_theta: float = 500000.0
38
  lora_rank: int = 64
 
 
 
 
 
 
 
 
39
  ffn_mult: float = 1.333
40
  tie_embeddings: bool = True
41
  mamba_headdim: int = 64
@@ -64,10 +71,57 @@ class FFN(nn.Module):
64
  return self.down(F.silu(self.gate(x)) * self.up(x))
65
 
66
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
  def make_ffn(cfg):
68
  return FFN(cfg.dim, int(cfg.dim * cfg.ffn_mult))
69
 
70
 
 
 
 
 
 
 
 
 
 
 
 
71
  def precompute_freqs_cis(head_dim, max_len, theta):
72
  inv = 1.0 / (theta ** (torch.arange(0, head_dim, 2).float() / head_dim))
73
  t = torch.arange(max_len).float()
@@ -162,7 +216,7 @@ class MLADenseBlock(nn.Module):
162
  self.norm1 = RMSNorm(cfg.dim)
163
  self.attn = MLAttention(cfg)
164
  self.norm2 = RMSNorm(cfg.dim)
165
- self.ffn = make_ffn(cfg)
166
 
167
  def forward(self, x, freqs_cis):
168
  x = x + self.attn(self.norm1(x), freqs_cis)
@@ -175,11 +229,11 @@ class Mamba3Block(nn.Module):
175
  super().__init__()
176
  self.norm1 = RMSNorm(cfg.dim)
177
  self.mixer = Mamba3(
178
- d_model=cfg.dim,
179
- d_state=cfg.mamba_d_state,
180
- headdim=cfg.mamba_headdim,
181
  expand=1,
182
- ngroups=1,
183
  is_mimo=False,
184
  chunk_size=64,
185
  )
@@ -187,7 +241,7 @@ class Mamba3Block(nn.Module):
187
  self.ffn = make_ffn(cfg)
188
 
189
  def forward(self, x):
190
- x = x + self.mixer(self.norm1(x))
191
  x = x + self.ffn(self.norm2(x))
192
  return x
193
 
@@ -211,40 +265,6 @@ class GDN2Block(nn.Module):
211
  return x
212
 
213
 
214
- class HyperConnections(nn.Module):
215
- def __init__(self, dim, n_streams):
216
- super().__init__()
217
- self.n = n_streams
218
- self.static_beta = nn.Parameter(torch.ones(n_streams) / n_streams)
219
- self.static_alpha = nn.Parameter(torch.eye(n_streams))
220
- self.static_alpha0 = nn.Parameter(torch.ones(n_streams) / n_streams)
221
- self.norm = RMSNorm(dim)
222
- self.dyn_beta = nn.Linear(dim, 1, bias=False)
223
- self.dyn_alpha = nn.Linear(dim, n_streams, bias=False)
224
- self.dyn_alpha0 = nn.Linear(dim, 1, bias=False)
225
- nn.init.zeros_(self.dyn_beta.weight)
226
- nn.init.zeros_(self.dyn_alpha.weight)
227
- nn.init.zeros_(self.dyn_alpha0.weight)
228
-
229
- def expand(self, x):
230
- return x.unsqueeze(-2).expand(*x.shape[:-1], self.n, x.shape[-1]).contiguous()
231
-
232
- def width(self, streams):
233
- ns = self.norm(streams)
234
- beta = self.static_beta + torch.tanh(self.dyn_beta(ns)).squeeze(-1)
235
- return (beta.unsqueeze(-1) * streams).sum(dim=-2)
236
-
237
- def depth(self, streams, block_out):
238
- ns = self.norm(streams)
239
- alpha = self.static_alpha + torch.tanh(self.dyn_alpha(ns))
240
- alpha0 = self.static_alpha0 + torch.tanh(self.dyn_alpha0(ns)).squeeze(-1)
241
- mixed = torch.einsum("btij,btjd->btid", alpha, streams)
242
- return mixed + alpha0.unsqueeze(-1) * block_out.unsqueeze(-2)
243
-
244
- def collapse(self, streams):
245
- return streams.sum(dim=-2)
246
-
247
-
248
  class LTIInjection(nn.Module):
249
  def __init__(self, dim):
250
  super().__init__()
@@ -295,24 +315,11 @@ class RecurrentDenseBlock(nn.Module):
295
  super().__init__()
296
  self.cfg = cfg
297
 
298
- # Pattern: (M3 -> GDN2 -> MLA) x 4
299
  self.m3_0 = Mamba3Block(cfg)
300
  self.gdn_0 = GDN2Block(cfg)
301
  self.mla_0 = MLADenseBlock(cfg)
302
 
303
- self.m3_1 = Mamba3Block(cfg)
304
- self.gdn_1 = GDN2Block(cfg)
305
- self.mla_1 = MLADenseBlock(cfg)
306
-
307
- self.m3_2 = Mamba3Block(cfg)
308
- self.gdn_2 = GDN2Block(cfg)
309
- self.mla_2 = MLADenseBlock(cfg)
310
-
311
- self.m3_3 = Mamba3Block(cfg)
312
- self.gdn_3 = GDN2Block(cfg)
313
- self.mla_3 = MLADenseBlock(cfg)
314
-
315
- self.hyper = HyperConnections(cfg.dim, cfg.hyper_n_streams)
316
  self.injection = LTIInjection(cfg.dim)
317
  self.act = ACTHalting(cfg.dim)
318
  self.lora = LoRADepthAdapter(cfg.dim, cfg.lora_rank, cfg.max_loop_iters)
@@ -324,38 +331,25 @@ class RecurrentDenseBlock(nn.Module):
324
  x = self.gdn_0(x)
325
  x = self.mla_0(x, freqs_cis)
326
 
327
- x = self.m3_1(x)
328
- x = self.gdn_1(x)
329
- x = self.mla_1(x, freqs_cis)
330
-
331
- x = self.m3_2(x)
332
- x = self.gdn_2(x)
333
- x = self.mla_2(x, freqs_cis)
334
-
335
- x = self.m3_3(x)
336
- x = self.gdn_3(x)
337
- x = self.mla_3(x, freqs_cis)
338
-
339
  return x + self.lora(x, t)
340
 
341
  def forward(self, h, e, freqs_cis, n_loops=None):
342
  n_loops = n_loops or self.cfg.max_loop_iters
343
  B, T, D = h.shape
344
 
345
- streams = self.hyper.expand(h)
346
  halted = torch.zeros(B, T, device=h.device, dtype=torch.bool)
347
  cumulative_p = torch.zeros(B, T, device=h.device, dtype=torch.float32)
348
  h_out = torch.zeros(B, T, D, device=h.device, dtype=torch.float32)
349
 
350
  for t in range(n_loops):
351
- x = self.hyper.width(streams)
352
  x = self.loop_emb(x, t)
353
  x = self.injection(x, e, torch.zeros_like(x))
354
  x = self.norm(x)
355
  block_out = self.inner(x, freqs_cis, t)
356
- streams = self.hyper.depth(streams, block_out)
357
 
358
- h_cur = self.hyper.collapse(streams)
359
  p = self.act(h_cur)
360
 
361
  still = (~halted).float()
 
9
  import torch.nn.functional as F
10
  from dataclasses import dataclass
11
 
12
+ from fla.layers.mamba3 import Mamba3
13
  from gdn2 import GatedDeltaNet2
14
 
15
 
 
28
  coda_attn_layers: int = 2
29
  max_loop_iters: int = 32
30
  act_threshold: float = 0.99
 
31
  audio_vocab: int = 1024
32
  audio_n_codebooks: int = 8
33
  image_vocab: int = 8192
 
35
  vision_encoder_dim: int = 1152
36
  rope_theta: float = 500000.0
37
  lora_rank: int = 64
38
+
39
+ # MoE upscale at the mla_exit FFN site only. Disabled by default --
40
+ # dense backbone trains with plain FFN everywhere. Flip moe_enabled
41
+ # to True to swap in MoEFFN at that one site.
42
+ moe_enabled: bool = False
43
+ moe_n_experts: int = 8
44
+ moe_expert_dim: int = 1024
45
+ moe_top_k: int = 2
46
  ffn_mult: float = 1.333
47
  tie_embeddings: bool = True
48
  mamba_headdim: int = 64
 
71
  return self.down(F.silu(self.gate(x)) * self.up(x))
72
 
73
 
74
+ class MoEFFN(nn.Module):
75
+ """MoE upscale for the mla_exit FFN site. Disabled by default
76
+ (cfg.moe_enabled=False) -- the dense backbone trains with plain FFN.
77
+ When enabled, swaps in N experts (each a standard SwiGLU FFN at
78
+ expert_dim) with top-k routing.
79
+ """
80
+ def __init__(self, cfg):
81
+ super().__init__()
82
+ self.n_experts = cfg.moe_n_experts
83
+ self.top_k = cfg.moe_top_k
84
+ self.router = nn.Linear(cfg.dim, cfg.moe_n_experts, bias=False)
85
+ self.experts = nn.ModuleList([
86
+ FFN(cfg.dim, cfg.moe_expert_dim) for _ in range(cfg.moe_n_experts)
87
+ ])
88
+
89
+ def forward(self, x):
90
+ B, T, D = x.shape
91
+ x_flat = x.view(B * T, D)
92
+
93
+ router_logits = self.router(x_flat)
94
+ router_weights = F.softmax(router_logits, dim=-1, dtype=torch.float32)
95
+ top_weights, top_idx = router_weights.topk(self.top_k, dim=-1)
96
+ top_weights = (top_weights / top_weights.sum(dim=-1, keepdim=True)).to(x.dtype)
97
+
98
+ out = torch.zeros_like(x_flat)
99
+ for k in range(self.top_k):
100
+ idx = top_idx[:, k]
101
+ w = top_weights[:, k].unsqueeze(-1)
102
+ for e in range(self.n_experts):
103
+ mask = idx == e
104
+ if mask.any():
105
+ out[mask] += w[mask] * self.experts[e](x_flat[mask])
106
+
107
+ return out.view(B, T, D)
108
+
109
+
110
  def make_ffn(cfg):
111
  return FFN(cfg.dim, int(cfg.dim * cfg.ffn_mult))
112
 
113
 
114
+ def make_ffn_mla(cfg):
115
+ """FFN factory specifically for the mla_exit site -- the one place
116
+ the original design called out for MoE upscaling. Everywhere else
117
+ (M3/GDN2 blocks) always uses plain make_ffn(), regardless of
118
+ cfg.moe_enabled.
119
+ """
120
+ if cfg.moe_enabled:
121
+ return MoEFFN(cfg)
122
+ return make_ffn(cfg)
123
+
124
+
125
  def precompute_freqs_cis(head_dim, max_len, theta):
126
  inv = 1.0 / (theta ** (torch.arange(0, head_dim, 2).float() / head_dim))
127
  t = torch.arange(max_len).float()
 
216
  self.norm1 = RMSNorm(cfg.dim)
217
  self.attn = MLAttention(cfg)
218
  self.norm2 = RMSNorm(cfg.dim)
219
+ self.ffn = make_ffn_mla(cfg)
220
 
221
  def forward(self, x, freqs_cis):
222
  x = x + self.attn(self.norm1(x), freqs_cis)
 
229
  super().__init__()
230
  self.norm1 = RMSNorm(cfg.dim)
231
  self.mixer = Mamba3(
232
+ hidden_size=cfg.dim,
233
+ state_size=cfg.mamba_d_state,
234
+ head_dim=cfg.mamba_headdim,
235
  expand=1,
236
+ n_groups=1,
237
  is_mimo=False,
238
  chunk_size=64,
239
  )
 
241
  self.ffn = make_ffn(cfg)
242
 
243
  def forward(self, x):
244
+ x = x + self.mixer(self.norm1(x))[0]
245
  x = x + self.ffn(self.norm2(x))
246
  return x
247
 
 
265
  return x
266
 
267
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
268
  class LTIInjection(nn.Module):
269
  def __init__(self, dim):
270
  super().__init__()
 
315
  super().__init__()
316
  self.cfg = cfg
317
 
318
+ # Pattern: (M3 -> GDN2 -> MLA) x 1, looped max_loop_iters times via forward()
319
  self.m3_0 = Mamba3Block(cfg)
320
  self.gdn_0 = GDN2Block(cfg)
321
  self.mla_0 = MLADenseBlock(cfg)
322
 
 
 
 
 
 
 
 
 
 
 
 
 
 
323
  self.injection = LTIInjection(cfg.dim)
324
  self.act = ACTHalting(cfg.dim)
325
  self.lora = LoRADepthAdapter(cfg.dim, cfg.lora_rank, cfg.max_loop_iters)
 
331
  x = self.gdn_0(x)
332
  x = self.mla_0(x, freqs_cis)
333
 
 
 
 
 
 
 
 
 
 
 
 
 
334
  return x + self.lora(x, t)
335
 
336
  def forward(self, h, e, freqs_cis, n_loops=None):
337
  n_loops = n_loops or self.cfg.max_loop_iters
338
  B, T, D = h.shape
339
 
340
+ x = h
341
  halted = torch.zeros(B, T, device=h.device, dtype=torch.bool)
342
  cumulative_p = torch.zeros(B, T, device=h.device, dtype=torch.float32)
343
  h_out = torch.zeros(B, T, D, device=h.device, dtype=torch.float32)
344
 
345
  for t in range(n_loops):
 
346
  x = self.loop_emb(x, t)
347
  x = self.injection(x, e, torch.zeros_like(x))
348
  x = self.norm(x)
349
  block_out = self.inner(x, freqs_cis, t)
350
+ x = x + block_out
351
 
352
+ h_cur = x
353
  p = self.act(h_cur)
354
 
355
  still = (~halted).float()