KitsuVp commited on
Commit
085c264
·
verified ·
1 Parent(s): 24a6f61

Update configuration_neollm.py

Browse files
Files changed (1) hide show
  1. configuration_neollm.py +6 -142
configuration_neollm.py CHANGED
@@ -2,12 +2,7 @@
2
  import math
3
 
4
  from transformers.configuration_utils import PretrainedConfig
5
- try:
6
- from transformers.modeling_rope_utils import ( # type: ignore[attr-defined]
7
- rope_config_validation as _legacy_rope_config_validation,
8
- )
9
- except ImportError: # pragma: no cover - only older Transformers releases.
10
- _legacy_rope_config_validation = None
11
  from transformers.utils import logging
12
 
13
  logger = logging.get_logger(__name__)
@@ -16,17 +11,14 @@ logger = logging.get_logger(__name__)
16
  class NeoLLMConfig(PretrainedConfig):
17
  r"""
18
  Configuration class for the NeoLLM model architecture.
19
-
20
  Instantiates a NeoLLM model according to the specified arguments, defining the
21
  full architecture including attention mechanisms, normalization, periodicity
22
  modeling, an optional Leviathan continuous token embedding generator (LEV
23
  layer, Batley & Saha 2026), and optional Spelling Bee character-level
24
  embedding augmentation.
25
-
26
  Configuration objects inherit from :class:`~transformers.PretrainedConfig` and
27
  can be used to control the model outputs. Read the documentation from
28
  :class:`~transformers.PretrainedConfig` for more information.
29
-
30
  Args:
31
  vocab_size (:obj:`int`, *optional*, defaults to 200005):
32
  Vocabulary size of the NeoLLM model. Defines the number of different
@@ -45,22 +37,7 @@ class NeoLLMConfig(PretrainedConfig):
45
  hidden_act (:obj:`str`, *optional*, defaults to ``"xielu"``):
46
  Non-linear activation function used in the MLP layers.
47
  max_position_embeddings (:obj:`int`, *optional*, defaults to 32768):
48
- Training/pretraining sequence length. It is kept separate from
49
- the opt-in inference context limit so a training checkpoint can
50
- retain its original curriculum length.
51
- inference_max_position_embeddings (:obj:`int`, *optional*, defaults
52
- to 32768): Maximum sequence length permitted by the explicit long
53
- context inference mode. This is a runtime guardrail, not a
54
- training setting.
55
- allow_long_context_inference (:obj:`bool`, *optional*, defaults to
56
- ``False``): If true, ``NeoLLMForCausalLM.generate`` temporarily
57
- exposes ``inference_max_position_embeddings`` to Transformers'
58
- generation length checks. Training is never affected.
59
- strict_cache_parity (:obj:`bool`, *optional*, defaults to ``False``):
60
- Disable low-precision incremental cache decoding and use the full
61
- sequence fallback when exact greedy parity is required. This is an
62
- inference-only safety switch; it takes priority over the default
63
- performance mode enabled by ``allow_cache_numerical_drift``.
64
  initializer_range (:obj:`float`, *optional*, defaults to 0.02):
65
  Standard deviation of the truncated-normal weight initializer.
66
  rms_norm_eps (:obj:`float`, *optional*, defaults to 1e-6):
@@ -123,9 +100,8 @@ class NeoLLMConfig(PretrainedConfig):
123
  Base period for Rotary Position Embeddings (RoPE).
124
  rope_scaling (:obj:`dict`, *optional*):
125
  Dictionary containing the RoPE scaling configuration. Must contain at
126
- least the key ``"rope_type"`` (or ``"type"``). Validated by the
127
- current ``PretrainedConfig.validate_rope`` API, with a compatibility
128
- fallback for older Transformers releases.
129
  partial_rotary_factor (:obj:`float`, *optional*, defaults to 0.25):
130
  Fraction of each attention head's dimension to rotate with RoPE.
131
  attention_bias (:obj:`bool`, *optional*, defaults to ``False``):
@@ -184,9 +160,7 @@ class NeoLLMConfig(PretrainedConfig):
184
  input-dependent per-head scaling factor α and a moving-average bias β
185
  directly to the softmax-normalized attention weights before the
186
  weighted sum with V:
187
-
188
  [α(X) · softmax(QKᵀ/√dk) + β(X)] V
189
-
190
  This relaxes the unit-sum constraint of softmax, reduces first-token
191
  bias, increases attention entropy, and promotes head diversity.
192
  Orthogonal to Gated Attention: the gate modulates the post-SDPA
@@ -204,15 +178,12 @@ class NeoLLMConfig(PretrainedConfig):
204
  along the direction of the token's own value vector, forcing the
205
  attention layer to carry only contextual information orthogonal to
206
  self-position.
207
-
208
  Two paths depending on active components:
209
-
210
  - **MEA active or LUCID active**: ``v_ref`` is the value vector
211
  after MEA mixing and after LUCID preconditioning — the vector that
212
  actually participated in the SDPA aggregation.
213
  - **MEA and LUCID inactive**: ``v_ref`` is the raw value projection
214
  — standard XSA as described in the paper.
215
-
216
  Applied after MEAHeadRMSNorm and before the Gated Attention gate.
217
  Gains increase with sequence length.
218
  xsa_eps (:obj:`float`, *optional*, defaults to 1e-6):
@@ -236,7 +207,6 @@ class NeoLLMConfig(PretrainedConfig):
236
  stack_memory_cache_size (:obj:`int`, *optional*, defaults to ``2048``):
237
  Cache length kept for parity with the released StackTrans source.
238
  The default training path keeps this cache disabled.
239
-
240
  fan_ratio (:obj:`float`, *optional*, defaults to 0.125):
241
  Ratio controlling the periodic-dimension size in FANformer attention.
242
  The transformed representation has dimension
@@ -297,9 +267,7 @@ class NeoLLMConfig(PretrainedConfig):
297
  use_token_generator (:obj:`bool`, *optional*, defaults to ``False``):
298
  Replace the discrete vocabulary embedding lookup table with a
299
  **Leviathan** continuous token generator (Batley & Saha, 2026).
300
-
301
  When enabled:
302
-
303
  - ``tie_word_embeddings`` is forced to ``False``.
304
  - ``model.embed_tokens`` is replaced by ``model.token_generator``
305
  (:class:`LeviathanGenerator`).
@@ -307,7 +275,6 @@ class NeoLLMConfig(PretrainedConfig):
307
  ``O(k · ⌈V^{1/k}⌉ · d_seed)`` instead of ``O(V · D)``.
308
  - The output head stays fully untied (``lm_head``), with a total
309
  parameter overhead below 0.2% at 1.2B scale.
310
-
311
  See :class:`LeviathanGenerator` in ``modeling_neollm.py``.
312
  generator_d_seed (:obj:`int`, *optional*, defaults to 128):
313
  Dimensionality of the latent seed space ``z̃ ∈ [0,1]^{d_seed}``,
@@ -341,93 +308,73 @@ class NeoLLMConfig(PretrainedConfig):
341
  use_spelling_bee_embeddings (:obj:`bool`, *optional*, defaults to ``False``):
342
  Augment token embeddings with character-level byte information
343
  (Rabe, Clymo & Dong, 2026).
344
-
345
  Each token's UTF-8 encoding (up to 16 bytes) is embedded through a
346
  shared ``nn.Embedding(256, d)`` table. Byte embeddings are
347
  position-encoded with RoPE using intra-token byte positions (not
348
  sequence positions), averaged over the fixed 16 byte slots, then
349
  averaged with the standard token embedding:
350
-
351
  .. math::
352
  e_{\\text{bee}}(t) = \\frac{1}{2}\\left(e_{\\text{tok}}(t) +
353
  \\frac{1}{16}\\sum_{i=1}^{16}
354
  \\text{RoPE}(e_{\\text{byte}}[b_i], i)\\right)
355
-
356
  The active configuration follows the reference fixed-length mean.
357
  A separate theoretical variant would mask padded positions and use
358
  ``1 / sqrt(|t|)`` over valid bytes; it is intentionally not active
359
  in this training configuration.
360
-
361
  Adds ``256 × hidden_size`` parameters (≈0.13M for d=512).
362
  Zero inference overhead when ``bake_inference_table()`` is called
363
  after training.
364
-
365
  Compatible with all four combinations of ``use_token_generator``
366
  and ``use_spelling_bee_embeddings``.
367
-
368
  **Setup required**: call
369
  ``model.model.spelling_bee.set_byte_table(tokenizer)`` once after
370
  model instantiation (handled automatically by ``setup_model`` in
371
  ``train.py``).
372
-
373
  Reference: Rabe, Clymo & Dong (2026). *Spelling Bee Embeddings for
374
  Language Modeling.* arXiv:2601.18030.
375
-
376
  use_hadamard_o_proj (:obj:`bool`, *optional*, defaults to ``False``):
377
  Replace the dense ``W_O ∈ R^{d×d}`` output projection in every
378
  multi-head attention block with a fixed Walsh–Hadamard Transform
379
  followed by a learnable per-channel affine rescaling
380
  ``α ⊙ FWHT(x)/√d + β``.
381
-
382
  The WHT is a parameter-free orthogonal matrix whose singular values
383
  are all identically 1, so the effective condition number is
384
  ``κ = 1`` by construction and cannot grow during training. This
385
  directly addresses the high-κ pathology (κ up to 10^5) observed in
386
  the dense ``o_proj`` matrices, which causes FP8 per-tensor
387
  quantisation to lose low-magnitude directions entirely.
388
-
389
  Parameter reduction: replaces ``d²`` weights with ``2d``
390
  (``α`` and ``β``), saving ≈25% of attention parameters per block.
391
  Requires ``hidden_size`` to be a power of 2 (512 ✓, 1024 ✓,
392
  768 ✗).
393
-
394
  Reference: Aggarwal & Kumar (2026). *Rethinking Attention Output
395
  Projection: Structured Hadamard Transforms for Efficient
396
  Transformers.* arXiv:2603.08343.
397
-
398
  use_repo (:obj:`bool`, *optional*, defaults to ``False``):
399
  Enable Context Re-Positioning (REPO) in attention layers at or
400
  above ``repo_start_layer`` (Li et al., 2026).
401
-
402
  REPO replaces the fixed linear position indices ``0…L-1`` fed to
403
  RoPE with continuous, data-dependent positions ``z_i = f_ϕ(h_i)``
404
  learned end-to-end. The attention score between tokens ``i`` and
405
  ``j`` becomes:
406
-
407
  .. math::
408
  A^{\\text{REPO}}_{i,j} = q_i^\\top\\, g_\\theta(z_j - z_i)\\, k_j
409
-
410
  where ``g_θ`` is the standard RoPE rotation and ``z_i`` is
411
  predicted from the hidden state ``h_i`` by a lightweight SwiGLU
412
  sub-layer ``f_ϕ``:
413
-
414
  .. math::
415
  r_i = \\text{Swish}(h_i W_g) \\odot (h_i W_c), \\quad
416
  z_i^{(h)} = r_i w_z^{(h)}
417
-
418
  ``W_g, W_c \\in \\mathbb{R}^{d \\times d_p}`` are shared across
419
  all query heads within a layer; ``w_z^{(h)} \\in \\mathbb{R}^{d_p}``
420
  is learned independently per head. The assigned positions are
421
  real-valued and unconstrained — the model may learn constant
422
  (NoPE-like), monotonic (RoPE-like), or hybrid patterns as needed.
423
-
424
  Lower layers (``layer_idx < repo_start_layer``) retain the
425
  standard integer RoPE positions because they primarily capture
426
  surface-level, locally-dependent features that benefit less from
427
  re-positioning (Li et al., 2026, §3).
428
-
429
  Overhead: +0.9% parameters; inference latency negligible.
430
-
431
  repo_start_layer (:obj:`int`, *optional*, defaults to
432
  ``num_hidden_layers // 3``):
433
  Index of the first decoder layer to which REPO is applied.
@@ -435,7 +382,6 @@ class NeoLLMConfig(PretrainedConfig):
435
  integer RoPE positions. Must satisfy
436
  ``0 <= repo_start_layer < num_hidden_layers``.
437
  Ignored when ``use_repo=False``.
438
-
439
  repo_d_p (:obj:`int`, *optional*, defaults to
440
  ``hidden_size // 8``):
441
  Dimensionality of the intermediate position representation
@@ -443,79 +389,55 @@ class NeoLLMConfig(PretrainedConfig):
443
  ``d_p = d/8`` on the assumption that positional information
444
  is less rich than the full hidden representation. Ignored
445
  when ``use_repo=False``.
446
-
447
  use_repo_grape (:obj:`bool`, *optional*, defaults to ``False``):
448
  Enable the proposed REPO-GRAPE positional operator. This reuses
449
  the REPO coordinate module ``f_ϕ`` and replaces the RoPE action
450
  with a GRAPE-M action using a learned per-head/per-plane angular
451
  spectrum:
452
-
453
  .. math::
454
  u_i^{(h)} = z_i^{(h)}, \\quad
455
  \\theta_{h,r}=\\theta^0_r\\exp(s_{h,r})
456
-
457
  When enabled, REPO-GRAPE activates the REPO coordinate path at
458
  ``repo_start_layer`` even if ``use_repo=False``. Lower layers keep
459
  standard integer RoPE.
460
-
461
- use_repo_grape_triton (:obj:`bool`, *optional*, defaults to ``False``):
462
- Enable the optional ``cut-cross-entropy`` Triton acceleration for
463
- REPO-GRAPE during inference. The model unconditionally keeps the
464
- reference PyTorch route for training or gradient-enabled forwards;
465
- unsupported shapes also fall back to that route.
466
-
467
  use_laurel (:obj:`bool`, *optional*, defaults to ``False``):
468
  Enable the Learned Augmented Residual Layer (LAUREL) framework
469
  (Menghani, Kumar & Kumar, ICML 2025). LAUREL generalises the
470
  canonical residual connection:
471
-
472
  .. math::
473
  x_{i+1} = \\alpha \\cdot f(x_i) + g(x_i)
474
-
475
  where :math:`g` is a learned linear function operating on the
476
  residual stream. Applied independently to both the attention
477
  and MLP sublayers of every decoder layer.
478
-
479
  At least one of ``use_laurel_rw`` or ``use_laurel_lr`` must be
480
  ``True`` when this flag is active; both may be active
481
  simultaneously, producing the combined **LAUREL-RW+LR** variant
482
  (paper eq. 5).
483
-
484
  Incompatible with ``use_attn_res=True`` — both methods modify
485
  the residual stream and their interaction is undefined.
486
-
487
  Reference: Menghani, G., Kumar, R. & Kumar, S. (2025).
488
  *LAUREL: Learned Augmented Residual Layer.* ICML 2025.
489
-
490
  use_laurel_rw (:obj:`bool`, *optional*, defaults to ``True``):
491
  Enable the **LAUREL-RW** (Residual Weights) variant. Assigns
492
  independent learned scalars :math:`\\alpha, \\beta` to the
493
  sublayer output and residual respectively:
494
-
495
  .. math::
496
  x_{i+1} = \\alpha_s \\cdot f(x_i) + \\beta_s \\cdot x_i
497
-
498
  :math:`\\alpha_s, \\beta_s = \\text{softmax}([\\tilde{\\alpha},
499
  \\tilde{\\beta}])` so that they are non-negative and sum to 1,
500
  preventing unbounded growth (paper §2.1). Adds **2 parameters
501
  per sublayer** (4 per decoder layer).
502
-
503
  When combined with ``use_laurel_lr=True`` (LAUREL-RW+LR,
504
  paper eq. 5):
505
-
506
  .. math::
507
  x_{i+1} = \\alpha_s \\cdot f(x_i)
508
  + \\beta_s \\cdot (B A x_i + x_i)
509
-
510
  Ignored when ``use_laurel=False``.
511
-
512
  use_laurel_lr (:obj:`bool`, *optional*, defaults to ``False``):
513
  Enable the **LAUREL-LR** (Low-Rank) variant. Augments the
514
  residual with a rank-``laurel_lr_rank`` correction:
515
-
516
  .. math::
517
  x_{i+1} = f(x_i) + B A x_i + x_i
518
-
519
  where :math:`A \\in \\mathbb{R}^{D \\times r}` and
520
  :math:`B \\in \\mathbb{R}^{r \\times D}` are learnable matrices
521
  (paper eq. 3). :math:`A` is initialised with column-orthogonal
@@ -524,27 +446,22 @@ class NeoLLMConfig(PretrainedConfig):
524
  convention and ensuring the residual starts as identity
525
  (paper §3.3). Adds **2·r·D parameters per sublayer**
526
  (4·r·D per decoder layer).
527
-
528
  Ignored when ``use_laurel=False``.
529
-
530
  laurel_lr_rank (:obj:`int`, *optional*, defaults to ``32``):
531
  Rank ``r`` of the low-rank matrices in LAUREL-LR. The paper
532
  recommends :math:`r \\in \\{32, 48, 64\\}` for LLMs
533
  (paper §3.3). Ignored when ``use_laurel=False`` or
534
  ``use_laurel_lr=False``.
535
-
536
  use_tweo (:obj:`bool`, *optional*, defaults to ``False``):
537
  Enable Transformers Without Extreme Outliers (TWEO), a
538
  training-only activation regularizer from Liang et al. (2026).
539
  TWEO adds a scaled :math:`L_p` penalty over the final output
540
  activations of every Transformer block:
541
-
542
  .. math::
543
  L_{total} = L_{task} + \lambda L_{TWEO}, \quad
544
  L_{TWEO} = \frac{1}{L}\sum_l
545
  \mathbb{E}\left[\left(\frac{|A^{(l)}|}
546
  {\tau + \epsilon}\right)^p\right]
547
-
548
  This is non-invasive: no architecture, inference path, or
549
  quantization backend is changed. It is intended for FP8/low-bit
550
  training runs where extreme activation outliers are harmful.
@@ -560,7 +477,6 @@ class NeoLLMConfig(PretrainedConfig):
560
  small activations while sharply penalizing extreme outliers.
561
  tweo_eps (:obj:`float`, *optional*, defaults to ``1e-6``):
562
  Numerical stability epsilon added to the TWEO denominator.
563
-
564
  use_nitp_temporal (:obj:`bool`, *optional*, defaults to ``False``):
565
  Instantiate the causal NITP temporal-transition extension. The
566
  module is a separate bias-free multiplicative residual updater and
@@ -613,7 +529,6 @@ class NeoLLMConfig(PretrainedConfig):
613
  Temperature controlling temporal label smoothing. Smaller values
614
  make the correct diagonal step more nearly one-hot, while retaining
615
  limited tolerance for genuinely similar adjacent states.
616
-
617
  Constraints:
618
  - ``use_spelling_bee_embeddings=True`` requires calling
619
  ``model.model.spelling_bee.set_byte_table(tokenizer)`` before
@@ -629,17 +544,13 @@ class NeoLLMConfig(PretrainedConfig):
629
  - ``stack_d_model`` must be divisible by ``num_mem_heads`` when
630
  ``use_stack_memory=True``.
631
  - ``use_nitp_temporal=True`` requires ``use_nitp=True``.
632
-
633
  Examples::
634
-
635
  >>> from configuration_neollm import NeoLLMConfig
636
  >>> from modeling_neollm import NeoLLMForCausalLM
637
-
638
  >>> # Standard dense-embedding model
639
  >>> config = NeoLLMConfig(use_token_generator=False,
640
  ... tie_word_embeddings=True)
641
  >>> model = NeoLLMForCausalLM(config)
642
-
643
  >>> # Full attention stack
644
  >>> config_full = NeoLLMConfig(
645
  ... use_affine_scaled_attention=True,
@@ -647,59 +558,45 @@ class NeoLLMConfig(PretrainedConfig):
647
  ... use_lucid_attention=True,
648
  ... )
649
  >>> model_full = NeoLLMForCausalLM(config_full)
650
-
651
  >>> # Leviathan generator (LEV layer, untied output head)
652
  >>> config_lev = NeoLLMConfig(
653
  ... use_token_generator=True,
654
  ... tie_word_embeddings=False,
655
  ... )
656
-
657
  >>> # REPO: context re-positioning from layer 4 onward (default for 12 layers)
658
  >>> config_repo = NeoLLMConfig(
659
  ... use_repo=True,
660
  ... # repo_start_layer defaults to num_hidden_layers // 3 = 4
661
  ... # repo_d_p defaults to hidden_size // 8 = 64
662
  ... )
663
-
664
  >>> # Proposed REPO-GRAPE-M: REPO coordinates + learned GRAPE spectrum
665
  >>> config_repo_grape = NeoLLMConfig(
666
  ... use_repo_grape=True,
667
  ... )
668
-
669
  >>> # REPO-GRAPE-M + GOAT-style factorised log-prior
670
  >>> config_repo_grape_goat = NeoLLMConfig(
671
  ... use_repo_grape=True,
672
  ... use_repo_goat_prior=True,
673
  ... repo_goat_num_frequencies=3,
674
  ... )
675
-
676
  References:
677
  Bae, J. et al. (2026). *Affine-Scaled Attention: Towards Flexible and
678
  Stable Transformer Attention.* arXiv:2602.23057.
679
-
680
  Duvvuri, S. et al. (2026). *LUCID: Attention with Preconditioned
681
  Representations.* arXiv:2602.10410.
682
-
683
  Zhai, S. (2026). *Exclusive Self Attention.* arXiv:2603.09078.
684
-
685
  Batley, R. T. & Saha, S. (2026). *A Separable Architecture for Continuous
686
  Token Representation in Language Models.* arXiv:2601.22040.
687
-
688
  Robinson, M. et al. (2025). *Token Embeddings Violate the Manifold
689
  Hypothesis.* arXiv:2504.01002.
690
-
691
  Rabe, M. N., Clymo, J. & Dong, Z. (2026). *Spelling Bee Embeddings for
692
  Language Modeling.* arXiv:2601.18030.
693
-
694
  Li, H., Zhao, T., Cai, D. & Sproat, R. (2026). *REPO: Language Models
695
  with Context Re-Positioning.* arXiv:2512.14391.
696
-
697
  Zhang, Y. et al. (2026). *Group Representational Position Encoding.*
698
  ICLR 2026 / arXiv:2512.07805.
699
-
700
  Litman, E. & Guo, G. (2026). *You Need Better Attention Priors.*
701
  arXiv:2601.15380.
702
-
703
  Menghani, G., Kumar, R. & Kumar, S. (2025). *LAUREL: Learned Augmented
704
  Residual Layer.* ICML 2025. arXiv:2411.07501.
705
  """
