Skip to content

Commit f604be6

Browse files
committed
transformerless_lm: factor lazy data loading into shared lazy_data module
Per the user's call, lazy-loading is now the default for all new experiments. Extracted from train_lazy_loading.py: fib_positions_in_window(window) -> sorted Fibonacci positions ∈ [0, window) get_fib_strided_batch(encoded, B, window, positions, gen) -> sparse batch get_dense_batch(encoded, B, seq_len, gen) -> comparator only Scaling at the IO axis: window=128: 11 positions (11.6x reduction) window=256: 13 positions (19.7x) window=512: 14 positions (36.6x) window=1024: 16 positions (64.0x) Validated speedup (from results_lazy_loading.json): 1500 steps on TinyShakespeare, dense 165.7s -> fib_strided 29.5s -> 5.62x wall-clock speedup at +3.6% val loss vs dense. The currently-running lazy_training bench (b: dense baseline + v1/v2/v3 lazy-training variants) is still using dense data because it is testing lazy-TRAINING. After that finishes, all new benches default to lazy_data.get_fib_strided_batch.
1 parent 4770dc8 commit f604be6

1 file changed

Lines changed: 71 additions & 0 deletions

File tree

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
"""Fibonacci-strided data ingestion — validated 5.6x training speedup.
2+
3+
The substrate-aligned data loader. Every experiment going forward should
4+
use `get_fib_strided_batch` instead of dense batching unless the
5+
experiment is explicitly testing dense as a comparator.
6+
7+
See results_lazy_loading.json for the validation: 1500 steps on
8+
TinyShakespeare, dense 165.7s → fib_strided 29.5s, val 2.4396 →
9+
2.5274 (+3.6%). Same model, same step count, just substrate-aligned IO.
10+
"""
11+
12+
import torch
13+
14+
15+
# Canonical Fibonacci table — matches omnimcode-core/src/phi_pi_fib.rs:32
16+
FIBONACCI = [1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597]
17+
18+
19+
def fib_positions_in_window(window: int) -> list[int]:
20+
"""Substrate-aligned positions in [0, window).
21+
22+
Returns sorted {0} ∪ {Fibonacci numbers ≤ window-1}.
23+
24+
Examples:
25+
window=128 → [0, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89] (11 pos)
26+
window=256 → [0, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233]
27+
window=1024 → 16 positions
28+
29+
Count grows as log_phi_pi(window), giving ~13x IO reduction at
30+
window=128 and ~64x at window=1024.
31+
"""
32+
return sorted(set([0] + [f for f in FIBONACCI if f < window]))
33+
34+
35+
def get_fib_strided_batch(encoded: torch.Tensor, batch_size: int,
36+
window: int, fib_positions: list[int],
37+
generator: torch.Generator):
38+
"""Return (x, y) batch where x[b, p] is encoded[start_b + fib_positions[p]]
39+
and y[b, p] is the next-token target encoded[start_b + fib_positions[p] + 1].
40+
41+
The "effective" sequence length is `window` but only len(fib_positions)
42+
tokens are actually loaded — substrate-aligned sparse sampling.
43+
44+
Args:
45+
encoded: 1-D int tensor of the corpus.
46+
batch_size: B
47+
window: effective sequence length (max offset = window - 1).
48+
fib_positions: result of fib_positions_in_window(window).
49+
generator: torch.Generator for the start-index sampling.
50+
51+
Returns:
52+
(x, y) each of shape [B, len(fib_positions)] containing token ids.
53+
"""
54+
n = encoded.numel()
55+
fib_t = torch.tensor(fib_positions, dtype=torch.long)
56+
max_off = fib_positions[-1] + 1
57+
ix = torch.randint(0, n - max_off - 1, (batch_size,), generator=generator)
58+
x = torch.stack([encoded[i + fib_t] for i in ix])
59+
y = torch.stack([encoded[i + fib_t + 1] for i in ix])
60+
return x, y
61+
62+
63+
def get_dense_batch(encoded: torch.Tensor, batch_size: int, seq_len: int,
64+
generator: torch.Generator):
65+
"""Standard contiguous-sequence batch. Kept as a comparator only —
66+
new experiments should default to get_fib_strided_batch."""
67+
n = encoded.numel()
68+
ix = torch.randint(0, n - seq_len - 1, (batch_size,), generator=generator)
69+
x = torch.stack([encoded[i:i + seq_len] for i in ix])
70+
y = torch.stack([encoded[i + 1:i + seq_len + 1] for i in ix])
71+
return x, y

0 commit comments

Comments
 (0)