| """M4 — Mixture of Recursions (token-level dynamic depth) for ARCHON. |
| |
| NeurIPS 2025 (https://github.com/raymin0223/mixture_of_recursions) |
| + ARCHON innovation: combine with MTP-5 task_conditional. |
| |
| Idea: ARCHON 18L stack is REUSED N times per token, where N depends on a |
| lightweight router. Easy tokens use 1× (~9L effective), hard tokens use 4× |
| (~72L effective). Same weights, dynamic compute. |
| |
| For ARCHON 282M: estimate equivalent of 1B-3B at hard tokens with no extra params. |
| |
| Architecture change required: router head. After warm SFT, train router with |
| distillation from Claude on (token, optimal_depth) pairs. |
| |
| PHASE D — requires architecture mod + retraining router (~$50 GPU, 12-16h V100). |
| """ |
| from __future__ import annotations |
|
|
| from dataclasses import dataclass |
|
|
| import torch |
| import torch.nn as nn |
| import torch.nn.functional as F |
|
|
|
|
| @dataclass |
| class MoRConfig: |
| """MoR hyper-params for ARCHON.""" |
|
|
| n_recursion_buckets: int = 3 |
| bucket_recursions: tuple = (1, 2, 4) |
| router_hidden: int = 128 |
| aux_loss_weight: float = 0.01 |
|
|
|
|
| class MoRRouter(nn.Module): |
| """Token-level depth router. Output: softmax over n buckets.""" |
|
|
| def __init__(self, hidden_dim: int, cfg: MoRConfig = MoRConfig()): |
| super().__init__() |
| self.cfg = cfg |
| self.proj1 = nn.Linear(hidden_dim, cfg.router_hidden) |
| self.proj2 = nn.Linear(cfg.router_hidden, cfg.n_recursion_buckets) |
|
|
| def forward(self, h: torch.Tensor) -> torch.Tensor: |
| """h [B, T, D] -> bucket_probs [B, T, n_buckets].""" |
| x = F.gelu(self.proj1(h)) |
| return F.softmax(self.proj2(x), dim=-1) |
|
|
|
|
| class ArchonMoRWrapper(nn.Module): |
| """Wrap ArchonBrain with MoR recursion logic. |
| |
| Forward: |
| 1. Embed -> h |
| 2. Router predicts bucket per token from initial h |
| 3. For each bucket, run h through layers N times (N = bucket_recursion) |
| 4. Mix outputs weighted by router probs |
| 5. Apply final norm + lm_head + MTP heads as usual |
| """ |
|
|
| def __init__(self, archon_model, cfg: MoRConfig = MoRConfig()): |
| super().__init__() |
| self.archon = archon_model |
| self.cfg = cfg |
| self.router = MoRRouter(archon_model.config.hidden_dim, cfg) |
|
|
| def forward(self, input_ids: torch.Tensor, targets: torch.Tensor = None): |
| h0 = self.archon.embed(input_ids) |
| bucket_probs = self.router(h0) |
|
|
| bucket_outputs = [] |
| for bucket_idx, n_recursions in enumerate(self.cfg.bucket_recursions): |
| h = h0 |
| for _ in range(n_recursions): |
| for layer in self.archon.layers: |
| h = layer(h) |
| bucket_outputs.append(h) |
|
|
| |
| stacked = torch.stack(bucket_outputs, dim=-2) |
| weights = bucket_probs.unsqueeze(-1) |
| h_mixed = (stacked * weights).sum(dim=-2) |
|
|
| h_mixed = self.archon.norm(h_mixed) |
| logits = self.archon.lm_head(h_mixed) |
|
|
| |
| aux = -(bucket_probs * (bucket_probs + 1e-9).log()).sum(dim=-1).mean() |
| aux_loss = -self.cfg.aux_loss_weight * aux |
|
|
| loss = None |
| if targets is not None: |
| ntp_loss = F.cross_entropy( |
| logits[:, :-1].reshape(-1, logits.shape[-1]), |
| targets[:, 1:].reshape(-1), |
| ignore_index=-100, |
| ) |
| loss = ntp_loss + aux_loss |
|
|
| return logits, loss, [] |
|
|
|
|
| def router_training_plan_doc() -> str: |
| """Plan for MoR router training (Phase D).""" |
| return """ |
| MoR ROUTER TRAINING: |
| 1. Start from ARCHON SFT v2 final ckpt |
| 2. Add router (init: uniform softmax over 3 buckets) |
| 3. Train router only (freeze backbone) for 3K steps on SFT mix |
| - LR 1e-4, batch=16, V100, ~6h |
| 4. Then unfreeze, joint fine-tune backbone+router for 5K steps |
| - LR 1e-5, distillation loss vs ARCHON-SFT-v2 outputs |
| - V100 ~10h, $7 |
| 5. Eval: GSM8K accuracy + average recursion depth |
| Target: depth_avg ≈ 1.8, accuracy >= ARCHON-SFT-v2 baseline |
| 6. Killer: if router AUC < 0.65 OR depth_avg < 1.3 → abandon |
| |
| Combo bonus: ARCHON-MoR + COCONUT (M3) + TTT (M12) = trio inédit, |
| soumettre brevet patent-scout. |
| """ |
|
|
|
|
| if __name__ == "__main__": |
| cfg = MoRConfig() |
| print(f"[M4 MoR] config: {cfg}, buckets: {cfg.bucket_recursions}") |
| print(router_training_plan_doc()) |
|
|