@@ -717,8 +614,6 @@ class NeoLLMConfig(PretrainedConfig):
717
  num_key_value_heads=4,
718
  hidden_act="xielu",
719
  max_position_embeddings=32768,
720
- inference_max_position_embeddings=32768,
721
- allow_long_context_inference=False,
722
  initializer_range=0.02,
723
  rms_norm_eps=1e-6,
724
  tie_word_embeddings=False,
@@ -761,11 +656,6 @@ class NeoLLMConfig(PretrainedConfig):
761
  mea_groupnorm_eps=1e-6,
762
  use_lucid_attention=False,
763
  lucid_attention_eps=1e-6,
764
- # Eager BF16/FP16 can round reductions differently for q_len=S and
765
- # q_len=1. The optimized inference path is enabled by default; users
766
- # requiring strict parity can set this to False or use strict_cache_parity.
767
- allow_cache_numerical_drift=True,
768
- strict_cache_parity=False,
769
  use_affine_scaled_attention=False,
770
  affine_momentum=0.9,
771
  use_xsa=True,
@@ -819,7 +709,6 @@ class NeoLLMConfig(PretrainedConfig):
819
  repo_start_layer=None,
820
  repo_d_p=None,
821
  use_repo_grape=True,
822
- use_repo_grape_triton=False,
823
  use_repo_goat_prior=False,
