N8Programs commited on
Commit
2405121
·
verified ·
1 Parent(s): fdb6169

NextTerm-2-50M: bf16 weights, model card, eval scripts and data

Browse files
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ radar_chart.png filter=lfs diff=lfs merge=lfs -text
README.md ADDED
@@ -0,0 +1,191 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: cc-by-sa-4.0
3
+ library_name: transformers
4
+ pipeline_tag: text-generation
5
+ tags:
6
+ - oeis
7
+ - integer-sequences
8
+ - qwen3
9
+ - causal-lm
10
+ - mlx
11
+ datasets:
12
+ - N8Programs/oeis-ladder-10b
13
+ ---
14
+
15
+ # NextTerm-2-50M
16
+
17
+ (Model Card Co-Written w/ Opus 5.5)
18
+
19
+ [![Benchmark radar](radar_chart.png)](radar_chart.png)
20
+
21
+ ## Model Summary
22
+
23
+ NextTerm-2-50M is a 51M parameter causal transformer trained to continue integer
24
+ sequences. It is the middle model in the NextTerm-2 series (5M, 50M and 440M), three
25
+ models trained on the same 10B tokens with identical hyperparameters for controlled comparison. It uses the Qwen3 architecture with a byte-level
26
+ vocabulary: the 256 byte values plus BOS, EOS and PAD.
27
+
28
+ The training corpus, [N8Programs/oeis-ladder-10b](https://huggingface.co/datasets/N8Programs/oeis-ladder-10b),
29
+ contains every training-split OEIS sequence once (terms from its b-file, up to 4,096
30
+ bytes) plus 9.2B tokens of distinct, synthetically transformed copies of OEIS sequences.
31
+
32
+ Compared with NextTerm-47M, a model of similar size, NextTerm-2-50M is better on every
33
+ benchmark below except Ryskina & Knight (66.67% vs 70.18%). The largest gains are on
34
+ polynomial continuation: +27 points on cubics and +33 on quartics.
35
+
36
+ The model reads integer sequences formatted as comma-separated values, with a trailing
37
+ comma, for example:
38
+
39
+ ```text
40
+ 1,-2,3,-4,
41
+ ```
42
+
43
+ Training data contained only digits, commas and `-`, with no spaces and no leading
44
+ zeros. Other characters are accepted by the byte-level tokenizer but are out of
45
+ distribution, so format prompts exactly as above.
46
+
47
+ ## Training Details
48
+
49
+ | Field | Value |
50
+ | --- | --- |
51
+ | Parameters | 50,617,856 |
52
+ | Architecture | Qwen3-style causal LM |
53
+ | Layers | 16 |
54
+ | Hidden size | 512 |
55
+ | FFN size | 1536 |
56
+ | Attention heads | 4 (head dim 128) |
57
+ | KV heads | 2 |
58
+ | Vocabulary size | 259 (256 bytes + BOS/EOS/PAD) |
59
+ | Training tokens | 9,999,999,999 (one epoch) |
60
+ | Sequence length cap | 4,096 bytes per sequence |
61
+ | Batch mode | Whole-document packing, 98,304 token positions per step (97% filled), no cross-document attention |
62
+ | Steps | 105,029 |
63
+ | Optimizer | Muon/AdamW hybrid with μP width scaling |
64
+ | LR schedule | Linear warmup over 2% of steps to `2e-3` for Muon, `5e-4` for AdamW, cosine decay to 0.1x |
65
+ | AdamW | β = (0.9, 0.99), weight decay 0.01 |
66
+ | Training hardware | 2× NVIDIA DGX Spark (GB10), data parallel, bf16 |
67
+ | Training time | 14 hours 38 minutes |
68
+ | Export dtype | bfloat16 |
69
+
70
+ Muon was used for 2D weight matrices and AdamW for embeddings, norm gains and the output
71
+ head. All three NextTerm-2 models share these settings.
72
+
73
+ ## Evaluation Results
74
+
75
+ ### Main Benchmarks
76
+
77
+ | Model | OEIS-Eval-Neo | Ryskina & Knight | M1 Competition 111 MAPE |
78
+ | --- | ---: | ---: | ---: |
79
+ | NextTerm-2-440M | **36.25%** | 66.67% | **17.1105** |
80
+ | **NextTerm-2-50M** | 31.56% | 66.67% | 18.3615 |
81
+ | NextTerm-2-5M | 23.38% | 42.11% | 20.8527 |
82
+ | NextTerm-440M | 34.43% | 52.63% | 17.6239 |
83
+ | NextTerm-47M | 29.49% | **70.18%** | 18.7621 |
84
+ | Qwen3-0.6B | 18.44% | 33.33% | 22.7984 |
85
+ | Qwen3-1.7B | 20.77% | 49.12% | 22.2411 |
86
+ | Qwen3-4B | 23.74% | 63.16% | 19.1731 |
87
+ | Qwen3-8B | 24.62% | 57.89% | 18.4027 |
88
+ | Qwen3-14B | 26.00% | 59.65% | 17.9837 |
89
+
90
+ OEIS-Eval-Neo is a held-out OEIS next-term evaluation (19,034 sequences). M1 Competition
91
+ 111 reports macro MAPE, where lower is better; the Naive2 forecasting baseline scores
92
+ 17.7987. Ryskina & Knight (2021) is a 57-sequence next-term benchmark based on
93
+ psychometrics and puzzles. NextTerm-47M remains ahead there, consistent with its strength
94
+ on very short prompts.
95
+
96
+
97
+ ### Polynomial Continuation
98
+
99
+ The polynomial continuation evaluation samples integer sequences from
100
+ polynomials of degree 1 through 4 and asks for the next term. Accuracy is exact
101
+ match across 200 samples for each prompt length `k`.
102
+
103
+ | Model | Arithmetic | Quadratic | Cubic | Quartic |
104
+ | --- | ---: | ---: | ---: | ---: |
105
+ | NextTerm-2-440M | 96.15% | **94.39%** | **88.70%** | **83.74%** |
106
+ | **NextTerm-2-50M** | **96.31%** | 84.11% | 63.95% | 47.86% |
107
+ | NextTerm-2-5M | 78.21% | 23.87% | 1.89% | 0.50% |
108
+ | NextTerm-440M | 94.38% | 86.39% | 75.20% | 67.83% |
109
+ | NextTerm-47M | 94.15% | 81.07% | 37.43% | 15.17% |
110
+ | Qwen3-0.6B | 90.31% | 8.72% | 0.30% | 0.02% |
111
+ | Qwen3-1.7B | 93.10% | 41.57% | 5.36% | 0.71% |
112
+ | Qwen3-4B | 93.90% | 77.26% | 28.18% | 5.98% |
113
+ | Qwen3-8B | 96.10% | 80.59% | 32.93% | 7.95% |
114
+ | Qwen3-14B | 95.60% | 84.61% | 49.16% | 14.98% |
115
+
116
+ ## Usage
117
+
118
+ ### MLX
119
+
120
+ ```bash
121
+ mlx_lm.generate --model N8Programs/NextTerm-2-50M --prompt "1,2,3,"
122
+ ```
123
+
124
+ ### Hugging Face Transformers
125
+
126
+ ```python
127
+ import torch
128
+ from transformers import AutoModelForCausalLM, AutoTokenizer
129
+
130
+ model_name = "N8Programs/NextTerm-2-50M"
131
+ tokenizer = AutoTokenizer.from_pretrained(model_name)
132
+ model = AutoModelForCausalLM.from_pretrained(
133
+ model_name,
134
+ dtype=torch.bfloat16,
135
+ device_map="auto",
136
+ )
137
+
138
+ prompt = "1,2,3,4,5,"
139
+ inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
140
+
141
+ outputs = model.generate(
142
+ **inputs,
143
+ max_new_tokens=64,
144
+ do_sample=False,
145
+ eos_token_id=[tokenizer.convert_tokens_to_ids(","), tokenizer.eos_token_id],
146
+ pad_token_id=tokenizer.pad_token_id,
147
+ )
148
+
149
+ print(tokenizer.decode(outputs[0], skip_special_tokens=True))
150
+ ```
151
+
152
+ For strict next-term evaluation, stop generation on *comma or EOS* and parse the
153
+ text before the first comma as the predicted integer. The tokenizer adds BOS
154
+ automatically.
155
+
156
+ ## Reproducibility
157
+
158
+ This repository contains the evaluation scripts and data used for the results above:
159
+
160
+ - `eval_neo.py` for OEIS-Eval-Neo (and the polynomial sets).
161
+ - `gen_poly_evals.py` to regenerate the arithmetic/quadratic/cubic/quartic sets.
162
+ - `eval_m1.py` for M1 Competition 111 MAPE.
163
+ - `eval_ryskina.py` for Ryskina & Knight.
164
+ - `oeis_val_neo.jsonl`, `m1_competition_111.jsonl` and `ryskina_knight_57.jsonl`.
165
+ - `eval_results.txt` for the compact result table.
166
+
167
+ The model was trained with [spark-gpt](https://github.com/N8python/spark-gpt) on the
168
+ [N8Programs/oeis-ladder-10b](https://huggingface.co/datasets/N8Programs/oeis-ladder-10b)
169
+ dataset, whose card documents the data recipe in full.
170
+
171
+ ## Citation
172
+
173
+ ```bibtex
174
+ @misc{nextterm2_2026,
175
+ author = {Nathan Breslow and Opus 5.5},
176
+ title = {NextTerm-2: A Scaling Ladder of Pretrained Transformers for Integer Sequence Prediction},
177
+ year = {2026},
178
+ publisher = {Hugging Face},
179
+ howpublished = {\url{https://huggingface.co/N8Programs/NextTerm-2-50M}},
180
+ note = {51M parameter model trained on 10B tokens of augmented OEIS data}
181
+ }
182
+ ```
183
+
184
+ ## Attribution
185
+
186
+ This model was trained on data from the
187
+ **On-Line Encyclopedia of Integer Sequences (OEIS)**.
188
+
189
+ - Source: https://oeis.org/
190
+ - License: Creative Commons Attribution-ShareAlike 4.0 (CC BY-SA 4.0)
191
+ - OEIS End-User License Agreement: https://oeis.org/wiki/The_OEIS_End-User_License_Agreement
config.json ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "Qwen3ForCausalLM"
4
+ ],
5
+ "model_type": "qwen3",
6
+ "vocab_size": 259,
7
+ "hidden_size": 512,
8
+ "num_hidden_layers": 16,
9
+ "intermediate_size": 1536,
10
+ "num_attention_heads": 4,
11
+ "num_key_value_heads": 2,
12
+ "head_dim": 128,
13
+ "hidden_act": "silu",
14
+ "rms_norm_eps": 1e-06,
15
+ "max_position_embeddings": 4096,
16
+ "rope_theta": 1000000.0,
17
+ "rope_scaling": null,
18
+ "attention_bias": false,
19
+ "attention_dropout": 0.0,
20
+ "tie_word_embeddings": false,
21
+ "use_cache": true,
22
+ "bos_token_id": 256,
23
+ "eos_token_id": 257,
24
+ "pad_token_id": 258,
25
+ "torch_dtype": "bfloat16"
26
+ }
eval_m1.py ADDED
@@ -0,0 +1,251 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """M1 Competition 111 forecasting eval (macro MAPE) for byte-level spark-gpt OEIS checkpoints.
2
+
3
+ A PyTorch port of eval_m1_competition_mape_mlx.py from the NextTerm-440M repository (the protocol
4
+ behind the NextTerm model cards: Naive2 17.7987, NextTerm-440M 17.6239, NextTerm-47M 18.7621),
5
+ unchanged in substance:
6
+ * each series' context is scaled to integers by the largest number of decimal places visible
7
+ in the context, joined by commas, with a trailing comma
8
+ * greedy decoding with EOS and PAD suppressed, stopping once `horizon` commas are generated
9
+ (or after --max-new-tokens); series are decoded together in left-padded batches with
10
+ per-row stopping (same greedy result as one at a time, up to batching numerics)
11
+ * the first `horizon` generated integers, divided back by the scale, are the forecast;
12
+ missing terms are scored as 0 (missing_policy "zero")
13
+ * series MAPE = mean APE over the horizon (zero actuals skipped); macro MAPE = mean over series
14
+ (the number on the model cards); median MAPE = median over series is also reported, since
15
+ one runaway forecast (e.g. a parabola on a flat series, APE ~700) can swing the macro mean
16
+ by several points
17
+ * prompts of --max-context-tokens or more tokens (BOS included) are skipped
18
+
19
+ Usage: python eval_m1.py <hf_dir> <m1_competition_111.jsonl> <out_prefix>
20
+ Writes <out_prefix>.series.jsonl and <out_prefix>.summary.json.
21
+ """
22
+ import argparse
23
+ import json
24
+ import math
25
+ from decimal import Decimal, InvalidOperation, localcontext
26
+ from statistics import mean, median
27
+
28
+ import torch
29
+ from transformers import AutoModelForCausalLM, AutoTokenizer
30
+
31
+
32
+ def parse_decimal(raw):
33
+ try:
34
+ value = Decimal(str(raw).strip())
35
+ except InvalidOperation as exc:
36
+ raise ValueError(f"Could not parse decimal value {raw!r}") from exc
37
+ if not value.is_finite():
38
+ raise ValueError(f"Non-finite decimal value {raw!r}")
39
+ return value
40
+
41
+
42
+ def context_scale(raw_context):
43
+ places = 0
44
+ for raw in raw_context:
45
+ exponent = parse_decimal(raw).as_tuple().exponent
46
+ if exponent < 0:
47
+ places = max(places, -exponent)
48
+ return 10 ** places
49
+
50
+
51
+ def scale_decimal_to_int(value, scale):
52
+ scaled = value * Decimal(scale)
53
+ with localcontext() as ctx:
54
+ ctx.prec = max(50, len(scaled.as_tuple().digits) + 10)
55
+ rounded = scaled.to_integral_value()
56
+ if rounded != scaled:
57
+ raise ValueError(f"Context scale {scale} does not make {value} integral")
58
+ return int(rounded)
59
+
60
+
61
+ def parse_generated_terms(text, limit):
62
+ terms, current, malformed = [], [], False
63
+
64
+ def flush():
65
+ nonlocal malformed
66
+ if not current:
67
+ return
68
+ token = "".join(current)
69
+ current.clear()
70
+ if token == "-":
71
+ malformed = True
72
+ return
73
+ try:
74
+ terms.append(int(token))
75
+ except ValueError:
76
+ malformed = True
77
+
78
+ for ch in text:
79
+ if len(terms) >= limit:
80
+ break
81
+ if ch.isdigit() or (ch == "-" and not current):
82
+ current.append(ch)
83
+ elif ch == ",":
84
+ flush()
85
+ elif ch.isspace():
86
+ continue
87
+ else:
88
+ malformed = True
89
+ flush()
90
+ break
91
+ if len(terms) < limit:
92
+ flush()
93
+ return terms[:limit], malformed
94
+
95
+
96
+ def ape(actual, prediction):
97
+ if actual == 0:
98
+ return None
99
+ return float(abs(actual - prediction) / abs(actual) * Decimal(100))
100
+
101
+
102
+ def mape_for_predictions(actuals, predictions, missing_policy, fallback):
103
+ apes, missing = [], 0
104
+ for actual, pred in zip(actuals, predictions):
105
+ if pred is None:
106
+ missing += 1
107
+ if missing_policy == "skip":
108
+ apes.append(None)
109
+ continue
110
+ pred = Decimal(0) if missing_policy == "zero" else fallback
111
+ apes.append(ape(actual, pred))
112
+ valid = [x for x in apes if x is not None and math.isfinite(x)]
113
+ return (mean(valid) if valid else None), apes, missing
114
+
115
+
116
+ def main():
117
+ p = argparse.ArgumentParser()
118
+ p.add_argument("hf_dir")
119
+ p.add_argument("data")
120
+ p.add_argument("out_prefix")
121
+ p.add_argument("--max-new-tokens", type=int, default=1024)
122
+ p.add_argument("--max-context-tokens", type=int, default=2048)
123
+ p.add_argument("--missing-policy", choices=["zero", "last_context", "skip"], default="zero")
124
+ p.add_argument("--batch-size", type=int, default=128,
125
+ help="series decoded together (greedy, left-padded, per-row stopping)")
126
+ args = p.parse_args()
127
+
128
+ tok = AutoTokenizer.from_pretrained(args.hf_dir)
129
+ model = AutoModelForCausalLM.from_pretrained(args.hf_dir, dtype=torch.float32).cuda().eval()
130
+ bos, eos, pad = tok.bos_token_id, tok.eos_token_id, tok.pad_token_id
131
+ comma = ord(",")
132
+ suppress = torch.tensor([t for t in (eos, pad) if t is not None], device="cuda")
133
+
134
+ rows = [json.loads(line) for line in open(args.data) if line.strip()]
135
+ series = []
136
+ skipped_long = 0
137
+ for row in rows:
138
+ raw_context = [str(x) for x in row["context"]]
139
+ context = [parse_decimal(x) for x in raw_context]
140
+ scale = context_scale(raw_context)
141
+ prompt_text = ",".join(str(scale_decimal_to_int(v, scale)) for v in context) + ","
142
+ prompt = [bos] + list(prompt_text.encode("utf-8"))
143
+ assert tok(prompt_text).input_ids == prompt, "tokenizer disagrees with BOS + bytes"
144
+ if args.max_context_tokens > 0 and len(prompt) >= args.max_context_tokens:
145
+ skipped_long += 1
146
+ continue
147
+ series.append((row, raw_context, context, scale, prompt, int(row["horizon"])))
148
+
149
+ @torch.no_grad()
150
+ def greedy_batch(batch):
151
+ """Greedy decode a left-padded batch with a KV cache, EOS/PAD suppressed; each row
152
+ stops once it has generated `horizon` commas (or after --max-new-tokens)."""
153
+ width = max(len(s[4]) for s in batch)
154
+ ids = torch.full((len(batch), width), pad, dtype=torch.long, device="cuda")
155
+ mask = torch.zeros((len(batch), width), dtype=torch.long, device="cuda")
156
+ for r, s in enumerate(batch):
157
+ ids[r, width - len(s[4]):] = torch.tensor(s[4], device="cuda")
158
+ mask[r, width - len(s[4]):] = 1
159
+ pos = (mask.cumsum(-1) - 1).clamp(min=0)
160
+ out = model(ids, attention_mask=mask, position_ids=pos, use_cache=True)
161
+ past, logits = out.past_key_values, out.logits[:, -1]
162
+ horizon = torch.tensor([s[5] for s in batch], device="cuda")
163
+ commas = torch.zeros(len(batch), dtype=torch.long, device="cuda")
164
+ done = torch.zeros(len(batch), dtype=torch.bool, device="cuda")
165
+ last_pos = pos[:, -1]
166
+ generated = []
167
+ for _ in range(args.max_new_tokens):
168
+ logits = logits.float()
169
+ logits[:, suppress] = float("-inf")
170
+ nxt = logits.argmax(-1)
171
+ generated.append(torch.where(done, torch.full_like(nxt, pad), nxt))
172
+ commas += (nxt == comma) & ~done
173
+ done |= commas >= horizon
174
+ if bool(done.all()):
175
+ break
176
+ mask = torch.cat([mask, torch.ones_like(mask[:, :1])], dim=1)
177
+ last_pos = last_pos + 1
178
+ out = model(nxt[:, None], attention_mask=mask, position_ids=last_pos[:, None],
179
+ past_key_values=past, use_cache=True)
180
+ past, logits = out.past_key_values, out.logits[:, -1]
181
+ gen = torch.stack(generated, dim=1).tolist()
182
+ return [bytes(t for t in g if t < 256).decode("utf-8", "replace") for g in gen]
183
+
184
+ texts = []
185
+ for b in range(0, len(series), args.batch_size):
186
+ texts.extend(greedy_batch(series[b:b + args.batch_size]))
187
+
188
+ records = []
189
+ for (row, raw_context, context, scale, prompt, horizon), text in zip(series, texts):
190
+ target = [parse_decimal(str(x)) for x in row["target"]]
191
+ naive2 = [parse_decimal(str(x)) for x in row["naive2_forecast"]]
192
+ terms, malformed = parse_generated_terms(text, horizon)
193
+ predictions = [Decimal(t) / Decimal(scale) for t in terms] + [None] * (horizon - len(terms))
194
+ fallback = context[-1] if context else Decimal(0)
195
+ mape, apes, missing = mape_for_predictions(target, predictions, args.missing_policy, fallback)
196
+ naive2_mape, naive2_apes, _ = mape_for_predictions(target, naive2, "skip", fallback)
197
+ records.append({
198
+ "row_index": row["row_index"], "series_name": row["series_name"], "period": row["period"],
199
+ "horizon": horizon, "scale": scale, "prompt_tokens": len(prompt),
200
+ "target": [str(x) for x in target],
201
+ "prediction": [str(x) if x is not None else None for x in predictions],
202
+ "parsed_terms": len(terms), "missing_terms": missing, "malformed": malformed,
203
+ "mape": mape, "apes": apes, "naive2_mape": naive2_mape, "naive2_apes": naive2_apes,
204
+ "generated_text": text,
205
+ })
206
+
207
+ def finite(rs, key):
208
+ return [float(r[key]) for r in rs if r[key] is not None and math.isfinite(float(r[key]))]
209
+
210
+ def macro(rs, key):
211
+ vals = finite(rs, key)
212
+ return mean(vals) if vals else None
213
+
214
+ def med(rs, key):
215
+ vals = finite(rs, key)
216
+ return median(vals) if vals else None
217
+
218
+ by_period = {}
219
+ for period in sorted({r["period"] for r in records}):
220
+ rs = [r for r in records if r["period"] == period]
221
+ by_period[period] = {"series": len(rs),
222
+ "model_median_series_mape": med(rs, "mape"),
223
+ "model_macro_mape": macro(rs, "mape"),
224
+ "naive2_median_series_mape": med(rs, "naive2_mape"),
225
+ "naive2_macro_mape": macro(rs, "naive2_mape")}
226
+ summary = {
227
+ "checkpoint": args.hf_dir,
228
+ "series_evaluated": len(records),
229
+ "skipped_long": skipped_long,
230
+ "model_median_series_mape": med(records, "mape"),
231
+ "model_macro_mape": macro(records, "mape"),
232
+ "naive2_median_series_mape": med(records, "naive2_mape"),
233
+ "naive2_macro_mape": macro(records, "naive2_mape"),
234
+ "parsed_full_series": sum(1 for r in records if r["parsed_terms"] >= r["horizon"]),
235
+ "total_missing_terms": sum(r["missing_terms"] for r in records),
236
+ "malformed_series": sum(1 for r in records if r["malformed"]),
237
+ "by_period": by_period,
238
+ }
239
+ with open(args.out_prefix + ".series.jsonl", "w") as f:
240
+ for r in records:
241
+ f.write(json.dumps(r) + "\n")
242
+ with open(args.out_prefix + ".summary.json", "w") as f:
243
+ json.dump(summary, f, indent=2)
244
+ print(json.dumps({k: summary[k] for k in ["series_evaluated", "skipped_long",
245
+ "model_median_series_mape", "naive2_median_series_mape",
246
+ "model_macro_mape", "naive2_macro_mape", "parsed_full_series",
247
+ "total_missing_terms", "malformed_series"]}))
248
+
249
+
250
+ if __name__ == "__main__":
251
+ main()
eval_neo.py ADDED
@@ -0,0 +1,165 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """OEIS-Eval-Neo: last-term exact-match accuracy on the decontaminated held-out OEIS set.
2
+
3
+ A batched PyTorch/transformers port of oeis_eval_mlx_neo.py from the NextTerm-440M repository
4
+ (the protocol behind that card's 34.43%), unchanged in substance:
5
+ * rows with fewer than 2 terms are skipped; prompt = every term but the last, comma-joined, with
6
+ a trailing comma; answer = the last term (compared as an exact integer)
7
+ * prompts of --max-context-tokens or more tokens (BOS included) are skipped
8
+ * greedy decoding, stopping at the comma token or EOS, up to --max-new-tokens (196)
9
+ * prediction = the generated text before the first comma, parsed as an integer
10
+ (unparseable, e.g. an immediate EOS, counts as wrong)
11
+ Works with any tokenizer that has a single comma token (the byte-level spark-gpt checkpoints, or
12
+ the NextTerm digit tokenizer).
13
+
14
+ Two modes, same accuracy: --mode teacher (default) checks greedy correctness in one forward pass
15
+ over prompt + answer + "," (correct iff the argmax reproduces every answer token and is then a
16
+ comma or EOS, which is exactly when greedy decoding would produce the answer); --mode generate
17
+ decodes greedily.
18
+
19
+ Usage: python eval_neo.py <hf_dir> <oeis_val_neo.jsonl> <out_prefix> [--batch-size 128]
20
+ Writes <out_prefix>.rows.jsonl and <out_prefix>.summary.json.
21
+ """
22
+ import argparse
23
+ import json
24
+ import time
25
+
26
+ import torch
27
+ from transformers import AutoModelForCausalLM, AutoTokenizer
28
+
29
+
30
+ def parse_generated(text):
31
+ text = text.split(",")[0]
32
+ try:
33
+ return int(text)
34
+ except ValueError:
35
+ return None
36
+
37
+
38
+ def main():
39
+ p = argparse.ArgumentParser()
40
+ p.add_argument("hf_dir")
41
+ p.add_argument("data")
42
+ p.add_argument("out_prefix")
43
+ p.add_argument("--batch-size", type=int, default=128)
44
+ p.add_argument("--max-new-tokens", type=int, default=196)
45
+ p.add_argument("--first-pass-tokens", type=int, default=24,
46
+ help="decode budget for the first pass; unfinished rows are redone at --max-new-tokens")
47
+ p.add_argument("--max-context-tokens", type=int, default=4096)
48
+ p.add_argument("--max-examples", type=int, default=0)
49
+ p.add_argument("--dtype", choices=["float32", "bfloat16"], default="bfloat16")
50
+ p.add_argument("--mode", choices=["teacher", "generate"], default="teacher",
51
+ help="teacher: one forward pass per row (exact for greedy); generate: decode")
52
+ args = p.parse_args()
53
+
54
+ started = time.perf_counter()
55
+ tok = AutoTokenizer.from_pretrained(args.hf_dir)
56
+ model = AutoModelForCausalLM.from_pretrained(
57
+ args.hf_dir, dtype=getattr(torch, args.dtype)).cuda().eval()
58
+ comma = tok.encode(",", add_special_tokens=False)
59
+ if not comma: # the NextTerm tokenizer strips a leading comma
60
+ comma = tok.encode("1,", add_special_tokens=False)[-1:]
61
+ assert len(comma) == 1, f"comma is not a single token: {comma}"
62
+ comma = comma[0]
63
+ stops = [comma] + ([tok.eos_token_id] if tok.eos_token_id is not None else [])
64
+ pad = tok.pad_token_id if tok.pad_token_id is not None else tok.eos_token_id
65
+
66
+ prompts, answers, rows = [], [], []
67
+ for i, line in enumerate(open(args.data)):
68
+ seq = json.loads(line, parse_int=str).get("seq", [])
69
+ if len(seq) < 2:
70
+ continue
71
+ prompts.append(tok(",".join(str(x) for x in seq[:-1]) + ",").input_ids)
72
+ answers.append(int(seq[-1]))
73
+ rows.append(i)
74
+ if args.max_examples > 0:
75
+ prompts, answers, rows = prompts[:args.max_examples], answers[:args.max_examples], rows[:args.max_examples]
76
+ keep = [k for k, pr in enumerate(prompts)
77
+ if args.max_context_tokens <= 0 or len(pr) < args.max_context_tokens]
78
+ skipped_long = len(prompts) - len(keep)
79
+ keep.sort(key=lambda k: len(prompts[k]))
80
+
81
+ def greedy(idx, max_new):
82
+ """Greedy-decode prompts idx (left-padded batches); return {k: tokens before the stop}
83
+ and the set of k that hit a stop token."""
84
+ gens, stopped = {}, set()
85
+ for b in range(0, len(idx), args.batch_size):
86
+ batch = idx[b:b + args.batch_size]
87
+ width = max(len(prompts[k]) for k in batch)
88
+ ids = torch.full((len(batch), width), pad, dtype=torch.long)
89
+ mask = torch.zeros((len(batch), width), dtype=torch.long)
90
+ for r, k in enumerate(batch):
91
+ ids[r, width - len(prompts[k]):] = torch.tensor(prompts[k])
92
+ mask[r, width - len(prompts[k]):] = 1
93
+ out = model.generate(ids.cuda(), attention_mask=mask.cuda(), do_sample=False,
94
+ max_new_tokens=max_new, eos_token_id=stops, pad_token_id=pad)
95
+ for r, k in enumerate(batch):
96
+ gen = out[r, width:].tolist()
97
+ cut = next((j for j, t in enumerate(gen) if t in stops), None)
98
+ if cut is not None:
99
+ stopped.add(k)
100
+ gens[k] = gen[:cut] if cut is not None else gen[:max_new]
101
+ return gens, stopped
102
+
103
+ results = []
104
+ if args.mode == "generate":
105
+ with torch.no_grad():
106
+ # Most answers are short. Decode everything briefly, then redo only rows that have
107
+ # not reached a stop token with the full budget (equivalent under greedy decoding).
108
+ gens, stopped = greedy(keep, min(args.first_pass_tokens, args.max_new_tokens))
109
+ long_rows = [k for k in keep if k not in stopped]
110
+ if long_rows and args.first_pass_tokens < args.max_new_tokens:
111
+ more, _ = greedy(long_rows, args.max_new_tokens)
112
+ gens.update(more)
113
+ for k in keep:
114
+ text = tok.decode(gens[k], skip_special_tokens=True)
115
+ pred = parse_generated(text)
116
+ results.append({"row_index": rows[k], "answer": str(answers[k]),
117
+ "prediction": None if pred is None else str(pred),
118
+ "correct": pred == answers[k], "parsed": pred is not None,
119
+ "generated_text": text})
120
+ else:
121
+ # Teacher-forced check, one forward pass per row: greedy decoding emits exactly the
122
+ # answer iff the argmax at every answer position is the answer's next token and the
123
+ # argmax after the last digit is a stop token. (Only differs from `generate` mode if a
124
+ # model emits leading zeros, which int() parsing would forgive.)
125
+ ans_ids = {k: tok.encode(str(answers[k]), add_special_tokens=False) for k in keep}
126
+ stop_t = torch.tensor(stops, device="cuda")
127
+ with torch.no_grad():
128
+ for b in range(0, len(keep), args.batch_size):
129
+ batch = keep[b:b + args.batch_size]
130
+ seqs = [prompts[k] + ans_ids[k] for k in batch]
131
+ width = max(map(len, seqs))
132
+ ids = torch.full((len(batch), width), pad, dtype=torch.long)
133
+ mask = torch.zeros((len(batch), width), dtype=torch.long)
134
+ for r, s in enumerate(seqs): # right padding is fine for teacher forcing
135
+ ids[r, :len(s)] = torch.tensor(s)
136
+ mask[r, :len(s)] = 1
137
+ top = model(ids.cuda(), attention_mask=mask.cuda()).logits.argmax(-1)
138
+ for r, k in enumerate(batch):
139
+ n_p, ans = len(prompts[k]), ans_ids[k]
140
+ pred = top[r, n_p - 1:n_p + len(ans)]
141
+ ok = (len(ans) < args.max_new_tokens
142
+ and bool((pred[:-1] == torch.tensor(ans, device="cuda")).all())
143
+ and bool(torch.isin(pred[-1], stop_t)))
144
+ results.append({"row_index": rows[k], "answer": str(answers[k]),
145
+ "correct": ok, "parsed": True})
146
+
147
+ correct = sum(r["correct"] for r in results)
148
+ summary = {
149
+ "checkpoint": args.hf_dir, "data": args.data, "documents": len(prompts),
150
+ "evaluated": len(results), "skipped_long": skipped_long,
151
+ "parsed": sum(r["parsed"] for r in results), "correct": correct,
152
+ "accuracy": correct / len(results) if results else 0.0,
153
+ "max_new_tokens": args.max_new_tokens, "dtype": args.dtype, "mode": args.mode,
154
+ "seconds": round(time.perf_counter() - started, 1),
155
+ }
156
+ with open(args.out_prefix + ".rows.jsonl", "w") as f:
157
+ for r in sorted(results, key=lambda r: r["row_index"]):
158
+ f.write(json.dumps(r) + "\n")
159
+ with open(args.out_prefix + ".summary.json", "w") as f:
160
+ json.dump(summary, f, indent=2)
161
+ print(json.dumps(summary))
162
+
163
+
164
+ if __name__ == "__main__":
165
+ main()
eval_results.txt ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ NextTerm-2 evaluation results (released bf16 weights; greedy decoding).
2
+ NextTerm-440M / NextTerm-47M / Naive2 rows are from the NextTerm-440M model card.
3
+
4
+ OEIS-Eval-Neo:
5
+ NextTerm-2-440M - 36.25%
6
+ NextTerm-2-50M - 31.56%
7
+ NextTerm-2-5M - 23.38%
8
+ NextTerm-440M - 34.43%
9
+ NextTerm-47M - 29.49%
10
+
11
+ Ryskina & Knight (2021):
12
+ NextTerm-2-440M - 66.67%
13
+ NextTerm-2-50M - 66.67%
14
+ NextTerm-2-5M - 42.11%
15
+ NextTerm-440M - 52.63%
16
+ NextTerm-47M - 70.18%
17
+
18
+ M1 Competition 111 MAPE (macro; canonical greedy; lower is better):
19
+ Naive2 - 17.7987
20
+ NextTerm-2-440M - 17.1105
21
+ NextTerm-2-50M - 18.3615
22
+ NextTerm-2-5M - 20.8527
23
+ NextTerm-440M - 17.6239
24
+ NextTerm-47M - 18.7621
25
+
26
+ M1 Competition 111 by frequency (macro MAPE):
27
+ Naive2 - monthly 17.3871 / quarterly 19.5958 / yearly 17.1314
28
+ NextTerm-2-440M - monthly 18.5442 / quarterly 16.6647 / yearly 12.7485
29
+ NextTerm-2-50M - monthly 20.7720 / quarterly 16.6578 / yearly 12.1251
30
+ NextTerm-2-5M - monthly 22.3369 / quarterly 23.4687 / yearly 12.7977
31
+ NextTerm-440M - monthly 18.3407 / quarterly 19.0475 / yearly 13.5498
32
+ NextTerm-47M - monthly 21.2719 / quarterly 16.0270 / yearly 13.3741
33
+
34
+ Polynomial continuation evals (accuracy; 200 samples per k):
35
+ Arithmetic (k=2-25): NextTerm-2-440M - 96.15%; NextTerm-2-50M - 96.31%; NextTerm-2-5M - 78.21%; NextTerm-440M - 94.38%; NextTerm-47M - 94.15%
36
+ Quadratic (k=3-25): NextTerm-2-440M - 94.39%; NextTerm-2-50M - 84.11%; NextTerm-2-5M - 23.87%; NextTerm-440M - 86.39%; NextTerm-47M - 81.07%
37
+ Cubic (k=4-25): NextTerm-2-440M - 88.70%; NextTerm-2-50M - 63.95%; NextTerm-2-5M - 1.89%; NextTerm-440M - 75.20%; NextTerm-47M - 37.43%
38
+ Quartic (k=5-25): NextTerm-2-440M - 83.74%; NextTerm-2-50M - 47.86%; NextTerm-2-5M - 0.50%; NextTerm-440M - 67.83%; NextTerm-47M - 15.17%
eval_ryskina.py ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Ryskina & Knight (2021) next-term eval for byte-level spark-gpt OEIS checkpoints.
2
+
3
+ Each item is a short sequence. The prompt is every term but the last, written
4
+ "t1,t2,...,tk," with a trailing comma. The answer is the last term.
5
+
6
+ Two scores per item:
7
+ exact greedy decode until the next comma or EOS; correct iff the text equals
8
+ str(answer). This matches the NextTerm model-card protocol.
9
+ logprob log P(answer is the next term) in nats: the sum of the log-probs of the
10
+ answer's bytes, plus log(P(",") + P(EOS)) at the position after it. A
11
+ continuous score, much less noisy than 57 binary outcomes.
12
+
13
+ Encoding is BOS + UTF-8 bytes, exactly as spark-gpt trains. The script checks
14
+ that the exported HF tokenizer agrees.
15
+
16
+ Usage: python eval_ryskina.py <hf_dir> <ryskina.jsonl> <out_prefix>
17
+ Writes <out_prefix>.items.jsonl and <out_prefix>.summary.json.
18
+ """
19
+ import json
20
+ import math
21
+ import statistics
22
+ import sys
23
+
24
+ import torch
25
+ from transformers import AutoModelForCausalLM, AutoTokenizer
26
+
27
+ MAX_NEW_TOKENS = 40 # longest answer is far shorter; a runaway decode just scores wrong
28
+
29
+
30
+ def main():
31
+ hf_dir, data_path, out_prefix = sys.argv[1:4]
32
+ tok = AutoTokenizer.from_pretrained(hf_dir)
33
+ model = AutoModelForCausalLM.from_pretrained(hf_dir, dtype=torch.float32).cuda().eval()
34
+ bos, eos = tok.bos_token_id, tok.eos_token_id
35
+ comma = ord(",")
36
+
37
+ def encode(text):
38
+ ids = [bos] + list(text.encode("utf-8"))
39
+ assert tok(text).input_ids == ids, f"tokenizer disagrees on {text!r}"
40
+ return ids
41
+
42
+ items = [json.loads(line)["seq"] for line in open(data_path)]
43
+ results = []
44
+ with torch.no_grad():
45
+ for idx, seq in enumerate(items):
46
+ prompt_text = ",".join(str(x) for x in seq[:-1]) + ","
47
+ answer = str(seq[-1])
48
+ prompt = encode(prompt_text)
49
+
50
+ # exact match: greedy until comma / EOS
51
+ ids = torch.tensor([prompt], device="cuda")
52
+ generated = []
53
+ for _ in range(MAX_NEW_TOKENS):
54
+ nxt = int(model(ids).logits[0, -1].argmax())
55
+ if nxt in (comma, eos):
56
+ break
57
+ generated.append(nxt)
58
+ ids = torch.cat([ids, torch.tensor([[nxt]], device="cuda")], dim=1)
59
+ prediction = bytes(b for b in generated if b < 256).decode("utf-8", "replace")
60
+
61
+ # log P(answer is the next term)
62
+ ans_ids = list(answer.encode("utf-8"))
63
+ full = torch.tensor([prompt + ans_ids], device="cuda")
64
+ logp = torch.log_softmax(model(full).logits[0].float(), dim=-1)
65
+ start = len(prompt) - 1 # logits at position i predict token i + 1
66
+ lp_answer = sum(float(logp[start + j, t]) for j, t in enumerate(ans_ids))
67
+ end = logp[start + len(ans_ids)]
68
+ lp_stop = float(torch.logaddexp(end[comma], end[eos]))
69
+ lp = lp_answer + lp_stop
70
+
71
+ results.append({
72
+ "idx": idx,
73
+ "prompt": prompt_text,
74
+ "answer": answer,
75
+ "prediction": prediction,
76
+ "correct": prediction == answer,
77
+ "logprob": lp,
78
+ "logprob_answer_bytes": lp_answer,
79
+ "logprob_stop": lp_stop,
80
+ })
81
+
82
+ lps = [r["logprob"] for r in results]
83
+ n_correct = sum(r["correct"] for r in results)
84
+ summary = {
85
+ "checkpoint": hf_dir,
86
+ "items": len(results),
87
+ "exact_correct": n_correct,
88
+ "exact_acc": n_correct / len(results),
89
+ "mean_logprob": statistics.fmean(lps),
90
+ "median_logprob": statistics.median(lps),
91
+ "mean_answer_prob": statistics.fmean(math.exp(x) for x in lps),
92
+ }
93
+ with open(out_prefix + ".items.jsonl", "w") as f:
94
+ for r in results:
95
+ f.write(json.dumps(r) + "\n")
96
+ with open(out_prefix + ".summary.json", "w") as f:
97
+ json.dump(summary, f, indent=2)
98
+ print(json.dumps(summary, indent=2))
99
+
100
+
101
+ if __name__ == "__main__":
102
+ main()
gen_poly_evals.py ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Write the NextTerm-440M card's polynomial-continuation eval sets as jsonl.
2
+
3
+ Reproduces arithmetic_eval.py's sampling exactly (same tasks, coefficient ranges, per-task
4
+ RNG random.Random(seed + degree), same draw order): for each prior-term count k from the
5
+ task's minimum up to --max-terms, --samples-per-k sequences f(0), ..., f(k) of a random
6
+ non-negative-integer polynomial; the prompt is the first k terms and the answer is f(k).
7
+ Each row is {"id", "seq", "k"} with seq = prompt + [answer], so scripts/eval_neo.py
8
+ (last-term exact match; teacher-forced greedy) scores it directly.
9
+
10
+ Degrees 5 and 6 (quintic, sextic; --extended) are an optional extension, not part of the
11
+ published polynomial evals: the x^5 and
12
+ x^6 coefficients are drawn from [0, 9] like x^4's, before the card's draws (highest degree
13
+ first, as the card orders them), so degrees 1-4 stay byte-identical.
14
+
15
+ Usage: python gen_poly_evals.py <out_dir> [--extended] [--seed 0 --max-terms 25 --samples-per-k 200]
16
+ """
17
+ import argparse
18
+ import json
19
+ import random
20
+ from pathlib import Path
21
+
22
+ COEFF_MAX = {"g": 9, "f": 9, "a": 9, "b": 99, "c": 999, "d": 9999, "e": 99999} # g: x^6, f: x^5
23
+ CARD_TASKS = (("arithmetic", 1, 2), ("quadratic", 2, 3), ("cubic", 3, 4), ("quartic", 4, 5))
24
+ EXTENDED_TASKS = (("quintic", 5, 6), ("sextic", 6, 7))
25
+
26
+ p = argparse.ArgumentParser()
27
+ p.add_argument("out_dir")
28
+ p.add_argument("--seed", type=int, default=0)
29
+ p.add_argument("--max-terms", type=int, default=25)
30
+ p.add_argument("--samples-per-k", type=int, default=200)
31
+ p.add_argument("--extended", action="store_true", help="write quintic and sextic instead")
32
+ args = p.parse_args()
33
+ out = Path(args.out_dir)
34
+ out.mkdir(parents=True, exist_ok=True)
35
+
36
+ for name, degree, min_terms in (EXTENDED_TASKS if args.extended else CARD_TASKS):
37
+ rng = random.Random(args.seed + degree)
38
+ with open(out / f"poly_{name}.jsonl", "w") as f:
39
+ for k in range(min_terms, args.max_terms + 1):
40
+ for i in range(args.samples_per_k):
41
+ g = rng.randint(0, COEFF_MAX["g"]) if degree >= 6 else 0
42
+ f5 = rng.randint(0, COEFF_MAX["f"]) if degree >= 5 else 0
43
+ # identical draw order to arithmetic_eval.sample_coefficients
44
+ a = rng.randint(0, COEFF_MAX["a"]) if degree >= 4 else 0
45
+ b = rng.randint(0, COEFF_MAX["b"]) if degree >= 3 else 0
46
+ c = rng.randint(0, COEFF_MAX["c"]) if degree >= 2 else 0
47
+ d = rng.randint(0, COEFF_MAX["d"]) if degree >= 1 else 0
48
+ e = rng.randint(0, COEFF_MAX["e"])
49
+ seq = [g * x**6 + f5 * x**5 + a * x**4 + b * x**3 + c * x**2 + d * x + e
50
+ for x in range(k + 1)]
51
+ f.write(json.dumps({"id": f"{name}_k{k}_{i}", "seq": seq, "k": k}) + "\n")
52
+ print(name, (args.max_terms - min_terms + 1) * args.samples_per_k, "rows")
generation_config.json ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ {
2
+ "bos_token_id": 256,
3
+ "eos_token_id": 257,
4
+ "pad_token_id": 258,
5
+ "transformers_version": "5.11.0"
6
+ }
m1_competition_111.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:d8eacfbf6c52b3e02401e90b5280b03f70be1c1d95d5e77739a8f74be5bc2a83
3
+ size 101255320
oeis_val_neo.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
radar_chart.png ADDED

Git LFS Details

  • SHA256: 3ae7dd4e17dae6ed408f4e4a1a2728397d71c21d160bd27bc256e6f6778e8a4e
  • Pointer size: 131 Bytes
  • Size of remote file: 388 kB
ryskina_knight_57.jsonl ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {"seq": [1, 2, 3, 4, 5], "source": "https://www.nibcode.com/en/psychometric-training/test-of-numerical-sequence"}
2
+ {"seq": [0, 2, 4, 6, 8], "source": "https://www.nibcode.com/en/psychometric-training/test-of-numerical-sequence"}
3
+ {"seq": [12, 19, 26, 33, 40], "source": "https://www.nibcode.com/en/psychometric-training/test-of-numerical-sequence"}
4
+ {"seq": [0, 1, 1, 2, 3, 5, 8], "source": "https://www.nibcode.com/en/psychometric-training/test-of-numerical-sequence"}
5
+ {"seq": [13, 15, 20, 22, 27, 29], "source": "https://www.nibcode.com/en/psychometric-training/test-of-numerical-sequence"}
6
+ {"seq": [32, 35, 39, 44, 50], "source": "https://www.nibcode.com/en/psychometric-training/test-of-numerical-sequence"}
7
+ {"seq": [1, 1, 8, 5, 15, 9, 22], "source": "https://www.nibcode.com/en/psychometric-training/test-of-numerical-sequence"}
8
+ {"seq": [89, 76, 65, 52, 41], "source": "https://www.nibcode.com/en/psychometric-training/test-of-numerical-sequence"}
9
+ {"seq": [17, -24, 41, -65, 106, -171], "source": "https://www.nibcode.com/en/psychometric-training/test-of-numerical-sequence"}
10
+ {"seq": [95, 89, 77, 59, 35], "source": "https://www.nibcode.com/en/psychometric-training/test-of-numerical-sequence"}
11
+ {"seq": [1, 3, 6, 10, 15, 21], "source": "https://www.nibcode.com/en/psychometric-training/test-of-numerical-sequence"}
12
+ {"seq": [1, 4, 10, 20, 35, 56], "source": "https://www.nibcode.com/en/psychometric-training/test-of-numerical-sequence"}
13
+ {"seq": [11, 23, 38, 11, 23, 38], "source": "https://www.nibcode.com/en/psychometric-training/test-of-numerical-sequence"}
14
+ {"seq": [6, 28, 12, 14, 24, 7, 48], "source": "https://www.nibcode.com/en/psychometric-training/test-of-numerical-sequence"}
15
+ {"seq": [7, 19, 43, 91, 187], "source": "https://www.nibcode.com/en/psychometric-training/test-of-numerical-sequence"}
16
+ {"seq": [17, 32, 61, 118, 231], "source": "https://www.nibcode.com/en/psychometric-training/test-of-numerical-sequence"}
17
+ {"seq": [23, 25, 28, 32, 34, 37, 41], "source": "https://www.nibcode.com/en/psychometric-training/test-of-numerical-sequence"}
18
+ {"seq": [1, 4, 9, 16, 25, 36], "source": "https://www.nibcode.com/en/psychometric-training/test-of-numerical-sequence"}
19
+ {"seq": [32, 16, 20, 10, 14, 7, 11], "source": "https://www.nibcode.com/en/psychometric-training/test-of-numerical-sequence"}
20
+ {"seq": [1, 1, 2, 6, 24, 120], "source": "https://www.nibcode.com/en/psychometric-training/test-of-numerical-sequence"}
21
+ {"seq": [65536, 256, 16, 4], "source": "https://www.nibcode.com/en/psychometric-training/test-of-numerical-sequence"}
22
+ {"seq": [32, 112, 392, 1372, 4802, 16807], "source": "https://www.nibcode.com/en/psychometric-training/test-of-numerical-sequence"}
23
+ {"seq": [12, 19, 38, 45, 90, 97], "source": "https://www.nibcode.com/en/psychometric-training/test-of-numerical-sequence"}
24
+ {"seq": [3, 8, 7, 15, 15, 29, 31, 57], "source": "https://www.nibcode.com/en/psychometric-training/test-of-numerical-sequence"}
25
+ {"seq": [1, 3, 19, 49, 93, 151], "source": "https://www.nibcode.com/en/psychometric-training/test-of-numerical-sequence"}
26
+ {"seq": [2, 6, 12, 20, 30, 42, 56], "source": "https://www.nibcode.com/en/psychometric-training/test-of-numerical-sequence"}
27
+ {"seq": [7, 14, 19, 29, 40, 44, 52], "source": "https://www.nibcode.com/en/psychometric-training/test-of-numerical-sequence"}
28
+ {"seq": [819, 648, 497, 366, 255], "source": "https://www.nibcode.com/en/psychometric-training/test-of-numerical-sequence"}
29
+ {"seq": [87, 165, 726, 1353, 4884], "source": "https://www.nibcode.com/en/psychometric-training/test-of-numerical-sequence"}
30
+ {"seq": [15, 47, 31, 54, 73, 15], "source": "https://www.nibcode.com/en/psychometric-training/test-of-numerical-sequence"}
31
+ {"seq": [4, 8, 16, 32, 64, 128], "source": "https://www.syvum.com/cgi/online/serve.cgi/iq/ar_series3.html?question_hide"}
32
+ {"seq": [2, 3, 5, 7, 11, 13, 17, 19, 23], "source": "https://www.syvum.com/cgi/online/serve.cgi/iq/ar_series3.html?question_hide"}
33
+ {"seq": [500, 475, 425, 350, 250, 125], "source": "https://www.syvum.com/cgi/online/serve.cgi/iq/ar_series3.html?question_hide"}
34
+ {"seq": [200, 196, 180, 116, -140], "source": "https://www.syvum.com/cgi/online/serve.cgi/iq/ar_series3.html?question_hide"}
35
+ {"seq": [2, 3, 4, 12, 6, 23, 8, 36, 10, 51], "source": "https://www.12minprep.com/knowledge-hub/number-series-practice/#sample-questions-horizontal"}
36
+ {"seq": [16, 18, 29, 49, 78], "source": "https://www.12minprep.com/knowledge-hub/number-series-practice/#sample-questions-horizontal"}
37
+ {"seq": [4, 11, 25, 53, 109], "source": "https://www.12minprep.com/knowledge-hub/number-series-practice/#sample-questions-horizontal"}
38
+ {"seq": [29, 41, 53, 65, 77, 89], "source": "https://www.12minprep.com/knowledge-hub/number-series-practice/#sample-questions-horizontal"}
39
+ {"seq": [2, 4, 8, 10, 20, 22], "source": "https://www.12minprep.com/knowledge-hub/number-series-practice/#sample-questions-horizontal"}
40
+ {"seq": [2, 3, 1, 4, 0, 5, -1], "source": "https://www.12minprep.com/knowledge-hub/number-series-practice/#sample-questions-horizontal"}
41
+ {"seq": [6, 18, 0, 24, -6, 30, -12], "source": "https://www.12minprep.com/knowledge-hub/number-series-practice/#sample-questions-horizontal"}
42
+ {"seq": [6, 3, 12, 6, 24, 12, 48], "source": "https://www.12minprep.com/knowledge-hub/number-series-practice/#sample-questions-horizontal"}
43
+ {"seq": [11, 21, 31, 41, 51], "source": "https://iqtestprep.com/number-sequence-test/"}
44
+ {"seq": [48, 42, 36, 30, 24], "source": "https://iqtestprep.com/number-sequence-test/"}
45
+ {"seq": [3, 9, 27, 81, 243], "source": "https://iqtestprep.com/number-sequence-test/"}
46
+ {"seq": [2, 8, 4, 16, 8, 32], "source": "https://iqtestprep.com/number-sequence-test/"}
47
+ {"seq": [249, 254, 127, 132, 66], "source": "https://iqtestprep.com/number-sequence-test/"}
48
+ {"seq": [8, 15, 12, 15, 16, 15, 20], "source": "https://iqtestprep.com/number-sequence-test/"}
49
+ {"seq": [22, 2, 22, 4, 22, 8, 22, 16], "source": "https://iqtestprep.com/number-sequence-test/"}
50
+ {"seq": [324, 361, 400, 441, 484], "source": "https://www.hitbullseye.com/Number-Series-Tricks.php"}
51
+ {"seq": [512, 729, 1000, 1331], "source": "https://www.hitbullseye.com/Number-Series-Tricks.php"}
52
+ {"seq": [4, 36, 324, 2916, 26244], "source": "https://www.hitbullseye.com/Number-Series-Tricks.php"}
53
+ {"seq": [4, 9, 14, 19, 24, 29, 34], "source": "https://www.hitbullseye.com/Number-Series-Tricks.php"}
54
+ {"seq": [1, 3, 6, 10, 15, 21], "source": "https://www.hitbullseye.com/Number-Series-Tricks.php"}
55
+ {"seq": [10, 22, 46, 94, 190, 382], "source": "https://www.hitbullseye.com/Number-Series-Tricks.php"}
56
+ {"seq": [1, 4, 8, 11, 22, 25, 50], "source": "https://www.hitbullseye.com/Number-Series-Tricks.php"}
57
+ {"seq": [1, 2, 6, 36, 44, 440, 452], "source": "https://www.hitbullseye.com/Number-Series-Tricks.php"}
tokenizer.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"version": "1.0", "truncation": null, "padding": null, "added_tokens": [{"id": 256, "content": "<bos>", "single_word": false, "lstrip": false, "rstrip": false, "normalized": false, "special": true}, {"id": 257, "content": "<eos>", "single_word": false, "lstrip": false, "rstrip": false, "normalized": false, "special": true}, {"id": 258, "content": "<pad>", "single_word": false, "lstrip": false, "rstrip": false, "normalized": false, "special": true}], "normalizer": null, "pre_tokenizer": {"type": "ByteLevel", "add_prefix_space": false, "trim_offsets": true, "use_regex": true}, "post_processor": {"type": "TemplateProcessing", "single": [{"SpecialToken": {"id": "<bos>", "type_id": 0}}, {"Sequence": {"id": "A", "type_id": 0}}], "pair": [{"SpecialToken": {"id": "<bos>", "type_id": 0}}, {"Sequence": {"id": "A", "type_id": 0}}, {"SpecialToken": {"id": "<bos>", "type_id": 1}}, {"Sequence": {"id": "B", "type_id": 1}}], "special_tokens": {"<bos>": {"id": "<bos>", "ids": [256], "tokens": ["<bos>"]}}}, "decoder": {"type": "ByteLevel", "add_prefix_space": false, "trim_offsets": true, "use_regex": true}, "model": {"type": "BPE", "dropout": null, "unk_token": null, "continuing_subword_prefix": null, "end_of_word_suffix": null, "fuse_unk": false, "byte_fallback": false, "ignore_merges": false, "vocab": {"Ā": 0, "ā": 1, "Ă": 2, "ă": 3, "Ą": 4, "ą": 5, "Ć": 6, "ć": 7, "Ĉ": 8, "ĉ": 9, "Ċ": 10, "ċ": 11, "Č": 12, "č": 13, "Ď": 14, "ď": 15, "Đ": 16, "đ": 17, "Ē": 18, "ē": 19, "Ĕ": 20, "ĕ": 21, "Ė": 22, "ė": 23, "Ę": 24, "ę": 25, "Ě": 26, "ě": 27, "Ĝ": 28, "ĝ": 29, "Ğ": 30, "ğ": 31, "Ġ": 32, "!": 33, "\"": 34, "#": 35, "$": 36, "%": 37, "&": 38, "'": 39, "(": 40, ")": 41, "*": 42, "+": 43, ",": 44, "-": 45, ".": 46, "/": 47, "0": 48, "1": 49, "2": 50, "3": 51, "4": 52, "5": 53, "6": 54, "7": 55, "8": 56, "9": 57, ":": 58, ";": 59, "<": 60, "=": 61, ">": 62, "?": 63, "@": 64, "A": 65, "B": 66, "C": 67, "D": 68, "E": 69, "F": 70, "G": 71, "H": 72, "I": 73, "J": 74, "K": 75, "L": 76, "M": 77, "N": 78, "O": 79, "P": 80, "Q": 81, "R": 82, "S": 83, "T": 84, "U": 85, "V": 86, "W": 87, "X": 88, "Y": 89, "Z": 90, "[": 91, "\\": 92, "]": 93, "^": 94, "_": 95, "`": 96, "a": 97, "b": 98, "c": 99, "d": 100, "e": 101, "f": 102, "g": 103, "h": 104, "i": 105, "j": 106, "k": 107, "l": 108, "m": 109, "n": 110, "o": 111, "p": 112, "q": 113, "r": 114, "s": 115, "t": 116, "u": 117, "v": 118, "w": 119, "x": 120, "y": 121, "z": 122, "{": 123, "|": 124, "}": 125, "~": 126, "ġ": 127, "Ģ": 128, "ģ": 129, "Ĥ": 130, "ĥ": 131, "Ħ": 132, "ħ": 133, "Ĩ": 134, "ĩ": 135, "Ī": 136, "ī": 137, "Ĭ": 138, "ĭ": 139, "Į": 140, "į": 141, "İ": 142, "ı": 143, "IJ": 144, "ij": 145, "Ĵ": 146, "ĵ": 147, "Ķ": 148, "ķ": 149, "ĸ": 150, "Ĺ": 151, "ĺ": 152, "Ļ": 153, "ļ": 154, "Ľ": 155, "ľ": 156, "Ŀ": 157, "ŀ": 158, "Ł": 159, "ł": 160, "¡": 161, "¢": 162, "£": 163, "¤": 164, "¥": 165, "¦": 166, "§": 167, "¨": 168, "©": 169, "ª": 170, "«": 171, "¬": 172, "Ń": 173, "®": 174, "¯": 175, "°": 176, "±": 177, "²": 178, "³": 179, "´": 180, "µ": 181, "¶": 182, "·": 183, "¸": 184, "¹": 185, "º": 186, "»": 187, "¼": 188, "½": 189, "¾": 190, "¿": 191, "À": 192, "Á": 193, "Â": 194, "Ã": 195, "Ä": 196, "Å": 197, "Æ": 198, "Ç": 199, "È": 200, "É": 201, "Ê": 202, "Ë": 203, "Ì": 204, "Í": 205, "Î": 206, "Ï": 207, "Ð": 208, "Ñ": 209, "Ò": 210, "Ó": 211, "Ô": 212, "Õ": 213, "Ö": 214, "×": 215, "Ø": 216, "Ù": 217, "Ú": 218, "Û": 219, "Ü": 220, "Ý": 221, "Þ": 222, "ß": 223, "à": 224, "á": 225, "â": 226, "ã": 227, "ä": 228, "å": 229, "æ": 230, "ç": 231, "è": 232, "é": 233, "ê": 234, "ë": 235, "ì": 236, "í": 237, "î": 238, "ï": 239, "ð": 240, "ñ": 241, "ò": 242, "ó": 243, "ô": 244, "õ": 245, "ö": 246, "÷": 247, "ø": 248, "ù": 249, "ú": 250, "û": 251, "ü": 252, "ý": 253, "þ": 254, "ÿ": 255, "<bos>": 256, "<eos>": 257, "<pad>": 258}, "merges": []}}
tokenizer_config.json ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "tokenizer_class": "PreTrainedTokenizerFast",
3
+ "bos_token": "<bos>",
4
+ "eos_token": "<eos>",
5
+ "pad_token": "<pad>",
6
+ "model_max_length": 4096,
7
+ "clean_up_tokenization_spaces": false
8
+ }