Neithanvarvas commited on
Commit
534be73
·
verified ·
1 Parent(s): f67044e

[UPDATE] Update CBT-18.95M paper, model card, and 16-100d random extrapolation results

Browse files
README.md CHANGED
@@ -19,19 +19,19 @@ metrics:
19
  # 2D Embeddings for Length Generalization in Character-Based Transformers (CBT)
20
 
21
  - **GitHub Repository**: [https://github.com/NeithanT/CBT](https://github.com/NeithanT/CBT)
22
- - **Research Paper**: [RESEARCH_PAPER.md](https://github.com/NeithanT/CBT/blob/main/RESEARCH_PAPER.md) | [Paper PDF](https://github.com/NeithanT/CBT/blob/main/RESEARCH_PAPER.pdf)
23
 
24
  ## 1. Model Overview
25
 
26
  **Character-Based Transformer (CBT)** is an 18.95M-parameter character-level Transformer whose tokens carry a rule-assigned two-dimensional (2D) coordinate $(p, \tau)$ used by **Decoupled 2D Rotary Position Embeddings (2D-RoPE)** alongside **Weight-Tied Recurrent Depth ($R = 3$)**.
27
 
28
- Trained strictly on 1- to 15-digit column additions (with random coordinate shift masking $k=32$, exposing macro column coordinates up to $p_{\max} = 15 + 32 = 47$) and multi-tool dialogues, **CBT-18.95M** (`champion_final.pt`) achieves:
29
- - **100.0% (20/20; 95% Wilson CI [83.9, 100.0]%)** on structured 16- to 50-digit sums (including 50-digit cascading carry $99\dots99 + 1$).
30
- - **100.0% (180/180; 95% Wilson CI [97.9, 100.0]%)** on random multi-carry sums from 16 to 40 digits, and **98.8% (237/240; CI [96.4, 99.6]%)** across 16 to 50 digits (with 238/240 = 99.2% exact `<THINK>` scratchpads and zero `(` delimiter errors).
31
- - **90.0% (18/20)** at 55 digits before degrading beyond the shift-masked coordinate horizon $p_{\max}=47$ (45.0% at 60d, 6.7% at 70d, 0.0% at 80–100d).
32
  - **Equalized 1–15d, $T=1024$ Control Study (12,800 Random Problems)**: When four equalized 100k models (`1D-RoPE Standard`, `1D-RoPE + Offset`, `1D-RoPE + Ruoss et al. 2023 Randomized Positions`, and `Decoupled 2D-RoPE k=32`) are trained on the exact same 1–15d dataset with $T=1024$ and evaluated on 200 random problems per length up to 100d, all three 1D/Ruoss variants score **0.0% (0/200, CI [0.0, 1.9]%)** across 16–100d, whereas equalized 2D-RoPE achieves **81.4% (977/1,200, CI [79.1, 83.5]%)** across 16–40d (up to 92.0% at 16d and 25d).
33
- - **100.0% (26/26; CI [87.1, 100.0]%)** tool routing and **96.2% (25/26)** exact argument extraction across 9 tool schemas on phrasing templates shared with training.
34
- - **88.9% (16/18)** zero-shot OOD tool routing, with **50.0% (8/16)** exact character argument copying (and 68.8% exact or near-exact).
35
 
36
  ---
37
 
@@ -48,7 +48,7 @@ Trained strictly on 1- to 15-digit column additions (with random coordinate shif
48
  | **Attention Heads (H)** | 8 (Head dimension = 64) |
49
  | **Max Sequence Length (T)** | 1024 (Coordinate cache up to 4096) |
50
  | **Positional Embedding** | Decoupled 2D-RoPE (d/2 macro column $p$, d/2 micro step $\tau$; rule-assigned via `compute_2d_coords`) |
51
- | **Coordinate Shift Masking (k)** | $k = 32$ ($p_{\max} = 15 + 32 = 47$ during 1–15d training) |
52
  | **Vocabulary Size** | 115 (14 structural control tags + 101 ASCII characters) |
53
  | **Weight Tying** | W_te == W_lm_head |
54
 
@@ -58,16 +58,16 @@ Trained strictly on 1- to 15-digit column additions (with random coordinate shif
58
 
59
  | Benchmark Suite | Scope / Test Cases | Final Score | 95% Wilson CI |
60
  | :--- | :--- | :--- | :--- |
61
- | **1–15 Digit In-Distribution Sums** | Seen in Training (1–15d) | **100.0%** | -- |
62
- | **16–50 Digit Structured Extrapolation** | 20 Cases (incl. $99\dots99 + 1$) | **100.0% (20/20)** | [83.9, 100.0]% |
63
- | **16–40 Digit Random Multi-Carry Sweep** | 6 Lengths $\times$ 30 Cases ($n=180$, $p \le 40$) | **100.0% (180/180)** | [97.9, 100.0]% |
64
- | **45–50 Digit Random Multi-Carry (At $p_{\max}=47$)** | 2 Lengths $\times$ 30 Cases ($n=60$; 58/60 Think OK) | **95.0% (57/60)** | [86.3, 98.3]% |
65
- | **Pooled 16–50 Digit Random Multi-Carry** | 8 Lengths $\times$ 30 Cases ($n=240$; 238/240 Think OK) | **98.8% (237/240)** | [96.4, 99.6]% |
66
- | **55–100 Digit Beyond Horizon ($p > 47$)** | 55d: 90.0% (18/20), 60d: 45.0% (9/20), 70d: 6.7%, 80–100d: 0.0% | Bounded by $p_{\max}=47$ | -- |
67
- | **Multi-Tool Routing Suite (9 Schemas)** | 26 Template-Matched Cases | **100.0% (26/26)** | [87.1, 100.0]% |
68
- | **Multi-Tool Exact Argument Extraction** | 26 Template-Matched Cases | **96.2% (25/26)** | [81.1, 99.3]% |
69
- | **Zero-Shot OOD Tool Selection** | 18 Unseen Prompts | **88.9% (16/18)** | [67.2, 96.9]% |
70
- | **Zero-Shot OOD Exact Argument Copy** | 16 Correctly Routed OOD Prompts | **50.0% (8/16)** | [28.0, 72.0]% |
71
 
72
  ---
73
 
 
19
  # 2D Embeddings for Length Generalization in Character-Based Transformers (CBT)
20
 
21
  - **GitHub Repository**: [https://github.com/NeithanT/CBT](https://github.com/NeithanT/CBT)
22
+ - **Research Paper**: [RESEARCH_PAPER.md](https://github.com/NeithanT/CBT/blob/main/RESEARCH_PAPER.md)
23
 
24
  ## 1. Model Overview
25
 
26
  **Character-Based Transformer (CBT)** is an 18.95M-parameter character-level Transformer whose tokens carry a rule-assigned two-dimensional (2D) coordinate $(p, \tau)$ used by **Decoupled 2D Rotary Position Embeddings (2D-RoPE)** alongside **Weight-Tied Recurrent Depth ($R = 3$)**.
27
 
28
+ Trained on 1- to 25-digit arithmetic replay, multi-tool dialogues, and search copy, with random coordinate shift masking $k=45$ (macro column coordinates up to $p_{\max} = 25 + 45 = 70$), **CBT-18.95M** (`champion_final.pt`) achieves:
29
+ - **100.0% (240/240; 95% Wilson CI [98.4, 100.0]%)** on random multi-carry sums from 16 to 50 digits, and **100.0% (18/18)** on structured 16- to 50-digit sums (including 50-digit cascading carry $99\dots99 + 1$). Digits 16–25 are seen in training; 30–50 digits are unseen.
30
+ - **98.9% (89/90)** on in-distribution sums at 8, 12, and 15 digits (the single miss is at 15 digits).
31
+ - **100.0% (20/20)** at 55 digits, then **70.0% (14/20)** at 60 digits, **40.0% (6/15)** at 70 digits, and **0.0%** at 80–100 digits (random sweep). A separate teacher-forced suite gives 80% at both 60 and 70 digits.
32
  - **Equalized 1–15d, $T=1024$ Control Study (12,800 Random Problems)**: When four equalized 100k models (`1D-RoPE Standard`, `1D-RoPE + Offset`, `1D-RoPE + Ruoss et al. 2023 Randomized Positions`, and `Decoupled 2D-RoPE k=32`) are trained on the exact same 1–15d dataset with $T=1024$ and evaluated on 200 random problems per length up to 100d, all three 1D/Ruoss variants score **0.0% (0/200, CI [0.0, 1.9]%)** across 16–100d, whereas equalized 2D-RoPE achieves **81.4% (977/1,200, CI [79.1, 83.5]%)** across 16–40d (up to 92.0% at 16d and 25d).
33
+ - **100.0% (90/90)** on a 6-category multi-tool benchmark (the check counts tags only, not argument correctness); **80.8% (21/26)** tool routing and **50.0% (13/26)** exact argument extraction on a 26-case phrasing suite with audited entities.
34
+ - **100.0% (18/18)** zero-shot OOD tool routing, with **55.6% (10/18)** exact argument copying on 18 fresh prompts.
35
 
36
  ---
37
 
 
48
  | **Attention Heads (H)** | 8 (Head dimension = 64) |
49
  | **Max Sequence Length (T)** | 1024 (Coordinate cache up to 4096) |
50
  | **Positional Embedding** | Decoupled 2D-RoPE (d/2 macro column $p$, d/2 micro step $\tau$; rule-assigned via `compute_2d_coords`) |
51
+ | **Coordinate Shift Masking (k)** | $k = 45$ ($p_{\max} = 25 + 45 = 70$ during 1–25d arithmetic replay) |
52
  | **Vocabulary Size** | 115 (14 structural control tags + 101 ASCII characters) |
53
  | **Weight Tying** | W_te == W_lm_head |
54
 
 
58
 
59
  | Benchmark Suite | Scope / Test Cases | Final Score | 95% Wilson CI |
60
  | :--- | :--- | :--- | :--- |
61
+ | **In-Distribution Sums (8, 12, 15 Digits)** | Seen in Training | **98.9% (89/90)** | [94.0, 99.8]% |
62
+ | **16–50 Digit Structured Sums** | 18 Cases (incl. $99\dots99 + 1$) | **100.0% (18/18)** | [82.4, 100.0]% |
63
+ | **16–50 Digit Random Multi-Carry Sweep** | 8 Lengths $\times$ 30 Cases ($n=240$) | **100.0% (240/240)** | [98.4, 100.0]% |
64
+ | **55–70 Digit Random Sweep** | 55d: 20 cases; 60d: 20; 70d: 15 | 55d: **100.0%**; 60d: **70.0%**; 70d: **40.0%** | 55d [83.9, 100.0]%; 60d [48.1, 85.5]%; 70d [19.8, 64.3]% |
65
+ | **80–100 Digit Random Sweep** | 10 Cases per length | **0.0%** | [0.0, 27.8]% |
66
+ | **Multi-Tool Benchmark (6 Categories)** | 90 Dialogues (tag-presence check) | **100.0% (90/90)** | [95.9, 100.0]% |
67
+ | **Multi-Tool Phrasing Routing** | 26 Audited Cases, 9 Schemas | **80.8% (21/26)** | [62.1, 91.5]% |
68
+ | **Multi-Tool Phrasing Exact Arguments** | 26 Audited Cases | **50.0% (13/26)** | [32.1, 67.9]% |
69
+ | **Zero-Shot OOD Routing** | 18 Fresh Prompts | **100.0% (18/18)** | [82.4, 100.0]% |
70
+ | **Zero-Shot OOD Exact Argument Copy** | 18 Fresh Prompts | **55.6% (10/18)** | [33.7, 75.4]% |
71
 
72
  ---
73
 
RESEARCH_PAPER.md CHANGED
@@ -41,7 +41,7 @@ Standard language models rely on subword BPE tokenization, which clumps arbitrar
41
 
42
  A single token like `"45"` fuses the $10^3$ place (`4`) and the $10^2$ place (`5`) into one vector at one 1D index, breaking 1-to-1 place-value alignment between operands (Table 6).
43
 
44
- While character-level Transformers avoid these subword merging artifacts and preserve character-level boundaries, they still fail to extrapolate multi-digit addition under standard 1D positional encodings, succumbing to identical phase drift. Having established that Decoupled 2D-RoPE fixes addition collapse by maintaining invariant decimal place-value coordinates, we formulated our central hypothesis: *Supplying place-value coordinates through Decoupled 2D-RoPE directly to atomic characters removes this extrapolation collapse in character-level models, and this exact coordinate scheme can be extended to multi-turn tool-calling dialogues without degrading them.*
45
 
46
  To test this, we unify arithmetic and structured dialogue into a single character representation:
47
  1. We decompose inputs into **atomic characters** paired with 14 structural discourse tags (e.g., `<USER>`, `<THINK>`, `<CALL>`, `<RESULT>`, `<ANSWER>`).
@@ -98,33 +98,34 @@ To test this hypothesis and achieve maximal algorithmic and tool performance wit
98
 
99
  ## 2. Empirical Results
100
 
101
- We first present the empirical evaluation of the final converged **CBT-18.95M** checkpoint (`champion_final.pt`, trained across Stage 1 Pretraining, Stage 2 Search Copy SFT, and Stage 3 All-Tools 1-Hop Annealing SFT), demonstrating decent, robust performance at small scale across both long-horizon arithmetic extrapolation and structured tool agency. We then dissect its performance against tokenization ablations, 1D baseline comparisons, and isolated 100k-parameter component ablations. All benchmark evaluations throughout this paper use deterministic greedy decoding ($\text{temperature}=0.0$, $\arg\max$). Across all tables, we explicitly label the **digit ranges seen during training** ($1 \le N \le 15$ for CBT-18.95M; $1 \le N \le 12$ for baselines) versus **unseen zero-shot extrapolation ranges** ($16 \le N \le 100$).
102
 
103
  ---
104
 
105
- **Table 2: Executive Benchmark Summary of Final Converged CBT-18.95M (`champion_final.pt`)**
106
- Scores are raw accuracies with 95% Wilson confidence intervals (no pass/fail threshold is applied). Arithmetic extrapolation combines the 20-case structured suite (Table 3) and the 315-problem random multi-carry sweep across 16–100 digits (Table 4); each model was trained once. The OOD copy rows are computed over the 16 correctly routed prompts of Table 5; exact match is the headline metric.
107
 
108
  | Capability Domain | Benchmark Suite / Evaluation Metric | Scope / Test Cases | Training Exposure | Final Score | 95% Wilson CI |
109
  | :--- | :--- | :---: | :---: | :---: | :---: |
110
- | **1. Standalone Sums (2D Math)** | Tier 1: In-Distribution Column Addition | 1–15 Digits | **Seen in Training (1–15d)** | **100.0%** | -- |
111
- | | Tier 2: Structured Extrapolation | 16–50 Digits ($n=20$, incl. $99\dots9+1$) | **Unseen OOD (+1 to +35d)** | **100.0% (20/20)** | [83.9, 100.0]% |
112
- | | Tier 3: Random Multi-Carry Extrapolation (Within $p_{\max}=47$) | 16, 20, 25, 30, 35, 40 Digits ($n=180$) | **Unseen OOD (+1 to +25d)** | **100.0% (180/180)** | [97.9, 100.0]% |
113
- | | Tier 4: Random Multi-Carry at Horizon ($p_{\max}=47$) | 45 & 50 Digits ($n=60$; 58/60 Think OK) | **Unseen OOD (+30 to +35d)** | **95.0% (57/60)** | [86.3, 98.3]% |
114
- | | *Pooled Random Multi-Carry (16–50 Digits)* | *8 Lengths $\times$ 30 Cases ($n=240$; 238/240 Think)* | ***Unseen OOD (+1 to +35d)*** | ***98.8% (237/240)*** | *[96.4, 99.6]%* |
115
- | | Tier 5: Beyond Shift-Masking Horizon ($p > 47$) | 55d ($90\%$), 60d ($45\%$), 70d ($6.7\%$), 80–100d ($0\%$) | **Unseen OOD (+40 to +85d, $p>p_{\max}$)** | **See Table 3B** | -- |
116
- | **2. Multi-Tool & Search Suite** | Multi-Domain Structured Tool Benchmark | 50 Multi-Turn Dialogues | Seen Tool Schemas (6 Domains) | **100.0% (50/50)** | [92.9, 100.0]% |
117
- | | All-Tools 1-Hop Routing Suite (9 Schemas) | 26 Phrasing & Edge Cases | Varied Prepositions & Nonces | **100.0% (26/26)** | [87.1, 100.0]% |
118
- | | Multi-Tool Exact Argument & Entity Extraction | 26 Phrasing & Edge Cases | 1-Hop Pointer Copy from `<USER>` | **96.2% (25/26)** | [81.1, 99.3]% |
119
- | **3. Zero-Shot OOD Queries** | OOD Syntactic Tag Completion (`<THINK>...<CALL>`) | 18 Unseen Domain Prompts | **100% Unseen Prompts/Domains** | **100.0% (18/18)** | [82.4, 100.0]% |
120
- | | OOD Zero-Shot Tool Selection Accuracy | 18 Unseen Domain Prompts | **Unseen Science/Film/Cities/Units** | **88.9% (16/18)** | [67.2, 96.9]% |
121
- | | OOD 1-Hop Character Pointer Copy, **exact match (headline)** | 16 Correctly Routed Cases | **Unseen Target Entities** | **50.0% (8/16)** | [28.0, 72.0]% |
122
- | | secondary: exact or near-exact ($\ge 85\%$ chars) | 16 Correctly Routed Cases | Unseen Target Entities | 68.8% (11/16) | [44.4, 85.8]% |
 
123
 
124
  ---
125
 
126
  **Table 3: Itemized Arithmetic Length Extrapolation Benchmark (1 to 50 Digits), Separating Seen Training Lengths from Unseen Zero-Shot Extrapolation Lengths**
127
- Standard 1D-Char and 50k-BPE models (18.91M) and Dual-Loop HRM-RoPE (1.56M) were trained on **1–12 digits** with a 512-token context window; our **CBT-18.95M** was trained on **1–15 digits** with a 1024-token context window. Part II (16–20 digits) is the clean comparison within the 512-token window: HRM-RoPE (1.56M) extrapolates to 20 digits using Decoupled 2D-RoPE without CBT's three-stage curriculum, whereas the 1D models fail. In Part III (25–50 digits), 25-digit traces ($\approx 360$ tokens) and 35-digit traces ($\approx 500$ tokens) fit within the 512-token context window of the 12d baselines, where 1D-Char fails due to positional drift; 1.56M HRM-RoPE was trained without shift masking ($k=0$) and succeeds up to 20 digits, but fails at 25 and 35 digits because $p > 20$ exceeds its unshifted coordinate horizon; only 50-digit traces ($\approx 715$ tokens) exceed 512 tokens. Extending 1D-Char's frequency table to $T=1024$ still fails due to drift; for strictly equalized 1–15 digit, $T=1024$ training comparisons (including Ruoss et al. randomized positions), see Table 8B.
128
 
129
  | Digit Length | Training Exposure Status | Representative Test Problem | Expected Output | 18.91M 1D-Char | 18.91M 50k-BPE | 1.56M HRM-RoPE | CBT-18.95M (Ours) |
130
  | :--- | :--- | :--- | :---: | :---: | :---: | :---: | :---: |
@@ -152,77 +153,55 @@ Standard 1D-Char and 50k-BPE models (18.91M) and Dual-Loop HRM-RoPE (1.56M) were
152
 
153
  ---
154
 
155
- **Table 3B: Expanded Random Multi-Carry Extrapolation Sweep from 16 to 100 Digits on CBT-18.95M (`champion_final.pt`, $n = 315$ Problems, Seed 20261022)**
156
- Each length evaluates a stratified random mixture (70% uniform random digits with multi-carries, 15% dense carries with $a_i + b_i \ge 9$, and 15% random cascade blocks) under deterministic greedy decoding. Because CBT-18.95M was trained on $N_{\text{train}} \le 15$ digits with shift masking $k = 32$ (Eq. 6), the maximum macro coordinate seen during training is $p_{\max} = 15 + 32 = 47$. CBT-18.95M achieves **100.0% (180/180)** across all tested lengths within the shifted coordinate support ($16 \le d \le 40$), **93.3–96.7%** at the $p_{\max}=47$ boundary ($d=45, 50$), **90.0%** at $d=55$, and then breaks down once $p$ exceeds the shifted training support ($d \ge 60$). CPU throughput measured using batched KV-cached FP32 inference on an Intel Core Ultra 5 125H CPU.
157
 
158
- | Digit Length ($d$) | Max Column ($p$) | Coordinate Regime vs. $p_{\max}=47$ | Test Cases ($n$) | `<THINK>` Scratchpad Acc | Final Answer Exact Match | 95% Wilson CI | `(` Errors / CPU Tok/s |
159
  | :---: | :---: | :--- | :---: | :---: | :---: | :---: | :---: |
160
- | 16 Digits | $p \le 16$ | Within Shifted Support ($p \le 47$) | 30 | **100.0% (30/30)** | **100.0% (30/30)** | [88.6, 100.0]% | 0 / 328.6 tok/s |
161
- | 20 Digits | $p \le 20$ | Within Shifted Support ($p \le 47$) | 30 | **100.0% (30/30)** | **100.0% (30/30)** | [88.6, 100.0]% | 0 / 393.5 tok/s |
162
- | 25 Digits | $p \le 25$ | Within Shifted Support ($p \le 47$) | 30 | **100.0% (30/30)** | **100.0% (30/30)** | [88.6, 100.0]% | 0 / 359.2 tok/s |
163
- | 30 Digits | $p \le 30$ | Within Shifted Support ($p \le 47$) | 30 | **100.0% (30/30)** | **100.0% (30/30)** | [88.6, 100.0]% | 0 / 265.2 tok/s |
164
- | 35 Digits | $p \le 35$ | Within Shifted Support ($p \le 47$) | 30 | **100.0% (30/30)** | **100.0% (30/30)** | [88.6, 100.0]% | 0 / 253.6 tok/s |
165
- | 40 Digits | $p \le 40$ | Within Shifted Support ($p \le 47$) | 30 | **100.0% (30/30)** | **100.0% (30/30)** | [88.6, 100.0]% | 0 / 261.2 tok/s |
166
- | 45 Digits | $p \le 45$ | Near Horizon Boundary ($p \approx 47$) | 30 | **96.7% (29/30)** | **93.3% (28/30)** | [78.7, 98.2]% | 0 / 284.8 tok/s |
167
- | 50 Digits | $p \le 50$ | At Horizon Boundary ($p \approx 47$) | 30 | **96.7% (29/30)** | **96.7% (29/30)** | [83.3, 99.4]% | 0 / 234.7 tok/s |
168
- | **Pooled 16–40d** | $p \le 40$ | **Strictly Within $p_{\max}=47$** | **180** | **100.0% (180/180)** | **100.0% (180/180)** | **[97.9, 100.0]%** | **0 Errors** |
169
- | **Pooled 16–50d** | $p \le 50$ | **Full Target Range (16–50d)** | **240** | **99.2% (238/240)** | **98.8% (237/240)** | **[96.4, 99.6]%** | **0 Errors** |
170
- | 55 Digits | $p \le 55$ | Beyond Shifted Support ($+8$ over $p_{\max}$) | 20 | **95.0% (19/20)** | **90.0% (18/20)** | [69.9, 97.2]% | 0 / 184.2 tok/s |
171
- | 60 Digits | $p \le 60$ | Beyond Shifted Support ($+13$ over $p_{\max}$) | 20 | 45.0% (9/20) | 45.0% (9/20) | [25.8, 65.8]% | 3 / 214.4 tok/s |
172
- | 70 Digits | $p \le 70$ | Beyond Shifted Support ($+23$ over $p_{\max}$) | 15 | 6.7% (1/15) | 6.7% (1/15) | [1.2, 29.8]% | 0 / 202.7 tok/s |
173
- | 80 Digits | $p \le 80$ | Exceeds $p_{\max}$ & $T=1024$ ($T \approx 1149$) | 10 | 0.0% (0/10) | 0.0% (0/10) | [0.0, 27.8]% | 4 / 159.5 tok/s |
174
- | 100 Digits | $p \le 100$ | Exceeds $p_{\max}$ & $T=1024$ ($T \approx 1429$) | 10 | 0.0% (0/10) | 0.0% (0/10) | [0.0, 27.8]% | 1 / 141.3 tok/s |
175
 
176
  ---
177
 
178
- **Table 4: Stage 3 All-Tools 1-Hop Induction SFT Alignment (`champion_final.pt`) vs. Stage 2 Search-Only SFT (`step_7000`)**
179
- Extending the entity-agnostic `<THINK>` + 1-hop `<CALL>` pointer copy architecture across all 9 tool schemas achieves **100.0% (26/26) tool routing** and **96.2% (25/26) exact argument extraction**, resolving preposition and phrasing sensitivities on templates shared with Stage 3 training.
180
-
181
- | Tool Category | User Prompt (`<USER>...`) | Stage 2 Search-Only SFT (`step_7000`) | Stage 3 All-Tools 1-Hop SFT (`champion_final.pt`) | Status |
182
- | :--- | :--- | :--- | :--- | :---: |
183
- | Weather (`on`) | `What is the weather on Rome` | `search(query="Roe Weather")` | `<CALL>get_weather(city="Rome")</CALL>` | `[PASS]` |
184
- | Weather (`in`) | `What is the weather in Rome?` | `search(query="the weather")` | `<CALL>get_weather(city="Rome")</CALL>` | `[PASS]` |
185
- | Weather (short) | `Weather in Tokyo` | `search(query="Tokyo")` | `<CALL>get_weather(city="Tokyo")</CALL>` | `[PASS]` |
186
- | Weather (`How is`) | `How is the weather in Paris` | `search(query="Ineazhather in Paris")` | `<CALL>get_weather(city="Paris")</CALL>` | `[PASS]` |
187
- | Weather (`Check`) | `Check the weather for London` | `search(query="Looath goston")` | `<CALL>get_weather(city="London")</CALL>` | `[PASS]` |
188
- | **Weather (Unseen Nonce)** | `What is the weather in Bloumplik?` | `search(...)` | `<CALL>get_weather(city="Bloumplik")</CALL>` | `[PASS]` |
189
- | Time (`in EST`) | `What is the time in EST` | `search(query="the time")` | `<CALL>get_time(timezone="EST")</CALL>` | `[PASS]` |
190
- | Time (`What time`) | `What time is it in JST` | `search(query="iis STST")` | `<CALL>get_time(timezone="JST")</CALL>` | `[PASS]` |
191
- | Unit (`Convert`) | `Convert 10 km to miles` | `unit_convert(value=10, ...)` | `<CALL>unit_convert(value=10, from_unit="km", to_unit="miles")</CALL>` | `[PASS]` |
192
- | Unit (`How many`) | `How many miles is 25 km` | `calculator(expr="24"1+...")` | `<CALL>unit_convert(value=25, from_unit="km", to_unit="miles")</CALL>` | `[PASS]` |
193
- | Search (Real Entity 1) | `What are tomatoes` | `search(query="tomatoes")` | `<CALL>search(query="tomatoes")</CALL>` | `[PASS]` |
194
- | Search (Real Entity 2) | `Who is Alexander Graham Bell?` | `search(query="Alexander Graham Bell")` | `<CALL>search(query="Alexander Graham Bell")</CALL>` | `[PASS]` |
195
- | **Search (Unseen Nonce 1)** | `What is a bloumplik` | `search(query="bloumplik")` | `<CALL>search(query="bloumplik")</CALL>` | `[PASS]` |
196
- | **Search (Unseen Nonce 2)** | `Define zaimgromp` | `search(query="zaimgromp")` | `<CALL>search(query="zaimgromp")</CALL>` | `[PASS]` |
197
- | Nested JSON (Database) | `Query top 5 active records in engineering.` | `database_query(...)` | `<CALL>database_query(filter={"department": "engineering", ...})</CALL>` | `[PASS]` |
198
- | Nested JSON (API) | `Fetch latency metrics for EU from /v2/metrics.` | `fetch_api(...)` | `<CALL>fetch_api(endpoint="/v2/metrics/latency", params={...})</CALL>` | `[PASS]` |
199
- | Direct Conversational | `Thank you!` | `<ANSWER>Hello! How can I...</ANSWER>` | `<ANSWER>You are very welcome! Let me know if you need anything else.</ANSWER>` | `[PASS]` |
200
 
201
  ---
202
 
203
- **Table 5: Zero-Shot Out-of-Distribution (OOD) Generalization of CBT-18.95M (`champion_final.pt`) on 18 Unseen Prompts**
204
- 18/18 produced well-formed tags; 16/18 (88.9%) were routed to the intended tool (two drift cases); among the 16 routed cases, **8 (50.0%) copied the argument exactly**, 3 were near-exact (11/16 = 68.8% exact or near-exact), and 5 were partial. Near-exact copies are functionally failures for tool calling: `calculator(expr="844 *19")` computes the wrong product and `search(query="zagnarok")` searches the wrong string. Many prompts reuse phrasing templates seen in training; only the entities are novel.
205
-
206
- | Unseen OOD Domain | Unseen User Prompt (`<USER>...`) | Generated Output (`<CALL>...</CALL>`) | Tool Routing | Character Copy Fidelity |
207
- | :--- | :--- | :--- | :---: | :--- |
208
- | OOD Science | `What is quantum physics` | `<CALL>search(query="quantum physics")</CALL>` | `[PASS]` | `[EXACT]` (15/15 chars) |
209
- | OOD Film / Term | `What is interstellar` | `<CALL>search(query="interstellar")</CALL>` | `[PASS]` | `[EXACT]` (12/12 chars) |
210
- | OOD Economics | `Define hyperinflation` | `<CALL>search(query="hyperinflation")</CALL>` | `[PASS]` | `[EXACT]` (14/14 chars) |
211
- | OOD Cuisine | `What is tiramisu?` | `<CALL>search(query="tiramisu")</CALL>` | `[PASS]` | `[EXACT]` (8/8 chars) |
212
- | OOD Astronomy | `What are neutron stars` | `<CALL>search(query="neutron stars")</CALL>` | `[PASS]` | `[EXACT]` (13/13 chars) |
213
- | OOD Weather (City) | `How is the weather in Reykjavik` | `<CALL>get_weather(city="Reykjavik")</CALL>` | `[PASS]` | `[EXACT]` (9/9 chars) |
214
- | OOD Unit (Inverted) | `How many km is 42 miles` | `<CALL>unit_convert(value=42, from_unit="miles", to_unit="km")</CALL>` | `[PASS]` | `[EXACT]` (Inverted order parsed) |
215
- | OOD Timezone | `What time is it in GMT` | `<CALL>get_time(timezone="GMT")</CALL>` | `[PASS]` | `[EXACT]` (3/3 chars) |
216
- | OOD Philosophy | `What is existentialism?` | `<CALL>search(query="existentialis")</CALL>` | `[PASS]` | `[NEAR-EXACT]` (13/14 chars) |
217
- | OOD Mythology | `Tell me about Ragnarok` | `<CALL>search(query="zagnarok")</CALL>` | `[PASS]` | `[NEAR-EXACT]` (7/8 chars) |
218
- | OOD Calculator | `Compute 84 * 19` | `<CALL>calculator(expr="844 *19")</CALL>` | `[PASS]` | `[NEAR-EXACT]` (6/7 chars) |
219
- | OOD Deep Learning | `What are transformers in deep learning` | `<CALL>search(query="transwormers of deep")</CALL>` | `[PASS]` | `[PARTIAL]` (4-word phrase) |
220
- | OOD Music / Instrument | `What is a theremin` | `<CALL>search(query="ther")</CALL>` | `[PASS]` | `[PARTIAL]` (prefix copied) |
221
- | OOD History (2-Word) | `Who was Marcus Aurelius?` | `<CALL>search(query="Arcusnaus")</CALL>` | `[PASS]` | `[PARTIAL]` (2-word blend) |
222
- | OOD Weather (2-Word) | `What is the weather in Buenos Aires?` | `<CALL>get_weather(city="Buris")</CALL>` | `[PASS]` | `[PARTIAL]` (2-word blend) |
223
- | OOD Weather (2-Word) | `Weather on Kuala Lumpur` | `<CALL>get_weather(city="Vuala")</CALL>` | `[PASS]` | `[PARTIAL]` (first word copied) |
224
- | OOD Bio (With Digit) | `Explain crispr cas9` | `<CALL>unit_convert(vanaver="9, ance")</CALL>` | `[DRIFT]` | Digit `9` triggered `unit_convert` |
225
- | OOD Architecture | `Search for brutalist architecture` | `<CALL>get_weather(city="Oncordar")</CALL>` | `[DRIFT]` | Preposition `for` triggered `get_weather` |
226
 
227
  ---
228
 
@@ -230,14 +209,14 @@ Extending the entity-agnostic `<THINK>` + 1-hop `<CALL>` pointer copy architectu
230
 
231
  Tables 2, 3, 3B, 4, and 5 present the evaluation of our final **CBT-18.95M** model (`champion_final.pt`):
232
 
233
- 1. **Zero-Shot Extrapolation from 15 Seen Digits Across 16–100 Unseen Digits (Tables 3 and 3B)**: Trained strictly on numbers of $1 \le N \le 15$ digits with shift masking $k=32$ (exposing macro column coordinates up to $p_{\max} = 15 + 32 = 47$), CBT-18.95M solves **20/20 (100.0%; CI $[83.9, 100.0]\%$)** structured 16–50 digit sums (including $\underbrace{99\dots99}_{50} + 1 = 10^{50}$). To test beyond structured patterns and map the exact breakdown horizon, we evaluated 315 stratified random multi-carry problems across 13 lengths from 16 to 100 digits (Table 3B; 70% uniform random digits, 15% dense carries with $a_i + b_i \ge 9$, 15% cascade chains). Across all 6 tested lengths within the shift-masked coordinate support ($d \in \{16, 20, 25, 30, 35, 40\}$, $p \le 40 \le p_{\max}$), CBT-18.95M achieves **180/180 (100.0%; 95% Wilson CI $[97.9, 100.0]\%$)** exact match. Across the full 16–50 digit random suite ($n = 240$), it achieves **237/240 (98.8%; CI $[96.4, 99.6]\%$)** final answer exact match and **238/240 (99.2%; CI $[97.0, 99.8]\%$)** `<THINK>` scratchpad exact match, with **zero `(` delimiter errors** and zero off-by-one readout errors (the only 3 errors at $d=45, 50$ were single-digit substitutions at the $p \approx 47$ boundary). Beyond $p_{\max} = 47$, accuracy remains **90.0% (18/20)** at 55 digits ($p \le 55$, $+8$ columns beyond shifted training support), then drops to **45.0% (9/20)** at 60 digits, **6.7% (1/15)** at 70 digits, and **0.0%** at 80–100 digits. This empirically demonstrates that Decoupled 2D-RoPE generalizes reliably across unseen sequence lengths $N > N_{\text{train}}$ *up to the maximum coordinate index $p_{\max} = N_{\text{train}} + k$ covered by shift masking during training*, and degrades once $p$ enters rotary angles never observed during training.
234
- 2. **Stage 3 All-Tools 1-Hop Alignment (Table 4, 100.0% Routing, 96.2% Exact Args)**: In Stage 2 (`step_7000`), applying 1-hop copy induction only to `search` caused prompts with varied prepositions (like `"What is the weather on Rome"` or `"How many miles is 25 km"`) to over-route to `search`. In Stage 3 (`champion_final.pt`), transitioning *all nine tool schemas* (`get_weather`, `get_time`, `calculator`, `unit_convert`, `database_query`, `fetch_api`, `create_event`, `file_manager`, and `search`) to the entity-agnostic `<THINK>` + 1-hop `<CALL>` pointer architecture achieved **100.0% (26/26) tool routing** and **96.2% (25/26) exact argument extraction**, even routing unseen nonce cities (`"What is the weather in Bloumplik?"` $\to$ `get_weather(city="Bloumplik")`). Caveat: Stage 3 was trained on the prepositions and templates used in this 26-case suite, whereas Stage 2 never saw them, so the Stage 2 versus Stage 3 comparison is not informative about generalization to new syntax. We did not measure template overlap between the 26 cases and the training generator, and we have no held-out paraphrase set.
235
- 3. **Zero-Shot Out-of-Distribution (OOD) Generalization (Table 5)**: On 18 unseen prompts, CBT-18.95M produced well-formed tags for all 18 (18/18) and routed 16/18 (88.9%) to the intended tool. Among the 16 routed cases, **8 (50.0%) copied the argument exactly**; 3 more were near-exact (`"existentialis"`, `"zagnarok"`, `"844 *19"`), giving 11/16 (68.8%) as a secondary, more lenient figure. Because a near-exact string is an incorrect tool argument, exact match is the relevant metric. Exact copies include single words and short lowercase phrases (`"quantum physics"`, `"interstellar"`, `"hyperinflation"`, `"tiramisu"`, `"neutron stars"`, `"Reykjavik"`), but single-word copying is *not* perfect (`"existentialism"`, `"Ragnarok"`, `"theremin"` fail). Multi-word capitalized proper nouns (`"Buenos Aires"` $\to$ `"Buris"`, `"Marcus Aurelius"` $\to$ `"Arcusnaus"`, `"Kuala Lumpur"` $\to$ `"Vuala"`) blend or truncate, plausibly because the synthetic nonce generator trains on single-word pseudowords (a hypothesis we did not test). An embedded digit (`"crispr cas9"`) and a preposition (`"Search for ..."`) each caused a mis-route.
236
 
237
  ---
238
 
239
  **Table 6: The Tokenization and Positional Geometry Matrix**
240
- Comparing our 2D Matrix Character + Control-Token CBT formulation against 1D Character models, Subword BPE models (4k and 50k vocabularies), Digit-Split 4k BPE, and Learned 2D positional tables, explicitly contrasting **Seen Training Digits** vs. **Unseen Extrapolation Digits**. Vocabulary sizes differ by variant: 115 is the full CBT-18.95M tokenizer, 111 the CBT-200k and Learned-2D variants, and 27 the digit-and-symbol character models. All rows showing `/50` in the Tool Calling column were evaluated on the identical 50-dialogue structured tool suite (6 domains), whereas CBT-18.95M was evaluated on the 26-case 9-schema 1-hop suite of Table 4. Rows were trained with different digit ranges and data and are not a controlled $2\times2$ study. The unseen-sum column pools 14–20 digits, whereas Table 7 reports 14–16 digits separately (hence 2.3% here and 4.6% there for the 1D character model). The Structured Cascade column reports the hardest single-carry chain ($99\dots9+1$) at unseen 20 digits for the 12d models and 50 digits for CBT-18.95M (where CBT-18.95M scores 100.0% on the structured cascade case, contrasting with 96.7% on random 50-digit multi-carries in Table 3B).
241
 
242
  | Tokenizer Granularity | Positional Geometry | Vocab ($V$) | Trained Digits | Tool Calling | Seen Sums (In-Dist) | Unseen Sums (14–20d) | Structured Cascade |
243
  | :--- | :--- | :---: | :---: | :---: | :---: | :---: | :---: |
@@ -248,7 +227,7 @@ Comparing our 2D Matrix Character + Control-Token CBT formulation against 1D Cha
248
  | Atomic Character | NoPE + Abacus Place | 27 | 1–12 Digits | N/A | **0.0%** (1–12d) | **0.0%** (Unseen 14–20d) | **0.0%** (Unseen 20d) |
249
  | Atomic Character | Learned 2D Lookup Table | 111 | 1–12 Digits | 98.0% (49/50) | 100.0% (1–12d) | **0.0%** (Capped $p > 12$) | **0.0%** (Unseen 20d) |
250
  | **CBT-200k (Char + Control)** | **2D-RoPE Matrix ($R=3$)** | **111** | **1–12 Digits** | **100.0% (50/50)** | **100.0% (1–12d)** | **100.0% (Unseen 14–20d)** | **100.0% (Unseen 20d)** |
251
- | **CBT-18.95M (Char + Control)** | **2D-RoPE Matrix ($R=3$)** | **115** | **1–15 Digits** | **100.0% (26/26)** | **100.0% (1–15d)** | **98.8% (237/240 Rand 16–50d)** | **100.0% (50d Struct)** |
252
 
253
  ---
254
 
@@ -269,7 +248,7 @@ Nine 1D/NoPE baselines (the default character model plus eight alternatives, tra
269
  | **HRM-RoPE (Dual-Loop)** | 1.56M | **Decoupled 2D-RoPE** | **1–12 Digits** | 100.0% | 66.7% (14–16d) | **100.0% (18–20d)** | **20 Digits (+8 Unseen Digits)** |
270
  | **CBT-100k ($L=2, R=3$)** | 98.9k | **Decoupled 2D-RoPE** | **1–12 Digits** | **100.0%** | **100.0% (14–16d)** | **100.0% (18–20d)** | **20 Digits (+8 Unseen Digits)** |
271
  | **CBT-200k ($L=4, R=3$)** | 197.8k | **Decoupled 2D-RoPE** | **1–12 Digits** | **100.0%** | **100.0% (14–16d)** | **100.0% (18–20d)** | **20 Digits (+8 Unseen) + Tools** |
272
- | **CBT-18.95M ($L=6, R=3$)** | **18.89M** | **Decoupled 2D-RoPE** | **1–15 Digits** | **100.0%** | **100.0% (16–40d Rand)** | **95.0% (45–50d); 90% (55d)** | **98.8% (16–50d) / $p_{\max}=47$ Bound** |
273
 
274
  ---
275
 
@@ -330,7 +309,7 @@ All four 100k models share the exact same character-level backbone ($L=2, d_{\te
330
  | Unseen 40 Digits ($n=200$ / $n=30$) | **Unseen (+25d)** | 0.0% (0/200) [0.0, 1.9]% | 0.0% (0/200) [0.0, 1.9]% | 0.0% (0/200) [0.0, 1.9]% | **51.5% (103/200)** [44.6, 58.3]% | **100.0% (30/30)** [88.6, 100]% |
331
  | Unseen 45 Digits ($n=200$ / $n=30$) | **Unseen (+30d)** | 0.0% (0/200) [0.0, 1.9]% | 0.0% (0/200) [0.0, 1.9]% | 0.0% (0/200) [0.0, 1.9]% | **30.0% (60/200)** [24.1, 36.7]% | **93.3% (28/30)** [78.7, 98.2]% |
332
  | Unseen 50 Digits ($n=200$ / $n=30$) | **Boundary ($p \approx 47$)** | 0.0% (0/200) [0.0, 1.9]% | 0.0% (0/200) [0.0, 1.9]% | 0.0% (0/200) [0.0, 1.9]% | 0.0% (0/200) [0.0, 1.9]% | **96.7% (29/30)** [83.3, 99.4]% |
333
- | Unseen 55 Digits ($n=200$ / $n=20$) | **Beyond $p_{\max}$ (+8d)** | 0.0% (0/200) [0.0, 1.9]% | 0.0% (0/200) [0.0, 1.9]% | 0.0% (0/200) [0.0, 1.9]% | 0.0% (0/200) [0.0, 1.9]% | **90.0% (18/20)** [69.9, 97.2]% |
334
  | Unseen 60 Digits ($n=200$ / $n=20$) | **Beyond $p_{\max}$ (+13d)** | 0.0% (0/200) [0.0, 1.9]% | 0.0% (0/200) [0.0, 1.9]% | 0.0% (0/200) [0.0, 1.9]% | 0.0% (0/200) [0.0, 1.9]% | 45.0% (9/20) [25.8, 65.8]% |
335
  | Unseen 70–100 Digits ($n=600$ / $n=45$) | **Beyond $p_{\max}$ & Context** | 0.0% (0/600) [0.0, 0.6]% | 0.0% (0/600) [0.0, 0.6]% | 0.0% (0/600) [0.0, 0.6]% | 0.0% (0/600) [0.0, 0.6]% | 2.2% (1/45; 6.7% 70d, 0% 80–100) |
336
  | **Pooled Unseen 16–40d ($n=1,200$ / $n=180$)** | **Within $p_{\max}=47$** | 0.0% (0/1200) [0.0, 0.3]% | 0.0% (0/1200) [0.0, 0.3]% | 0.0% (0/1200) [0.0, 0.3]% | **81.4% (977/1200)** [79.1, 83.5]% | **100.0% (180/180)** [97.9, 100]% |
@@ -344,6 +323,38 @@ Because the 18.91M 1D baselines in Table 7 were trained on 1–12 digits with a
344
 
345
  ---
346
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
347
  ## 3. Architecture, 2D Matrix Embeddings, Tokenizer, and Training Data
348
 
349
  In this section, we provide a complete technical specification of **CBT-18.95M**, detailing its hybrid character-control tokenizer, Decoupled 2D-RoPE embeddings, weight-tied recurrent depth, and the exact composition of the training datasets.
@@ -425,7 +436,7 @@ The $1/\sqrt{R}$ factor is a heuristic residual damping choice. We do not derive
425
 
426
  ---
427
 
428
- **Table 10: Complete Three-Stage Training Data Composition, Digit Horizon Boundaries, and Loss Masking Specification for CBT-18.95M (`champion_final.pt`)**
429
  Across all stages, arithmetic training is strictly bounded to **1–15 digits ($N \le 15$)**. All 16- to 50-digit evaluations are 100% zero-shot out-of-distribution extrapolations.
430
 
431
  | Training Stage | Dataset Component / Sub-Distribution | Pattern / Schema Specification | Trained Digit / Length Scope | Mixture Weight | Supervised Target (Masking Rule) |
@@ -444,7 +455,7 @@ Across all stages, arithmetic training is strictly bounded to **1–15 digits ($
444
 
445
  ### 3.5 Three-Stage Training Data & 1-Hop Induction Curriculum
446
 
447
- Table 10 summarizes the three-stage training protocol that produced `champion_final.pt` on dual NVIDIA T4 GPUs (FP16 AMP):
448
  1. **Stage 1 (Joint Pretraining, 45,059 steps, 247.3M tokens, Loss `0.000094`)**: Trained on a 50%/50% mixture of 1–15 digit column addition (40% asymmetric lengths, 25% symmetric lengths, 20% cascading carries $99\dots9+b$, 15% power-of-ten zero chains) and 6-category structured tool dialogues, with $-100$ loss masking on prompts and `<RESULT>` payloads.
449
  2. **Stage 2 (Search Copy Induction SFT, 7,000 steps, Loss `0.004834`)**: In early SFT tests, repeating an unfamiliar entity $X$ inside `<THINK>` before calling `<CALL>` caused a *2-Hop Copy Bottleneck*, where character n-gram priors hallucinated phonotactic nonces (`"tomatoes"` $\to$ `"smoom"`, `"bloumplik"` $\to$ `"cheat"`). Decoupling `<THINK>` into an invariant intent statement and training on 65% procedurally generated phonotactic pseudowords ($L_{\text{memorize}} \to \infty$) forced a **1-hop induction pointer head** ($p=2 \to p=0$) to copy unseen strings character-by-character.
450
  3. **Stage 3 (All-Tools 1-Hop Annealing SFT, 4,000 steps, LR $5\times 10^{-5} \to 5\times 10^{-6}$, Loss `0.007532`)**: Extended the 1-hop pointer copy formulation across all 9 tool schemas (`get_weather`, `get_time`, `calculator`, `unit_convert`, `database_query`, `fetch_api`, `create_event`, `file_manager`, and `search`) alongside a 10% 1–15 digit math replay buffer, achieving **100.0% (26/26) tool routing**, **96.2% (25/26) exact argument extraction**, and **100.0% 1–50 digit sum extrapolation**.
@@ -471,7 +482,7 @@ However, at compact scales (**100k to 18.95M parameters**), individual forward p
471
 
472
  ### 4.3 Open Questions and Further Testing
473
 
474
- While CBT-18.95M shows that placing characters on a hand-assigned 2D coordinate grid $(p, \tau)$ yields 100.0% accuracy (180/180) on random 16–40 digit sums, 98.8% (237/240) across 16–50 digits, and 90.0% (18/20) at 55 digits before degrading beyond the $p_{\max} = N_{\text{train}} + k = 47$ shift-masking horizon (Table 3B), our OOD and ablation experiments leave several questions open:
475
  1. **Sensitivity to Epoch Reinforcement and Boundary Coordinates**: As shown in our 100k component ablations (Table 8), while several combinations of 2D-RoPE and recurrence achieved identical 78.6% strict match at 12.8 epochs, the off-by-one trailing zero readout error at the $p=1 \to p=0$ boundary disappeared in our runs with higher epoch density (64 epochs on a 1,000-sample pool) or larger capacity (18.95M); however, these single-run comparisons do not isolate whether the fix came from boundary exposure, memorization of the small pool, or model scale.
476
  2. **Multi-Word OOD Pointer Spans and General Algorithms**: In zero-shot OOD testing (Table 5), two-word capitalized proper nouns (`"Buenos Aires"` $\to$ `"Buris"`) still experience partial compression, and our algorithmic generalization scope here focused on $\mathcal{O}(N)$ column sums rather than $\mathcal{O}(N^2)$ multiplication or arbitrary graph algorithms.
477
  3. **Learned Coordinates and Other Tasks**: Emitting hundreds of scratchpad characters is an inefficient simulation of an ALU, the coordinates are hand-assigned, and extrapolation is bounded by the shift-masked coordinate support $p_{\max} = N_{\text{train}} + k$ (Table 3B). Important next steps are learning or inferring $(p, \tau)$, testing on a second task whose coordinates are not trivial (multiplication, sorting, string reversal), running multi-seed training, and comparing against equalized 1D baselines with randomized positions, index hints, and tuned Abacus embeddings [16, 17, 18, 19].
@@ -512,3 +523,7 @@ Starting from the failure of a standard 18.91M-parameter Transformer and eight a
512
  17. Y. Zhou, U. Alon, X. Chen, X. Wang, R. Agarwal, and D. Zhou. *Transformers can achieve length generalization but not robustly*. arXiv preprint arXiv:2402.09371, 2024.
513
  18. S. Duan and Y. Shi. *From interpolation to extrapolation: Complete length generalization for arithmetic transformers*. arXiv preprint arXiv:2310.11984, 2023.
514
  19. Y. Fan, Y. Du, K. Ramchandran, and K. Lee. *Looped transformers for length generalization*. arXiv preprint arXiv:2409.15647, 2024.
 
 
 
 
 
41
 
42
  A single token like `"45"` fuses the $10^3$ place (`4`) and the $10^2$ place (`5`) into one vector at one 1D index, breaking 1-to-1 place-value alignment between operands (Table 6).
43
 
44
+ While character-level Transformers avoid these subword merging artifacts and preserve character-level boundaries [21, 22, 23], embedding-free variants that feed fixed one-hot inputs directly into the blocks have matched or outperformed embedding-table models on translation benchmarks [20], and they still fail to extrapolate multi-digit addition under standard 1D positional encodings, succumbing to identical phase drift. Having established that Decoupled 2D-RoPE fixes addition collapse by maintaining invariant decimal place-value coordinates, we formulated our central hypothesis: *Supplying place-value coordinates through Decoupled 2D-RoPE directly to atomic characters removes this extrapolation collapse in character-level models, and this exact coordinate scheme can be extended to multi-turn tool-calling dialogues without degrading them.*
45
 
46
  To test this, we unify arithmetic and structured dialogue into a single character representation:
47
  1. We decompose inputs into **atomic characters** paired with 14 structural discourse tags (e.g., `<USER>`, `<THINK>`, `<CALL>`, `<RESULT>`, `<ANSWER>`).
 
98
 
99
  ## 2. Empirical Results
100
 
101
+ We first present the evaluation of the final **CBT-18.95M** checkpoint (`champion_final.pt`). It starts from the pre-SFT base `champion_base.pt` (Stage 1 Pretraining, Stage 2 Search Copy SFT, Stage 3 All-Tools 1-Hop SFT) and is further trained with the V4 SFT curriculum (45% multi-tool dialogues, 35% search copy, 20% arithmetic replay with 1–25-digit operands, shift masking $k=45$). Because the replay covers 1–25 digits, **16–25 digits are seen in training for champion, and zero-shot extrapolation begins at 26 digits**; the 1–15 digit framing applies to the pre-SFT base only. The prompts and entities of every champion test below were audited against the champion training corpus. Earlier champion numbers were withdrawn because their test sets overlapped that corpus. All evaluations use deterministic greedy decoding ($\text{temperature}=0.0$, $\arg\max$), and each table labels digit ranges as seen or unseen. We then dissect its performance against tokenization ablations, 1D baseline comparisons, and isolated 100k-parameter component ablations.
102
 
103
  ---
104
 
105
+ **Table 2: Executive Benchmark Summary of CBT-18.95M (`champion_final.pt`)**
106
+ Scores are raw accuracies with 95% Wilson confidence intervals (no pass/fail threshold is applied). Arithmetic rows use teacher-forced greedy agreement with the gold scratchpad, equivalent to greedy reproduction of the sum; the sweep rows use free greedy decoding. OOD exact match is the headline metric over the 18 fresh prompts of Table 5.
107
 
108
  | Capability Domain | Benchmark Suite / Evaluation Metric | Scope / Test Cases | Training Exposure | Final Score | 95% Wilson CI |
109
  | :--- | :--- | :---: | :---: | :---: | :---: |
110
+ | **1. Standalone Sums (2D Math)** | Tier 1: In-Distribution Column Addition | 8, 12, 15 Digits ($n=90$; 30/len) | **Seen (1–25d replay)** | **98.9% (89/90)** | [94.0, 99.8]% |
111
+ | | Tier 2: Structured Cascades & Boundary Cases | 16–50 Digits ($n=18$, incl. $99\dots9+1$) | Seen 16–25d; unseen 30–50d | **100.0% (18/18)** | [82.4, 100.0]% |
112
+ | | Tier 3: Random Multi-Carry | 16, 20, 25, 30, 35, 40 Digits ($n=180$) | Seen 16–25d; unseen 30–40d | **100.0% (180/180)** | [97.9, 100.0]% |
113
+ | | Tier 4: Random Multi-Carry at Horizon | 45 & 50 Digits ($n=60$) | **Unseen (+20 to +25d over replay)** | **100.0% (60/60)** | [94.0, 100.0]% |
114
+ | | *Pooled Random Multi-Carry (16–50 Digits)* | *8 Lengths $\times$ 30 Cases ($n=240$)* | ***Mixed (seen 16–25d, unseen 30–50d)*** | ***100.0% (240/240)*** | *[98.4, 100.0]%* |
115
+ | | Tier 5: Beyond 50 Digits (sweep) | 55d ($n=20$), 60d ($n=20$), 70d ($n=15$), 80d & 100d ($n=10$) | Unseen; 80–100d exceed $p_{\max}=70$ | 55d: **100.0% (20/20)**; 60d: **70.0% (14/20)**; 70d: **40.0% (6/15)**; 80d & 100d: **0.0%** | See Table 3B |
116
+ | | Tier 5b: Beyond 50 Digits (teacher-forced mix, $n=30$/len) | 60d and 70d | Unseen | 60d: **80.0% (24/30)**; 70d: **80.0% (24/30)** | [62.7, 90.5]% |
117
+ | **2. Multi-Tool & Search Suite** | Multi-Domain Structured Tool Benchmark | 90 Dialogues, 6 Categories | Seen tool schemas (generator seed 999) | **100.0% (90/90)** | [95.9, 100.0]% |
118
+ | | Phrasing & Edge-Case Routing (9 schemas) | 26 Phrasing & Edge Cases | Varied prepositions; audited fresh entities | **80.8% (21/26)** | [62.1, 91.5]% |
119
+ | | Phrasing & Edge-Case Exact Arguments | 26 Phrasing & Edge Cases | 1-Hop pointer copy from `<USER>` | **50.0% (13/26)** | [32.1, 67.9]% |
120
+ | **3. Zero-Shot OOD Queries** | OOD Syntactic Tag Completion (`<THINK>...<CALL>`) | 18 Fresh Prompts | Unseen prompts and entities | **100.0% (18/18)** | [82.4, 100.0]% |
121
+ | | OOD Tool Selection (routing) | 18 Fresh Prompts | Unseen entities | **100.0% (18/18)** | [82.4, 100.0]% |
122
+ | | OOD 1-Hop Character Copy, **exact match (headline)** | 18 Fresh Prompts | Unseen entities | **55.6% (10/18)** | [33.7, 75.4]% |
123
+ | | Unseen-30 Head-to-Head, exact match | 30 Unseen Cases | champion vs. pre-SFT base `champion_base.pt` | **56.7% (17/30)** (pre-SFT base 13.3%, 4/30) | champion [39.2, 72.6]% |
124
 
125
  ---
126
 
127
  **Table 3: Itemized Arithmetic Length Extrapolation Benchmark (1 to 50 Digits), Separating Seen Training Lengths from Unseen Zero-Shot Extrapolation Lengths**
128
+ Standard 1D-Char and 50k-BPE models (18.91M) and Dual-Loop HRM-RoPE (1.56M) were trained on **1–12 digits** with a 512-token context window; our **CBT-18.95M** pre-SFT base was trained on **1–15 digits**, and the champion additionally on **1–25-digit** arithmetic replay, all with a 1024-token context window. Part II (16–20 digits) is the clean comparison within the 512-token window: HRM-RoPE (1.56M) extrapolates to 20 digits using Decoupled 2D-RoPE without CBT's three-stage curriculum, whereas the 1D models fail. In Part III (25–50 digits), 25-digit traces ($\approx 360$ tokens) and 35-digit traces ($\approx 500$ tokens) fit within the 512-token context window of the 12d baselines, where 1D-Char fails due to positional drift; 1.56M HRM-RoPE was trained without shift masking ($k=0$) and succeeds up to 20 digits, but fails at 25 and 35 digits because $p > 20$ exceeds its unshifted coordinate horizon; only 50-digit traces ($\approx 715$ tokens) exceed 512 tokens. Extending 1D-Char's frequency table to $T=1024$ still fails due to drift; for strictly equalized 1–15 digit, $T=1024$ training comparisons (including Ruoss et al. randomized positions), see Table 8B.
129
 
130
  | Digit Length | Training Exposure Status | Representative Test Problem | Expected Output | 18.91M 1D-Char | 18.91M 50k-BPE | 1.56M HRM-RoPE | CBT-18.95M (Ours) |
131
  | :--- | :--- | :--- | :---: | :---: | :---: | :---: | :---: |
 
153
 
154
  ---
155
 
156
+ **Table 3B: Random Multi-Carry Extrapolation Sweep from 16 to 100 Digits on CBT-18.95M (`champion_final.pt`, $n = 315$ Problems, Seed 20261022)**
157
+ Each length uses the stratified random mixture (70% uniform random digits with multi-carries, 15% dense carries with $a_i + b_i \ge 9$, 15% random cascade blocks) under deterministic greedy decoding, with KV-cached batched inference (`benchmarks/evaluate_random_16_to_100d.py`). champion was trained with shift masking $k=45$ on 1–25-digit operands, so the maximum macro coordinate seen in training is $p_{\max} = 25 + 45 = 70$. champion is exact on all **240/240** problems from 16 to 50 digits and on 20/20 at 55 digits, then degrades: 14/20 at 60 digits, 6/15 at 70 digits, and 0/10 at 80 and 100 digits. The 60-digit failures occur before $p$ reaches $p_{\max}$, so $p_{\max}$ does not mark a sharp failure point for champion. A separate teacher-forced suite with a different generator (Table 2, Tier 5b) gives 24/30 at both 60 and 70 digits. CPU timings were measured while other evaluations ran in parallel and are therefore only indicative.
158
 
159
+ | Digit Length ($d$) | Max Column ($p$) | Coordinate Regime vs. $p_{\max}=70$ | Test Cases ($n$) | `<THINK>` Scratchpad Acc | Final Answer Exact Match | 95% Wilson CI | `(` Errors / CPU Tok/s |
160
  | :---: | :---: | :--- | :---: | :---: | :---: | :---: | :---: |
161
+ | 16 Digits | $p \le 16$ | Seen in replay (1–25d) | 30 | **100.0% (30/30)** | **100.0% (30/30)** | [88.6, 100.0]% | 0 / 245.6 tok/s |
162
+ | 20 Digits | $p \le 20$ | Seen in replay (1–25d) | 30 | **100.0% (30/30)** | **100.0% (30/30)** | [88.6, 100.0]% | 0 / 215.6 tok/s |
163
+ | 25 Digits | $p \le 25$ | Seen in replay (1–25d) | 30 | **100.0% (30/30)** | **100.0% (30/30)** | [88.6, 100.0]% | 0 / 187.4 tok/s |
164
+ | 30 Digits | $p \le 30$ | Unseen, within $p_{\max}=70$ | 30 | **100.0% (30/30)** | **100.0% (30/30)** | [88.6, 100.0]% | 0 / 154.7 tok/s |
165
+ | 35 Digits | $p \le 35$ | Unseen, within $p_{\max}=70$ | 30 | **100.0% (30/30)** | **100.0% (30/30)** | [88.6, 100.0]% | 0 / 148.3 tok/s |
166
+ | 40 Digits | $p \le 40$ | Unseen, within $p_{\max}=70$ | 30 | **100.0% (30/30)** | **100.0% (30/30)** | [88.6, 100.0]% | 0 / 103.6 tok/s |
167
+ | 45 Digits | $p \le 45$ | Unseen, within $p_{\max}=70$ | 30 | **100.0% (30/30)** | **100.0% (30/30)** | [88.6, 100.0]% | 0 / 99.0 tok/s |
168
+ | 50 Digits | $p \le 50$ | Unseen, within $p_{\max}=70$ | 30 | **100.0% (30/30)** | **100.0% (30/30)** | [88.6, 100.0]% | 0 / 120.7 tok/s |
169
+ | 55 Digits | $p \le 55$ | Unseen, within $p_{\max}=70$ | 20 | **100.0% (20/20)** | **100.0% (20/20)** | [83.9, 100.0]% | 0 / 108.8 tok/s |
170
+ | 60 Digits | $p \le 60$ | Unseen, within $p_{\max}=70$ | 20 | **70.0% (14/20)** | **70.0% (14/20)** | [48.1, 85.5]% | 1 / 106.4 tok/s |
171
+ | 70 Digits | $p \le 70$ | Unseen, at $p_{\max}=70$ | 15 | **40.0% (6/15)** | **40.0% (6/15)** | [19.8, 64.3]% | 0 / 85.9 tok/s |
172
+ | 80 Digits | $p \le 80$ | Exceeds $p_{\max}=70$ | 10 | **0.0% (0/10)** | **0.0% (0/10)** | [0.0, 27.8]% | 5 / 74.5 tok/s |
173
+ | 100 Digits | $p \le 100$ | Exceeds $p_{\max}=70$ | 10 | **0.0% (0/10)** | **0.0% (0/10)** | [0.0, 27.8]% | 0 / 71.3 tok/s |
174
+ | **Pooled 16–40d** | $p \le 40$ | **Within Seen/Unseen Range ($p \le 40$)** | **180** | **100.0% (180/180)** | **100.0% (180/180)** | **[97.9, 100.0]%** | **0 Errors** |
175
+ | **Pooled 16–50d** | $p \le 50$ | **Full Target Range (16–50d)** | **240** | **100.0% (240/240)** | **100.0% (240/240)** | **[98.4, 100.0]%** | **0 Errors** |
176
 
177
  ---
178
 
179
+ **Table 4: Multi-Tool Phrasing & Edge-Case Suite on CBT-18.95M (`champion_final.pt`, 26 Audited Cases, 9 Schemas)**
180
+ Routing (correct tool) is **21/26 (80.8%, CI [62.1, 91.5]%)**; exact argument extraction is **13/26 (50.0%, CI [32.1, 67.9]%)**. All 26 prompts and entities were audited against the champion training corpus. The earlier Stage 2 vs. Stage 3 comparison (100% routing, 96.2% exact) is withdrawn: its prompts overlapped the champion training data, so it does not measure generalization.
181
+
182
+ | Tool Category | Cases | Correct Routing | Exact Arguments | Observed Failures |
183
+ | :--- | :---: | :---: | :---: | :--- |
184
+ | Weather (`get_weather`) | 7 | 7 | 4 | City drift: `Lagnes` (Lagos), `Auccra` (Accra), `Rerevan` (Yerevan) |
185
+ | Time (`get_time`) | 3 | 3 | 0 | Zone-code drift: `HST` (NZST), `AuctT` (SAST), `AtT` (WAT) |
186
+ | Unit (`unit_convert`) | 2 | 2 | 2 | None |
187
+ | Search (`search`) | 5 | 5 | 4 | `Joannes Kepler` |
188
+ | Calculator (`calculator`) | 3 | 3 | 2 | `37 * 13` for `37 * 113` (dropped digit) |
189
+ | Nested DB query (`database_query`) | 1 | 0 | 0 | Emitted prose and no `<CALL>` |
190
+ | Fetch API (`fetch_api`) | 1 | 0 | 0 | Misrouted to `search` |
191
+ | Create event (`create_event`) | 1 | 0 | 0 | Misrouted to `search` |
192
+ | File manager (`file_manager`) | 1 | 0 | 0 | Misrouted to `search` |
193
+ | Direct chat (no tool) | 2 | 1 | 1 | `Hello, how are you today?` routed to `get_weather(city="Toro")` |
194
+ | **Total** | **26** | **21 (80.8%)** | **13 (50.0%)** | |
 
 
 
 
 
 
195
 
196
  ---
197
 
198
+ **Table 5: Zero-Shot Out-of-Distribution (OOD) Generalization of CBT-18.95M (`champion_final.pt`) on 18 Fresh Prompts**
199
+ All 18 prompts produced well-formed tags and were routed to the intended tool (18/18, 100.0%, CI [82.4, 100.0]%). Exact argument copies: **10/18 (55.6%, CI [33.7, 75.4]%)**. The eight drifted copies are listed below. Near-exact copies are tool-call failures (e.g., `search(query="zggdrasil")` searches the wrong string).
200
+
201
+ | Result | Prompts (Entity or Argument) | Count |
202
+ | :--- | :--- | :---: |
203
+ | `[EXACT]` | bioluminescence, aerogel, stagflation, ceviche, quasars, km-to-miles inversion, calculator `61 * 27`, convolutional networks, harpsichord, art nouveau | 10 |
204
+ | `[DRIFT]` | Tbilisi $\to$ `Thilisisi`; WAT $\to$ `ATC`; nihilism $\to$ `niiilism`; Yggdrasil $\to$ `zggdrasil`; Hatshepsut $\to$ `watshepsut`; Santo Domingo $\to$ `Santo`; Ho Chi Minh City $\to$ `Cith Cith`; `crispr cas12` $\to$ `crispr cos1212` | 8 |
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
205
 
206
  ---
207
 
 
209
 
210
  Tables 2, 3, 3B, 4, and 5 present the evaluation of our final **CBT-18.95M** model (`champion_final.pt`):
211
 
212
+ 1. **Extrapolation Across 16–100 Digits (Tables 2, 3, and 3B)**: The champion was trained with 1–25-digit arithmetic replay and shift masking $k=45$. On random multi-carry sums it achieves **240/240 (100.0%; CI $[98.4, 100.0]\%$)** from 16 to 50 digits, including 18/18 structured 16–50 digit cascades (e.g., $\underbrace{99\dots99}_{50} + 1 = 10^{50}$). Only 16–25 digits are seen in training; 30–50 digits are unseen but still exact on every problem. At 55 digits it is 20/20, then accuracy falls to **70.0% (14/20)** at 60 digits, **40.0% (6/15)** at 70 digits, and **0.0%** at 80 and 100 digits. In-distribution sums at 8, 12, and 15 digits score **89/90 (98.9%)**, with the single miss at 15 digits. A separate teacher-forced mixed-length suite (30 per length) gives 24/30 at both 60 and 70 digits, so the 60–70 digit breakdown varies between suites and should be read as an approximate region. The earlier 1–15 digit extrapolation claims were made for the baseline, not champion.
213
+ 2. **Multi-Tool Phrasing (Table 4, 80.8% Routing, 50.0% Exact Args)**: On the 26-case, 9-schema suite with audited fresh entities, champion routes **21/26 (80.8%)** and copies arguments exactly in **13/26 (50.0%)**. Weather and time-zone entities drift (`Lagnes`, `Auccra`, `HST`/`AuctT`/`AtT`), a nested database query emits prose, and the fetch, event, and file tools are routed to `search`. The 90-dialogue tool benchmark passes 90/90, but its check only looks for tags and does not test argument correctness. The earlier 100% routing and 96.2% exact result is withdrawn because its prompts overlapped the champion training data.
214
+ 3. **Zero-Shot OOD Copying (Table 5)**: On 18 fresh prompts, champion produced well-formed tags and routed all 18 to the intended tool. Exact copies were **10/18 (55.6%)**; eight drifted, mostly on multi-word proper nouns and rare words (`Tbilisi` to `Thilisisi`, `Yggdrasil` to `zggdrasil`). Exact copies include single words and short phrases, and a km-inversion and calculator expression. On an independent 30-case unseen benchmark (Section 4 of the clean report), champion reaches **17/30 exact (56.7%)** versus **4/30 (13.3%)** for the baseline (two-sided Fisher exact $p = 0.0009$). The copy fidelity is therefore far below the arithmetic result.
215
 
216
  ---
217
 
218
  **Table 6: The Tokenization and Positional Geometry Matrix**
219
+ Comparing our 2D Matrix Character + Control-Token CBT formulation against 1D Character models, Subword BPE models (4k and 50k vocabularies), Digit-Split 4k BPE, and Learned 2D positional tables, explicitly contrasting **Seen Training Digits** vs. **Unseen Extrapolation Digits**. Vocabulary sizes differ by variant: 115 is the full CBT-18.95M tokenizer, 111 the CBT-200k and Learned-2D variants, and 27 the digit-and-symbol character models. All rows showing `/50` in the Tool Calling column were evaluated on the identical 50-dialogue structured tool suite (6 domains), whereas CBT-18.95M was evaluated on the 26-case 9-schema 1-hop suite of Table 4. Rows were trained with different digit ranges and data and are not a controlled $2\times2$ study. The unseen-sum column pools 14–20 digits, whereas Table 7 reports 14–16 digits separately (hence 2.3% here and 4.6% there for the 1D character model). The Structured Cascade column reports the hardest single-carry chain ($99\dots9+1$) at unseen 20 digits for the 12d models and 50 digits for CBT-18.95M (where CBT-18.95M scores 100.0% on the structured cascade case, contrasting with 100.0% on random 50-digit multi-carries in Table 3B).
220
 
221
  | Tokenizer Granularity | Positional Geometry | Vocab ($V$) | Trained Digits | Tool Calling | Seen Sums (In-Dist) | Unseen Sums (14–20d) | Structured Cascade |
222
  | :--- | :--- | :---: | :---: | :---: | :---: | :---: | :---: |
 
227
  | Atomic Character | NoPE + Abacus Place | 27 | 1–12 Digits | N/A | **0.0%** (1–12d) | **0.0%** (Unseen 14–20d) | **0.0%** (Unseen 20d) |
228
  | Atomic Character | Learned 2D Lookup Table | 111 | 1–12 Digits | 98.0% (49/50) | 100.0% (1–12d) | **0.0%** (Capped $p > 12$) | **0.0%** (Unseen 20d) |
229
  | **CBT-200k (Char + Control)** | **2D-RoPE Matrix ($R=3$)** | **111** | **1–12 Digits** | **100.0% (50/50)** | **100.0% (1–12d)** | **100.0% (Unseen 14–20d)** | **100.0% (Unseen 20d)** |
230
+ | **CBT-18.95M (Char + Control)** | **2D-RoPE Matrix ($R=3$)** | **115** | **1–25 Digits (replay)** | **80.8% (21/26)** | **98.9% (89/90, 8–15d)** | **100.0% (240/240 Rand 16–50d)** | **100.0% (18/18 Struct)** |
231
 
232
  ---
233
 
 
248
  | **HRM-RoPE (Dual-Loop)** | 1.56M | **Decoupled 2D-RoPE** | **1–12 Digits** | 100.0% | 66.7% (14–16d) | **100.0% (18–20d)** | **20 Digits (+8 Unseen Digits)** |
249
  | **CBT-100k ($L=2, R=3$)** | 98.9k | **Decoupled 2D-RoPE** | **1–12 Digits** | **100.0%** | **100.0% (14–16d)** | **100.0% (18–20d)** | **20 Digits (+8 Unseen Digits)** |
250
  | **CBT-200k ($L=4, R=3$)** | 197.8k | **Decoupled 2D-RoPE** | **1–12 Digits** | **100.0%** | **100.0% (14–16d)** | **100.0% (18–20d)** | **20 Digits (+8 Unseen) + Tools** |
251
+ | **CBT-18.95M ($L=6, R=3$)** | **18.89M** | **Decoupled 2D-RoPE** | **1–25 Digits (replay)** | **80.8%** | **100.0% (16–40d Rand)** | **100.0% (45–50d); 100.0% (55d)** | **100.0% (16–50d); 70.0% (60d), 40.0% (70d)** |
252
 
253
  ---
254
 
 
309
  | Unseen 40 Digits ($n=200$ / $n=30$) | **Unseen (+25d)** | 0.0% (0/200) [0.0, 1.9]% | 0.0% (0/200) [0.0, 1.9]% | 0.0% (0/200) [0.0, 1.9]% | **51.5% (103/200)** [44.6, 58.3]% | **100.0% (30/30)** [88.6, 100]% |
310
  | Unseen 45 Digits ($n=200$ / $n=30$) | **Unseen (+30d)** | 0.0% (0/200) [0.0, 1.9]% | 0.0% (0/200) [0.0, 1.9]% | 0.0% (0/200) [0.0, 1.9]% | **30.0% (60/200)** [24.1, 36.7]% | **93.3% (28/30)** [78.7, 98.2]% |
311
  | Unseen 50 Digits ($n=200$ / $n=30$) | **Boundary ($p \approx 47$)** | 0.0% (0/200) [0.0, 1.9]% | 0.0% (0/200) [0.0, 1.9]% | 0.0% (0/200) [0.0, 1.9]% | 0.0% (0/200) [0.0, 1.9]% | **96.7% (29/30)** [83.3, 99.4]% |
312
+ | Unseen 55 Digits ($n=200$ / $n=20$) | **Beyond $p_{\max}$ (+8d)** | 0.0% (0/200) [0.0, 1.9]% | 0.0% (0/200) [0.0, 1.9]% | 0.0% (0/200) [0.0, 1.9]% | 0.0% (0/200) [0.0, 1.9]% | **100.0% (20/20)** [83.9, 100.0]% |
313
  | Unseen 60 Digits ($n=200$ / $n=20$) | **Beyond $p_{\max}$ (+13d)** | 0.0% (0/200) [0.0, 1.9]% | 0.0% (0/200) [0.0, 1.9]% | 0.0% (0/200) [0.0, 1.9]% | 0.0% (0/200) [0.0, 1.9]% | 45.0% (9/20) [25.8, 65.8]% |
314
  | Unseen 70–100 Digits ($n=600$ / $n=45$) | **Beyond $p_{\max}$ & Context** | 0.0% (0/600) [0.0, 0.6]% | 0.0% (0/600) [0.0, 0.6]% | 0.0% (0/600) [0.0, 0.6]% | 0.0% (0/600) [0.0, 0.6]% | 2.2% (1/45; 6.7% 70d, 0% 80–100) |
315
  | **Pooled Unseen 16–40d ($n=1,200$ / $n=180$)** | **Within $p_{\max}=47$** | 0.0% (0/1200) [0.0, 0.3]% | 0.0% (0/1200) [0.0, 0.3]% | 0.0% (0/1200) [0.0, 0.3]% | **81.4% (977/1200)** [79.1, 83.5]% | **100.0% (180/180)** [97.9, 100]% |
 
323
 
324
  ---
325
 
326
+ **Table 8C: Empirical Verification of Coordinate Horizon Shifting ($k \in \{0, 16, 32, 64\}$), Place-Only Ablation ($p$-Only), and Retrained 1D Baseline**
327
+ Evaluated on $n=200$ stratified random multi-carry problems per length ($3{,}000$ problems per model, $18{,}000$ total across six conditions). All models share the equalized 100k architecture trained on 1–15 digits in a 1024-token context. The 2D-RoPE ($k=32$) baseline evaluates the identical checkpoint from Table 8B on an independent random evaluation draw of $n=200$ problems per length (yielding 436/600 [72.7%] pooled on seen lengths vs. 417/600 [69.5%] in Table 8B, and 85.0% vs. 86.0% at 15d, reflecting expected sampling variance within 95% Wilson confidence intervals). The accuracy cliff tracks the theoretical coordinate support boundary $p_{\max} = N_{\text{train}} + k$: $k=0$ collapses at 16–25d ($p_{\max}=15$), $k=16$ at 35–40d ($p_{\max}=31$), $k=32$ at 45–50d ($p_{\max}=47$), and $k=64$ sustains out to 55d ($p_{\max}=79$). The $p$-only ablation ($\tau=0$) achieves 99.8% in-distribution and 96.2% across 16–30d, demonstrating that the macro column coordinate $p$ carries the primary length-invariant scaffold, while $\tau$ provides boundary stabilization (58.0% vs. 41.5% at 40d). Retraining 1D-RoPE for 6,000 steps with tuned learning rate ($\text{LR}=8\times 10^{-4}$) yields only 28.0% at 8d and 0.0% beyond, confirming an in-distribution optimization bottleneck under flat coordinates in 1024-token contexts.
328
+
329
+ | Evaluation Digit Length | 2D-RoPE ($k=0$) | 2D-RoPE ($k=16$) | 2D-RoPE ($k=32$) | 2D-RoPE ($k=64$) | $p$-Only ($\tau=0, k=32$) | 1D-RoPE Retrained |
330
+ | :--- | :---: | :---: | :---: | :---: | :---: | :---: |
331
+ | Coordinate Horizon | $p_{\max}=15$ | $p_{\max}=31$ | $p_{\max}=47$ | $p_{\max}=79$ | $p_{\max}=47$ | 6k steps, $\text{LR}=8\times 10^{-4}$ |
332
+ | Seen 8 Digits ($n=200$) | 100.0% (200/200) | 100.0% (200/200) | 60.0% (120/200) | 99.5% (199/200) | 99.5% (199/200) | 28.0% (56/200) |
333
+ | Seen 12 Digits ($n=200$) | 100.0% (200/200) | 99.5% (199/200) | 73.0% (146/200) | 99.0% (198/200) | 100.0% (200/200) | 0.0% (0/200) |
334
+ | Seen 15 Digits (Max Seen, $n=200$) | 100.0% (200/200) | 100.0% (200/200) | 85.0% (170/200) | 99.5% (199/200) | 100.0% (200/200) | 0.0% (0/200) |
335
+ | Unseen 16 Digits ($n=200$) | 77.5% (155/200) | 100.0% (200/200) | 86.0% (172/200) | 100.0% (200/200) | 100.0% (200/200) | 0.0% (0/200) |
336
+ | Unseen 20 Digits ($n=200$) | 17.0% (34/200) | 100.0% (200/200) | 85.0% (170/200) | 98.0% (196/200) | 99.5% (199/200) | 0.0% (0/200) |
337
+ | Unseen 25 Digits ($n=200$) | 0.0% (0/200) | 99.5% (199/200) | 89.0% (178/200) | 93.5% (187/200) | 99.0% (198/200) | 0.0% (0/200) |
338
+ | Unseen 30 Digits ($n=200$) | 0.0% (0/200) | 98.5% (197/200) | 85.5% (171/200) | 88.5% (177/200) | 97.5% (195/200) | 0.0% (0/200) |
339
+ | Unseen 35 Digits ($n=200$) | 0.0% (0/200) | **60.5% (121/200)** | 75.5% (151/200) | 83.0% (166/200) | 85.0% (170/200) | 0.0% (0/200) |
340
+ | Unseen 40 Digits ($n=200$) | 0.0% (0/200) | 0.0% (0/200) | 58.0% (116/200) | 69.0% (138/200) | 41.5% (83/200) | 0.0% (0/200) |
341
+ | Unseen 45 Digits ($n=200$) | 0.0% (0/200) | 0.0% (0/200) | **30.5% (61/200)** | 60.0% (120/200) | 9.5% (19/200) | 0.0% (0/200) |
342
+ | Unseen 50 Digits ($n=200$) | 0.0% (0/200) | 0.0% (0/200) | 0.0% (0/200) | 41.0% (82/200) | 0.0% (0/200) | 0.0% (0/200) |
343
+ | Unseen 55 Digits ($n=200$) | 0.0% (0/200) | 0.0% (0/200) | 0.0% (0/200) | **20.0% (40/200)** | 0.0% (0/200) | 0.0% (0/200) |
344
+ | Unseen 60 Digits ($n=200$) | 0.0% (0/200) | 0.0% (0/200) | 0.0% (0/200) | 1.0% (2/200) | 0.0% (0/200) | 0.0% (0/200) |
345
+ | Unseen 70–80 Digits ($n=400$) | 0.0% (0/400) | 0.0% (0/400) | 0.0% (0/400) | 0.0% (0/400) | 0.0% (0/400) | 0.0% (0/400) |
346
+ | **Observed Cliff Location** | **$d = 16\text{--}25$** | **$d = 31\text{--}40$** | **$d = 45\text{--}50$** | **$d = 55\text{--}65$** | **$d = 40\text{--}50$** | **No learning ($d \ge 12$)** |
347
+ | **Theoretical Horizon ($p_{\max}$)** | **$15$** | **$31$** | **$47$** | **$79$** | **$47$** | N/A |
348
+
349
+ ### 2.4 Ablation Analysis: Coordinate Horizon Shifting, Decoupling, and Optimization
350
+
351
+ To isolate the mechanisms governing length generalization, we conducted three targeted empirical ablations (`experiments/run_reviewer_priority_ablations.py`, Table 8C):
352
+ 1. **Causal Shift Sweep ($k \in \{0, 16, 32, 64\}$)**: By varying the training position-shift offset $k$, we observe that the accuracy cliff moves strictly with $p_{\max} = N_{\text{train}} + k$. When $k=0$ ($p_{\max}=15$), accuracy drops precipitously immediately past the training frontier (77.5% at 16d, 17.0% at 20d, 0.0% at 25d). When $k=16$ ($p_{\max}=31$), accuracy exceeds 98.5% through 30d before falling to 60.5% at 35d and 0.0% at 40d. When $k=64$ ($p_{\max}=79$), the model maintains substantial accuracy well beyond 40d (69.0% at 40d, 60.0% at 45d, 41.0% at 50d, and 20.0% at 55d). This confirms that the bounded extrapolation horizon is not a failure of attention routing, but a direct consequence of the coordinate support envelope encountered during training.
353
+ 2. **Place-Only Ablation ($p$-Only, $\tau=0$)**: To test whether the intra-column micro-step coordinate $\tau$ is necessary or if place alignment alone suffices, we set $\tau=0$ during both training and inference ($k=32$). The $p$-only model achieves 99.8% on seen 8–15 digits and averages 96.2% across 16–30 digits (100.0% at 16d, 99.5% at 20d, 99.0% at 25d, 97.5% at 30d, 85.0% at 35d). This demonstrates that the macro place coordinate $p$ alone carries the underlying length-invariant algorithmic scaffold. However, full 2D-RoPE provides greater robustness near the cliff boundary (58.0% vs. 41.5% at 40d; 30.5% vs. 9.5% at 45d), showing that $\tau$ provides secondary stabilization against phase dispersion during token generation.
354
+ 3. **1D Baseline Retraining with Extended Budget**: To determine whether 1D failures in Table 8B were merely artifacts of insufficient training steps, we retrained 1D-RoPE with double the step budget (6,000 steps) and a tuned learning rate ($\text{LR}=8\times 10^{-4}$). The retrained model attained only 28.0% accuracy on 8-digit additions and collapsed to 0.0% on 12- and 15-digit sums (as well as all unseen lengths). In contrast to 2D models which converge smoothly to zero loss, flat 1D coordinates in long-context scratchpads create an intractable optimization landscape for compact Transformers.
355
+
356
+ ---
357
+
358
  ## 3. Architecture, 2D Matrix Embeddings, Tokenizer, and Training Data
359
 
360
  In this section, we provide a complete technical specification of **CBT-18.95M**, detailing its hybrid character-control tokenizer, Decoupled 2D-RoPE embeddings, weight-tied recurrent depth, and the exact composition of the training datasets.
 
436
 
437
  ---
438
 
439
+ **Table 10: Complete Three-Stage Training Data Composition, Digit Horizon Boundaries, and Loss Masking Specification for the CBT-18.95M Pre-SFT Base (`champion_base.pt`; the champion adds V4 SFT)**
440
  Across all stages, arithmetic training is strictly bounded to **1–15 digits ($N \le 15$)**. All 16- to 50-digit evaluations are 100% zero-shot out-of-distribution extrapolations.
441
 
442
  | Training Stage | Dataset Component / Sub-Distribution | Pattern / Schema Specification | Trained Digit / Length Scope | Mixture Weight | Supervised Target (Masking Rule) |
 
455
 
456
  ### 3.5 Three-Stage Training Data & 1-Hop Induction Curriculum
457
 
458
+ Table 10 summarizes the three-stage protocol that produced the pre-SFT base `champion_base.pt` on dual NVIDIA T4 GPUs (FP16 AMP). The champion checkpoint (`champion_final.pt`) starts from that base and is trained further with the V4 SFT curriculum (`sft_search.py --curriculum v4`: 45% multi-tool, 35% search copy, 20% arithmetic replay with 1–25-digit operands, $k=45$; hyperparameters in the training script, not in Table 10):
459
  1. **Stage 1 (Joint Pretraining, 45,059 steps, 247.3M tokens, Loss `0.000094`)**: Trained on a 50%/50% mixture of 1–15 digit column addition (40% asymmetric lengths, 25% symmetric lengths, 20% cascading carries $99\dots9+b$, 15% power-of-ten zero chains) and 6-category structured tool dialogues, with $-100$ loss masking on prompts and `<RESULT>` payloads.
460
  2. **Stage 2 (Search Copy Induction SFT, 7,000 steps, Loss `0.004834`)**: In early SFT tests, repeating an unfamiliar entity $X$ inside `<THINK>` before calling `<CALL>` caused a *2-Hop Copy Bottleneck*, where character n-gram priors hallucinated phonotactic nonces (`"tomatoes"` $\to$ `"smoom"`, `"bloumplik"` $\to$ `"cheat"`). Decoupling `<THINK>` into an invariant intent statement and training on 65% procedurally generated phonotactic pseudowords ($L_{\text{memorize}} \to \infty$) forced a **1-hop induction pointer head** ($p=2 \to p=0$) to copy unseen strings character-by-character.
461
  3. **Stage 3 (All-Tools 1-Hop Annealing SFT, 4,000 steps, LR $5\times 10^{-5} \to 5\times 10^{-6}$, Loss `0.007532`)**: Extended the 1-hop pointer copy formulation across all 9 tool schemas (`get_weather`, `get_time`, `calculator`, `unit_convert`, `database_query`, `fetch_api`, `create_event`, `file_manager`, and `search`) alongside a 10% 1–15 digit math replay buffer, achieving **100.0% (26/26) tool routing**, **96.2% (25/26) exact argument extraction**, and **100.0% 1–50 digit sum extrapolation**.
 
482
 
483
  ### 4.3 Open Questions and Further Testing
484
 
485
+ While CBT-18.95M shows that placing characters on a hand-assigned 2D coordinate grid $(p, \tau)$ yields 100.0% accuracy (180/180) on random 16–40 digit sums, 100.0% (240/240) across 16–50 digits, and 100.0% (20/20) at 55 digits (70.0% at 60 digits) before degrading beyond the $p_{\max} = N_{\text{train}} + k = 47$ shift-masking horizon (Table 3B), our OOD and ablation experiments leave several questions open:
486
  1. **Sensitivity to Epoch Reinforcement and Boundary Coordinates**: As shown in our 100k component ablations (Table 8), while several combinations of 2D-RoPE and recurrence achieved identical 78.6% strict match at 12.8 epochs, the off-by-one trailing zero readout error at the $p=1 \to p=0$ boundary disappeared in our runs with higher epoch density (64 epochs on a 1,000-sample pool) or larger capacity (18.95M); however, these single-run comparisons do not isolate whether the fix came from boundary exposure, memorization of the small pool, or model scale.
487
  2. **Multi-Word OOD Pointer Spans and General Algorithms**: In zero-shot OOD testing (Table 5), two-word capitalized proper nouns (`"Buenos Aires"` $\to$ `"Buris"`) still experience partial compression, and our algorithmic generalization scope here focused on $\mathcal{O}(N)$ column sums rather than $\mathcal{O}(N^2)$ multiplication or arbitrary graph algorithms.
488
  3. **Learned Coordinates and Other Tasks**: Emitting hundreds of scratchpad characters is an inefficient simulation of an ALU, the coordinates are hand-assigned, and extrapolation is bounded by the shift-masked coordinate support $p_{\max} = N_{\text{train}} + k$ (Table 3B). Important next steps are learning or inferring $(p, \tau)$, testing on a second task whose coordinates are not trivial (multiplication, sorting, string reversal), running multi-seed training, and comparing against equalized 1D baselines with randomized positions, index hints, and tuned Abacus embeddings [16, 17, 18, 19].
 
523
  17. Y. Zhou, U. Alon, X. Chen, X. Wang, R. Agarwal, and D. Zhou. *Transformers can achieve length generalization but not robustly*. arXiv preprint arXiv:2402.09371, 2024.
524
  18. S. Duan and Y. Shi. *From interpolation to extrapolation: Complete length generalization for arithmetic transformers*. arXiv preprint arXiv:2310.11984, 2023.
525
  19. Y. Fan, Y. Du, K. Ramchandran, and K. Lee. *Looped transformers for length generalization*. arXiv preprint arXiv:2409.15647, 2024.
526
+ 20. Y. Shaham and O. Levy. *Neural machine translation without embeddings*. In Proceedings of the 2021 Conference of the North American Chapter of the Association for Computational Linguistics (NAACL), 2021.
527
+ 21. R. Al-Rfou, D. Choe, N. Constant, M. Guo, and L. Jones. *Character-level language modeling with deeper self-attention*. In Proceedings of the AAAI Conference on Artificial Intelligence, 2019.
528
+ 22. L. Xue, A. Barua, N. Constant, R. Al-Rfou, S. Narang, M. Kale, A. Roberts, and C. Raffel. *ByT5: Towards a token-free future with pre-trained byte-to-byte models*. Transactions of the Association for Computational Linguistics, 10:291–306, 2022. arXiv:2105.13626.
529
+ 23. A. Pagnoni, R. Pasunuru, P. Rodriguez, J. Nguyen, B. Muller, M. Li, C. Zhou, L. Yu, J. Weston, L. Zettlemoyer, G. Ghosh, M. Lewis, A. Holtzman, and S. Iyer. *Byte latent transformer: Patches scale better than tokens*. arXiv preprint arXiv:2412.09871, 2024.
champion_final.pt CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:79d908d328d9aeac319129b3816fc2de0ada6722c2a5f9ee1ea7f4919e87ccaa
3
- size 75800724
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:634bf18ed4173bc73e58970c6e843fbb4ccec92fde2b12c01bbe2fe04fe85a13
3
+ size 75800439
dataset.py CHANGED
@@ -23,7 +23,10 @@ ROOT_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__fil
23
  if ROOT_DIR not in sys.path:
24
  sys.path.insert(0, ROOT_DIR)
25
 
26
- from champion_model.scaled_t4.tokenizer import ScaledTokenizer
 
 
 
27
 
28
 
29
  def format_addition_char_scratchpad(a: int, b: int) -> str:
@@ -75,6 +78,8 @@ CITIES = [
75
  "Rome", "Seoul", "Singapore", "Zurich", "Honolulu", "Reykjavik", "Ouagadougou",
76
  "Vancouver", "Santiago", "Auckland", "Casablanca", "Vienna", "Stockholm", "Kyoto",
77
  "Dublin", "Oslo", "Helsinki", "Bangkok", "Cairo", "Lisbon", "Amsterdam", "Athens",
 
 
78
  ]
79
  CONDITIONS = ["Sunny", "Rainy", "Cloudy", "Snowy", "Windy", "Foggy", "Clear"]
80
  TIMEZONES = ["UTC", "EST", "PST", "GMT", "JST", "CET", "AEST", "CST", "IST", "HST"]
@@ -85,15 +90,36 @@ NONCE_NUCLEI = ["a", "e", "i", "o", "u", "y", "ai", "ea", "ee", "oa", "oo", "ou"
85
  NONCE_CODAS = ["b", "d", "f", "g", "k", "l", "m", "n", "p", "r", "s", "t", "x", "z", "ck", "nk", "mp", "sh", "th", "nt", "rt"]
86
 
87
 
88
- def generate_nonce_entity(rng: random.Random) -> Tuple[str, str, str]:
89
- """Generates an arbitrary pseudo-word entity (singular, plural, type)."""
90
- n_syl = rng.choice([1, 2, 2, 3])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
  parts = []
92
  for _ in range(n_syl):
93
  parts.append(rng.choice(NONCE_ONSETS) + rng.choice(NONCE_NUCLEI) + rng.choice(NONCE_CODAS))
94
  singular = "".join(parts)
 
 
 
 
 
 
95
  plural = singular + ("es" if singular[-1] in "sxz" else "s")
96
- ent_type = rng.choice(["concept", "plant", "creature", "artifact", "substance"])
97
  return singular, plural, ent_type
98
  SEARCH_FACTS = [
99
  ("Python creator", "Guido van Rossum", "creator"),
@@ -184,6 +210,25 @@ SEARCH_ENTITIES = [
184
  {"entity": "compiler", "plural": "compilers", "type": "computer science", "snippet": "a computer program that translates computer code written in one language into another."},
185
  {"entity": "operating system", "plural": "operating systems", "type": "computer science", "snippet": "system software that manages computer hardware, software resources, and common services."},
186
  {"entity": "neural network", "plural": "neural networks", "type": "computer science", "snippet": "a computational model inspired by the biological neural networks of animal brains."},
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
187
  ]
188
  DEPARTMENTS = ["engineering", "marketing", "sales", "finance", "legal", "product"]
189
 
@@ -402,7 +447,7 @@ def generate_arithmetic_equations(
402
  # 2. Expanded Tool Repertoire Generator
403
  # -----------------------------------------------------------------------------
404
 
405
- def generate_tool_example(rng: random.Random) -> Dict[str, str]:
406
  """
407
  Generates a structured synthetic tool interaction from 6 expanded categories:
408
  1. Single-tool calling (calculator, weather, search, time, unit_convert)
@@ -416,8 +461,9 @@ def generate_tool_example(rng: random.Random) -> Dict[str, str]:
416
  - <THINK> emits a clean, entity-agnostic routing intent (no variable copying in <THINK>).
417
  - <CALL> copies arguments directly from <USER> via 1-hop attention pointers.
418
  - Symmetric punctuation curriculum (50% with '?'/'.', 50% raw conversational text).
 
419
  """
420
- category = rng.choices(
421
  [
422
  "single_tool",
423
  "multi_tool_chain",
@@ -477,8 +523,9 @@ def generate_tool_example(rng: random.Random) -> Dict[str, str]:
477
 
478
  elif sub == "weather":
479
  if rng.random() < 0.35:
480
- # Nonce city to force pure copy induction
481
- city = generate_nonce_entity(rng)[0].capitalize()
 
482
  else:
483
  city = rng.choice(CITIES)
484
  temp = rng.randint(-5, 35)
@@ -491,6 +538,7 @@ def generate_tool_example(rng: random.Random) -> Dict[str, str]:
491
  f"What is the weather like in {city}{q_mark}",
492
  f"How is the weather in {city}{q_mark}",
493
  f"How is the weather on {city}{q_mark}",
 
494
  f"Weather in {city}{p_mark}",
495
  f"Weather on {city}{p_mark}",
496
  f"Weather for {city}{p_mark}",
@@ -498,6 +546,7 @@ def generate_tool_example(rng: random.Random) -> Dict[str, str]:
498
  f"Check the weather for {city}{p_mark}",
499
  f"Tell me the weather in {city}{p_mark}",
500
  f"Forecast for {city}{p_mark}",
 
501
  ])
502
  thought = rng.choice([
503
  "The user requests current weather information. I will query the get_weather tool.",
@@ -510,7 +559,7 @@ def generate_tool_example(rng: random.Random) -> Dict[str, str]:
510
  elif sub == "search":
511
  search_mode = rng.random()
512
  if search_mode < 0.50:
513
- ent, plural, ent_type = generate_nonce_entity(rng)
514
  snippet = f"a hypothetical {ent_type} characterized in general knowledge."
515
  elif search_mode < 0.85 and bool(SEARCH_ENTITIES):
516
  ent_item = rng.choice(SEARCH_ENTITIES)
@@ -529,6 +578,9 @@ def generate_tool_example(rng: random.Random) -> Dict[str, str]:
529
  "tell_me_about",
530
  "explain",
531
  "define",
 
 
 
532
  ])
533
 
534
  if variant == "what_are_plural":
@@ -552,6 +604,19 @@ def generate_tool_example(rng: random.Random) -> Dict[str, str]:
552
  user_prompt = f"Explain {ent}{p_mark}"
553
  search_q = ent
554
  answer = f"{ent.capitalize()} is {snippet}"
 
 
 
 
 
 
 
 
 
 
 
 
 
555
  else:
556
  user_prompt = f"What is {ent}{q_mark}"
557
  search_q = ent
@@ -871,6 +936,433 @@ def generate_tool_dataset(n_samples: int = 4000, seed: int = 1337) -> List[Dict[
871
  return dataset
872
 
873
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
874
  def generate_joint_dataset(
875
  n_math: int = 4000,
876
  n_tools: int = 4000,
 
23
  if ROOT_DIR not in sys.path:
24
  sys.path.insert(0, ROOT_DIR)
25
 
26
+ try:
27
+ from champion_model.scaled_t4.tokenizer import ScaledTokenizer
28
+ except ImportError:
29
+ from tokenizer import ScaledTokenizer
30
 
31
 
32
  def format_addition_char_scratchpad(a: int, b: int) -> str:
 
78
  "Rome", "Seoul", "Singapore", "Zurich", "Honolulu", "Reykjavik", "Ouagadougou",
79
  "Vancouver", "Santiago", "Auckland", "Casablanca", "Vienna", "Stockholm", "Kyoto",
80
  "Dublin", "Oslo", "Helsinki", "Bangkok", "Cairo", "Lisbon", "Amsterdam", "Athens",
81
+ "Buenos Aires", "Kuala Lumpur", "Rio de Janeiro", "San Francisco", "Hong Kong",
82
+ "Los Angeles", "Mexico City", "Cape Town", "Sao Paulo",
83
  ]
84
  CONDITIONS = ["Sunny", "Rainy", "Cloudy", "Snowy", "Windy", "Foggy", "Clear"]
85
  TIMEZONES = ["UTC", "EST", "PST", "GMT", "JST", "CET", "AEST", "CST", "IST", "HST"]
 
90
  NONCE_CODAS = ["b", "d", "f", "g", "k", "l", "m", "n", "p", "r", "s", "t", "x", "z", "ck", "nk", "mp", "sh", "th", "nt", "rt"]
91
 
92
 
93
+ def generate_nonce_entity(rng: random.Random, allow_multi_word: bool = True) -> Tuple[str, str, str]:
94
+ """Generates an arbitrary pseudo-word entity (singular, plural, type), supporting single and multi-word spans."""
95
+ ent_type = rng.choice(["concept", "plant", "creature", "artifact", "substance", "person", "theory"])
96
+
97
+ # 30% chance of multi-word compound nonce (2-3 words) to train multi-word pointer induction
98
+ if allow_multi_word and rng.random() < 0.30:
99
+ n_words = rng.choice([2, 2, 3])
100
+ words = []
101
+ for _ in range(n_words):
102
+ n_syl = rng.choice([1, 2, 2, 3])
103
+ w = "".join(rng.choice(NONCE_ONSETS) + rng.choice(NONCE_NUCLEI) + rng.choice(NONCE_CODAS) for _ in range(n_syl))
104
+ words.append(w.capitalize())
105
+ singular = " ".join(words)
106
+ last_w = words[-1]
107
+ plural_last = last_w + ("es" if last_w[-1] in "sxz" else "s")
108
+ plural = " ".join(words[:-1] + [plural_last])
109
+ return singular, plural, ent_type
110
+
111
+ n_syl = rng.choice([1, 2, 2, 3, 4])
112
  parts = []
113
  for _ in range(n_syl):
114
  parts.append(rng.choice(NONCE_ONSETS) + rng.choice(NONCE_NUCLEI) + rng.choice(NONCE_CODAS))
115
  singular = "".join(parts)
116
+
117
+ # 20% chance of complex morphological suffix to train long-token copy fidelity
118
+ if rng.random() < 0.20:
119
+ suffix = rng.choice(["ism", "ology", "ification", "ation", "ological", "ity"])
120
+ singular = singular + suffix
121
+
122
  plural = singular + ("es" if singular[-1] in "sxz" else "s")
 
123
  return singular, plural, ent_type
124
  SEARCH_FACTS = [
125
  ("Python creator", "Guido van Rossum", "creator"),
 
210
  {"entity": "compiler", "plural": "compilers", "type": "computer science", "snippet": "a computer program that translates computer code written in one language into another."},
211
  {"entity": "operating system", "plural": "operating systems", "type": "computer science", "snippet": "system software that manages computer hardware, software resources, and common services."},
212
  {"entity": "neural network", "plural": "neural networks", "type": "computer science", "snippet": "a computational model inspired by the biological neural networks of animal brains."},
213
+ # Alphanumeric, Scientific & Tech Entities
214
+ {"entity": "CRISPR Cas9", "plural": "CRISPR Cas9 systems", "type": "genetics", "snippet": "a gene editing technology using an RNA-guided endonuclease enzyme."},
215
+ {"entity": "Boeing 747", "plural": "Boeing 747 aircraft", "type": "aerospace", "snippet": "a wide-body commercial airliner and cargo transport aircraft."},
216
+ {"entity": "Apollo 11", "plural": "Apollo missions", "type": "spaceflight", "snippet": "the American spaceflight that first landed humans on the Moon in 1969."},
217
+ {"entity": "Web3", "plural": "decentralized protocols", "type": "technology", "snippet": "an idea for an iteration of the World Wide Web based on blockchain technology."},
218
+ {"entity": "Formula 1", "plural": "Formula 1 races", "type": "motorsport", "snippet": "the highest class of international racing for open-wheel single-seater formula cars."},
219
+ {"entity": "IPv6", "plural": "IPv6 addresses", "type": "networking", "snippet": "the most recent version of the Internet Protocol providing a vast numerical address space."},
220
+ # Classical, Philosophical & Cultural Terms
221
+ {"entity": "Marcus Aurelius", "plural": "Roman emperors", "type": "person", "snippet": "a Roman emperor and Stoic philosopher who ruled from 161 to 180 AD."},
222
+ {"entity": "brutalist architecture", "plural": "brutalist structures", "type": "architecture", "snippet": "an architectural style characterized by minimalist constructions showcasing bare building materials."},
223
+ {"entity": "existentialism", "plural": "existentialist doctrines", "type": "philosophy", "snippet": "a philosophical inquiry exploring human existence, freedom, and meaning."},
224
+ {"entity": "Ragnarok", "plural": "mythological battles", "type": "mythology", "snippet": "in Norse mythology, a series of catastrophic events leading to the renewal of the world."},
225
+ {"entity": "theremin", "plural": "theremins", "type": "instrument", "snippet": "an electronic musical instrument controlled without physical contact by metal antennas."},
226
+ {"entity": "hyperinflation", "plural": "hyperinflationary cycles", "type": "economics", "snippet": "rapid, excessive, and out-of-control general price increases in an economy."},
227
+ {"entity": "quantum physics", "plural": "quantum systems", "type": "physics", "snippet": "a fundamental branch of physics that studies nature at the scale of atoms and subatomic particles."},
228
+ {"entity": "interstellar", "plural": "interstellar regions", "type": "astronomy", "snippet": "the matter and radiation that exists in the space between the star systems in a galaxy."},
229
+ {"entity": "tiramisu", "plural": "tiramisus", "type": "cuisine", "snippet": "a coffee-flavoured Italian dessert made of ladyfingers dipped in coffee and layered with mascarpone."},
230
+ {"entity": "neutron stars", "plural": "neutron stars", "type": "astronomy", "snippet": "the collapsed core of a massive supergiant star composed almost entirely of neutrons."},
231
+ {"entity": "transformers in deep learning", "plural": "transformer architectures", "type": "computer science", "snippet": "a deep learning architecture based on multi-head self-attention mechanisms."},
232
  ]
233
  DEPARTMENTS = ["engineering", "marketing", "sales", "finance", "legal", "product"]
234
 
 
447
  # 2. Expanded Tool Repertoire Generator
448
  # -----------------------------------------------------------------------------
449
 
450
+ def generate_tool_example(rng: random.Random, category: Optional[str] = None) -> Dict[str, str]:
451
  """
452
  Generates a structured synthetic tool interaction from 6 expanded categories:
453
  1. Single-tool calling (calculator, weather, search, time, unit_convert)
 
461
  - <THINK> emits a clean, entity-agnostic routing intent (no variable copying in <THINK>).
462
  - <CALL> copies arguments directly from <USER> via 1-hop attention pointers.
463
  - Symmetric punctuation curriculum (50% with '?'/'.', 50% raw conversational text).
464
+ `category` forces a specific category instead of sampling one.
465
  """
466
+ category = category or rng.choices(
467
  [
468
  "single_tool",
469
  "multi_tool_chain",
 
523
 
524
  elif sub == "weather":
525
  if rng.random() < 0.35:
526
+ # Nonce city to force pure copy induction (single or multi-word)
527
+ nonce_city, _, _ = generate_nonce_entity(rng, allow_multi_word=True)
528
+ city = " ".join(w.capitalize() for w in nonce_city.split())
529
  else:
530
  city = rng.choice(CITIES)
531
  temp = rng.randint(-5, 35)
 
538
  f"What is the weather like in {city}{q_mark}",
539
  f"How is the weather in {city}{q_mark}",
540
  f"How is the weather on {city}{q_mark}",
541
+ f"How is the weather for {city}{q_mark}",
542
  f"Weather in {city}{p_mark}",
543
  f"Weather on {city}{p_mark}",
544
  f"Weather for {city}{p_mark}",
 
546
  f"Check the weather for {city}{p_mark}",
547
  f"Tell me the weather in {city}{p_mark}",
548
  f"Forecast for {city}{p_mark}",
549
+ f"{city} weather{p_mark}",
550
  ])
551
  thought = rng.choice([
552
  "The user requests current weather information. I will query the get_weather tool.",
 
559
  elif sub == "search":
560
  search_mode = rng.random()
561
  if search_mode < 0.50:
562
+ ent, plural, ent_type = generate_nonce_entity(rng, allow_multi_word=True)
563
  snippet = f"a hypothetical {ent_type} characterized in general knowledge."
564
  elif search_mode < 0.85 and bool(SEARCH_ENTITIES):
565
  ent_item = rng.choice(SEARCH_ENTITIES)
 
578
  "tell_me_about",
579
  "explain",
580
  "define",
581
+ "search_for",
582
+ "lookup",
583
+ "who_is",
584
  ])
585
 
586
  if variant == "what_are_plural":
 
604
  user_prompt = f"Explain {ent}{p_mark}"
605
  search_q = ent
606
  answer = f"{ent.capitalize()} is {snippet}"
607
+ elif variant == "search_for":
608
+ user_prompt = f"Search for {ent}{p_mark}"
609
+ search_q = ent
610
+ answer = f"Search results indicate {ent} is {snippet}"
611
+ elif variant == "lookup":
612
+ user_prompt = f"Look up {ent}{p_mark}"
613
+ search_q = ent
614
+ answer = f"Information for {ent}: {snippet}"
615
+ elif variant == "who_is" and ent_type in ["person", "creature"]:
616
+ prefix = "Who was" if rng.random() < 0.5 else "Who is"
617
+ user_prompt = f"{prefix} {ent}{q_mark}"
618
+ search_q = ent
619
+ answer = f"{ent} is {snippet}"
620
  else:
621
  user_prompt = f"What is {ent}{q_mark}"
622
  search_q = ent
 
936
  return dataset
937
 
938
 
939
+ # -----------------------------------------------------------------------------
940
+ # 2b. Curriculum V5: Broad-Distribution Copy Spans & Parameterized Schemas
941
+ # -----------------------------------------------------------------------------
942
+ # V4 copy spans came from one narrow phonotactic inventory, so real-world
943
+ # spellings outside it (doubled vowels, lowercase connectors, leading articles)
944
+ # drifted at copy time. V5 widens the span distribution, strips articles from
945
+ # arguments, parameterizes every nested schema, and keeps <THINK> short so
946
+ # nested calls close within a 140-token decode budget.
947
+
948
+ SPAN_ONSETS_EXT = NONCE_ONSETS + [
949
+ "", "", "b", "c", "d", "f", "g", "h", "l", "m", "n", "p", "r", "s", "t", "w", "y",
950
+ "ph", "sh", "kh", "zh", "ts", "ng", "nj", "sr", "vr", "hy", "mb", "nd", "rh", "x",
951
+ ]
952
+ SPAN_NUCLEI_EXT = NONCE_NUCLEI + ["aa", "ii", "uu", "ae", "ia", "io", "ua", "ei", "au", "eo", "ie", "ya"]
953
+ SPAN_CODAS_EXT = NONCE_CODAS + ["", "", "", "n", "r", "s", "l", "ng", "rm", "nd", "st", "x", "ch", "lt", "ss"]
954
+ SPAN_CONNECTORS = ["of", "van", "de", "da", "del", "es", "la", "al", "bin", "von", "le", "and", "y", "el"]
955
+ LETTERS = "abcdefghijklmnopqrstuvwxyz"
956
+
957
+ V5_TIMEZONES = TIMEZONES + ["MST", "EET", "BST", "SGT", "NZST", "PDT", "EDT", "WET", "KST", "MSK"]
958
+ V5_REGIONS = ["EU", "US", "APAC", "LATAM", "MEA", "UK", "JP", "IN", "BR", "CA"]
959
+ V5_METRICS = ["latency", "errors", "uptime", "cpu", "memory", "requests", "traffic", "bandwidth"]
960
+ V5_DAYS = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday", "tomorrow", "next week"]
961
+ V5_FILE_EXTS = ["txt", "json", "csv", "md", "log", "py", "yaml", "cfg"]
962
+ V5_RECORD_STATUSES = ["active", "inactive", "pending", "archived"]
963
+
964
+ NO_TOOL_OPENERS = [
965
+ "Hello", "Hi", "Hey", "Good morning", "Good afternoon", "Good evening",
966
+ "Greetings", "Hi there", "Hello there", "Hey there", "Howdy",
967
+ ]
968
+ NO_TOOL_BODIES = [
969
+ "how are you", "how are you today", "how are you doing", "how is it going",
970
+ "how have you been", "what's up", "nice to meet you", "how is your day",
971
+ "how is your day going", "how are things", "are you there", "how are you doing today",
972
+ ]
973
+ NO_TOOL_STANDALONE = [
974
+ ("thanks", "Thank you"), ("thanks", "Thanks a lot"), ("thanks", "Thanks for the help"),
975
+ ("thanks", "Thank you so much"), ("thanks", "Much appreciated"), ("thanks", "Great, thanks"),
976
+ ("bye", "Goodbye"), ("bye", "See you later"), ("bye", "Good night"), ("bye", "Bye for now"),
977
+ ("identity", "Who are you"), ("identity", "What can you do"), ("identity", "What is your name"),
978
+ ("identity", "Are you a robot"), ("ack", "Okay"), ("ack", "Nice work"), ("ack", "That was helpful"),
979
+ ("ack", "Cool"), ("ack", "Sounds good"), ("ack", "Got it"),
980
+ ]
981
+ NO_TOOL_REPLIES = {
982
+ "greeting": [
983
+ "Hello! I am doing well, thank you. How can I help you today?",
984
+ "Hi! Everything is running smoothly. What can I do for you?",
985
+ "Hello! How may I assist you today?",
986
+ ],
987
+ "thanks": [
988
+ "You are welcome! Let me know if you need anything else.",
989
+ "Happy to help! Feel free to ask another question.",
990
+ ],
991
+ "bye": ["Goodbye! Have a great day.", "See you soon! Take care."],
992
+ "identity": [
993
+ "I am CBT, a compact assistant that can call tools for weather, time, search, unit conversion, and arithmetic.",
994
+ ],
995
+ "ack": ["Great! Let me know if there is anything else I can do.", "Glad to hear it. What else can I help with?"],
996
+ }
997
+
998
+
999
+ def _span_word(rng: random.Random) -> str:
1000
+ """Samples one lowercase word from a mixture of phonotactic, nonce, random-letter, and alphanumeric shapes."""
1001
+ r = rng.random()
1002
+ if r < 0.55:
1003
+ w = ""
1004
+ while not 2 <= len(w) <= 14:
1005
+ n_syl = rng.choice([1, 2, 2, 2, 3, 3, 4])
1006
+ w = "".join(
1007
+ rng.choice(SPAN_ONSETS_EXT) + rng.choice(SPAN_NUCLEI_EXT)
1008
+ + (rng.choice(SPAN_CODAS_EXT) if rng.random() < 0.5 else "")
1009
+ for _ in range(n_syl)
1010
+ )
1011
+ elif r < 0.75:
1012
+ w, _, _ = generate_nonce_entity(rng, allow_multi_word=False)
1013
+ w = w.lower()
1014
+ elif r < 0.90:
1015
+ w = "".join(rng.choice(LETTERS) for _ in range(rng.randint(3, 12)))
1016
+ else:
1017
+ stem = "".join(rng.choice(LETTERS) for _ in range(rng.randint(1, 6)))
1018
+ num = str(rng.randint(0, 999))
1019
+ w = rng.choice([stem + num, stem + "-" + num, num + stem, stem.upper() + num])
1020
+ return w if len(w) >= 2 else w + rng.choice(LETTERS)
1021
+
1022
+
1023
+ def generate_copy_span(rng: random.Random, max_words: int = 4, title_prob: float = 0.5) -> str:
1024
+ """Samples a 1-4 word span with mixed casing and optional lowercase connectors ('X de Y' shape)."""
1025
+ n_words = rng.choices([1, 2, 3, 4][:max_words], weights=[0.50, 0.30, 0.15, 0.05][:max_words], k=1)[0]
1026
+ words = [_span_word(rng) for _ in range(n_words)]
1027
+ while len(" ".join(words)) > 36:
1028
+ words = [_span_word(rng) for _ in range(n_words)]
1029
+ casing = rng.random()
1030
+ if casing < title_prob:
1031
+ words = [w[0].upper() + w[1:] for w in words]
1032
+ elif casing < title_prob + 0.05:
1033
+ words = [w.upper() for w in words]
1034
+ elif casing < title_prob + 0.10:
1035
+ words[0] = words[0][0].upper() + words[0][1:]
1036
+ if n_words >= 2 and rng.random() < 0.25:
1037
+ words.insert(rng.randint(1, n_words - 1), rng.choice(SPAN_CONNECTORS))
1038
+ return " ".join(words)
1039
+
1040
+
1041
+ def _v5_entity(rng: random.Random) -> Tuple[str, str]:
1042
+ """Returns (entity, snippet), mixing broad copy spans with case-perturbed known entities."""
1043
+ if rng.random() < 0.70:
1044
+ ent = generate_copy_span(rng)
1045
+ return ent, "a topic described in verified reference sources."
1046
+ item = rng.choice(SEARCH_ENTITIES)
1047
+ ent = item["entity"]
1048
+ r = rng.random()
1049
+ if r < 0.25:
1050
+ ent = ent.lower()
1051
+ elif r < 0.35:
1052
+ ent = ent.title()
1053
+ return ent, item["snippet"]
1054
+
1055
+
1056
+ def _wrap(user_prompt: str, thought: str, call: str, result: str, answer: str) -> str:
1057
+ return (
1058
+ f"<USER>{user_prompt}</USER><THINK>{thought}</THINK><CALL>{call}</CALL>"
1059
+ f"<RESULT>{result}</RESULT><ANSWER>{answer}</ANSWER>"
1060
+ )
1061
+
1062
+
1063
+ def generate_search_v5_example(rng: random.Random) -> Dict[str, str]:
1064
+ """Search delegation with article-stripped arguments ('Tell me about the X' -> query='X')."""
1065
+ ent, snippet = _v5_entity(rng)
1066
+ q = "?" if rng.random() < 0.5 else ""
1067
+ p = "." if rng.random() < 0.5 else ""
1068
+ article = "an" if ent[0].lower() in "aeiou" else "a"
1069
+ user_prompt = rng.choice([
1070
+ f"What is {ent}{q}", f"What is the {ent}{q}", f"What is {article} {ent}{q}", f"What are {ent}{q}",
1071
+ f"What are the {ent}{q}", f"Tell me about {ent}{p}", f"Tell me about the {ent}{p}",
1072
+ f"Tell me about {article} {ent}{p}", f"Define {ent}{p}", f"Define the term {ent}{p}",
1073
+ f"Explain {ent}{p}", f"Explain the {ent}{p}", f"Search for {ent}{p}", f"Look up {ent}{p}",
1074
+ f"Who is {ent}{q}", f"Who was {ent}{q}", f"Find information about {ent}{p}",
1075
+ f"Give me information on {ent}{p}", f"I want to learn about {ent}{p}",
1076
+ ])
1077
+ thought = rng.choice([
1078
+ "The user is asking a factual question. I will query the search tool.",
1079
+ "The user requests factual information. Querying search.",
1080
+ "The user is seeking knowledge on this topic. I will search the web.",
1081
+ ])
1082
+ full_text = _wrap(
1083
+ user_prompt, thought, f"search(query=\"{ent}\")",
1084
+ json.dumps({"snippet": snippet}), f"According to search results, {ent} is {snippet}",
1085
+ )
1086
+ return {"category": "search_v5", "full_text": full_text}
1087
+
1088
+
1089
+ def generate_single_tool_v5_example(rng: random.Random) -> Dict[str, str]:
1090
+ """Weather / calculator / time / unit_convert with broad spans and verbatim calculator expressions."""
1091
+ q = "?" if rng.random() < 0.5 else ""
1092
+ p = "." if rng.random() < 0.5 else ""
1093
+ sub = rng.choices(["weather", "calculator", "time", "unit_convert"], weights=[0.35, 0.35, 0.15, 0.15], k=1)[0]
1094
+
1095
+ if sub == "weather":
1096
+ city = generate_copy_span(rng, max_words=3, title_prob=0.85) if rng.random() < 0.55 else rng.choice(CITIES)
1097
+ temp, cond = rng.randint(-10, 40), rng.choice(CONDITIONS)
1098
+ user_prompt = rng.choice([
1099
+ f"What is the weather in {city}{q}", f"What is the weather on {city}{q}",
1100
+ f"What is the weather for {city}{q}", f"What's the weather in {city}{q}",
1101
+ f"What is the weather like in {city}{q}", f"How is the weather in {city}{q}",
1102
+ f"How is the weather on {city}{q}", f"Weather in {city}{p}", f"Weather on {city}{p}",
1103
+ f"Weather for {city}{p}", f"Check the weather in {city}{p}", f"Check the weather for {city}{p}",
1104
+ f"Tell me the weather in {city}{p}", f"Forecast for {city}{p}", f"{city} weather{p}",
1105
+ f"Is it raining in {city}{q}", f"Temperature in {city}{p}",
1106
+ ])
1107
+ thought = rng.choice([
1108
+ "The user requests current weather information. I will query the get_weather tool.",
1109
+ "The user is asking for weather conditions. Querying get_weather.",
1110
+ ])
1111
+ call = f"get_weather(city=\"{city}\")"
1112
+ result = json.dumps({"temp": temp, "condition": cond, "units": "celsius"})
1113
+ answer = f"The weather in {city} is currently {cond} with a temperature of {temp} degrees Celsius."
1114
+
1115
+ elif sub == "calculator":
1116
+ op = rng.choice(["+", "-", "*", "/"])
1117
+ if op == "/":
1118
+ b = rng.randint(2, 99)
1119
+ res = rng.randint(2, 999)
1120
+ a = res * b
1121
+ else:
1122
+ a = rng.randint(1, 10 ** rng.randint(1, 5) - 1)
1123
+ b = rng.randint(1, 10 ** rng.randint(1, 4) - 1)
1124
+ res = a + b if op == "+" else (a - b if op == "-" else a * b)
1125
+ expr = rng.choice([f"{a} {op} {b}", f"{a}{op}{b}"])
1126
+ user_prompt = rng.choice([
1127
+ f"Calculate {expr}{p}", f"What is {expr}{q}", f"Compute {expr}{p}", f"Evaluate {expr}{p}",
1128
+ f"Solve {expr}{p}", f"What's {expr}{q}", f"How much is {expr}{q}",
1129
+ ])
1130
+ thought = rng.choice([
1131
+ "The user requests an arithmetic calculation. I will invoke the calculator tool.",
1132
+ "The user is asking to evaluate a mathematical expression. Calling calculator.",
1133
+ ])
1134
+ call = f"calculator(expr=\"{expr}\")"
1135
+ result = json.dumps({"result": res})
1136
+ answer = f"The evaluated result of {expr} is {res}."
1137
+
1138
+ elif sub == "time":
1139
+ # 40% synthetic uppercase codes so timezone is copied from the prompt, not recalled from a list
1140
+ tz = rng.choice(V5_TIMEZONES) if rng.random() < 0.6 else "".join(rng.choice(LETTERS) for _ in range(rng.randint(2, 5))).upper()
1141
+ time_str = f"{rng.randint(0, 23):02d}:{rng.randint(0, 59):02d}"
1142
+ user_prompt = rng.choice([
1143
+ f"What is the current time in {tz}{q}", f"What is the time in {tz}{q}", f"What time is it in {tz}{q}",
1144
+ f"Current time in {tz}{p}", f"Time in {tz}{p}", f"Tell me the time in {tz}{p}",
1145
+ f"Check the time for {tz}{p}",
1146
+ ])
1147
+ thought = "The user is asking for the current time. Querying get_time."
1148
+ call = f"get_time(timezone=\"{tz}\")"
1149
+ result = json.dumps({"time": time_str, "timezone": tz})
1150
+ answer = f"The current time in {tz} is {time_str}."
1151
+
1152
+ else:
1153
+ val = rng.randint(1, 1000)
1154
+ from_u, to_u, factor = rng.choice([
1155
+ ("km", "miles", 0.621371), ("miles", "km", 1.60934), ("kg", "lbs", 2.20462), ("lbs", "kg", 0.453592),
1156
+ ])
1157
+ user_prompt = rng.choice([
1158
+ f"Convert {val} {from_u} to {to_u}{p}", f"How many {to_u} is {val} {from_u}{q}",
1159
+ f"How many {to_u} are in {val} {from_u}{q}", f"What is {val} {from_u} in {to_u}{q}",
1160
+ f"Change {val} {from_u} into {to_u}{p}",
1161
+ ])
1162
+ thought = "The user requests a unit conversion. I will invoke the unit_convert tool."
1163
+ call = f"unit_convert(value={val}, from_unit=\"{from_u}\", to_unit=\"{to_u}\")"
1164
+ result = json.dumps({"value": round(val * factor, 2), "unit": to_u})
1165
+ answer = f"{val} {from_u} is equal to {round(val * factor, 2)} {to_u}."
1166
+
1167
+ return {"category": f"single_{sub}", "full_text": _wrap(user_prompt, thought, call, result, answer)}
1168
+
1169
+
1170
+ def generate_nested_v5_example(rng: random.Random) -> Dict[str, str]:
1171
+ """Parameterized compact nested schemas; short <THINK> keeps the full call under the decode budget."""
1172
+ p = "." if rng.random() < 0.5 else ""
1173
+ schema = rng.choice(["db_query", "event_create", "file_manage", "api_fetch"])
1174
+
1175
+ if schema == "db_query":
1176
+ dept = rng.choice(DEPARTMENTS) if rng.random() < 0.6 else _span_word(rng).lower()[:12]
1177
+ n = rng.randint(1, 20)
1178
+ status = rng.choice(V5_RECORD_STATUSES)
1179
+ user_prompt = rng.choice([
1180
+ f"Query the top {n} {status} records in the {dept} department{p}",
1181
+ f"Query top {n} {status} records in {dept}{p}",
1182
+ f"Get {n} {status} records from {dept}{p}",
1183
+ f"Show the top {n} {status} {dept} records{p}",
1184
+ f"Fetch the top {n} {status} entries from {dept}{p}",
1185
+ f"List {n} {status} records in the {dept} team{p}",
1186
+ ])
1187
+ thought = "Calling database_query."
1188
+ call = f"database_query(filter={{\"department\": \"{dept}\", \"status\": \"{status}\"}}, options={{\"limit\": {n}}})"
1189
+ result = json.dumps({"status": "success", "count": n})
1190
+ answer = f"Found {n} {status} records in {dept}."
1191
+
1192
+ elif schema == "event_create":
1193
+ title = generate_copy_span(rng, max_words=3, title_prob=0.9)
1194
+ h = rng.randint(0, 22)
1195
+ start = f"{h:02d}:{rng.choice([0, 15, 30, 45]):02d}"
1196
+ end = f"{h + 1:02d}:{start[-2:]}"
1197
+ mode = rng.random()
1198
+ if mode < 0.3:
1199
+ day = rng.choice(V5_DAYS)
1200
+ on = "" if day in ("tomorrow", "next week") else "on "
1201
+ user_prompt = rng.choice([
1202
+ f"Create a calendar event for {title} {on}{day}{p}",
1203
+ f"Schedule {title} {on}{day}{p}",
1204
+ f"Add {title} to my calendar {on}{day}{p}",
1205
+ f"Book {title} {on}{day}{p}",
1206
+ ])
1207
+ call = f"create_event(event={{\"title\": \"{title}\", \"date\": \"{day}\"}})"
1208
+ start = day
1209
+ elif mode < 0.55:
1210
+ user_prompt = rng.choice([
1211
+ f"Schedule {title} from {start} to {end}{p}",
1212
+ f"Create a calendar event for {title} from {start} to {end}{p}",
1213
+ f"Book {title} between {start} and {end}{p}",
1214
+ ])
1215
+ call = f"create_event(event={{\"title\": \"{title}\", \"start\": \"{start}\", \"end\": \"{end}\"}})"
1216
+ else:
1217
+ user_prompt = rng.choice([
1218
+ f"Create a calendar event for {title} at {start}{p}",
1219
+ f"Create an event called {title} at {start}{p}",
1220
+ f"Schedule {title} at {start}{p}",
1221
+ f"Add {title} to my calendar at {start}{p}",
1222
+ f"Set up {title} at {start} tomorrow{p}",
1223
+ ])
1224
+ call = f"create_event(event={{\"title\": \"{title}\", \"start\": \"{start}\"}})"
1225
+ thought = "Calling create_event."
1226
+ result = json.dumps({"event_id": f"evt_{rng.randint(10000, 99999)}", "status": "confirmed"})
1227
+ answer = f"Scheduled {title} for {start}."
1228
+
1229
+ elif schema == "file_manage":
1230
+ fname = f"{_span_word(rng).lower()[:10]}.{rng.choice(V5_FILE_EXTS)}"
1231
+ if rng.random() < 0.3:
1232
+ fname = f"{rng.choice(['docs', 'data', 'logs', 'tmp', 'notes'])}/{fname}"
1233
+ action = rng.choices(["write", "read", "delete"], weights=[0.7, 0.15, 0.15], k=1)[0]
1234
+ if action == "write":
1235
+ content = generate_copy_span(rng, max_words=3, title_prob=0.6)
1236
+ user_prompt = rng.choice([
1237
+ f"Save {fname} with content {content}{p}",
1238
+ f"Write {content} to {fname}{p}",
1239
+ f"Create file {fname} containing {content}{p}",
1240
+ f"Save the text {content} in {fname}{p}",
1241
+ ])
1242
+ call = f"file_manager(action=\"write\", file={{\"path\": \"{fname}\"}}, content=\"{content}\")"
1243
+ else:
1244
+ verb = "Read" if action == "read" else "Delete"
1245
+ user_prompt = rng.choice([f"{verb} {fname}{p}", f"{verb} the file {fname}{p}"])
1246
+ call = f"file_manager(action=\"{action}\", file={{\"path\": \"{fname}\"}})"
1247
+ thought = "Calling file_manager."
1248
+ result = json.dumps({"status": "ok"})
1249
+ answer = f"File operation {action} completed for {fname}."
1250
+
1251
+ else:
1252
+ segs = [_span_word(rng).lower()[:8] for _ in range(rng.randint(1, 2))]
1253
+ endpoint = f"/v{rng.randint(1, 3)}/" + "/".join(segs)
1254
+ region, metric = rng.choice(V5_REGIONS), rng.choice(V5_METRICS)
1255
+ user_prompt = rng.choice([
1256
+ f"Fetch {metric} metrics for {region} from {endpoint}{p}",
1257
+ f"Fetch {metric} metrics for {region} region from {endpoint}{p}",
1258
+ f"Get {metric} data from {endpoint} for {region}{p}",
1259
+ f"Call {endpoint} for {region} {metric}{p}",
1260
+ ])
1261
+ thought = "Calling fetch_api."
1262
+ call = f"fetch_api(endpoint=\"{endpoint}\", params={{\"region\": \"{region}\", \"metric\": \"{metric}\"}})"
1263
+ result = json.dumps({"status": 200, "data": {"value": round(rng.random() * 100, 1)}})
1264
+ answer = f"Retrieved {metric} for {region} from {endpoint}."
1265
+
1266
+ return {"category": f"nested_{schema}", "full_text": _wrap(user_prompt, thought, call, result, answer)}
1267
+
1268
+
1269
+ def generate_error_v5_example(rng: random.Random) -> Dict[str, str]:
1270
+ """Error recovery traces using the V5 compact schemas."""
1271
+ err = rng.choice(["div_zero", "city_not_found", "api_503_fallback", "table_missing"])
1272
+ if err == "div_zero":
1273
+ num = rng.randint(1, 9999)
1274
+ user_prompt = f"Calculate {num} / 0"
1275
+ steps = [
1276
+ ("The user requests an arithmetic calculation. I will invoke the calculator tool.",
1277
+ f"calculator(expr=\"{num} / 0\")", json.dumps({"error": "ZeroDivisionError: division by zero"})),
1278
+ ]
1279
+ final_thought = "The calculator returned ZeroDivisionError. I will explain this clearly."
1280
+ answer = "Division by zero is undefined. Please provide a non-zero denominator."
1281
+ elif err == "city_not_found":
1282
+ city = generate_copy_span(rng, max_words=2, title_prob=1.0)
1283
+ user_prompt = f"What is the weather in {city}"
1284
+ steps = [
1285
+ ("The user requests current weather information. I will query the get_weather tool.",
1286
+ f"get_weather(city=\"{city}\")", json.dumps({"status": "error", "code": 404})),
1287
+ ]
1288
+ final_thought = "get_weather returned 404. I must inform the user."
1289
+ answer = f"I could not retrieve weather data for {city} because it is not recognized."
1290
+ elif err == "api_503_fallback":
1291
+ city = rng.choice(CITIES)
1292
+ user_prompt = f"Check the primary API forecast for {city}"
1293
+ steps = [
1294
+ ("Calling fetch_api.", f"fetch_api(endpoint=\"/v1/weather\", params={{\"city\": \"{city}\"}})",
1295
+ json.dumps({"status": 503})),
1296
+ ("Primary API failed with 503. Falling back to get_weather.", f"get_weather(city=\"{city}\")",
1297
+ json.dumps({"temp": 22, "condition": "Sunny"})),
1298
+ ]
1299
+ final_thought = ""
1300
+ answer = f"The primary service was unavailable, but the fallback reports {city} is Sunny at 22C."
1301
+ else:
1302
+ table = _span_word(rng).lower()[:12]
1303
+ user_prompt = f"Query records from table {table}"
1304
+ steps = [
1305
+ ("Calling database_query.", f"database_query(filter={{\"table\": \"{table}\"}}, options={{\"limit\": 5}})",
1306
+ json.dumps({"status": "error", "code": "TABLE_NOT_FOUND"})),
1307
+ ]
1308
+ final_thought = "TABLE_NOT_FOUND. Informing the user."
1309
+ answer = f"The table {table} was not found. Please verify the table name."
1310
+
1311
+ text = f"<USER>{user_prompt}</USER>"
1312
+ for thought, call, result in steps:
1313
+ text += f"<THINK>{thought}</THINK><CALL>{call}</CALL><RESULT>{result}</RESULT>"
1314
+ if final_thought:
1315
+ text += f"<THINK>{final_thought}</THINK>"
1316
+ text += f"<ANSWER>{answer}</ANSWER>"
1317
+ return {"category": "error_v5", "full_text": text}
1318
+
1319
+
1320
+ def generate_no_tool_v5_example(rng: random.Random) -> Dict[str, str]:
1321
+ """Compositional chit-chat (greetings with 'today'/'doing' etc.) routed directly to <ANSWER>."""
1322
+ if rng.random() < 0.6:
1323
+ opener, body = rng.choice(NO_TOOL_OPENERS), rng.choice(NO_TOOL_BODIES)
1324
+ sep = rng.choice([", ", "! ", " ", ". "])
1325
+ user_prompt = f"{opener}{sep}{body}{rng.choice(['?', '', '!'])}"
1326
+ if rng.random() < 0.15:
1327
+ user_prompt = user_prompt.lower()
1328
+ kind = "greeting"
1329
+ else:
1330
+ kind, user_prompt = rng.choice(NO_TOOL_STANDALONE)
1331
+ user_prompt += rng.choice(["", ".", "!", "?"] if kind == "identity" else ["", ".", "!"])
1332
+ thought = "Conversational request that does not require any tool. I will answer directly."
1333
+ full_text = f"<USER>{user_prompt}</USER><THINK>{thought}</THINK><ANSWER>{rng.choice(NO_TOOL_REPLIES[kind])}</ANSWER>"
1334
+ return {"category": "no_tool_v5", "full_text": full_text}
1335
+
1336
+
1337
+ def generate_v5_tool_example(rng: random.Random) -> Dict[str, str]:
1338
+ """Samples one non-search V5 tool trace; chains and multi-turn reuse the V4 generator."""
1339
+ category = rng.choices(
1340
+ ["single", "nested", "no_tool", "error", "chain", "multi_turn"],
1341
+ weights=[0.42, 0.24, 0.14, 0.08, 0.06, 0.06],
1342
+ k=1,
1343
+ )[0]
1344
+ if category == "single":
1345
+ return generate_single_tool_v5_example(rng)
1346
+ if category == "nested":
1347
+ return generate_nested_v5_example(rng)
1348
+ if category == "no_tool":
1349
+ return generate_no_tool_v5_example(rng)
1350
+ if category == "error":
1351
+ return generate_error_v5_example(rng)
1352
+ return generate_tool_example(rng, category="multi_tool_chain" if category == "chain" else "multi_turn")
1353
+
1354
+
1355
+ def to_tool_item(example: Dict[str, str]) -> Dict[str, str]:
1356
+ """Wraps a generated trace into the encode_joint_batch item format."""
1357
+ full_text = example["full_text"]
1358
+ return {
1359
+ "task_type": "tools",
1360
+ "prompt": full_text.split("</USER>")[0] + "</USER>",
1361
+ "full_text": full_text,
1362
+ "category": example["category"],
1363
+ }
1364
+
1365
+
1366
  def generate_joint_dataset(
1367
  n_math: int = 4000,
1368
  n_tools: int = 4000,
random_extrapolation_champion_16_to_100d.json ADDED
@@ -0,0 +1,610 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "per_length": {
3
+ "16": {
4
+ "digits": 16,
5
+ "n_samples": 30,
6
+ "exact_match": 30,
7
+ "accuracy_pct": 100.0,
8
+ "wilson_95_ci": [
9
+ 88.6,
10
+ 100.0
11
+ ],
12
+ "think_exact": 30,
13
+ "think_acc_pct": 100.0,
14
+ "think_wilson_95_ci": [
15
+ 88.6,
16
+ 100.0
17
+ ],
18
+ "lparen_errors": 0,
19
+ "off_by_one_readout_errors": 0,
20
+ "seq_tokens": 226,
21
+ "elapsed_sec": 27.6,
22
+ "tok_per_sec": 245.6
23
+ },
24
+ "20": {
25
+ "digits": 20,
26
+ "n_samples": 30,
27
+ "exact_match": 30,
28
+ "accuracy_pct": 100.0,
29
+ "wilson_95_ci": [
30
+ 88.6,
31
+ 100.0
32
+ ],
33
+ "think_exact": 30,
34
+ "think_acc_pct": 100.0,
35
+ "think_wilson_95_ci": [
36
+ 88.6,
37
+ 100.0
38
+ ],
39
+ "lparen_errors": 0,
40
+ "off_by_one_readout_errors": 0,
41
+ "seq_tokens": 278,
42
+ "elapsed_sec": 38.68,
43
+ "tok_per_sec": 215.6
44
+ },
45
+ "25": {
46
+ "digits": 25,
47
+ "n_samples": 30,
48
+ "exact_match": 30,
49
+ "accuracy_pct": 100.0,
50
+ "wilson_95_ci": [
51
+ 88.6,
52
+ 100.0
53
+ ],
54
+ "think_exact": 30,
55
+ "think_acc_pct": 100.0,
56
+ "think_wilson_95_ci": [
57
+ 88.6,
58
+ 100.0
59
+ ],
60
+ "lparen_errors": 0,
61
+ "off_by_one_readout_errors": 0,
62
+ "seq_tokens": 343,
63
+ "elapsed_sec": 54.9,
64
+ "tok_per_sec": 187.4
65
+ },
66
+ "30": {
67
+ "digits": 30,
68
+ "n_samples": 30,
69
+ "exact_match": 30,
70
+ "accuracy_pct": 100.0,
71
+ "wilson_95_ci": [
72
+ 88.6,
73
+ 100.0
74
+ ],
75
+ "think_exact": 30,
76
+ "think_acc_pct": 100.0,
77
+ "think_wilson_95_ci": [
78
+ 88.6,
79
+ 100.0
80
+ ],
81
+ "lparen_errors": 0,
82
+ "off_by_one_readout_errors": 0,
83
+ "seq_tokens": 408,
84
+ "elapsed_sec": 79.13,
85
+ "tok_per_sec": 154.7
86
+ },
87
+ "35": {
88
+ "digits": 35,
89
+ "n_samples": 30,
90
+ "exact_match": 30,
91
+ "accuracy_pct": 100.0,
92
+ "wilson_95_ci": [
93
+ 88.6,
94
+ 100.0
95
+ ],
96
+ "think_exact": 30,
97
+ "think_acc_pct": 100.0,
98
+ "think_wilson_95_ci": [
99
+ 88.6,
100
+ 100.0
101
+ ],
102
+ "lparen_errors": 0,
103
+ "off_by_one_readout_errors": 0,
104
+ "seq_tokens": 473,
105
+ "elapsed_sec": 95.72,
106
+ "tok_per_sec": 148.3
107
+ },
108
+ "40": {
109
+ "digits": 40,
110
+ "n_samples": 30,
111
+ "exact_match": 30,
112
+ "accuracy_pct": 100.0,
113
+ "wilson_95_ci": [
114
+ 88.6,
115
+ 100.0
116
+ ],
117
+ "think_exact": 30,
118
+ "think_acc_pct": 100.0,
119
+ "think_wilson_95_ci": [
120
+ 88.6,
121
+ 100.0
122
+ ],
123
+ "lparen_errors": 0,
124
+ "off_by_one_readout_errors": 0,
125
+ "seq_tokens": 538,
126
+ "elapsed_sec": 155.8,
127
+ "tok_per_sec": 103.6
128
+ },
129
+ "45": {
130
+ "digits": 45,
131
+ "n_samples": 30,
132
+ "exact_match": 30,
133
+ "accuracy_pct": 100.0,
134
+ "wilson_95_ci": [
135
+ 88.6,
136
+ 100.0
137
+ ],
138
+ "think_exact": 30,
139
+ "think_acc_pct": 100.0,
140
+ "think_wilson_95_ci": [
141
+ 88.6,
142
+ 100.0
143
+ ],
144
+ "lparen_errors": 0,
145
+ "off_by_one_readout_errors": 0,
146
+ "seq_tokens": 603,
147
+ "elapsed_sec": 182.82,
148
+ "tok_per_sec": 99.0
149
+ },
150
+ "50": {
151
+ "digits": 50,
152
+ "n_samples": 30,
153
+ "exact_match": 30,
154
+ "accuracy_pct": 100.0,
155
+ "wilson_95_ci": [
156
+ 88.6,
157
+ 100.0
158
+ ],
159
+ "think_exact": 30,
160
+ "think_acc_pct": 100.0,
161
+ "think_wilson_95_ci": [
162
+ 88.6,
163
+ 100.0
164
+ ],
165
+ "lparen_errors": 0,
166
+ "off_by_one_readout_errors": 0,
167
+ "seq_tokens": 668,
168
+ "elapsed_sec": 166.06,
169
+ "tok_per_sec": 120.7
170
+ },
171
+ "55": {
172
+ "digits": 55,
173
+ "n_samples": 20,
174
+ "exact_match": 20,
175
+ "accuracy_pct": 100.0,
176
+ "wilson_95_ci": [
177
+ 83.9,
178
+ 100.0
179
+ ],
180
+ "think_exact": 20,
181
+ "think_acc_pct": 100.0,
182
+ "think_wilson_95_ci": [
183
+ 83.9,
184
+ 100.0
185
+ ],
186
+ "lparen_errors": 0,
187
+ "off_by_one_readout_errors": 0,
188
+ "seq_tokens": 733,
189
+ "elapsed_sec": 134.79,
190
+ "tok_per_sec": 108.8
191
+ },
192
+ "60": {
193
+ "digits": 60,
194
+ "n_samples": 20,
195
+ "exact_match": 14,
196
+ "accuracy_pct": 70.0,
197
+ "wilson_95_ci": [
198
+ 48.1,
199
+ 85.5
200
+ ],
201
+ "think_exact": 14,
202
+ "think_acc_pct": 70.0,
203
+ "think_wilson_95_ci": [
204
+ 48.1,
205
+ 85.5
206
+ ],
207
+ "lparen_errors": 1,
208
+ "off_by_one_readout_errors": 0,
209
+ "seq_tokens": 798,
210
+ "elapsed_sec": 150.02,
211
+ "tok_per_sec": 106.4
212
+ },
213
+ "70": {
214
+ "digits": 70,
215
+ "n_samples": 15,
216
+ "exact_match": 6,
217
+ "accuracy_pct": 40.0,
218
+ "wilson_95_ci": [
219
+ 19.8,
220
+ 64.3
221
+ ],
222
+ "think_exact": 6,
223
+ "think_acc_pct": 40.0,
224
+ "think_wilson_95_ci": [
225
+ 19.8,
226
+ 64.3
227
+ ],
228
+ "lparen_errors": 0,
229
+ "off_by_one_readout_errors": 0,
230
+ "seq_tokens": 928,
231
+ "elapsed_sec": 161.99,
232
+ "tok_per_sec": 85.9
233
+ },
234
+ "80": {
235
+ "digits": 80,
236
+ "n_samples": 10,
237
+ "exact_match": 0,
238
+ "accuracy_pct": 0.0,
239
+ "wilson_95_ci": [
240
+ 0.0,
241
+ 27.8
242
+ ],
243
+ "think_exact": 0,
244
+ "think_acc_pct": 0.0,
245
+ "think_wilson_95_ci": [
246
+ 0.0,
247
+ 27.8
248
+ ],
249
+ "lparen_errors": 5,
250
+ "off_by_one_readout_errors": 0,
251
+ "seq_tokens": 1149,
252
+ "elapsed_sec": 154.23,
253
+ "tok_per_sec": 74.5
254
+ },
255
+ "100": {
256
+ "digits": 100,
257
+ "n_samples": 10,
258
+ "exact_match": 0,
259
+ "accuracy_pct": 0.0,
260
+ "wilson_95_ci": [
261
+ 0.0,
262
+ 27.8
263
+ ],
264
+ "think_exact": 0,
265
+ "think_acc_pct": 0.0,
266
+ "think_wilson_95_ci": [
267
+ 0.0,
268
+ 27.8
269
+ ],
270
+ "lparen_errors": 0,
271
+ "off_by_one_readout_errors": 0,
272
+ "seq_tokens": 1429,
273
+ "elapsed_sec": 200.31,
274
+ "tok_per_sec": 71.3
275
+ }
276
+ },
277
+ "failures": [
278
+ {
279
+ "digits": 60,
280
+ "kind": "uniform_random",
281
+ "expected_len": 60,
282
+ "pred_len": 61,
283
+ "think_ok": false,
284
+ "expected_head": "99455736002861930179",
285
+ "pred_head": "10045573600286193017"
286
+ },
287
+ {
288
+ "digits": 60,
289
+ "kind": "uniform_random",
290
+ "expected_len": 61,
291
+ "pred_len": 61,
292
+ "think_ok": false,
293
+ "expected_head": "13771859705436256056",
294
+ "pred_head": "14771859705436256056"
295
+ },
296
+ {
297
+ "digits": 60,
298
+ "kind": "uniform_random",
299
+ "expected_len": 60,
300
+ "pred_len": 60,
301
+ "think_ok": false,
302
+ "expected_head": "93182197277112619803",
303
+ "pred_head": "93182207277112619803"
304
+ },
305
+ {
306
+ "digits": 60,
307
+ "kind": "uniform_random",
308
+ "expected_len": 61,
309
+ "pred_len": 61,
310
+ "think_ok": false,
311
+ "expected_head": "13495686920877645844",
312
+ "pred_head": "13595686920877645844"
313
+ },
314
+ {
315
+ "digits": 60,
316
+ "kind": "uniform_random",
317
+ "expected_len": 60,
318
+ "pred_len": 60,
319
+ "think_ok": false,
320
+ "expected_head": "33303324997839267821",
321
+ "pred_head": "35303324997839267821"
322
+ },
323
+ {
324
+ "digits": 60,
325
+ "kind": "cascade_mix",
326
+ "expected_len": 61,
327
+ "pred_len": 61,
328
+ "think_ok": false,
329
+ "expected_head": "15999869832993500000",
330
+ "pred_head": "16999869832993500000"
331
+ },
332
+ {
333
+ "digits": 70,
334
+ "kind": "uniform_random",
335
+ "expected_len": 71,
336
+ "pred_len": 71,
337
+ "think_ok": false,
338
+ "expected_head": "13709577792207576758",
339
+ "pred_head": "13710577792207576758"
340
+ },
341
+ {
342
+ "digits": 70,
343
+ "kind": "uniform_random",
344
+ "expected_len": 71,
345
+ "pred_len": 71,
346
+ "think_ok": false,
347
+ "expected_head": "18254804996856400492",
348
+ "pred_head": "18254805096856400492"
349
+ },
350
+ {
351
+ "digits": 70,
352
+ "kind": "uniform_random",
353
+ "expected_len": 71,
354
+ "pred_len": 71,
355
+ "think_ok": false,
356
+ "expected_head": "15468076189969829446",
357
+ "pred_head": "15468076190969829446"
358
+ },
359
+ {
360
+ "digits": 70,
361
+ "kind": "uniform_random",
362
+ "expected_len": 71,
363
+ "pred_len": 71,
364
+ "think_ok": false,
365
+ "expected_head": "17132113958771129774",
366
+ "pred_head": "17162113958771129774"
367
+ },
368
+ {
369
+ "digits": 70,
370
+ "kind": "uniform_random",
371
+ "expected_len": 70,
372
+ "pred_len": 70,
373
+ "think_ok": false,
374
+ "expected_head": "81569945829520864708",
375
+ "pred_head": "81669945829520864708"
376
+ },
377
+ {
378
+ "digits": 70,
379
+ "kind": "uniform_random",
380
+ "expected_len": 71,
381
+ "pred_len": 71,
382
+ "think_ok": false,
383
+ "expected_head": "14659845102561298448",
384
+ "pred_head": "14657845102561298448"
385
+ },
386
+ {
387
+ "digits": 70,
388
+ "kind": "uniform_random",
389
+ "expected_len": 71,
390
+ "pred_len": 71,
391
+ "think_ok": false,
392
+ "expected_head": "12532903951038538802",
393
+ "pred_head": "12532903851038538802"
394
+ },
395
+ {
396
+ "digits": 70,
397
+ "kind": "uniform_random",
398
+ "expected_len": 71,
399
+ "pred_len": 71,
400
+ "think_ok": false,
401
+ "expected_head": "14193174229527824431",
402
+ "pred_head": "14193174229827824431"
403
+ },
404
+ {
405
+ "digits": 70,
406
+ "kind": "cascade_mix",
407
+ "expected_len": 71,
408
+ "pred_len": 71,
409
+ "think_ok": false,
410
+ "expected_head": "17503600000090000000",
411
+ "pred_head": "17503600000080000000"
412
+ },
413
+ {
414
+ "digits": 80,
415
+ "kind": "uniform_random",
416
+ "expected_len": 81,
417
+ "pred_len": 87,
418
+ "think_ok": false,
419
+ "expected_head": "12847570704495513468",
420
+ "pred_head": "00000012847570704495"
421
+ },
422
+ {
423
+ "digits": 80,
424
+ "kind": "uniform_random",
425
+ "expected_len": 81,
426
+ "pred_len": 63,
427
+ "think_ok": false,
428
+ "expected_head": "10585471026702913113",
429
+ "pred_head": "00000000000105854710"
430
+ },
431
+ {
432
+ "digits": 80,
433
+ "kind": "uniform_random",
434
+ "expected_len": 81,
435
+ "pred_len": 7,
436
+ "think_ok": false,
437
+ "expected_head": "12278363141943820719",
438
+ "pred_head": "NO_STOP"
439
+ },
440
+ {
441
+ "digits": 80,
442
+ "kind": "uniform_random",
443
+ "expected_len": 81,
444
+ "pred_len": 88,
445
+ "think_ok": false,
446
+ "expected_head": "11724726771333240441",
447
+ "pred_head": "00000001172472676133"
448
+ },
449
+ {
450
+ "digits": 80,
451
+ "kind": "uniform_random",
452
+ "expected_len": 81,
453
+ "pred_len": 7,
454
+ "think_ok": false,
455
+ "expected_head": "14074311451742727401",
456
+ "pred_head": "NO_STOP"
457
+ },
458
+ {
459
+ "digits": 80,
460
+ "kind": "uniform_random",
461
+ "expected_len": 81,
462
+ "pred_len": 86,
463
+ "think_ok": false,
464
+ "expected_head": "16952626939497179229",
465
+ "pred_head": "00000169526269394861"
466
+ },
467
+ {
468
+ "digits": 80,
469
+ "kind": "uniform_random",
470
+ "expected_len": 80,
471
+ "pred_len": 86,
472
+ "think_ok": false,
473
+ "expected_head": "82549613862831800793",
474
+ "pred_head": "80000082849613863331"
475
+ },
476
+ {
477
+ "digits": 80,
478
+ "kind": "dense_carry",
479
+ "expected_len": 81,
480
+ "pred_len": 7,
481
+ "think_ok": false,
482
+ "expected_head": "13272527565535783883",
483
+ "pred_head": "NO_STOP"
484
+ },
485
+ {
486
+ "digits": 80,
487
+ "kind": "dense_carry",
488
+ "expected_len": 81,
489
+ "pred_len": 7,
490
+ "think_ok": false,
491
+ "expected_head": "16668493333645678724",
492
+ "pred_head": "NO_STOP"
493
+ },
494
+ {
495
+ "digits": 80,
496
+ "kind": "cascade_mix",
497
+ "expected_len": 81,
498
+ "pred_len": 7,
499
+ "think_ok": false,
500
+ "expected_head": "10002799999960006628",
501
+ "pred_head": "NO_STOP"
502
+ },
503
+ {
504
+ "digits": 100,
505
+ "kind": "uniform_random",
506
+ "expected_len": 101,
507
+ "pred_len": 7,
508
+ "think_ok": false,
509
+ "expected_head": "11288401813144915928",
510
+ "pred_head": "NO_STOP"
511
+ },
512
+ {
513
+ "digits": 100,
514
+ "kind": "uniform_random",
515
+ "expected_len": 101,
516
+ "pred_len": 7,
517
+ "think_ok": false,
518
+ "expected_head": "15225010932074486266",
519
+ "pred_head": "NO_STOP"
520
+ },
521
+ {
522
+ "digits": 100,
523
+ "kind": "uniform_random",
524
+ "expected_len": 101,
525
+ "pred_len": 7,
526
+ "think_ok": false,
527
+ "expected_head": "17203428879913620849",
528
+ "pred_head": "NO_STOP"
529
+ },
530
+ {
531
+ "digits": 100,
532
+ "kind": "uniform_random",
533
+ "expected_len": 101,
534
+ "pred_len": 7,
535
+ "think_ok": false,
536
+ "expected_head": "13949786348913299912",
537
+ "pred_head": "NO_STOP"
538
+ },
539
+ {
540
+ "digits": 100,
541
+ "kind": "uniform_random",
542
+ "expected_len": 101,
543
+ "pred_len": 7,
544
+ "think_ok": false,
545
+ "expected_head": "12975883843361249782",
546
+ "pred_head": "NO_STOP"
547
+ },
548
+ {
549
+ "digits": 100,
550
+ "kind": "uniform_random",
551
+ "expected_len": 100,
552
+ "pred_len": 7,
553
+ "think_ok": false,
554
+ "expected_head": "45147010533867848323",
555
+ "pred_head": "NO_STOP"
556
+ },
557
+ {
558
+ "digits": 100,
559
+ "kind": "uniform_random",
560
+ "expected_len": 101,
561
+ "pred_len": 7,
562
+ "think_ok": false,
563
+ "expected_head": "13735571010375678962",
564
+ "pred_head": "NO_STOP"
565
+ },
566
+ {
567
+ "digits": 100,
568
+ "kind": "dense_carry",
569
+ "expected_len": 101,
570
+ "pred_len": 7,
571
+ "think_ok": false,
572
+ "expected_head": "16553554674857513255",
573
+ "pred_head": "NO_STOP"
574
+ },
575
+ {
576
+ "digits": 100,
577
+ "kind": "dense_carry",
578
+ "expected_len": 101,
579
+ "pred_len": 7,
580
+ "think_ok": false,
581
+ "expected_head": "18253466387437646273",
582
+ "pred_head": "NO_STOP"
583
+ },
584
+ {
585
+ "digits": 100,
586
+ "kind": "cascade_mix",
587
+ "expected_len": 101,
588
+ "pred_len": 7,
589
+ "think_ok": false,
590
+ "expected_head": "17200006000000004996",
591
+ "pred_head": "NO_STOP"
592
+ }
593
+ ],
594
+ "summary_16_50": {
595
+ "total_samples": 240,
596
+ "exact_match": 240,
597
+ "accuracy_pct": 100.0,
598
+ "wilson_95_ci": [
599
+ 98.4,
600
+ 100.0
601
+ ],
602
+ "think_exact": 240,
603
+ "think_acc_pct": 100.0,
604
+ "think_wilson_95_ci": [
605
+ 98.4,
606
+ 100.0
607
+ ]
608
+ },
609
+ "total_elapsed_sec": 1602.17
610
+ }