824
  repo_goat_num_frequencies=3,
825
  repo_goat_sink_decay=4.0,
@@ -1230,21 +1119,6 @@ class NeoLLMConfig(PretrainedConfig):
1230
  # ── Core Transformer ──────────────────────────────────────────────
1231
  self.vocab_size = vocab_size
1232
  self.max_position_embeddings = max_position_embeddings
1233
- # ``max_position_embeddings`` is the checkpoint's training limit. Do
1234
- # not overwrite it when enabling the inference-only long-context
1235
- # context manager in modeling_neollm.py.
1236
- self.training_max_position_embeddings = int(max_position_embeddings)
1237
- if inference_max_position_embeddings is None:
1238
- inference_max_position_embeddings = max_position_embeddings
1239
- if int(inference_max_position_embeddings) <= 0:
1240
- raise ValueError(
1241
- "`inference_max_position_embeddings` must be positive, got "
1242
- f"{inference_max_position_embeddings}."
1243
- )
1244
- self.inference_max_position_embeddings = int(
1245
- inference_max_position_embeddings
1246
- )
1247
- self.allow_long_context_inference = bool(allow_long_context_inference)
1248
  self.hidden_size = hidden_size
1249
  self.intermediate_size = intermediate_size
1250
  self.num_hidden_layers = num_hidden_layers
