Skip to content

Commit 92afe8c

Browse files
committed
transformerless_lm: cross-sentence subject threading
substrate_subject_threading: at sentence-start positions, boost tokens that appeared at past sentence-starts (likely subjects). Memory of last F(5)=8 sentence-starts; each contributes F(k)/phi^(pi*k) where k = sentences-ago. Substrate-canonical paragraph-scale topic threading, no English-word lists. Wired into autoregressive_generate and _single_stage_refine, fires only when prev token is .!?\n.
1 parent 9ea77c0 commit 92afe8c

1 file changed

Lines changed: 67 additions & 0 deletions

File tree

experiments/transformerless_lm/train_self_recursive.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,53 @@ 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_subject_threading(sequence: list, vocab: list,
401+
probs: torch.Tensor,
402+
is_sentence_start: bool) -> torch.Tensor:
403+
"""Cross-sentence dependency: at sentence-start positions, boost
404+
tokens that appeared at past sentence-starts (likely subjects).
405+
406+
Maintains a substrate-canonical memory: the last F(5)=8 sentence-
407+
starts. Each contributes a boost F(k)/phi^(pi*k) where k = how
408+
many sentences ago. Most-recent subject boosted full F(0)=1;
409+
older subjects decay by phi^pi per sentence.
410+
411+
Substrate "topic threading" across paragraph scale.
412+
"""
413+
if not is_sentence_start or not vocab:
414+
return probs
415+
# Find tokens at sentence-start positions in the sequence.
416+
sentence_starts = []
417+
for i, tok_id in enumerate(sequence):
418+
tok = vocab[tok_id] if tok_id < len(vocab) else ''
419+
# A token is a sentence-start if it follows .!?, newline,
420+
# OR is at position 0.
421+
if i == 0:
422+
sentence_starts.append(tok_id)
423+
continue
424+
prev = vocab[sequence[i-1]] if sequence[i-1] < len(vocab) else ''
425+
if prev in ('.', '!', '?', '\n'):
426+
# The current token is the subject of a new sentence.
427+
sentence_starts.append(tok_id)
428+
if not sentence_starts:
429+
return probs
430+
# Keep last F(5)=8 sentence-starts.
431+
sentence_starts = sentence_starts[-8:]
432+
n = len(sentence_starts)
433+
phi_pi = _PHI_FOR_SAMPLING ** math.pi
434+
boost = torch.zeros_like(probs)
435+
for i, tok_id in enumerate(reversed(sentence_starts)):
436+
# i=0 = most recent sentence-start
437+
k_tier = min(i, len(_FIB_NUMS_FOR_BIGRAM) - 1)
438+
weight = (_FIB_NUMS_FOR_BIGRAM[k_tier]
439+
/ (phi_pi ** k_tier))
440+
boost[tok_id] += weight
441+
# Apply boost multiplicatively (substrate-canonical log-boost).
442+
boost_factor = 1.0 + boost * (math.pi * math.log(_PHI_FOR_SAMPLING))
443+
out = probs * boost_factor
444+
return out / (out.sum() + 1e-8)
445+
446+
400447
def substrate_sentence_boundary_boost(prev_token: int, vocab: list,
401448
probs: torch.Tensor) -> torch.Tensor:
402449
"""Substrate sentence-boundary primitive.
@@ -612,6 +659,16 @@ def autoregressive_generate(model, prompt: torch.Tensor, n_new: int,
612659
probs[0] = substrate_syntax_blend(
613660
int(seq[0, -1]), bigram_prior, probs[0],
614661
context_tokens=ctx_back, vocab=vocab)
662+
# Cross-sentence subject threading at sentence-starts.
663+
if vocab is not None and seq.shape[1] >= 1:
664+
prev_tok_id = int(seq[0, -1])
665+
prev_str = (vocab[prev_tok_id]
666+
if prev_tok_id < len(vocab) else '')
667+
if prev_str in ('.', '!', '?', '\n'):
668+
seq_list = seq[0].tolist()
669+
probs[0] = substrate_subject_threading(
670+
seq_list, vocab, probs[0],
671+
is_sentence_start=True)
615672
# Substrate anti-stagnation on the full window.
616673
history_aw = seq[0, -21:]
617674
probs[0] = substrate_anti_stagnation(history_aw, probs[0],
@@ -678,6 +735,16 @@ def _single_stage_refine(model, draft, vocab_size, scorer, mode: str,
678735
pos_probs = substrate_syntax_blend(
679736
int(new[0, t_draft - 1]), bigram_prior, pos_probs,
680737
context_tokens=ctx_back, vocab=vocab)
738+
# Cross-sentence subject threading at sentence-starts.
739+
if vocab is not None and t_draft >= 1:
740+
prev_tok_id = int(new[0, t_draft - 1])
741+
prev_str = (vocab[prev_tok_id]
742+
if prev_tok_id < len(vocab) else '')
743+
if prev_str in ('.', '!', '?', '\n'):
744+
seq_list = new[0, :t_draft].tolist()
745+
pos_probs = substrate_subject_threading(
746+
seq_list, vocab, pos_probs,
747+
is_sentence_start=True)
681748
# Anti-stagnation on full prior context.
682749
aw_start = max(0, t_draft - 21)
683750
history_aw = new[0, aw_start:t_draft]

0 commit comments

Comments
 (0)