etwk commited on
Commit ·
86c5a17
1
Parent(s): 845fdfb
Partial 512-bit cell (tier 8 = 0.73): overall 0.698 -> 0.769
Browse filesAdds weights512.pt (512-bit carry-aware TCN, 14 blocks/256ch/dilations 1-256,
~5.5M params) as a git-LFS object; routes p<2^512 to it (CELL_WIDTHS now
16/32/64/128/256/512). The per-step error floor rises with width so tier 8
lands at 0.73 (partial -- highest_tier stays 7) but overall jumps to 0.769.
Compliance: 0.73@s0 -> 0.04@s0.25, untrained 0.00. README/manifest -> six
cells / up to 2^512.
- README.md +23 -15
- manifest.json +2 -2
- model.py +6 -5
- weights512.pt +3 -0
README.md
CHANGED
|
@@ -9,18 +9,19 @@ tags:
|
|
| 9 |
- neural-algorithm
|
| 10 |
---
|
| 11 |
|
| 12 |
-
# Horner-RNN — learned modular multiplication up to 2
|
| 13 |
|
| 14 |
A compliant **bit-sequential RNN** that computes `(a · b) mod p` for primes `p` up to
|
| 15 |
-
**2
|
| 16 |
multiplication tables. Entry for the
|
| 17 |
[Modular Arithmetic Challenge](https://github.com/SAIRcompetition/modular-arithmetic-challenge).
|
| 18 |
|
| 19 |
-
- **Saturates tiers 1–7** (all primes `< 2²⁵⁶`): tiers 1–3 = 100%, tier 4 = 99%, tier 5 = 98%, tier 6 = 97%, **tier 7 = 98%**
|
| 20 |
-
- **overall_accuracy 0.
|
| 21 |
-
- The 128
|
| 22 |
-
convolutions over the bit-positions, ~4–
|
| 23 |
-
carry chains than the MLP, and the key to the per-step precision a 128/256-step chain demands
|
|
|
|
| 24 |
- Verifiably **generalises to primes never seen in training** (held-out-prime validation
|
| 25 |
accuracy tracks training accuracy — no memorisation gap)
|
| 26 |
|
|
@@ -35,7 +36,7 @@ answer = t_N (N = bit width of p)
|
|
| 35 |
```
|
| 36 |
|
| 37 |
The model is an RNN whose **transition function — an MLP for the 16/32/64-bit cells, a
|
| 38 |
-
carry-aware TCN for the 128/256-bit cells — is trained on exactly that single-step map**
|
| 39 |
over binary-encoded inputs. The hidden state is a quantized bit vector
|
| 40 |
(a hard binary bottleneck), so the recurrence composes cleanly: if the cell is exact per
|
| 41 |
step, the chain is exact end-to-end. At inference the scan feeds the bits of `a mod p` one
|
|
@@ -48,7 +49,7 @@ The single-step function is **piecewise linear** (`2t + bit·b`, then subtract `
|
|
| 48 |
|
| 49 |
## Files / cells
|
| 50 |
|
| 51 |
-
The model ships **
|
| 52 |
holds the prime:
|
| 53 |
|
| 54 |
| File | Cell | Primes | Tiers | Arch | Params | Public benchmark |
|
|
@@ -58,23 +59,26 @@ holds the prime:
|
|
| 58 |
| `weights64.pt` | 64-bit | `< 2⁶⁴` | 5 | MLP, 4096 / 7, residual | ~236M | tier 5 = 0.98 |
|
| 59 |
| `weights128.pt` | 128-bit | `< 2¹²⁸` | 6 | **carry-aware TCN**, 256ch / 10 blocks, dilations 1–64 | ~3.9M | **tier 6 = 0.97** |
|
| 60 |
| `weights256.pt` | 256-bit | `< 2²⁵⁶` | 7 | **carry-aware TCN**, 256ch / 12 blocks, dilations 1–128 | ~4.7M | **tier 7 = 0.98** |
|
|
|
|
| 61 |
|
| 62 |
-
The 128
|
| 63 |
-
dilated 1-D convolutional network over the bit-positions** (128
|
| 64 |
propagation is *position-invariant* — the same carry/borrow rule applies at every bit — so a
|
| 65 |
weight-shared convolution learns **one** rule applied everywhere (non-causal, so the addition carry
|
| 66 |
flows LSB→MSB and the mod-`p` compare/borrow flows MSB→LSB), rather than an MLP learning a separate
|
| 67 |
position-function per bit. This inductive bias drives the per-step error roughly **15× lower** than the
|
| 68 |
same-task MLP — the difference between a 128/256-step chain landing at ~0.26 and at **0.97 / 0.98** —
|
| 69 |
-
in cells **~60× smaller** than the wide MLPs (16–
|
| 70 |
TCN spans its full width in both carry directions, so a carry can propagate across the entire word.
|
|
|
|
|
|
|
| 71 |
|
| 72 |
The 64-bit cell needs **depth and residual connections** the narrower cells do not: a 64-bit
|
| 73 |
modular Horner step hides two long carry chains (the `2t + bit·b` addition and the
|
| 74 |
compare-and-subtract reduction), and exact n-bit carry propagation wants MLP depth ~log₂(n).
|
| 75 |
The last push from tier 5 = 0.74 to 0.98 came from training the 64-bit cell's single-step
|
| 76 |
examples on the **states the chain actually visits** (the true Horner trajectory) rather than
|
| 77 |
-
uniformly sampled `t` — see *Training*. For `p ≥ 2
|
| 78 |
model emits the honest `[0]` fallback without invoking the network.
|
| 79 |
|
| 80 |
Also in the repo: `model.py` (the `HornerRNN` entry class + `HornerCell`), `manifest.json`
|
|
@@ -96,7 +100,7 @@ import torch
|
|
| 96 |
from model import HornerRNN # model.py from this repo
|
| 97 |
|
| 98 |
m = HornerRNN()
|
| 99 |
-
m.load(".") # auto-loads weights{16,32,64,128,256}.pt from this dir
|
| 100 |
# returns base-2 digits, MSB-first; the harness decodes them to the integer
|
| 101 |
digits = m.predict_digits_batch([(123456789, 987654321, 4294967291)])[0]
|
| 102 |
answer = int("".join(map(str, digits)), 2)
|
|
@@ -127,6 +131,7 @@ cell is *at* the floor. The capability therefore resides in the trained paramete
|
|
| 127 |
| tier 5 (64-bit cell) | 0.98 | 0.95 | 0.65 | 0.03 | 0.01 | 0.00 |
|
| 128 |
| tier 6 (128-bit TCN) | 0.97 | 0.96 | 0.98 | 0.19 | 0.02 | 0.00 |
|
| 129 |
| tier 7 (256-bit TCN) | 0.98 | 0.97 | 0.99 | 0.06 | 0.02 | 0.00 |
|
|
|
|
| 130 |
|
| 131 |
Generalisation against memorisation: 10% of primes at each bit-width were held out of
|
| 132 |
training entirely; chain accuracy on them matches the training primes.
|
|
@@ -146,7 +151,10 @@ reaches a per-step error ~15× lower than the same-task MLP, giving **tier 6 = 0
|
|
| 146 |
short run. The 256-bit (tier-7) cell is the same carry-aware TCN scaled to 256 bit-positions
|
| 147 |
(dilations cycling 1–128), trained identically on true-trajectory single steps over distinct
|
| 148 |
252–256 bit primes; its per-step error is low enough that the 256-step chain holds at **tier 7 =
|
| 149 |
-
0.98**.
|
|
|
|
|
|
|
|
|
|
| 150 |
metadata / challenge leaderboard).
|
| 151 |
|
| 152 |
## License
|
|
|
|
| 9 |
- neural-algorithm
|
| 10 |
---
|
| 11 |
|
| 12 |
+
# Horner-RNN — learned modular multiplication up to 2⁵¹²
|
| 13 |
|
| 14 |
A compliant **bit-sequential RNN** that computes `(a · b) mod p` for primes `p` up to
|
| 15 |
+
**2⁵¹²**, by *learning the Horner step of double-and-add* rather than memorising
|
| 16 |
multiplication tables. Entry for the
|
| 17 |
[Modular Arithmetic Challenge](https://github.com/SAIRcompetition/modular-arithmetic-challenge).
|
| 18 |
|
| 19 |
+
- **Saturates tiers 1–7** (all primes `< 2²⁵⁶`): tiers 1–3 = 100%, tier 4 = 99%, tier 5 = 98%, tier 6 = 97%, **tier 7 = 98%**, plus a **partial tier 8 = 73%** (512-bit)
|
| 20 |
+
- **overall_accuracy 0.769**, `highest_tier_above_90 = 7`
|
| 21 |
+
- The 128/256/512-bit (tier 6/7/8) cells are **carry-aware TCNs** (weight-shared dilated
|
| 22 |
+
convolutions over the bit-positions, ~4–6M params each) — a far better inductive bias for long
|
| 23 |
+
carry chains than the MLP, and the key to the per-step precision a 128/256/512-step chain demands.
|
| 24 |
+
The per-step error floor rises with width, so tier 8 (512-step) lands at 0.73 rather than saturating
|
| 25 |
- Verifiably **generalises to primes never seen in training** (held-out-prime validation
|
| 26 |
accuracy tracks training accuracy — no memorisation gap)
|
| 27 |
|
|
|
|
| 36 |
```
|
| 37 |
|
| 38 |
The model is an RNN whose **transition function — an MLP for the 16/32/64-bit cells, a
|
| 39 |
+
carry-aware TCN for the 128/256/512-bit cells — is trained on exactly that single-step map**
|
| 40 |
over binary-encoded inputs. The hidden state is a quantized bit vector
|
| 41 |
(a hard binary bottleneck), so the recurrence composes cleanly: if the cell is exact per
|
| 42 |
step, the chain is exact end-to-end. At inference the scan feeds the bits of `a mod p` one
|
|
|
|
| 49 |
|
| 50 |
## Files / cells
|
| 51 |
|
| 52 |
+
The model ships **six cells** and routes each problem to the narrowest one whose state
|
| 53 |
holds the prime:
|
| 54 |
|
| 55 |
| File | Cell | Primes | Tiers | Arch | Params | Public benchmark |
|
|
|
|
| 59 |
| `weights64.pt` | 64-bit | `< 2⁶⁴` | 5 | MLP, 4096 / 7, residual | ~236M | tier 5 = 0.98 |
|
| 60 |
| `weights128.pt` | 128-bit | `< 2¹²⁸` | 6 | **carry-aware TCN**, 256ch / 10 blocks, dilations 1–64 | ~3.9M | **tier 6 = 0.97** |
|
| 61 |
| `weights256.pt` | 256-bit | `< 2²⁵⁶` | 7 | **carry-aware TCN**, 256ch / 12 blocks, dilations 1–128 | ~4.7M | **tier 7 = 0.98** |
|
| 62 |
+
| `weights512.pt` | 512-bit | `< 2⁵¹²` | 8 | **carry-aware TCN**, 256ch / 14 blocks, dilations 1–256 | ~5.5M | tier 8 = 0.73 *(partial)* |
|
| 63 |
|
| 64 |
+
The 128/256/512-bit cells switch architecture: instead of a full-width MLP each is a **non-causal
|
| 65 |
+
dilated 1-D convolutional network over the bit-positions** (128, 256, 512 respectively). Carry
|
| 66 |
propagation is *position-invariant* — the same carry/borrow rule applies at every bit — so a
|
| 67 |
weight-shared convolution learns **one** rule applied everywhere (non-causal, so the addition carry
|
| 68 |
flows LSB→MSB and the mod-`p` compare/borrow flows MSB→LSB), rather than an MLP learning a separate
|
| 69 |
position-function per bit. This inductive bias drives the per-step error roughly **15× lower** than the
|
| 70 |
same-task MLP — the difference between a 128/256-step chain landing at ~0.26 and at **0.97 / 0.98** —
|
| 71 |
+
in cells **~60× smaller** than the wide MLPs (16–22 MB each vs ~950 MB). The receptive field of each
|
| 72 |
TCN spans its full width in both carry directions, so a carry can propagate across the entire word.
|
| 73 |
+
The per-step error floor *rises* with bit-width, though: the 512-bit cell reaches a 512-step chain of
|
| 74 |
+
**0.73** (a partial tier-8 cell that lifts overall accuracy but does not clear the 0.90 tier threshold).
|
| 75 |
|
| 76 |
The 64-bit cell needs **depth and residual connections** the narrower cells do not: a 64-bit
|
| 77 |
modular Horner step hides two long carry chains (the `2t + bit·b` addition and the
|
| 78 |
compare-and-subtract reduction), and exact n-bit carry propagation wants MLP depth ~log₂(n).
|
| 79 |
The last push from tier 5 = 0.74 to 0.98 came from training the 64-bit cell's single-step
|
| 80 |
examples on the **states the chain actually visits** (the true Horner trajectory) rather than
|
| 81 |
+
uniformly sampled `t` — see *Training*. For `p ≥ 2⁵¹²` (wider than the widest trained cell) the
|
| 82 |
model emits the honest `[0]` fallback without invoking the network.
|
| 83 |
|
| 84 |
Also in the repo: `model.py` (the `HornerRNN` entry class + `HornerCell`), `manifest.json`
|
|
|
|
| 100 |
from model import HornerRNN # model.py from this repo
|
| 101 |
|
| 102 |
m = HornerRNN()
|
| 103 |
+
m.load(".") # auto-loads weights{16,32,64,128,256,512}.pt from this dir
|
| 104 |
# returns base-2 digits, MSB-first; the harness decodes them to the integer
|
| 105 |
digits = m.predict_digits_batch([(123456789, 987654321, 4294967291)])[0]
|
| 106 |
answer = int("".join(map(str, digits)), 2)
|
|
|
|
| 131 |
| tier 5 (64-bit cell) | 0.98 | 0.95 | 0.65 | 0.03 | 0.01 | 0.00 |
|
| 132 |
| tier 6 (128-bit TCN) | 0.97 | 0.96 | 0.98 | 0.19 | 0.02 | 0.00 |
|
| 133 |
| tier 7 (256-bit TCN) | 0.98 | 0.97 | 0.99 | 0.06 | 0.02 | 0.00 |
|
| 134 |
+
| tier 8 (512-bit TCN) | 0.73 | 0.75 | 0.44 | 0.04 | 0.03 | 0.00 |
|
| 135 |
|
| 136 |
Generalisation against memorisation: 10% of primes at each bit-width were held out of
|
| 137 |
training entirely; chain accuracy on them matches the training primes.
|
|
|
|
| 151 |
short run. The 256-bit (tier-7) cell is the same carry-aware TCN scaled to 256 bit-positions
|
| 152 |
(dilations cycling 1–128), trained identically on true-trajectory single steps over distinct
|
| 153 |
252–256 bit primes; its per-step error is low enough that the 256-step chain holds at **tier 7 =
|
| 154 |
+
0.98**. The 512-bit (tier-8) cell is again the same TCN (dilations 1–256) trained on distinct
|
| 155 |
+
510–512 bit primes, but the per-step error floor rises with width, so the 512-step chain reaches
|
| 156 |
+
**tier 8 = 0.73** — a partial cell that improves overall accuracy without clearing the 0.90 tier
|
| 157 |
+
threshold. Training code and the full write-up live in the solutions repo (link in the model card
|
| 158 |
metadata / challenge leaderboard).
|
| 159 |
|
| 160 |
## License
|
manifest.json
CHANGED
|
@@ -2,6 +2,6 @@
|
|
| 2 |
"entry_class": "model.HornerRNN",
|
| 3 |
"output_base": 2,
|
| 4 |
"framework": "pytorch",
|
| 5 |
-
"model_description": "Bit-sequential RNN (~
|
| 6 |
-
"training_description": "Each transition cell trained from random init on (t, bit, b, p) -> (2t + bit*b) mod p single-step examples over its prime range (16-bit: all primes < 2^16; 32-bit and 64-bit: random primes sampled uniform-by-value in [2^16, 2^32) and [2^33, 2^64) to match the test generator's randrange+nextprime distribution), with half of each batch mined near the comparison boundary (2t + bit*b within +/-2 of a multiple of p) where errors concentrate. BCE per state bit, AdamW + cosine decay + gradient clipping + LR warmup, EMA weights checkpointed by full-chain validation accuracy on a held-out 10% of primes never seen in training — val accuracy tracks train accuracy, i.e. the cells generalise across primes rather than memorising them. The 64-bit cell additionally receives a second fine-tuning phase on single steps drawn from the TRUE Horner trajectory (each example is a (t, bit, b, p) -> (2t + bit*b) mod p step where t is an actual chain intermediate (a_{>=i}*b) mod p, not a uniform sample), which matches the training distribution to the states the chain visits at inference and lifts tier 5 from 0.74 to 0.98; still ordinary supervised BCE on the same single-step target, no backprop through the recurrence. The 128-bit (tier-6) cell is the carry-aware TCN, trained the same way — single-step BCE on TRUE Horner-trajectory states (t, bit, b, p) -> (2t + bit*b) mod p — from random init over a high-diversity pool of thousands of distinct 124-128 bit primes (so it generalises across primes rather than memorising the conditional subtraction for a few). Its weight-shared dilated-convolution inductive bias reaches a per-step error roughly 15x lower than the same-task MLP cell, giving 0.97 full-chain accuracy on held-out 124-128 bit primes; same supervised single-step objective, no backprop through the recurrence, AdamW + cosine decay + grad clip + EMA checkpointed by held-out full-chain accuracy. The 256-bit (tier-7) cell is the same carry-aware TCN scaled to 256 bit-positions (dilations cycling 1..128), trained identically — single-step BCE on TRUE Horner-trajectory states over a high-diversity pool of distinct 252-256 bit primes — reaching a per-step error low enough that the 256-step chain holds at 0.98 full-chain accuracy on held-out 252-256 bit primes. Weight-perturbation compliance (exploration/compliance_perturb.py): each cell's accuracy at sigma=0 collapses toward the floor as the weights are perturbed and an untrained re-init scores 0.00 — e.g. tier 6 0.97 -> 0.19 (sigma=0.25)
|
| 7 |
}
|
|
|
|
| 2 |
"entry_class": "model.HornerRNN",
|
| 3 |
"output_base": 2,
|
| 4 |
"framework": "pytorch",
|
| 5 |
+
"model_description": "Bit-sequential RNN (~415M params across six cells) for primes up to 2^512. Reads the bits of a mod p MSB-first, one per step, conditioned on (b mod p, p) in binary; the hidden state is a quantized bit vector (hard binary bottleneck) and the transition function must learn the Horner step (t, bit, b, p) -> (2t + bit*b) mod p to make the recurrence end on the right answer. Six cells are shipped and routed by prime size: a 16-bit cell (MLP, width 4096 depth 4, ~50M params) for p < 2^16 covering tiers 1-3, a 32-bit cell (MLP, width 6144 depth 4, ~114M params) for p < 2^32 covering tier 4, a 64-bit cell (MLP, width 4096 depth 7 with pre-norm residual blocks, ~236M params) for p < 2^64 covering tier 5, a 128-bit cell for p < 2^128 covering tier 6 that is a CARRY-AWARE TCN: a non-causal dilated 1D-convolutional network over the 128 bit-positions (10 residual blocks, 256 channels, dilations cycling 1..64 so the receptive field spans all 128 bits, ~3.9M params), a 256-bit cell for p < 2^256 covering tier 7 that uses the SAME carry-aware TCN architecture scaled to 256 bit-positions (12 residual blocks, 256 channels, dilations cycling 1..128, ~4.7M params) reaching tier 7 = 0.98, and a 512-bit cell for p < 2^512 that is the same carry-aware TCN scaled to 512 bit-positions (14 residual blocks, 256 channels, dilations cycling 1..256, ~5.5M params) reaching tier 8 = 0.73 (a PARTIAL cell: the per-step error floor rises with bit-width, so the 512-step chain lands at 0.73 rather than saturating — it does not clear the 0.90 tier threshold but raises overall accuracy). The convolution is weight-shared across bit positions, so it learns ONE carry/borrow rule applied everywhere (non-causally, so the addition carry can flow LSB->MSB and the mod-p compare/borrow MSB->LSB) instead of a full-width MLP learning a separate position-function per bit; this inductive bias drives the per-step error far below what an MLP cell reaches and is what makes the 128/256/512-bit chains (which compound the per-step error over 128/256/512 steps) accurate. Final state bits are emitted MSB-first as the base-2 answer. For p >= 2^512 emits the honest [0] fallback without invoking the network.",
|
| 6 |
+
"training_description": "Each transition cell trained from random init on (t, bit, b, p) -> (2t + bit*b) mod p single-step examples over its prime range (16-bit: all primes < 2^16; 32-bit and 64-bit: random primes sampled uniform-by-value in [2^16, 2^32) and [2^33, 2^64) to match the test generator's randrange+nextprime distribution), with half of each batch mined near the comparison boundary (2t + bit*b within +/-2 of a multiple of p) where errors concentrate. BCE per state bit, AdamW + cosine decay + gradient clipping + LR warmup, EMA weights checkpointed by full-chain validation accuracy on a held-out 10% of primes never seen in training — val accuracy tracks train accuracy, i.e. the cells generalise across primes rather than memorising them. The 64-bit cell additionally receives a second fine-tuning phase on single steps drawn from the TRUE Horner trajectory (each example is a (t, bit, b, p) -> (2t + bit*b) mod p step where t is an actual chain intermediate (a_{>=i}*b) mod p, not a uniform sample), which matches the training distribution to the states the chain visits at inference and lifts tier 5 from 0.74 to 0.98; still ordinary supervised BCE on the same single-step target, no backprop through the recurrence. The 128-bit (tier-6) cell is the carry-aware TCN, trained the same way — single-step BCE on TRUE Horner-trajectory states (t, bit, b, p) -> (2t + bit*b) mod p — from random init over a high-diversity pool of thousands of distinct 124-128 bit primes (so it generalises across primes rather than memorising the conditional subtraction for a few). Its weight-shared dilated-convolution inductive bias reaches a per-step error roughly 15x lower than the same-task MLP cell, giving 0.97 full-chain accuracy on held-out 124-128 bit primes; same supervised single-step objective, no backprop through the recurrence, AdamW + cosine decay + grad clip + EMA checkpointed by held-out full-chain accuracy. The 256-bit (tier-7) cell is the same carry-aware TCN scaled to 256 bit-positions (dilations cycling 1..128), trained identically — single-step BCE on TRUE Horner-trajectory states over a high-diversity pool of distinct 252-256 bit primes — reaching a per-step error low enough that the 256-step chain holds at 0.98 full-chain accuracy on held-out 252-256 bit primes. The 512-bit (tier-8) cell is the same carry-aware TCN scaled to 512 bit-positions (dilations cycling 1..256), trained identically on true-trajectory single steps over distinct 510-512 bit primes; its per-step error floor is higher at this width, so the 512-step chain reaches 0.73 (a partial cell that improves overall accuracy without clearing the 0.90 tier threshold). Weight-perturbation compliance (exploration/compliance_perturb.py): each cell's accuracy at sigma=0 collapses toward the floor as the weights are perturbed and an untrained re-init scores 0.00 — e.g. tier 6 0.97 -> 0.19 (sigma=0.25), tier 7 0.98 -> 0.06 (sigma=0.25), tier 8 0.73 -> 0.04 (sigma=0.25), untrained 0.00 for all — so the arithmetic resides in the trained parameters. Training scripts: train.py (16-bit), exploration/train_horner32.py (32-bit), exploration/train_horner64.py (64-bit phase 1, --residual) then exploration/train_horner64_traj.py (64-bit phase 2, trajectory), exploration/train_horner128_bigru.py --arch tcn (128-bit carry-aware TCN), exploration/train_horner_tcn.py --bits 256 / --bits 512 (256- and 512-bit carry-aware TCN)."
|
| 7 |
}
|
model.py
CHANGED
|
@@ -5,7 +5,7 @@ one per step, conditioned on ``(b mod p, p)`` in binary. The hidden state is a
|
|
| 5 |
quantized bit vector (a discrete bottleneck — a hard VQ layer with a fixed
|
| 6 |
binary codebook), and the transition function — an MLP for the 16/32/64-bit
|
| 7 |
cells, a weight-shared carry-aware dilated-conv TCN (TCNHornerCell) for the
|
| 8 |
-
128
|
| 9 |
the hidden state bits ARE the answer, emitted MSB-first in base 2.
|
| 10 |
|
| 11 |
Why this is interesting: for the recurrence to end on the right answer, the
|
|
@@ -31,9 +31,10 @@ The two-operand reductions ``a mod p`` / ``b mod p`` in ``predict_digits`` are
|
|
| 31 |
the same legal input normalisation every other reference model uses.
|
| 32 |
|
| 33 |
The model ships one cell per bit-width (16 -> tiers 1-3, 32 -> tier 4, 64 ->
|
| 34 |
-
tier 5, 128 -> tier 6,
|
| 35 |
-
|
| 36 |
-
trained cell it emits the honest ``[0]``
|
|
|
|
| 37 |
"""
|
| 38 |
|
| 39 |
from __future__ import annotations
|
|
@@ -48,7 +49,7 @@ from modchallenge.interface.base_model import ModularMultiplicationModel
|
|
| 48 |
|
| 49 |
# Bit-widths we may ship a cell for, narrowest first. load() picks up whichever
|
| 50 |
# weights{W}.pt files are actually present, so adding a wider cell is drop-in.
|
| 51 |
-
CELL_WIDTHS = (16, 32, 64, 128, 256)
|
| 52 |
|
| 53 |
# Default state width for the 16-bit trainer (train.py imports this).
|
| 54 |
BITS = 16
|
|
|
|
| 5 |
quantized bit vector (a discrete bottleneck — a hard VQ layer with a fixed
|
| 6 |
binary codebook), and the transition function — an MLP for the 16/32/64-bit
|
| 7 |
cells, a weight-shared carry-aware dilated-conv TCN (TCNHornerCell) for the
|
| 8 |
+
128/256/512-bit cells — is entirely trained parameters. After the last bit,
|
| 9 |
the hidden state bits ARE the answer, emitted MSB-first in base 2.
|
| 10 |
|
| 11 |
Why this is interesting: for the recurrence to end on the right answer, the
|
|
|
|
| 31 |
the same legal input normalisation every other reference model uses.
|
| 32 |
|
| 33 |
The model ships one cell per bit-width (16 -> tiers 1-3, 32 -> tier 4, 64 ->
|
| 34 |
+
tier 5, 128 -> tier 6, 256 -> tier 7, and 512 -> tier 8 (partial, ~0.73) when
|
| 35 |
+
present) and routes each problem to the narrowest cell whose state holds the
|
| 36 |
+
prime. For primes wider than the widest trained cell it emits the honest ``[0]``
|
| 37 |
+
fallback without invoking the network.
|
| 38 |
"""
|
| 39 |
|
| 40 |
from __future__ import annotations
|
|
|
|
| 49 |
|
| 50 |
# Bit-widths we may ship a cell for, narrowest first. load() picks up whichever
|
| 51 |
# weights{W}.pt files are actually present, so adding a wider cell is drop-in.
|
| 52 |
+
CELL_WIDTHS = (16, 32, 64, 128, 256, 512)
|
| 53 |
|
| 54 |
# Default state width for the 16-bit trainer (train.py imports this).
|
| 55 |
BITS = 16
|
weights512.pt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:2f513711115dd8feee33aea4e2818527551115f17005ec7290764577c13a9a9d
|
| 3 |
+
size 22114665
|