@@ -1299,8 +1173,6 @@ class NeoLLMConfig(PretrainedConfig):
1299
  self.mea_groupnorm_eps = mea_groupnorm_eps
1300
  self.use_lucid_attention = use_lucid_attention
1301
  self.lucid_attention_eps = lucid_attention_eps
1302
- self.allow_cache_numerical_drift = bool(allow_cache_numerical_drift)
1303
- self.strict_cache_parity = bool(strict_cache_parity)
1304
  self.use_affine_scaled_attention = use_affine_scaled_attention
1305
  self.affine_momentum = affine_momentum
1306
  self.use_xsa = use_xsa
@@ -1328,14 +1200,7 @@ class NeoLLMConfig(PretrainedConfig):
1328
  self.num_mem_heads = num_mem_heads
1329
  self.stack_slots = stack_slots
1330
  self.stack_memory_cache_size = stack_memory_cache_size
1331
- # Transformers 5.x moved RoPE validation onto PretrainedConfig and the
1332
- # old module-level helper now emits a deprecation warning. Prefer the
1333
- # new method while retaining a path for older installed versions.
1334
- validate_rope = getattr(self, "validate_rope", None)
1335
- if callable(validate_rope):
1336
- validate_rope()
1337
- elif _legacy_rope_config_validation is not None:
1338
- _legacy_rope_config_validation(self)
1339
 
