Skip to content

Commit fb96769

Browse files
committed
transformerless_lm: golden-phase primitive (2π/φ² rhythm)
Function/content alternation primitive: cos(t * golden_angle) modulates rank polarity. Period φ²≈2.618 tokens; boost bounded [1/φ, φ]. Wired into autoregressive_generate and _single_stage_refine after syntax-blend, before subject threading.
1 parent 92afe8c commit fb96769

1 file changed

Lines changed: 39 additions & 0 deletions

File tree

experiments/transformerless_lm/train_self_recursive.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,39 @@ def build_substrate_bigram(vocab_size: int) -> torch.Tensor:
397397
_SUBSTRATE_BIGRAM_ALPHA = 1.0 / (_PHI_FOR_SAMPLING ** math.pi) # ~0.221
398398

399399

400+
def substrate_golden_phase(t_pos: int, probs: torch.Tensor,
401+
vocab_size: int) -> torch.Tensor:
402+
"""Golden-angle phase: functional/content rhythm primitive.
403+
404+
Each position advances a phase counter by the golden angle
405+
2*pi/phi^2 -- the irrational angle that maximizes spread
406+
(sunflower/phyllotaxis canon). cos(phase) modulates rank polarity:
407+
408+
cos(phase) ≈ +1 -> boost LOW rank (functional, common)
409+
cos(phase) ≈ -1 -> boost HIGH rank (content, rare/proper-noun)
410+
cos(phase) ≈ 0 -> neutral (mixed)
411+
412+
Positional axis = "how far". Phase axis = "what kind, now".
413+
Together they collapse word order into the substrate groove.
414+
415+
Polarity: pol(r) = 1 - 2*r/(V-1) in [-1, +1].
416+
Log-boost: log(phi) * cos(phase) * pol (max boost phi, min 1/phi).
417+
Substrate-bounded.
418+
"""
419+
phi = _PHI_FOR_SAMPLING
420+
if vocab_size <= 1:
421+
return probs
422+
golden_angle = 2.0 * math.pi / (phi ** 2)
423+
cos_phase = math.cos(t_pos * golden_angle)
424+
ranks = torch.arange(vocab_size, dtype=probs.dtype,
425+
device=probs.device)
426+
rank_pol = 1.0 - 2.0 * ranks / (vocab_size - 1)
427+
log_boost = math.log(phi) * cos_phase * rank_pol
428+
boost = torch.exp(log_boost)
429+
out = probs * boost
430+
return out / (out.sum() + 1e-8)
431+
432+
400433
def substrate_subject_threading(sequence: list, vocab: list,
401434
probs: torch.Tensor,
402435
is_sentence_start: bool) -> torch.Tensor:
@@ -659,6 +692,9 @@ def autoregressive_generate(model, prompt: torch.Tensor, n_new: int,
659692
probs[0] = substrate_syntax_blend(
660693
int(seq[0, -1]), bigram_prior, probs[0],
661694
context_tokens=ctx_back, vocab=vocab)
695+
# Golden-phase rhythm (functional/content alternation).
696+
probs[0] = substrate_golden_phase(
697+
seq.shape[1], probs[0], vocab_size)
662698
# Cross-sentence subject threading at sentence-starts.
663699
if vocab is not None and seq.shape[1] >= 1:
664700
prev_tok_id = int(seq[0, -1])
@@ -735,6 +771,9 @@ def _single_stage_refine(model, draft, vocab_size, scorer, mode: str,
735771
pos_probs = substrate_syntax_blend(
736772
int(new[0, t_draft - 1]), bigram_prior, pos_probs,
737773
context_tokens=ctx_back, vocab=vocab)
774+
# Golden-phase rhythm (functional/content alternation).
775+
pos_probs = substrate_golden_phase(
776+
t_draft, pos_probs, vocab_size_local)
738777
# Cross-sentence subject threading at sentence-starts.
739778
if vocab is not None and t_draft >= 1:
740779
prev_tok_id = int(new[0, t_draft - 1])

0 commit comments

Comments
 (0)