Bug: setdefault('moe_intermediate_size', ...) doesn't override the
1728 value from the full-scale config.json. Result: each expert is
SwiGLUMLP(256, 1728) = 1.3M params × 17 experts × 7 layers = 158M
params in MoE alone (70% of model), when it should be ~4M.
Fix: when a scale preset is active, force-override moe_intermediate_size
to intermediate_size // 4 (= 128 for tiny). Also force n_routed_experts
to 8 (not 16 from full config).
Param reduction: 227M → ~73M total. Step time ~3× faster."
fix: print every step + first-step timing to diagnose slow forward
With 227M params on CPU, each step can take 30-60s. With log_every=10,
the first output wouldn't appear for 5-10 minutes — looks like a hang.
Changes:
- Print step 1 timing immediately after first forward+backward
- Log every step for the first 5 steps, then every log_every
- Flush stdout after every print to ensure immediate display
- Add sys.stdout.flush() calls"
fix: batch_size 32→4 base (GrowLength scales up, _safe_batch caps)
- Exclude tcmalloc_debug variants from LD_PRELOAD (they abort Python)
- Prefer libtcmalloc.so.4 or libtcmalloc_minimal.so.4 (non-debug)
- Add trap for error reporting with set -e
- Print the actual python command before executing
- Add chmod +x reminder in usage comment"
perf: 4-stage GrowLength + CLI defaults for 300-step target
GrowLength schedule redesigned for joint throughput + convergence:
- 4 stages: seq 16→32→64→128 (was 2-stage: half→full)
- Front-loads throughput: seq=16 at batch=256 → ~2800 tok/s
- Constant tokens/step (4096) across all stages
- 50% of training at full seq=128 for long-range structure
CLI defaults updated:
- seq_len 64→128: full TinyStories context
- batch_size 8→32: fill memory budget, works with GrowLength scaling
- lr 1.5e-3→1.2e-2: Muon optimal for ternary STE (overridden in loop)
- warmup 750→30: 10% of 300-step budget
- max_steps 5000→300: convergence target
- save_every 1000→100: more frequent checkpoints for short run"
perf: tune train_hyper_loop for 300-step convergence
- muon_lr 0.008→0.012: max stable rate for ternary STE with clamp-aware
gradient gating (grads zero outside [-1,1], so higher LR is safe)
- muon_warmup hardcoded to 30 (10% of 300 steps)
- weight_decay 0.01→0.02
- llrd_decay 0.92→0.90 (0.90^27=0.058 vs 0.92^27=0.093; both give
meaningful bottom-layer gradients, but 0.90 is more aggressive)
- grokfast_alpha 0.98→0.95, grokfast_lambda 1.0→1.5
- Force loops=1 for all steps (no progressive 1→2→3); at 300 steps,
throughput matters more than iterative refinement
- Progressive loop scheduler still imported but overridden"
perf: tune chimera_turbo.py for 300-step convergence + throughput
All changes target joint throughput ≥1000 tok/s + near-optimal loss by step 300:
apply() defaults:
- lr 0.02→0.012: ternary STE clamp zone [-1,1] causes overshoot at 0.02
- weight_decay 0.01→0.02: BitNet SLM paper finds wd=0.05 optimal; 0.02
balances with Muon's NS regularization
- warmup_steps 200→30: 200 wastes 67% of a 300-step budget at sub-optimal LR
- mtp_heads 3→0: each head adds Linear(256,200073)=51M params; 3 heads =
153M extra params (4.4× model) destroying cache residency + throughput
- llrd_decay 0.85→0.90: 0.85^27=0.009 nearly freezes bottom layers;
0.90^27=0.058 gives 6× more gradient at bottom, critical for 300 steps
- grokfast_alpha 0.98→0.95: EMA window ~50→~20 steps, better for short runs
- grokfast_lambda 2.0→1.5: reduce instability risk with Muon NS updates
TokenTriage:
- select_ratio 0.6→0.50: focus top-50% informative tokens
- floor_weight 0.1→0.15: ensure minimum signal from all tokens
- warmup_steps 500→30: original never activates in 300-step run
Plat…
Throughput optimization for i7-14700T (8P+12E hybrid):
- Pin OMP threads to 8 P-cores only; E-cores lack AVX-512 BF16
and cause barrier stalls that reduce GEMM throughput by ~25%
- KMP_BLOCKTIME=0: yield immediately, save TDP headroom on 35W chip
- Explicit proclist affinity for P-cores 0-7
- tcmalloc warning elevated to hard requirement
- Add CHIMERA_PCORE_THREADS env override for non-Raptor-Lake CPUs"
Fix loss rebound: lower Muon LR (0.02→0.008), clamp ternary latents, steeper cosine decay
Root cause: Muon's NS orthogonal update + momentum=0.95 pushed ternary latent
weights outside the STE clamp zone [-1, 1] after ~230 steps at LR=0.02. The
clamp-aware STE gradient is ZERO for weights outside [-1, 1] — those weights
become permanently dead (no gradient to recover them). This progressively
degraded model capacity, causing loss to rebound from 5.43 back to 6.48.
Three fixes:
1. LR 0.02→0.008: Standard Muon LR is 0.02 for dense fp32 weights with
unbounded range. Ternary STE restricts the useful weight range to [-1,1]
and the gradient-active zone to the same interval. The per-step weight
perturbation must be proportionally smaller. 0.008 gives ~2.5x slower
convergence but prevents overshoot past the STE boundary.
2. Latent weight clamping to [-2, 2]: After every Muon 2D update, clamp
weights to [-2, 2]. This is a safety net — weights that drift past
±1 from accumulated momentum are pulled back into the gradient-active
zone. The ±2 bound (not ±1) allow…
Skip SpanEngine/Grammar/DebtLedger during training (inference-only ops on 200K logits)
THROUGHPUT (26 tok/s → ~80+ tok/s estimated):
Root cause: lm_head [256, 200073] matmul costs 52 GFLOPs per step — 3.8x
the ENTIRE 28-layer transformer stack. MTP added another 52 GFLOPs head.
The model spent 75% of its time on vocabulary projection, not learning.
Fixes:
1. MTP disabled (mtp_heads=0): removes 51M-param head that costs as much
as lm_head itself. At loss=13 the model can't predict token+1, so
multi-token prediction is pure overhead. Re-enable once loss < 5.
2. Skip model's internal CE loss: training_step passes labels=None to
forward(), avoiding a redundant 200K-dim cross_entropy computation
(training_step computes its own weighted CE for triage/metabolism).
3. SpanInferenceEngine skipped during training: risk-gated modulation
on hidden states is inference-only, no training signal.
4. Grammar + DebtLedger skipped during training: these are identity/
near-identity on 200K-dim logits, but still allocate intermediates.
5. Faster grad sanitization: single …
Fix NaN loss reporting: show nan instead of 0.0 when all steps in window are NaN
Three NaN-related bugs:
1. Gradient sanitization was reduced from every step to every 10 steps as a
throughput optimization. But BitLinear STE + complex recurrent layers produce
occasional NaN gradients that MUST be caught immediately. A single uncaught
NaN gradient corrupts Muon's momentum buffer, which then corrupts the weights
on the next optimizer step, causing permanent all-NaN forward passes.
Fix: restore per-step sanitization.
2. NaN guard only zeroed gradients and halved LR — but never repaired the
already-corrupted weights or Muon momentum buffers. So once NaN entered
the weights, every subsequent step also produced NaN, triggering the LR
halving cascade (5 NaN → halve → 5 NaN → halve → ... → LR = 0).
Fix: NaN guard now sanitizes model weights AND optimizer momentum buffers.
Also increased threshold from 5 to 10 consecutive NaN before halving.
3. Newton-Schulz could produce NaN if input gradient matrix had near-zero norm
(< 1e-12) or already…
1. LR was hardcoded at 0.02 (13x too high), now uses args.lr (1.5e-3)
2. GrowLength spent 30% of training at seq=16 (useless fragments), now 10% at seq/2 + 90% at full
3. Token Triage discarded 40% of gradient signal at loss=10+ (no easy tokens exist yet), now anneals floor from 1.0→0.1 over 500 steps
4. LLRD decay=0.85 created 80x LR gap between layers, softened to 0.92 (10x gap)
5. Evolution engine fired 7x per forward pass (expensive HDC/Hamming ops), now 1x
6. MTP heads 3→2 (saves 51M params of gradient overhead), weight 0.3→0.1
7. Batch Metabolism z-scores unclamped with [0.5,2.0] range on B=32 batches, now clamped ±2σ with [0.7,1.4] range
Performance fixes:
- Muon NS steps 5→3 (40% fewer matmuls per optimizer step)
- BitLinear cache lookup amortized (was walking all modules every step)
- Gradient sanitization every 10 steps instead of every step
- Loop classifier bypassed during training (was calling .item() every forward)
- Plateau breaker patience 100→200, variance threshold 0…
fix: v12 GENESIS — fix 6 interaction bugs between paradigms\n\n1. P13 MTP heads added to optimizer (were dead — never updated)\n2. P18 Grokfast: skip Muon 2D params (NS normalisation cancels amplification)\n Apply only to 1D/embed params where AdamW preserves the signal\n3. P16 Plateau: save/restore ALL group LRs (was destroying LLRD ratios)\n4. P15 Token Triage applied to MTP loss too (was only on base loss)\n5. P16 Plateau: gentler burst ×2 instead of ×3 (Grokfast already amplifies)\n6. P15 Triage: per-position EMA disabled, use global excess only"
feat: v11 CHIMERA GENESIS — Grokfast-EMA + fused loss + LLRD + kill EMA distill overhead\n\nMajor rewrite of training step:\n\n1. P18 Grokfast-EMA (arxiv 2405.20233): 43× convergence acceleration.\n Amplifies slow gradient components (generalization signal),\n filters fast components (memorization/STE noise). 5 lines, 0 overhead.\n Especially powerful for ternary STE where gradient noise is high.\n\n2. FUSED LOSS: P15 Token Triage + P17 Batch Metabolism now COMBINE\n instead of elif. Token triage weights individual tokens, batch\n metabolism weights sequences. Multiplicative composition.\n\n3. P19 Layer-wise LR Decay: higher LR for top layers (task-specific),\n lower for bottom (general features). decay_rate=0.85 per layer.\n Proven for ternary by TernaryLM (arxiv 2602.07374).\n\n4. REMOVED EMA Self-Distillation: doubled forward pass time for marginal\n gain. The EMA model copy consumed 227M params of memory for a KL loss\n that barely helps in from-scratch pretraining (Baby Llama recipe was\n for fine-tuning with a DIFFERENT teacher, not self-EMA)."
feat: v10 — P15 Selective Token Triage, P16 Plateau Breaker, P17 Batch Metabolism\n\nThree new paradigms fusionné dans le concept 'Adaptive Token Metabolism':\n\nP15 Token Triage (inspiré Rho-1, arxiv 2404.07965):\nCompute per-token excess loss vs EMA baseline. Top 60% tokens get\nfull gradient, bottom 40% get 0.1× gradient. No reference model needed —\nuses running EMA of per-position loss as baseline. This focuses\n~90% of gradient energy on the actually-learnable tokens.\n\nP16 Plateau Breaker:\nTrack loss EMA variance. When loss stagnates (variance < threshold\nfor 100 steps), trigger a 'warm restart': boost LR by 3× for 50 steps\nthen decay back. Inspired by SGDR (arxiv 1608.03983) but adaptive.\n\nP17 Batch Metabolism (Online Hard Example Mining for LLM):\nWithin each batch, weight sequences by their loss relative to\nbatch mean. High-loss sequences get weight up to 2×, easy ones\nget 0.5×. The model 'digests' harder examples more thoroughly."
feat: P12 Muon optimizer, P13 Multi-Token Prediction, P14 EMA Self-Distillation\n\nThree new paradigms for revolutionary sample efficiency:\n\nP12 Muon: Newton-Schulz orthogonalized momentum for 2D weight matrices.\nSame loss in 52% of FLOPs vs AdamW (arxiv 2502.16982). AdamW fallback\nfor 1D params (biases, norms, embeddings).\n\nP13 MTP: predict next 3 tokens instead of 1. Each forward pass yields\n3x gradient signal. Implemented as auxiliary loss heads sharing the trunk.\n\nP14 EMA Self-Distillation: EMA copy of model acts as teacher. KL loss\nbetween student and EMA soft targets gives dense signal across full vocab\nvs sparse one-hot labels. α=0.5, T=2.0 (Baby Llama recipe, arxiv 2308.02019)."
feat: activate dormant paradigms — progressive looping, evolution with loss feedback, no progressive_unfreeze\n\nWith STE+AdamW (not MeZO), we can afford multi-loop training.\nProgressive loop schedule: 1→2→3 loops as training advances.\nEvolution engine now receives previous step loss for surprise\ndetection and memory writes.\nProgressive unfreeze disabled by default (counterproductive with backprop)."
fix: NaN skip + grad sanitization — detect NaN loss, zero corrupted grads, skip optimizer step\n\nWhen a rare batch produces NaN loss (step 380/500), the backward pass\ncontaminates all gradients with NaN. Without detection, optimizer.step()\npushes all weights to NaN → irrecoverable.\n\nFix: check loss for NaN/Inf before backward. If detected, zero grads\nand skip the optimizer step. Training recovers on the next batch."
fix: NaN at step 150 — add gradient clamping to STE detach trick + lower max_grad_norm to 0.5\n\nThe pure detach() STE passes gradients through unbounded, causing\ngradient explosion around step 140-150 when loss is still high.\n\nFix: clamp the gradient contribution within the detach trick:\n w_q = clamp(w_scaled, -1, 1) + (round(clamped) - clamped).detach()\nThis ensures gradients are zero outside [-1, 1] (weights already at\nquantization boundary get no gradient push) while keeping the STE\nidentity pass-through inside the valid range.\n\nAlso reduces max_grad_norm from 1.0 to 0.5 for additional stability.\n\nRef: 4-bit CPU training paper (2603.13931) uses tanh soft clipping\nfor the same reason."
perf: replace _RoundTernarySTE autograd.Function with detach() trick — zero graph breaks for torch.compile\n\nThe detach() identity pattern (w + (round(clamp(w)) - w).detach()) is\nmathematically equivalent to the old STE but uses only standard aten ops\nthat torch.compile/Inductor can trace through. This eliminates 84+\ngraph breaks, enabling full kernel fusion of quantize+linear.\n\nPattern from official BitNet b1.58 implementation (1bitLLM/bitnet_b1_58-large).\nRef: arxiv 2402.17764"