1340
  # ── FANformer periodicity ─────────────────────────────────────────
1341
  self.use_fan_residual = use_fan_residual
@@ -1389,7 +1254,6 @@ class NeoLLMConfig(PretrainedConfig):
1389
  self.repo_start_layer = repo_start_layer
1390
  self.repo_d_p = repo_d_p
1391
  self.use_repo_grape = use_repo_grape
1392
- self.use_repo_grape_triton = bool(use_repo_grape_triton)
1393
  self.use_repo_goat_prior = use_repo_goat_prior
1394
  self.repo_goat_num_frequencies = int(repo_goat_num_frequencies)
1395
  self.repo_goat_sink_decay = float(repo_goat_sink_decay)
@@ -1480,4 +1344,4 @@ class NeoLLMConfig(PretrainedConfig):
1480
  }
1481
 
1482
 
1483
- __all__ = ["NeoLLMConfig"]
 
2
  import math
3
 
4
  from transformers.configuration_utils import PretrainedConfig
5
+ from transformers.modeling_rope_utils import rope_config_validation
 
 
 
 
 
6
  from transformers.utils import logging
7
 
8
  logger = logging.get_logger(__name__)
 
11
  class NeoLLMConfig(PretrainedConfig):
12
  r"""
13
  Configuration class for the NeoLLM model architecture.
 
14
  Instantiates a NeoLLM model according to the specified arguments, defining the
15
  full architecture including attention mechanisms, normalization, periodicity
16
  modeling, an optional Leviathan continuous token embedding generator (LEV
17
  layer, Batley & Saha 2026), and optional Spelling Bee character-level
18
  embedding augmentation.
 
19
  Configuration objects inherit from :class:`~transformers.PretrainedConfig` and
20
  can be used to control the model outputs. Read the documentation from
21
  :class:`~transformers.PretrainedConfig` for more information.
 
22
  Args:
23
  vocab_size (:obj:`int`, *optional*, defaults to 200005):
24
  Vocabulary size of the NeoLLM model. Defines the number of different
 
37
  hidden_act (:obj:`str`, *optional*, defaults to ``"xielu"``):
38
  Non-linear activation function used in the MLP layers.
39
  max_position_embeddings (:obj:`int`, *optional*, defaults to 32768):
40
+ Maximum sequence length supported by the positional encoding.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
  initializer_range (:obj:`float`, *optional*, defaults to 0.02):
42
  Standard deviation of the truncated-normal weight initializer.
43
  rms_norm_eps (:obj:`float`, *optional*, defaults to 1e-6):
 
100
  Base period for Rotary Position Embeddings (RoPE).
101
  rope_scaling (:obj:`dict`, *optional*):
102
  Dictionary containing the RoPE scaling configuration. Must contain at
103
+ least the key ``"rope_type"`` (or ``"type"``). Validated by
104
+ :func:`~transformers.modeling_rope_utils.rope_config_validation`.
 
105
  partial_rotary_factor (:obj:`float`, *optional*, defaults to 0.25):
106
  Fraction of each attention head's dimension to rotate with RoPE.
107
  attention_bias (:obj:`bool`, *optional*, defaults to ``False``):
 
160
  input-dependent per-head scaling factor α and a moving-average bias β
161
  directly to the softmax-normalized attention weights before the
162
  weighted sum with V:
 
163
  [α(X) · softmax(QKᵀ/√dk) + β(X)] V
 
164
  This relaxes the unit-sum constraint of softmax, reduces first-token
165
  bias, increases attention entropy, and promotes head diversity.
166
  Orthogonal to Gated Attention: the gate modulates the post-SDPA
 
178
  along the direction of the token's own value vector, forcing the
179
  attention layer to carry only contextual information orthogonal to
180
  self-position.
 
181
  Two paths depending on active components:
 
182
  - **MEA active or LUCID active**: ``v_ref`` is the value vector
183
  after MEA mixing and after LUCID preconditioning — the vector that
184
  actually participated in the SDPA aggregation.
185
  - **MEA and LUCID inactive**: ``v_ref`` is the raw value projection
186
  — standard XSA as described in the paper.
 
187
  Applied after MEAHeadRMSNorm and before the Gated Attention gate.
188
  Gains increase with sequence length.
189
  xsa_eps (:obj:`float`, *optional*, defaults to 1e-6):
 
207
  stack_memory_cache_size (:obj:`int`, *optional*, defaults to ``2048``):
208
  Cache length kept for parity with the released StackTrans source.
209
  The default training path keeps this cache disabled.
 
210
  fan_ratio (:obj:`float`, *optional*, defaults to 0.125):
211
  Ratio controlling the periodic-dimension size in FANformer attention.
212
  The transformed representation has dimension
 
267
  use_token_generator (:obj:`bool`, *optional*, defaults to ``False``):
268
  Replace the discrete vocabulary embedding lookup table with a
269
  **Leviathan** continuous token generator (Batley & Saha, 2026).
 
270
  When enabled:
 
271
  - ``tie_word_embeddings`` is forced to ``False``.
272
  - ``model.embed_tokens`` is replaced by ``model.token_generator``
273
  (:class:`LeviathanGenerator`).
 
275
  ``O(k · ⌈V^{1/k}⌉ · d_seed)`` instead of ``O(V · D)``.
276
  - The output head stays fully untied (``lm_head``), with a total
277
  parameter overhead below 0.2% at 1.2B scale.
 
278
  See :class:`LeviathanGenerator` in ``modeling_neollm.py``.
279
  generator_d_seed (:obj:`int`, *optional*, defaults to 128):
280
  Dimensionality of the latent seed space ``z̃ ∈ [0,1]^{d_seed}``,
 
308
  use_spelling_bee_embeddings (:obj:`bool`, *optional*, defaults to ``False``):
309
  Augment token embeddings with character-level byte information
310
  (Rabe, Clymo & Dong, 2026).
 
311
  Each token's UTF-8 encoding (up to 16 bytes) is embedded through a
312
  shared ``nn.Embedding(256, d)`` table. Byte embeddings are
313
  position-encoded with RoPE using intra-token byte positions (not
314
  sequence positions), averaged over the fixed 16 byte slots, then
315
  averaged with the standard token embedding:
 
316
  .. math::
317
  e_{\\text{bee}}(t) = \\frac{1}{2}\\left(e_{\\text{tok}}(t) +
318
  \\frac{1}{16}\\sum_{i=1}^{16}
319
  \\text{RoPE}(e_{\\text{byte}}[b_i], i)\\right)
 
320
  The active configuration follows the reference fixed-length mean.
321
  A separate theoretical variant would mask padded positions and use
322
  ``1 / sqrt(|t|)`` over valid bytes; it is intentionally not active
323
  in this training configuration.
 
324
  Adds ``256 × hidden_size`` parameters (≈0.13M for d=512).
325
  Zero inference overhead when ``bake_inference_table()`` is called
326
  after training.
 
327
  Compatible with all four combinations of ``use_token_generator``
328
  and ``use_spelling_bee_embeddings``.
 
329
  **Setup required**: call
330
  ``model.model.spelling_bee.set_byte_table(tokenizer)`` once after
331
  model instantiation (handled automatically by ``setup_model`` in
332
  ``train.py``).
 
333
  Reference: Rabe, Clymo & Dong (2026). *Spelling Bee Embeddings for
334
  Language Modeling.* arXiv:2601.18030.
 
335
  use_hadamard_o_proj (:obj:`bool`, *optional*, defaults to ``False``):
336
  Replace the dense ``W_O ∈ R^{d×d}`` output projection in every
337
  multi-head attention block with a fixed Walsh–Hadamard Transform
338
  followed by a learnable per-channel affine rescaling
339
  ``α ⊙ FWHT(x)/√d + β``.
 
340
  The WHT is a parameter-free orthogonal matrix whose singular values
341
  are all identically 1, so the effective condition number is
342
  ``κ = 1`` by construction and cannot grow during training. This
343
  directly addresses the high-κ pathology (κ up to 10^5) observed in
344
  the dense ``o_proj`` matrices, which causes FP8 per-tensor
345
  quantisation to lose low-magnitude directions entirely.
 
346
  Parameter reduction: replaces ``d²`` weights with ``2d``
347
  (``α`` and ``β``), saving ≈25% of attention parameters per block.
348
  Requires ``hidden_size`` to be a power of 2 (512 ✓, 1024 ✓,
349
  768 ✗).
 
350
  Reference: Aggarwal & Kumar (2026). *Rethinking Attention Output
351
  Projection: Structured Hadamard Transforms for Efficient
352
  Transformers.* arXiv:2603.08343.
 
353
  use_repo (:obj:`bool`, *optional*, defaults to ``False``):
354
  Enable Context Re-Positioning (REPO) in attention layers at or
355
  above ``repo_start_layer`` (Li et al., 2026).
 
356
  REPO replaces the fixed linear position indices ``0…L-1`` fed to
357
  RoPE with continuous, data-dependent positions ``z_i = f_ϕ(h_i)``
358
  learned end-to-end. The attention score between tokens ``i`` and
359
  ``j`` becomes:
 
360
  .. math::
361
  A^{\\text{REPO}}_{i,j} = q_i^\\top\\, g_\\theta(z_j - z_i)\\, k_j
 
362
  where ``g_θ`` is the standard RoPE rotation and ``z_i`` is
363
  predicted from the hidden state ``h_i`` by a lightweight SwiGLU
364
  sub-layer ``f_ϕ``:
 
365
  .. math::
366
  r_i = \\text{Swish}(h_i W_g) \\odot (h_i W_c), \\quad
367
  z_i^{(h)} = r_i w_z^{(h)}
 
368
  ``W_g, W_c \\in \\mathbb{R}^{d \\times d_p}`` are shared across
369
  all query heads within a layer; ``w_z^{(h)} \\in \\mathbb{R}^{d_p}``
370
  is learned independently per head. The assigned positions are
371
  real-valued and unconstrained — the model may learn constant
372
  (NoPE-like), monotonic (RoPE-like), or hybrid patterns as needed.
 
373
  Lower layers (``layer_idx < repo_start_layer``) retain the
374
  standard integer RoPE positions because they primarily capture
375
  surface-level, locally-dependent features that benefit less from
376
  re-positioning (Li et al., 2026, §3).
 
377
  Overhead: +0.9% parameters; inference latency negligible.
 
378
  repo_start_layer (:obj:`int`, *optional*, defaults to
379
  ``num_hidden_layers // 3``):
380
  Index of the first decoder layer to which REPO is applied.
 
382
  integer RoPE positions. Must satisfy
383
  ``0 <= repo_start_layer < num_hidden_layers``.
384
  Ignored when ``use_repo=False``.
 
385
  repo_d_p (:obj:`int`, *optional*, defaults to
386
  ``hidden_size // 8``):
387
  Dimensionality of the intermediate position representation
 
389
  ``d_p = d/8`` on the assumption that positional information
390
  is less rich than the full hidden representation. Ignored
391
  when ``use_repo=False``.
 
392
  use_repo_grape (:obj:`bool`, *optional*, defaults to ``False``):
393
  Enable the proposed REPO-GRAPE positional operator. This reuses
394
  the REPO coordinate module ``f_ϕ`` and replaces the RoPE action
395
  with a GRAPE-M action using a learned per-head/per-plane angular
396
  spectrum:
 
397
  .. math::
398
  u_i^{(h)} = z_i^{(h)}, \\quad
399
  \\theta_{h,r}=\\theta^0_r\\exp(s_{h,r})
 
400
  When enabled, REPO-GRAPE activates the REPO coordinate path at
401
  ``repo_start_layer`` even if ``use_repo=False``. Lower layers keep
402
  standard integer RoPE.
 
 
 
 
 
 
 
403
  use_laurel (:obj:`bool`, *optional*, defaults to ``False``):
404
  Enable the Learned Augmented Residual Layer (LAUREL) framework
405
  (Menghani, Kumar & Kumar, ICML 2025). LAUREL generalises the
406
  canonical residual connection:
 
407
  .. math::
408
  x_{i+1} = \\alpha \\cdot f(x_i) + g(x_i)
 
409
  where :math:`g` is a learned linear function operating on the
410
  residual stream. Applied independently to both the attention
411
  and MLP sublayers of every decoder layer.
 
412
  At least one of ``use_laurel_rw`` or ``use_laurel_lr`` must be
413
  ``True`` when this flag is active; both may be active
414
  simultaneously, producing the combined **LAUREL-RW+LR** variant
415
  (paper eq. 5).
 
416
  Incompatible with ``use_attn_res=True`` — both methods modify
417
  the residual stream and their interaction is undefined.
 
418
  Reference: Menghani, G., Kumar, R. & Kumar, S. (2025).
419
  *LAUREL: Learned Augmented Residual Layer.* ICML 2025.
 
420
  use_laurel_rw (:obj:`bool`, *optional*, defaults to ``True``):
421
  Enable the **LAUREL-RW** (Residual Weights) variant. Assigns
422
  independent learned scalars :math:`\\alpha, \\beta` to the
423
  sublayer output and residual respectively:
 
424
  .. math::
425
  x_{i+1} = \\alpha_s \\cdot f(x_i) + \\beta_s \\cdot x_i
 
426
  :math:`\\alpha_s, \\beta_s = \\text{softmax}([\\tilde{\\alpha},
427
  \\tilde{\\beta}])` so that they are non-negative and sum to 1,
428
  preventing unbounded growth (paper §2.1). Adds **2 parameters
429
  per sublayer** (4 per decoder layer).
 
430
  When combined with ``use_laurel_lr=True`` (LAUREL-RW+LR,
431
  paper eq. 5):
 
432
  .. math::
433
  x_{i+1} = \\alpha_s \\cdot f(x_i)
434
  + \\beta_s \\cdot (B A x_i + x_i)
 
435
  Ignored when ``use_laurel=False``.
 
436
  use_laurel_lr (:obj:`bool`, *optional*, defaults to ``False``):
437
  Enable the **LAUREL-LR** (Low-Rank) variant. Augments the
438
  residual with a rank-``laurel_lr_rank`` correction:
 
439
  .. math::
440
  x_{i+1} = f(x_i) + B A x_i + x_i
 
441
  where :math:`A \\in \\mathbb{R}^{D \\times r}` and
442
  :math:`B \\in \\mathbb{R}^{r \\times D}` are learnable matrices
443
  (paper eq. 3). :math:`A` is initialised with column-orthogonal
 
446
  convention and ensuring the residual starts as identity
447
  (paper §3.3). Adds **2·r·D parameters per sublayer**
448
  (4·r·D per decoder layer).
 
449
  Ignored when ``use_laurel=False``.
 
450
  laurel_lr_rank (:obj:`int`, *optional*, defaults to ``32``):
451
  Rank ``r`` of the low-rank matrices in LAUREL-LR. The paper
452
  recommends :math:`r \\in \\{32, 48, 64\\}` for LLMs
453
  (paper §3.3). Ignored when ``use_laurel=False`` or
454
  ``use_laurel_lr=False``.
 
455
  use_tweo (:obj:`bool`, *optional*, defaults to ``False``):
456
  Enable Transformers Without Extreme Outliers (TWEO), a
457
  training-only activation regularizer from Liang et al. (2026).
458
  TWEO adds a scaled :math:`L_p` penalty over the final output
459
  activations of every Transformer block:
 
460
  .. math::
461
  L_{total} = L_{task} + \lambda L_{TWEO}, \quad
462
  L_{TWEO} = \frac{1}{L}\sum_l
463
  \mathbb{E}\left[\left(\frac{|A^{(l)}|}
464
  {\tau + \epsilon}\right)^p\right]
 
465
  This is non-invasive: no architecture, inference path, or
466
  quantization backend is changed. It is intended for FP8/low-bit
467
  training runs where extreme activation outliers are harmful.
 
477
  small activations while sharply penalizing extreme outliers.
478
  tweo_eps (:obj:`float`, *optional*, defaults to ``1e-6``):
479
  Numerical stability epsilon added to the TWEO denominator.
 
480
  use_nitp_temporal (:obj:`bool`, *optional*, defaults to ``False``):
481
  Instantiate the causal NITP temporal-transition extension. The
482
  module is a separate bias-free multiplicative residual updater and
 
529
  Temperature controlling temporal label smoothing. Smaller values
530
  make the correct diagonal step more nearly one-hot, while retaining
531
  limited tolerance for genuinely similar adjacent states.
 
532
  Constraints:
533
  - ``use_spelling_bee_embeddings=True`` requires calling
534
  ``model.model.spelling_bee.set_byte_table(tokenizer)`` before
 
544
  - ``stack_d_model`` must be divisible by ``num_mem_heads`` when
545
  ``use_stack_memory=True``.
546
  - ``use_nitp_temporal=True`` requires ``use_nitp=True``.
 
547
  Examples::
 
548
  >>> from configuration_neollm import NeoLLMConfig
549
  >>> from modeling_neollm import NeoLLMForCausalLM
 
550
  >>> # Standard dense-embedding model
551
  >>> config = NeoLLMConfig(use_token_generator=False,
552
  ... tie_word_embeddings=True)
553
  >>> model = NeoLLMForCausalLM(config)
 
554
  >>> # Full attention stack
555
  >>> config_full = NeoLLMConfig(
556
  ... use_affine_scaled_attention=True,
 
558
  ... use_lucid_attention=True,
559
  ... )
560
  >>> model_full = NeoLLMForCausalLM(config_full)
 
561
  >>> # Leviathan generator (LEV layer, untied output head)
562
  >>> config_lev = NeoLLMConfig(
563
  ... use_token_generator=True,
564
  ... tie_word_embeddings=False,
565
  ... )
 
566
  >>> # REPO: context re-positioning from layer 4 onward (default for 12 layers)
567
  >>> config_repo = NeoLLMConfig(
568
  ... use_repo=True,
569
  ... # repo_start_layer defaults to num_hidden_layers // 3 = 4
570
  ... # repo_d_p defaults to hidden_size // 8 = 64
571
  ... )
 
572
  >>> # Proposed REPO-GRAPE-M: REPO coordinates + learned GRAPE spectrum
573
  >>> config_repo_grape = NeoLLMConfig(
574
  ... use_repo_grape=True,
575
  ... )
 
576
  >>> # REPO-GRAPE-M + GOAT-style factorised log-prior
577
  >>> config_repo_grape_goat = NeoLLMConfig(
578
  ... use_repo_grape=True,
579
  ... use_repo_goat_prior=True,
580
  ... repo_goat_num_frequencies=3,
581
  ... )
 
582
  References:
583
  Bae, J. et al. (2026). *Affine-Scaled Attention: Towards Flexible and
584
  Stable Transformer Attention.* arXiv:2602.23057.
 
585
  Duvvuri, S. et al. (2026). *LUCID: Attention with Preconditioned
586
  Representations.* arXiv:2602.10410.
 
587
  Zhai, S. (2026). *Exclusive Self Attention.* arXiv:2603.09078.
 
588
  Batley, R. T. & Saha, S. (2026). *A Separable Architecture for Continuous
589
  Token Representation in Language Models.* arXiv:2601.22040.
 
590
  Robinson, M. et al. (2025). *Token Embeddings Violate the Manifold
591
  Hypothesis.* arXiv:2504.01002.
 
592
  Rabe, M. N., Clymo, J. & Dong, Z. (2026). *Spelling Bee Embeddings for
593
  Language Modeling.* arXiv:2601.18030.
 
594
  Li, H., Zhao, T., Cai, D. & Sproat, R. (2026). *REPO: Language Models
595
  with Context Re-Positioning.* arXiv:2512.14391.
 
596
  Zhang, Y. et al. (2026). *Group Representational Position Encoding.*
597
  ICLR 2026 / arXiv:2512.07805.
 
598
  Litman, E. & Guo, G. (2026). *You Need Better Attention Priors.*
599
  arXiv:2601.15380.
 
600
  Menghani, G., Kumar, R. & Kumar, S. (2025). *LAUREL: Learned Augmented
601
  Residual Layer.* ICML 2025. arXiv:2411.07501.
602
  """
 
