| import os |
| import sys |
| import math |
| import torch |
| import torch.nn as nn |
| import torch.nn.functional as F |
| import torch.utils.checkpoint as cp |
| from dataclasses import dataclass |
|
|
| @dataclass |
| class ModelConfig: |
| vocab_size: int = 50272 |
| d_model: int = 768 |
| n_iterations: int = 16 |
| n_heads: int = 12 |
| n_kv_heads: int = 4 |
| d_ff: int = 2048 |
| max_seq_len: int = 512 |
| bias: bool = False |
|
|
| class RMSNorm(nn.Module): |
| """Llama-style Root Mean Square Normalization with optional step-conditioned adaptive scale (AdaRMSNorm). |
| Includes FP32 upcasting to prevent FP16 numerical underflow/overflow NaN corruption. |
| """ |
| def __init__(self, dim: int, n_iterations: int = None, eps: float = 1e-5): |
| super().__init__() |
| self.eps = eps |
| self.weight = nn.Parameter(torch.ones(dim)) |
| |
| |
| if n_iterations is not None: |
| self.step_scales = nn.Parameter(torch.zeros(n_iterations, dim)) |
| else: |
| self.step_scales = None |
|
|
| def forward(self, x, r_idx: int = None): |
| x_fp32 = x.to(torch.float32) |
| variance = x_fp32.pow(2).mean(-1, keepdim=True) |
| normed = x_fp32 * torch.rsqrt(variance + self.eps) |
| normed = normed.to(x.dtype) |
| |
| if self.step_scales is not None and r_idx is not None: |
| idx = r_idx % self.step_scales.shape[0] |
| scale = self.weight + self.step_scales[idx] |
| return normed * scale |
| else: |
| return normed * self.weight |
|
|
| class RoPE(nn.Module): |
| """Rotary Positional Embeddings (RoPE) applied to Query and Key states. |
| Includes a Dynamic Frequency Extension safeguard to support sequence lengths beyond max_seq_len. |
| """ |
| def __init__(self, dim: int, max_seq_len: int = 512, theta: float = 10000.0): |
| super().__init__() |
| self.dim = dim |
| self.max_seq_len = max_seq_len |
| self.theta = theta |
| |
| inv_freq = 1.0 / (theta ** (torch.arange(0, dim, 2).float() / dim)) |
| self.register_buffer("inv_freq", inv_freq, persistent=False) |
| |
| t = torch.arange(max_seq_len, dtype=torch.float32) |
| freqs = torch.outer(t, self.inv_freq) |
| emb = torch.cat((freqs, freqs), dim=-1) |
| self.register_buffer("cos_cached", emb.cos(), persistent=False) |
| self.register_buffer("sin_cached", emb.sin(), persistent=False) |
|
|
| def _rotate_half(self, x): |
| half_dim = self.dim // 2 |
| x1 = x[..., :half_dim] |
| x2 = x[..., half_dim:] |
| return torch.cat((-x2, x1), dim=-1) |
|
|
| def forward(self, x, seq_len: int, start_pos: int = 0): |
| end_pos = start_pos + seq_len |
| |
| if end_pos > self.max_seq_len: |
| t = torch.arange(end_pos, dtype=torch.float32, device=x.device) |
| freqs = torch.outer(t, self.inv_freq) |
| emb = torch.cat((freqs, freqs), dim=-1) |
| cos = emb.cos()[start_pos:end_pos, :].unsqueeze(0).unsqueeze(2) |
| sin = emb.sin()[start_pos:end_pos, :].unsqueeze(0).unsqueeze(2) |
| else: |
| cos = self.cos_cached[start_pos:end_pos, :].unsqueeze(0).unsqueeze(2) |
| sin = self.sin_cached[start_pos:end_pos, :].unsqueeze(0).unsqueeze(2) |
| |
| cos = cos.to(device=x.device, dtype=x.dtype) |
| sin = sin.to(device=x.device, dtype=x.dtype) |
| |
| return (x * cos) + (self._rotate_half(x) * sin) |
|
|
| class ModulatedLinear(nn.Module): |
| """A linear layer with frozen weights augmented with SVD-initialized low-rank bases |
| which are dynamically scaled by an input-conditioned modulation vector (Ouroboros Weight Modulation). |
| """ |
| def __init__(self, in_features: int, out_features: int, rank_ctrl: int = 64, bias: bool = False): |
| super().__init__() |
| self.in_features = in_features |
| self.out_features = out_features |
| self.rank_ctrl = rank_ctrl |
| |
| |
| self.base_layer = nn.Linear(in_features, out_features, bias=bias) |
| self.base_layer.weight.requires_grad = False |
| if self.base_layer.bias is not None: |
| self.base_layer.bias.requires_grad = False |
| |
| |
| self.A = nn.Parameter(torch.zeros(out_features, rank_ctrl)) |
| self.B = nn.Parameter(torch.zeros(in_features, rank_ctrl)) |
| |
| self.svd_initialized = False |
|
|
| def initialize_svd(self): |
| if self.svd_initialized: |
| return |
| with torch.no_grad(): |
| W_base = self.base_layer.weight.float() |
| U, S, Vh = torch.linalg.svd(W_base, full_matrices=False) |
| rank = min(self.rank_ctrl, S.numel()) |
| self.A.copy_((U[:, :rank] * torch.sqrt(S[:rank])).to(self.A.dtype)) |
| self.B.copy_((Vh[:rank, :].t() * torch.sqrt(S[:rank])).to(self.B.dtype)) |
| self.svd_initialized = True |
|
|
| def forward(self, x, mod_vector=None): |
| out_base = self.base_layer(x) |
| if mod_vector is None: |
| return out_base |
| |
| |
| |
| |
| |
| hb = torch.matmul(x, self.B) |
| if mod_vector.dim() == hb.dim() - 1: |
| hb_scaled = hb * mod_vector.unsqueeze(-2) |
| elif mod_vector.dim() == hb.dim(): |
| hb_scaled = hb * mod_vector |
| else: |
| hb_scaled = hb * mod_vector |
| out_extra = torch.matmul(hb_scaled, self.A.t()) |
| |
| return out_base + out_extra |
|
|
| class ControllerHypernetwork(nn.Module): |
| """Generates dynamic step-dependent weight modulation diagonal scalars from the mean-pooled state.""" |
| def __init__(self, d_model: int, num_modulated_projs: int = 6, rank_ctrl: int = 64): |
| super().__init__() |
| self.d_model = d_model |
| self.num_modulated_projs = num_modulated_projs |
| self.rank_ctrl = rank_ctrl |
| |
| self.fc1 = nn.Linear(d_model, 256, bias=False) |
| self.fc2 = nn.Linear(256, num_modulated_projs * rank_ctrl, bias=False) |
| |
| nn.init.normal_(self.fc1.weight, std=0.01) |
| nn.init.normal_(self.fc2.weight, std=0.01) |
|
|
| def forward(self, h, step_emb): |
| if h.dim() == 2: |
| inp = h + step_emb.unsqueeze(0) |
| out = self.fc2(F.silu(self.fc1(inp))) |
| mod = 1.0 + out.view(-1, self.num_modulated_projs, self.rank_ctrl) |
| else: |
| inp = h + step_emb.view(1, 1, -1) |
| out = self.fc2(F.silu(self.fc1(inp))) |
| B, T, _ = h.shape |
| mod = 1.0 + out.view(B, T, self.num_modulated_projs, self.rank_ctrl) |
| return mod |
|
|
| class LoRAExit(nn.Module): |
| """Decoupled low-rank intermediate early exit adapter (LoRAExit) to prevent gradient conflict.""" |
| def __init__(self, d_model: int, r: int = 32): |
| super().__init__() |
| self.up_proj = nn.Linear(d_model, r, bias=False) |
| self.down_proj = nn.Linear(r, d_model, bias=False) |
| |
| nn.init.zeros_(self.down_proj.weight) |
| nn.init.normal_(self.up_proj.weight, std=0.02) |
|
|
| def initialize_svd(self, W_i, W_j): |
| with torch.no_grad(): |
| diff = W_i.float() - W_j.float() |
| U, S, Vh = torch.linalg.svd(diff, full_matrices=False) |
| r = min(self.up_proj.out_features, S.numel()) |
| |
| A = U[:, :r] * S[:r] |
| B = Vh[:r, :] |
| |
| self.down_proj.weight.copy_(A.to(self.down_proj.weight.dtype)) |
| self.up_proj.weight.copy_(B.to(self.up_proj.weight.dtype)) |
|
|
| def forward(self, x): |
| return self.down_proj(self.up_proj(x)) |
|
|
| class ContextAnchoredMLA(nn.Module): |
| """Context-Anchored Recurrent Attention (CART) using Multi-Head Latent Attention (MLA).""" |
| def __init__(self, config: ModelConfig, r_latent: int = 128, d_r: int = 64): |
| super().__init__() |
| self.n_heads = config.n_heads |
| self.head_dim = config.d_model // config.n_heads |
| self.d_r = d_r |
| self.r_latent = r_latent |
| |
| |
| self.q_proj = ModulatedLinear(config.d_model, config.n_heads * self.head_dim, bias=config.bias) |
| self.q_rope_proj = ModulatedLinear(config.d_model, config.n_heads * d_r, bias=config.bias) |
| |
| |
| self.k_proj = nn.Linear(r_latent, config.n_heads * self.head_dim, bias=config.bias) |
| self.k_rope_proj = nn.Linear(r_latent, config.n_heads * d_r, bias=config.bias) |
| self.v_proj = nn.Linear(r_latent, config.n_heads * self.head_dim, bias=config.bias) |
| |
| |
| self.out_proj = ModulatedLinear(config.n_heads * self.head_dim, config.d_model, bias=config.bias) |
| |
| self.rope = RoPE(dim=d_r, max_seq_len=config.max_seq_len) |
| |
| |
| self.dkv_weight_dummy = nn.Parameter(torch.empty(r_latent, config.d_model)) |
| nn.init.normal_(self.dkv_weight_dummy, std=0.02) |
|
|
| def forward(self, x, r_idx: int = 0, anchor_ckv=None, mod_vector=None, kv_cache=None): |
| B, T, _ = x.shape |
| |
| if anchor_ckv is None: |
| anchor_ckv = F.linear(x, self.dkv_weight_dummy) |
| |
| T_anchor = anchor_ckv.shape[1] |
| |
| q_mod = mod_vector[..., 0, :] if mod_vector is not None else None |
| q_rope_mod = mod_vector[..., 1, :] if mod_vector is not None else None |
| out_mod = mod_vector[..., 2, :] if mod_vector is not None else None |
| |
| q_c = self.q_proj(x, q_mod).view(B, T, self.n_heads, self.head_dim) |
| q_r = self.q_rope_proj(x, q_rope_mod).view(B, T, self.n_heads, self.d_r) |
| |
| k_c = self.k_proj(anchor_ckv).view(B, T_anchor, self.n_heads, self.head_dim) |
| k_r = self.k_rope_proj(anchor_ckv).view(B, T_anchor, self.n_heads, self.d_r) |
| v = self.v_proj(anchor_ckv).view(B, T_anchor, self.n_heads, self.head_dim) |
| |
| q_r = self.rope(q_r, T, start_pos=T_anchor - T) |
| k_r = self.rope(k_r, T_anchor, start_pos=0) |
| |
| q = torch.cat([q_c, q_r], dim=-1).transpose(1, 2) |
| k = torch.cat([k_c, k_r], dim=-1).transpose(1, 2) |
| v = v.transpose(1, 2) |
| |
| is_causal = (T > 1) and (T == T_anchor) |
| |
| try: |
| context = F.scaled_dot_product_attention( |
| q, k, v, is_causal=is_causal |
| ) |
| except Exception: |
| scores = torch.matmul(q, k.transpose(-2, -1)) / ((self.head_dim + self.d_r) ** 0.5) |
| if T > 1 and T == T_anchor: |
| mask = torch.triu(torch.full((T, T_anchor), float('-inf'), device=x.device), diagonal=1) |
| scores = scores + mask.unsqueeze(0).unsqueeze(1) |
| scores_fp32 = scores.to(torch.float32) |
| attn = F.softmax(scores_fp32, dim=-1).to(x.dtype) |
| context = torch.matmul(attn, v) |
| |
| context = context.transpose(1, 2).contiguous().view(B, T, -1) |
| return self.out_proj(context, out_mod) |
|
|
| class GQAAttention(nn.Module): |
| """Grouped-Query Attention (GQA) with multi-step recursive KV Caching.""" |
| def __init__(self, config: ModelConfig): |
| super().__init__() |
| self.n_heads = config.n_heads |
| self.n_kv_heads = config.n_kv_heads |
| self.head_dim = config.d_model // config.n_heads |
| self.num_queries_per_kv = config.n_heads // config.n_kv_heads |
| |
| self.q_proj = nn.Linear(config.d_model, config.n_heads * self.head_dim, bias=config.bias) |
| self.k_proj = nn.Linear(config.d_model, config.n_kv_heads * self.head_dim, bias=config.bias) |
| self.v_proj = nn.Linear(config.d_model, config.n_kv_heads * self.head_dim, bias=config.bias) |
| self.out_proj = nn.Linear(config.n_heads * self.head_dim, config.d_model, bias=config.bias) |
| |
| self.rope = RoPE(dim=self.head_dim, max_seq_len=config.max_seq_len) |
|
|
| def forward(self, x, r_idx: int = 0, kv_cache_info=None): |
| B, T, _ = x.shape |
| |
| q = self.q_proj(x).view(B, T, self.n_heads, self.head_dim) |
| k = self.k_proj(x).view(B, T, self.n_kv_heads, self.head_dim) |
| v = self.v_proj(x).view(B, T, self.n_kv_heads, self.head_dim) |
| |
| if kv_cache_info is not None: |
| cache_obj, layer_idx, zone_name = kv_cache_info |
| if zone_name == "prelude": |
| start_pos = cache_obj.prelude_lengths[layer_idx] |
| else: |
| start_pos = cache_obj.coda_lengths[layer_idx] |
| else: |
| start_pos = 0 |
| |
| q = self.rope(q, T, start_pos=start_pos) |
| k = self.rope(k, T, start_pos=start_pos) |
| |
| if kv_cache_info is not None: |
| cache_obj, layer_idx, zone_name = kv_cache_info |
| if zone_name == "prelude": |
| k, v = cache_obj.update_prelude(k, v, layer_idx) |
| else: |
| k, v = cache_obj.update_coda(k, v, layer_idx) |
| T_total = k.shape[1] |
| else: |
| T_total = T |
| |
| q = q.transpose(1, 2) |
| |
| if self.num_queries_per_kv > 1: |
| k_expanded = k.repeat_interleave(self.num_queries_per_kv, dim=2) |
| v_expanded = v.repeat_interleave(self.num_queries_per_kv, dim=2) |
| else: |
| k_expanded = k |
| v_expanded = v |
| |
| k_expanded = k_expanded.transpose(1, 2) |
| v_expanded = v_expanded.transpose(1, 2) |
| |
| is_causal = (T > 1) |
| |
| try: |
| context = F.scaled_dot_product_attention( |
| q, |
| k_expanded, |
| v_expanded, |
| is_causal=is_causal |
| ) |
| except Exception: |
| scores = torch.matmul(q, k_expanded.transpose(-2, -1)) / (self.head_dim ** 0.5) |
| if T > 1: |
| mask = torch.triu(torch.full((T, T_total), float('-inf'), device=x.device), diagonal=T_total - T + 1) |
| scores = scores + mask.unsqueeze(0).unsqueeze(1) |
| scores_fp32 = scores.to(torch.float32) |
| attn = F.softmax(scores_fp32, dim=-1).to(x.dtype) |
| context = torch.matmul(attn, v_expanded) |
| |
| context = context.transpose(1, 2).contiguous().view(B, T, -1) |
| return self.out_proj(context) |
|
|
| class SwiGLUFFN(nn.Module): |
| """Standard Gated Linear Unit with Swish (SiLU) activation for LLMs.""" |
| def __init__(self, config: ModelConfig): |
| super().__init__() |
| self.gate_proj = nn.Linear(config.d_model, config.d_ff, bias=config.bias) |
| self.up_proj = nn.Linear(config.d_model, config.d_ff, bias=config.bias) |
| self.down_proj = nn.Linear(config.d_ff, config.d_model, bias=config.bias) |
|
|
| def forward(self, x): |
| return self.down_proj(F.silu(self.gate_proj(x)) * self.up_proj(x)) |
|
|
| class ModulatedSwiGLUFFN(nn.Module): |
| """Modulated Gated Linear Unit with Swish (SiLU) activation.""" |
| def __init__(self, config: ModelConfig, rank_ctrl: int = 64): |
| super().__init__() |
| self.gate_proj = ModulatedLinear(config.d_model, config.d_ff, rank_ctrl=rank_ctrl, bias=config.bias) |
| self.up_proj = ModulatedLinear(config.d_model, config.d_ff, rank_ctrl=rank_ctrl, bias=config.bias) |
| self.down_proj = ModulatedLinear(config.d_ff, config.d_model, rank_ctrl=rank_ctrl, bias=config.bias) |
|
|
| def forward(self, x, mod_vector=None): |
| gate_mod = mod_vector[..., 3, :] if mod_vector is not None else None |
| up_mod = mod_vector[..., 4, :] if mod_vector is not None else None |
| down_mod = mod_vector[..., 5, :] if mod_vector is not None else None |
| |
| return self.down_proj(F.silu(self.gate_proj(x, gate_mod)) * self.up_proj(x, up_mod), down_mod) |
|
|
| class StepAdapter(nn.Module): |
| """A lightweight, low-rank step adapter to allow depth-specific specialization.""" |
| def __init__(self, d_model: int, r: int = 64, alpha: int = 128): |
| super().__init__() |
| self.up_proj = nn.Linear(d_model, r, bias=False) |
| self.down_proj = nn.Linear(r, d_model, bias=False) |
| self.scale = alpha / r |
| |
| nn.init.zeros_(self.down_proj.weight) |
| nn.init.normal_(self.up_proj.weight, std=0.02) |
|
|
| def forward(self, x): |
| return self.down_proj(F.silu(self.up_proj(x))) * self.scale |
|
|
| class TransformerBlock(nn.Module): |
| """A unified block class that acts as either a standard GQA layer or a recurrent core layer.""" |
| def __init__(self, config: ModelConfig, layer_type: str = "standard"): |
| super().__init__() |
| self.layer_type = layer_type |
| |
| self.attn_norm = RMSNorm(config.d_model, n_iterations=config.n_iterations) |
| self.ffn_norm = RMSNorm(config.d_model, n_iterations=config.n_iterations) |
| |
| if layer_type == "recurrent_core": |
| self.attn = ContextAnchoredMLA(config) |
| self.ffn = ModulatedSwiGLUFFN(config) |
| self.adapters = nn.ModuleList([ |
| StepAdapter(config.d_model, r=64) for _ in range(config.n_iterations) |
| ]) |
| else: |
| self.attn = GQAAttention(config) |
| self.ffn = SwiGLUFFN(config) |
| |
| self.adapters = nn.ModuleList([ |
| StepAdapter(config.d_model, r=64) for _ in range(config.n_iterations) |
| ]) |
|
|
| def forward(self, x, r_idx: int = 0, kv_cache=None, anchor_ckv=None, mod_vector=None): |
| if self.layer_type == "recurrent_core": |
| attn_norm_out = self.attn_norm(x, r_idx) |
| attn_out = self.attn(attn_norm_out, r_idx=r_idx, anchor_ckv=anchor_ckv, mod_vector=mod_vector) |
| adapter_out = self.adapters[r_idx](attn_out) |
| |
| h = x + attn_out + adapter_out |
| ffn_norm_out = self.ffn_norm(h, r_idx) |
| ffn_out = self.ffn(ffn_norm_out, mod_vector=mod_vector) |
| |
| return attn_out + adapter_out + ffn_out |
| else: |
| |
| attn_norm_out = self.attn_norm(x, r_idx) |
| attn_out = self.attn(attn_norm_out, r_idx=r_idx, kv_cache_info=kv_cache) |
| |
| h = x + attn_out |
| ffn_norm_out = self.ffn_norm(h, r_idx) |
| ffn_out = self.ffn(ffn_norm_out) |
| |
| return h + ffn_out |
|
|
| class RecursiveCausalLM(nn.Module): |
| """The main Unified Recurrent Language Model (Prelude-Core-Coda Layout).""" |
| def __init__(self, config: ModelConfig): |
| super().__init__() |
| self.config = config |
| self.embeddings = nn.Embedding(config.vocab_size, config.d_model) |
| |
| |
| self.step_embeddings = nn.Parameter(torch.zeros(config.n_iterations, config.d_model)) |
| nn.init.normal_(self.step_embeddings, std=0.02) |
| |
| |
| self.depth_gate = nn.Parameter(torch.ones(config.n_iterations, config.d_model) * 1.73) |
| |
| |
| self.lora_exits = nn.ModuleList([ |
| LoRAExit(config.d_model, r=32) for _ in range(config.n_iterations) |
| ]) |
| |
| |
| self.halt_head = nn.Linear(config.d_model, 1, bias=False) |
| nn.init.zeros_(self.halt_head.weight) |
| |
| |
| self.prelude = nn.ModuleList([TransformerBlock(config, layer_type="standard") for _ in range(4)]) |
| |
| |
| self.core_blocks = nn.ModuleList([TransformerBlock(config, layer_type="recurrent_core") for _ in range(2)]) |
| |
| |
| self.coda = nn.ModuleList([TransformerBlock(config, layer_type="standard") for _ in range(4)]) |
| |
| |
| self.controller = ControllerHypernetwork(config.d_model, num_modulated_projs=6, rank_ctrl=64) |
| |
| |
| self.dkv_weight = nn.Parameter(torch.empty(128, config.d_model)) |
| nn.init.normal_(self.dkv_weight, std=0.02) |
| |
| self.final_norm = RMSNorm(config.d_model) |
| self.lm_head_bias = nn.Parameter(torch.zeros(config.vocab_size)) if config.bias else None |
| |
| |
| self.speculative_projs = nn.ModuleList([ |
| nn.Linear(config.d_model, config.d_model, bias=config.bias) for _ in range(4) |
| ]) |
| self.speculative_biases = nn.ParameterList([ |
| nn.Parameter(torch.zeros(config.vocab_size)) for _ in range(4) |
| ]) |
| |
| |
| self.apply(self._init_weights) |
| |
| |
| for bias in self.speculative_biases: |
| nn.init.zeros_(bias) |
| |
| |
| for core_block in self.core_blocks: |
| for adapter in core_block.adapters: |
| nn.init.zeros_(adapter.down_proj.weight) |
| |
| |
| std_scale = 1.0 / (2 * config.n_iterations) ** 0.5 |
| with torch.no_grad(): |
| for core_block in self.core_blocks: |
| core_block.attn.out_proj.base_layer.weight.mul_(std_scale) |
| core_block.ffn.down_proj.base_layer.weight.mul_(std_scale) |
|
|
| @property |
| def core_block(self): |
| """Property to support legacy code that accesses core_block directly.""" |
| return self.core_blocks[0] |
|
|
| @property |
| def block(self): |
| """Property to keep diagnostic and audit scripts perfectly backward compatible.""" |
| return self.core_block |
|
|
| def _init_weights(self, module): |
| if isinstance(module, nn.Linear): |
| nn.init.normal_(module.weight, std=0.02) |
| if module.bias is not None: |
| nn.init.zeros_(module.bias) |
| elif isinstance(module, nn.Embedding): |
| nn.init.normal_(module.weight, std=0.02) |
|
|
| def load_state_dict(self, state_dict, strict=False): |
| """Saves representational accuracy by automatically copying unshared block weights |
| and initializing SVD low-rank bases. |
| """ |
| new_state_dict = {} |
| for k, v in state_dict.items(): |
| if k in self.state_dict(): |
| new_state_dict[k] = v |
| continue |
| |
| if k.startswith("block."): |
| |
| for idx in range(4): |
| pre_key = k.replace("block.", f"prelude.{idx}.") |
| if pre_key in self.state_dict(): |
| new_state_dict[pre_key] = v |
| |
| |
| for b_idx in range(2): |
| core_key = k.replace("block.", f"core_blocks.{b_idx}.") |
| if "attn.k_proj" in core_key or "attn.v_proj" in core_key: |
| pass |
| elif core_key in self.state_dict(): |
| new_state_dict[core_key] = v |
| else: |
| if ".q_proj." in k: |
| new_state_dict[core_key.replace(".q_proj.", ".q_proj.base_layer.")] = v |
| elif ".out_proj." in k: |
| new_state_dict[core_key.replace(".out_proj.", ".out_proj.base_layer.")] = v |
| elif ".gate_proj." in k: |
| new_state_dict[core_key.replace(".gate_proj.", ".gate_proj.base_layer.")] = v |
| elif ".up_proj." in k: |
| new_state_dict[core_key.replace(".up_proj.", ".up_proj.base_layer.")] = v |
| elif ".down_proj." in k: |
| new_state_dict[core_key.replace(".down_proj.", ".down_proj.base_layer.")] = v |
| |
| |
| for idx in range(4): |
| cod_key = k.replace("block.", f"coda.{idx}.") |
| if cod_key in self.state_dict(): |
| new_state_dict[cod_key] = v |
| |
| res = super().load_state_dict(new_state_dict, strict=False) |
| |
| |
| with torch.no_grad(): |
| for name, module in self.named_modules(): |
| if isinstance(module, ModulatedLinear): |
| module.initialize_svd() |
| |
| return res |
|
|
| def get_num_params(self, unique_only: bool = True): |
| """Returns the physical parameters saved on disk vs unrolled virtual parameter capacity.""" |
| if unique_only: |
| return sum(p.numel() for p in self.parameters()) |
| else: |
| embeds = self.embeddings.weight.numel() |
| steps = self.step_embeddings.numel() |
| gate = self.depth_gate.numel() |
| halt = self.halt_head.weight.numel() |
| norm = sum(p.numel() for p in self.final_norm.parameters()) |
| bias_count = self.lm_head_bias.numel() if self.lm_head_bias is not None else 0 |
| |
| |
| pre_params = sum(p.numel() for p in self.prelude.parameters()) |
| core_unrolled = sum(p.numel() for p in self.core_blocks.parameters()) * 4 |
| coda_params = sum(p.numel() for p in self.coda.parameters()) |
| |
| return embeds + steps + gate + halt + norm + bias_count + pre_params + core_unrolled + coda_params |
|
|
| def forward(self, input_ids, targets=None, kv_cache=None, return_spec: bool = False, spec_coef: float = 0.0): |
| B, T = input_ids.shape |
| x = self.embeddings(input_ids) |
| |
| |
| for idx in range(4): |
| if self.training and targets is not None: |
| def make_prelude_fn(layer_idx): |
| def custom_forward(tensor_in): |
| return self.prelude[layer_idx](tensor_in, r_idx=layer_idx) |
| return custom_forward |
| x = cp.checkpoint(make_prelude_fn(idx), x, use_reentrant=False) |
| else: |
| cache_info = (kv_cache, idx, "prelude") if kv_cache is not None else None |
| x = self.prelude[idx](x, r_idx=idx, kv_cache=cache_info) |
| |
| |
| c_kv = F.linear(x, self.dkv_weight) |
| if kv_cache is not None: |
| anchor_ckv = kv_cache.update_anchor(c_kv) |
| else: |
| anchor_ckv = c_kv |
| |
| |
| xs = [] |
| for r in range(4, 12): |
| |
| x = x + self.step_embeddings[r].view(1, 1, -1) |
| |
| |
| gate = (0.02 + 0.96 * torch.sigmoid(self.depth_gate[r])).view(1, 1, -1) |
| |
| |
| mod_vector = self.controller(x, self.step_embeddings[r]) |
| |
| block_idx = 0 if r < 8 else 1 |
| curr_core_block = self.core_blocks[block_idx] |
| |
| if self.training and targets is not None: |
| def make_core_fn(r_val, b_idx): |
| def custom_forward(tensor_in, anchor, mod): |
| return self.core_blocks[b_idx](tensor_in, r_idx=r_val, anchor_ckv=anchor, mod_vector=mod) |
| return custom_forward |
| block_out = cp.checkpoint(make_core_fn(r, block_idx), x, anchor_ckv, mod_vector, use_reentrant=False) |
| else: |
| block_out = curr_core_block(x, r_idx=r, anchor_ckv=anchor_ckv, mod_vector=mod_vector) |
| |
| x = gate * x + (1.0 - gate) * block_out |
| |
| if targets is not None: |
| xs.append(x) |
| |
| |
| is_training_mode = self.training or (targets is not None) |
| is_cached_inference = (kv_cache is not None) |
| |
| if not is_training_mode and not is_cached_inference and T == 1: |
| |
| x_exit = x[:, -1, :] + self.lora_exits[r](x[:, -1, :]) |
| halt_logit = self.halt_head(x_exit) |
| halt_prob = torch.sigmoid(halt_logit).min().item() |
| if halt_prob > 0.95: |
| break |
| |
| |
| for idx in range(4): |
| virtual_idx = 12 + idx |
| if self.training and targets is not None: |
| def make_coda_fn(layer_idx): |
| def custom_forward(tensor_in): |
| return self.coda[layer_idx](tensor_in, r_idx=virtual_idx) |
| return custom_forward |
| x = cp.checkpoint(make_coda_fn(idx), x, use_reentrant=False) |
| else: |
| cache_info = (kv_cache, idx, "coda") if kv_cache is not None else None |
| x = self.coda[idx](x, r_idx=virtual_idx, kv_cache=cache_info) |
| |
| x = self.final_norm(x) |
| logits = F.linear(x, self.embeddings.weight, self.lm_head_bias) |
| |
| |
| spec_logits = [] |
| for k in range(4): |
| h_k = F.silu(self.speculative_projs[k](x)) |
| logits_k = F.linear(h_k, self.embeddings.weight, self.speculative_biases[k]) |
| spec_logits.append(logits_k) |
| |
| loss = None |
| if targets is not None: |
| loss_lm = F.cross_entropy(logits.to(torch.float32).view(-1, logits.size(-1)), targets.view(-1)) |
| |
| |
| loss_halt = 0.0 |
| num_halt_steps = len(xs) - 1 |
| if num_halt_steps > 0: |
| final_x = xs[-1].detach() |
| for i in range(num_halt_steps): |
| r = 4 + i |
| sim = F.cosine_similarity(xs[i], final_x, dim=-1) |
| target_halt = (sim >= 0.985).to(dtype=xs[i].dtype) |
| |
| |
| x_exit = xs[i] + self.lora_exits[r](xs[i]) |
| halt_logits = self.halt_head(x_exit).squeeze(-1) |
| loss_halt += F.binary_cross_entropy_with_logits( |
| halt_logits.to(torch.float32), |
| target_halt.to(torch.float32) |
| ) |
| loss_halt = loss_halt / num_halt_steps |
| |
| |
| if spec_coef > 0.0: |
| loss_spec = 0.0 |
| for k in range(4): |
| shift_len = k + 1 |
| if T > shift_len: |
| logits_slice = spec_logits[k][:, :-shift_len, :].contiguous() |
| targets_slice = targets[:, shift_len:].contiguous() |
| loss_spec_k = F.cross_entropy( |
| logits_slice.to(torch.float32).view(-1, logits_slice.size(-1)), |
| targets_slice.view(-1) |
| ) |
| loss_spec += loss_spec_k |
| loss_spec = loss_spec / 4.0 |
| loss = loss_lm + 0.1 * loss_halt + spec_coef * loss_spec |
| else: |
| loss = loss_lm + 0.1 * loss_halt |
| |
| if return_spec: |
| stacked_spec_logits = torch.stack(spec_logits, dim=2) |
| return logits, loss, stacked_spec_logits |
| else: |
| return logits, loss |
|
|
| class KVCache: |
| """A highly-optimized key-value cache that stores states recursively across prelude, anchor, and coda phases.""" |
| def __init__(self, config: ModelConfig, max_batch_size: int, device: str, dtype: torch.dtype = torch.float16, max_seq_len: int = None): |
| super().__init__() |
| self.max_batch_size = max_batch_size |
| self.head_dim = config.d_model // config.n_heads |
| self.dtype = dtype |
| |
| cache_seq_len = max_seq_len if max_seq_len is not None else config.max_seq_len |
| self.cache_seq_len = cache_seq_len |
| |
| |
| self.prelude_k = torch.zeros(4, max_batch_size, config.n_kv_heads, cache_seq_len, self.head_dim, device=device, dtype=dtype) |
| self.prelude_v = torch.zeros(4, max_batch_size, config.n_kv_heads, cache_seq_len, self.head_dim, device=device, dtype=dtype) |
| self.prelude_lengths = [0] * 4 |
| |
| |
| self.anchor_ckv = torch.zeros(max_batch_size, cache_seq_len, 128, device=device, dtype=dtype) |
| self.anchor_length = 0 |
| |
| |
| self.coda_k = torch.zeros(4, max_batch_size, config.n_kv_heads, cache_seq_len, self.head_dim, device=device, dtype=dtype) |
| self.coda_v = torch.zeros(4, max_batch_size, config.n_kv_heads, cache_seq_len, self.head_dim, device=device, dtype=dtype) |
| self.coda_lengths = [0] * 4 |
| |
| |
| self.current_lengths = [0] * config.n_iterations |
|
|
| def update_prelude(self, k_new, v_new, layer_idx: int): |
| B, T_new, H_kv, d_k = k_new.shape |
| start_pos = self.prelude_lengths[layer_idx] |
| end_pos = start_pos + T_new |
| |
| k_new = k_new.to(self.prelude_k.dtype) |
| v_new = v_new.to(self.prelude_v.dtype) |
| |
| self.prelude_k[layer_idx, :B, :, start_pos:end_pos, :] = k_new.transpose(1, 2) |
| self.prelude_v[layer_idx, :B, :, start_pos:end_pos, :] = v_new.transpose(1, 2) |
| |
| self.prelude_lengths[layer_idx] = end_pos |
| self.current_lengths[layer_idx] = end_pos |
| |
| k_out = self.prelude_k[layer_idx, :B, :, :end_pos, :].transpose(1, 2) |
| v_out = self.prelude_v[layer_idx, :B, :, :end_pos, :].transpose(1, 2) |
| return k_out, v_out |
|
|
| def update_coda(self, k_new, v_new, layer_idx: int): |
| B, T_new, H_kv, d_k = k_new.shape |
| start_pos = self.coda_lengths[layer_idx] |
| end_pos = start_pos + T_new |
| |
| k_new = k_new.to(self.coda_k.dtype) |
| v_new = v_new.to(self.coda_v.dtype) |
| |
| self.coda_k[layer_idx, :B, :, start_pos:end_pos, :] = k_new.transpose(1, 2) |
| self.coda_v[layer_idx, :B, :, start_pos:end_pos, :] = v_new.transpose(1, 2) |
| |
| self.coda_lengths[layer_idx] = end_pos |
| self.current_lengths[12 + layer_idx] = end_pos |
| |
| k_out = self.coda_k[layer_idx, :B, :, :end_pos, :].transpose(1, 2) |
| v_out = self.coda_v[layer_idx, :B, :, :end_pos, :].transpose(1, 2) |
| return k_out, v_out |
|
|
| def update_anchor(self, c_kv_new): |
| B, T_new, r_lat = c_kv_new.shape |
| start_pos = self.anchor_length |
| end_pos = start_pos + T_new |
| |
| self.anchor_ckv[:B, start_pos:end_pos, :] = c_kv_new.to(self.anchor_ckv.dtype) |
| self.anchor_length = end_pos |
| |
| return self.anchor_ckv[:B, :end_pos, :] |
|
|