614
  num_key_value_heads=4,
615
  hidden_act="xielu",
616
  max_position_embeddings=32768,
 
 
617
  initializer_range=0.02,
618
  rms_norm_eps=1e-6,
619
  tie_word_embeddings=False,
 
656
  mea_groupnorm_eps=1e-6,
657
  use_lucid_attention=False,
658
  lucid_attention_eps=1e-6,
 
 
 
 
 
659
  use_affine_scaled_attention=False,
660
  affine_momentum=0.9,
661
  use_xsa=True,
 
709
  repo_start_layer=None,
710
  repo_d_p=None,
711
  use_repo_grape=True,
 
712
  use_repo_goat_prior=False,
713
  repo_goat_num_frequencies=3,
714
  repo_goat_sink_decay=4.0,
 
1119
  # ── Core Transformer ──────────────────────────────────────────────
1120
  self.vocab_size = vocab_size
1121
  self.max_position_embeddings = max_position_embeddings
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1122
  self.hidden_size = hidden_size
1123
  self.intermediate_size = intermediate_size
1124
  self.num_hidden_layers = num_hidden_layers
 
1173
  self.mea_groupnorm_eps = mea_groupnorm_eps
1174
  self.use_lucid_attention = use_lucid_attention
1175
  self.lucid_attention_eps = lucid_attention_eps
 
 
1176
  self.use_affine_scaled_attention = use_affine_scaled_attention
1177
  self.affine_momentum = affine_momentum
1178
  self.use_xsa = use_xsa
 
1200
  self.num_mem_heads = num_mem_heads
1201
  self.stack_slots = stack_slots
1202
  self.stack_memory_cache_size = stack_memory_cache_size
1203
+ rope_config_validation(self)
 
 
 
 
 
 
 
1204
 
1205
  # ── FANformer periodicity ─────────────────────────────────────────
1206
  self.use_fan_residual = use_fan_residual
 
1254
  self.repo_start_layer = repo_start_layer
1255
  self.repo_d_p = repo_d_p
1256
  self.use_repo_grape = use_repo_grape
 
1257
  self.use_repo_goat_prior = use_repo_goat_prior
1258
  self.repo_goat_num_frequencies = int(repo_goat_num_frequencies)
1259
  self.repo_goat_sink_decay = float(repo_goat_sink_decay)
 
1344
  }
1345
 
1346
 
1347
+ __all__ = ["NeoLLMConfig"]