File size: 20,583 Bytes
5c6c847
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
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
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
---
license: apache-2.0
language:
- en
tags:
- zeropoint
- zerocg
- numpy
- from-scratch
- sequence-modeling
- memory-slots
- linear-attention
- research
pretty_name: ZeroPoint
---

# ZeroPoint — a new, from-scratch framework for sequence modeling

**Status: v0 research prototype (November 2026). This is a brand-new framework: it is not a
fine-tune, not a wrapper around PyTorch / `transformers`, and not a derivative of an existing
released model. Both the framework and the architecture are implemented here from scratch,
in pure Python + NumPy.**

ZeroPoint is two things:

1. **ZeroCG** — a small deep-learning framework written from scratch: `Tensor` with
   reverse-mode automatic differentiation, `nn` layers, AdamW (checkpointable), and
   matrix-multiply FLOP counting. Dependencies: Python 3 + NumPy. Nothing else.
2. **ZeroPoint** — a sequence architecture that replaces self-attention with a set of
   **memory slots that forget at different, learnable speeds**. Training uses a
   **chunked-parallel** form (chunk = 32); inference uses a **per-character recurrence**
   whose state size is fixed and independent of text length, and it needs **no positional
   encoding**.

**This repository contains no pretrained weights.** It is an architecture + framework
release, together with the full experiment suite that compares ZeroPoint against a
GPT-style Transformer baseline at ~115k parameters and a character level. A separate
1.4M-parameter model trained on a private corpus (internal name *ZeroX*) is **not** part
of this release, and neither are its weights, corpus, or training runs.

---

## TL;DR — the measured comparison

On the only head-to-head experiment (same data, same parameter budget, same training
recipe, same evaluation), **ZeroPoint and the Transformer are statistically tied** under
the project's own "difference > 2× seed std" rule. We do **not** claim ZeroPoint is better.

| model | params | val loss (nats/char, 3 seeds) | matmul FLOPs/char @T=64 | inference state @64 / @1024 / @4096 (floats) |
|---|---|---|---|---|
| Transformer (learned PE) | 116,576 | 1.5452 ± 0.0100 | 241,664 | 16,384 / 262,144 / 1,048,576 |
| Transformer (sinusoidal PE) | 112,480 | 1.5271 ± 0.0083 | 241,664 | 16,384 / 262,144 / 1,048,576 |
| **ZeroPoint** | **115,240** | **1.5214 ± 0.0134** | **232,448** | **2,048 / 2,048 / 2,048** |

- ZeroPoint − Transformer = 0.0238; 2 × max seed std = 0.0268 → **ratio 0.89, not
  significant**. ZeroPoint − Transformer(sin) = 0.0057 → ratio 0.21, not significant.
- The transformer's KV cache is **8×** ZeroPoint's state at 64 characters, **128×** at
  1,024 characters and **512×** at 4,096 characters. ZeroPoint's state is 2,048 floats
  (8 KiB in fp32) at any length.
- The Transformer's per-character matmul cost grows with context (2,306,048 FLOPs/char at
  4,096) while ZeroPoint's stays ~constant (234,464). **Wall-clock speed was not measured**
  — this release ships FLOP counts, not throughput numbers.

Read [**Comparison conditions**](#comparison-conditions-read-before-quoting-any-number)
before quoting any number, and [**Limitations**](#limitations) before drawing conclusions.

---

## What is actually new (and what is not)

**New code.** `zerocg/` is a self-contained NumPy implementation: reverse-mode autograd,
layers, AdamW, checkpointing, FLOP counting. `models/zeropoint.py` is the architecture
implementation. Neither depends on PyTorch; the early PyTorch reference scripts of the
project are not part of this release and were never used for the results.

**New combination.** The specific design — **per-slot learnable decay λ with a geometric
half-life initialisation (1.5 → 64 characters) + softmax competition when writing +
a write-strength gate + chunked-parallel / recurrent dual form + no positional encoding +
learnable initial slot state** — is, to our knowledge, a new combination. It is the object
of study here.

**Not new.** Every individual ingredient has prior art, and the design document says so:
memory networks / Neural Turing Machines (soft read-write memory), linear attention
(Katharopoulos et al., 2020 — parallel/recurrent dual form), RetNet (Sun et al., 2023 —
decayed recurrence without positional encoding), and Mamba / state-space models (fixed-size
recurrent state). This work makes **no priority claim** and is not "the first" anything.
It is also not a claim that memory slots are generally better than attention: at this scale
they tie.

---

## Comparison conditions (read before quoting any number)

Everything below is what the two sides of the comparison actually shared, measured on
**2026-10-11** (head-to-head and ablation) and **2026-10-18** (length re-evaluation).

| item | setting |
|---|---|
| Corpus | ASCII-only Python standard-library `.py` source, **1,558,395** characters, vocabulary **96** |
| Split | contiguous 90 % train / 10 % validation |
| Task | character-level next-character prediction |
| Models | width 64, 2 layers, 4 heads (D = 16), MLP hidden 256 (4×), Pre-LN, GELU, no dropout, no weight tying |
| ZeroPoint specifics | 16 slots/head, initial half-lives geometric 1.5→64 chars, learnable λ and s0, chunk 32, no positional encoding |
| Context length | 64 characters (training and short-context eval) |
| Batch | 32 sequences × 64 characters = 2,048 chars/step |
| Steps | 2,000 (about 2 minutes per model on one CPU core) |
| Optimizer | AdamW β = (0.9, 0.999), weight decay 0.01, gradient clip 1.0 |
| LR schedule | 100-step warmup, cosine decay to 10 % |
| LR selection | per model: sweep {1e-3, 3e-3, 6e-3} on seed 0, take the best for seeds 1–2; all three models selected 6e-3 |
| Seeds | 0, 1, 2 (seed controls initialisation and data order) |
| Evaluation | mean cross-entropy over 40 fixed validation batches × 32 sequences × 64 chars (seed 999); mean ± sample std over 3 seeds |
| Hardware | one Apple Silicon Mac, CPU only, NumPy float32 — no GPU |
| Data used | only the reports in `experiments/`; the numbers below were independently re-derived from saved checkpoints where possible |

**Not controlled / things this comparison does not tell you:**

- **One corpus, one domain, one split.** Source code is not natural language. No downstream
  tasks, no instruction following, no reasoning evals — only validation loss.
- **Tiny scale.** 115k parameters, 2 layers, 64-char context, 2,000 steps. Nothing here
  extrapolates to large models or long training.
- **The baseline is a minimal GPT-style decoder** with learned or sinusoidal positional
  encoding, Pre-LN and GELU. It is not tuned beyond a 3-value LR sweep; no RoPE/ALiBi, no
  dropout, no weight decay tuning.
- **3 seeds only**, and the LR is selected on seed 0, which is also included in the 3-seed
  mean (a winner's-curse of ≤ ~0.01 nats/char; the same protocol was used for all models).
- **Transformer checkpoints were not saved**, so the Transformer rows cannot be re-derived
  from artifacts — they rest on the original report. The ZeroPoint side *was* re-derived
  bit-for-bit (see [Data verification](#data-verification)).
- **No wall-clock or memory benchmark.** FLOPs count matrix multiplications only; CPU
  wall-clock is dominated by Python overhead and would not be a meaningful comparison.
- **Length extrapolation is evaluated at two different sample sizes** (32 sequences for
  ZeroPoint, 8 for the sinusoidal Transformer — the baseline checkpoints are gone).
- **Ablation numbers use a different fixed LR** (3e-3) than the head-to-head (6e-3), so the
  two tables are only internally comparable. Do not rank across them.
- **Exact recall is not measured** by this release: the recall experiment is inconclusive
  because of its learning-rate configuration (see below), and must not be cited as an
  architecture comparison.

---

## Head-to-head results

Protocol: identical width/layer/head/MLP configuration; parameter counts within ~4 %
(115,240 / 116,576 / 112,480); identical data, batches, seeds, optimiser, schedule and
evaluation; the only difference is the token-mixing layer (memory slots vs self-attention)
and the positional encoding.

```
validation loss (nats/char, lower is better; 3 seeds, 2000 steps, lr 6e-3)
ZeroPoint            1.5214 ± 0.0134
Transformer (sin)    1.5271 ± 0.0083
Transformer (learned) 1.5452 ± 0.0100
```

Per-seed ZeroPoint values: 1.5311 / 1.5307 / 1.5024. The largest gap (vs learned-PE
Transformer) is 0.0238 nats/char, **below the project's 2 × seed-std decision line of
0.0268**. Under a stricter standard-error criterion the gap would be ~2.5σ in ZeroPoint's
favour, but that is not the rule this project pre-registered, and 3 seeds is thin. **The
honest reading is: indistinguishable at this scale.**

### Inference state and compute

| | @64 chars | @1,024 chars | @4,096 chars |
|---|---|---|---|
| Transformer KV cache (floats) | 16,384 | 262,144 (128×) | 1,048,576 (512×) |
| ZeroPoint state (floats) | 2,048 | 2,048 | 2,048 |
| Transformer matmul FLOPs/char | 241,664 | 733,184 | 2,306,048 |
| ZeroPoint matmul FLOPs/char | 232,448 | 234,368 | 234,464 |

ZeroPoint's state is per-layer slots (2 layers × 4 heads × 16 slots × 16 dims) and is
independent of sequence length. This is the property the architecture was designed for: a
fixed-size recurrent state with no KV cache. It is **not** a claim that this is faster in
wall-clock time — see the limitations.

---

## Length behaviour (corrected 32-sequence evaluation)

Trained on 64 characters, then evaluated on 4,096-character sequences, in segments. 3
seeds, 32 validation sequences, same chunked-parallel algorithm for every model:

| positions | ZeroPoint (trained at 64) | ZeroPoint (trained at 256) |
|---|---|---|
| 0–63 | 1.4372 ± 0.0187 | 1.4741 ± 0.0117 |
| 64–255 (4× training length) | 1.4742 ± 0.0341 | 1.4486 ± 0.0098 |
| 256–1023 | 1.6617 ± 0.0234 | 1.5098 ± 0.0022 |
| 1024–4095 (64× training length) | 1.6932 ± 0.0305 | 1.5155 ± 0.0048 |
| far − near gap | **+0.2190 ± 0.0630** | **+0.0669 ± 0.0051** |

- At 4× the training length the loss rises by **0.037** nats/char; at 64× by **0.219**.
  Extrapolation degrades gracefully, but it **does** degrade — do not quote "handles 4×
  training length" without the +0.037.
- Training at 256 characters reduces the far−near gap 3.3× (to +0.067) but costs +0.036 at
  64 characters. That run also changed batch size 32 → 8 (to keep 2,048 chars/step), so the
  short-range cost is confounded with batch size; treat it as a hypothesis, not isolated.
- **Sinusoidal-PE Transformer collapses outside the training window:** 1.4512 within
  0–63, then **4.6359** at 64–255 and **4.6057** at 256–1023, versus ln 96 = 4.5642, i.e.
  chance level. This is an 8-sequence × 3-seed measurement, and the baseline checkpoints
  were not retained, so it cannot be re-run with 32 sequences. It is a real, large effect,
  but it is also a known weakness of plain sinusoidal absolute PE — **it is not evidence
  that attention in general cannot extrapolate** (relative-position and NoPE models are
  outside this comparison).

The earlier 8-sequence values (1.5550 / 1.6164 / 1.6410 / 1.7040) are kept only in the
archived report and are **superseded** by the table above; the 8-sequence sample was
noise-dominated (the same model scores 1.5550 vs 1.4372 on 0–63 depending on sample size).

---

## Ablations (fixed LR 3e-3; internally comparable only)

Each row changes one thing; parameter counts are matched within 1 % by adjusting the MLP
width; 2,000 steps, 3 seeds, same corpus. Base: **1.5500 ± 0.0073**. Decision line per
row: 2 × max(base std, row std). Δ is row − base (positive = worse).

| variant | Δ (nats/char) | Δ / threshold | verdict |
|---|---|---|---|
| uniform half-life init (no hierarchy) | **+0.0510** | 3.23× | clear: hierarchy matters |
| + sinusoidal positional encoding | **+0.0606** | 3.88× | clear: no PE is better here |
| λ frozen at initial values | **+0.0284** | 1.46× | clear: learnable decay matters |
| 1 head (64 dims, MLP widened to match) | **+0.0276** | 1.89× | clear: multiple heads matter |
| 8 heads (8 dims each, MLP narrowed) | +0.0173 | 1.19× | marginal / weak |
| 4 slots/head | −0.0034 | 0.20× | no significant difference |
| 32 slots/head | +0.0124 | 0.85× | no significant difference |
| no write-strength gate | +0.0022 | 0.15× | no significant difference |
| sigmoid write instead of softmax competition | −0.0013 | 0.09× | no significant difference |

At this scale, the things that **do** matter are the hierarchical half-life initialisation,
learnable λ, multiple heads and the absence of positional encoding. Slot count (4–32),
the write-strength gate, and write competition do **not** show a significant effect here.
Note the base loss differs from the head-to-head table because the ablation fixes
lr = 3e-3 (base 1.5500) while the head-to-head uses the selected lr = 6e-3 (1.5214).

---

## Exact recall: inconclusive — do not cite as an architecture comparison

The long-distance associative-recall experiment (`k1 v1 … kN vN [query kq] → vq`) was meant
to test the expected weakness of a fixed slot state. It produced **no usable conclusion**:

- With the original constant lr = 3e-3, both architectures plateau near 50 % on N=2
  (chance is 6 % for 16 values) and near 16–23 % for larger N, after 20,000 steps. The
  plateau is a **training-configuration** artefact, not an architecture property: with a
  1e-3 cosine schedule, a Transformer trained on N=2 alone reaches **100 %** in 8,000
  steps, and the diagnostic shows the loss ≈ ln 2 (50/50 hedge) trap.
- The mixed-N setup also dilutes the easy examples (N=2 is ~1/15 of the data), so the
  experiment needs a curriculum and/or per-N weighting before it can compare architectures.

The 20,000-step table (Transformer 50/30/23/20/18 %; ZeroPoint-16 51/32/23/20/16 %;
ZeroPoint-32 49/31/24/20/17 %) is therefore **not** evidence that ZeroPoint is worse at
recall. It is a negative result about the experimental setup. A corrected re-run is future
work.

---

## Repository layout

```
zerocg/                 from-scratch NumPy framework (autograd, nn, AdamW, FLOP counter)
models/zeropoint.py     ZeroPoint architecture + the small char-LM harness used in the experiments
models/transformer.py   GPT-style Transformer baseline (learned or sinusoidal PE)
experiments/            compare / ablation / recall (+ recall_diag), length/ema/slot diagnostics
experiments/results/    dated archives of the reports (kept, annotated as historical)
tests/                  numerical gradient checks, parallel=recurrent equivalence, golden reference
docs/ZeroPoint.md       design document (Chinese; structured after "Attention Is All You Need")
docs/ZeroPoint_EN.md    English translation of the design document
docs/AUDIT.md           independent verification notes for the numbers in this card
```

## Reproducing

```bash
pip install numpy
python tests/test_zerocg.py          # framework self-checks
python tests/test_zeropoint.py       # architecture + parallel/recurrent equivalence (~20 s)
cd experiments
python compare.py                    # ~35 min on one CPU core
python ablation.py                   # ~70 min
python recall.py                     # ~15 min; known inconclusive (see above)
```

Experiments are pure NumPy on CPU. `compare.py` / `ablation.py` write a dated archive to
`experiments/results/` and update the latest report in `experiments/`.

---

## Data verification

The numbers in this card were independently audited, not merely copied from the project's
own reports:

- The **ZeroPoint side was re-derived bit-for-bit** from the saved diagnostic checkpoints
  (`val64 = 1.5214 ± 0.0134`, per-seed 1.5311 / 1.5307 / 1.5024; the 32-sequence segment
  values above; the ablation parameter counts). The Transformer checkpoints were never
  saved, so those rows could not be re-derived (stated as a limitation above).
- Corrections applied after the audit: the 8-sequence length-extrapolation table was
  superseded by the 32-sequence re-evaluation; the "effective write slots 3.2 / 5.0"
  number was a metric bug (entropy over a non-normalised, gate-scaled write distribution —
  the normalised values are ~6–10 write slots and ~10 read slots out of 16) and is not
  used; "precise recall is a known weakness" was downgraded to "inconclusive"; "one matrix
  multiply, as fast as attention" was corrected to "chunked parallel, one matmul per chunk";
  "~110k parameters" was corrected to the exact 115,240.
- See [`docs/AUDIT.md`](docs/AUDIT.md) for the claim-by-claim audit table.

---

## Limitations (summary)

- Small scale: 115k params, 2 layers, 64-char context, 2,000 steps, one source-code corpus.
- Only validation loss was measured; no downstream tasks, no generation-quality evaluation,
  no scaling study.
- The baseline is a minimal GPT-style decoder, not a tuned Transformer; the comparison is
  fair in configuration but does not represent "Transformers" in general.
- 3 seeds; the LR was selected on seed 0 (small selection bias).
- No wall-clock or memory measurements; FLOP counts only.
- Length extrapolation: ZeroPoint degrades +0.037 nats/char at 4× training length; the
  sinusoidal Transformer's collapse is a known property of absolute PE, measured with only
  8 sequences.
- Exact recall: inconclusive; needs a corrected training configuration.
- The framework is a research prototype, not a production framework: no GPU kernels, no
  distributed training, no mixed precision.

---

## Citation

```bibtex
@misc{zeropoint2026,
  title        = {ZeroPoint: a from-scratch NumPy framework and a hierarchical memory-slot
                  sequence architecture},
  author       = {Holmes2011},
  year         = {2026},
  howpublished = {\url{https://huggingface.co/Holmes2011/ZeroPoint}},
  note         = {v0 research prototype; architecture and framework release, no pretrained weights}
}
```

## License

Apache-2.0 (code and documentation). This repository contains **no model weights, no
training corpus, and no training runs** of the project's separate 1.4M-parameter model.

---

## 中文摘要

**ZeroPoint 是一个全新的框架,不是已有模型的封装、微调或衍生品。** 本仓库从零实现了两部分:

1. **ZeroCG**:纯 Python + NumPy 的深度学习框架 —— 反向自动求导、`nn` 层、AdamW、矩阵乘
   FLOP 统计,不依赖 PyTorch。
2. **ZeroPoint**:用一组**遗忘速度可学习、按存储层级初始化**的记忆槽取代自注意力。训练用
   **分块并行**(块长 32,块间串行传状态),推理用**逐字递推**,状态固定、与文本长度无关,
   **不需要位置编码**。

**对比条件(引用任何数字前请先看)**:Python 标准库源码 1,558,395 字符、字符级、词表 96;
三个模型同宽 64 / 2 层 / 4 头 / MLP 256 / Pre-LN / GELU;上下文 64、batch 32、2000 步、
AdamW、100 步预热 + 余弦、学习率在 {1e-3, 3e-3, 6e-3} 里按种子 0 选(三者都选 6e-3)、
种子 0/1/2;验证 loss = 40 个固定 batch × 32 序列 × 64 字的平均交叉熵;单机 CPU、NumPy。

**主要结果**:

- 头对头验证 loss:ZeroPoint **1.5214 ± 0.0134**,Transformer **1.5452 ± 0.0100**,
  正弦位置编码 Transformer **1.5271 ± 0.0083**。最大差 0.0238 < 2× 种子标准差 0.0268
  → **统计上没有差别,不声称 ZeroPoint 更好**。
- 推理状态:ZeroPoint 固定 2,048 个浮点数(8 KiB fp32);Transformer KV 缓存在第 64 字时
  16,384(8×)、第 1024 字时 262,144(**128×**)、第 4096 字时 1,048,576(**512×**)。
- 长度外推:训练 64 字,4 倍长度 loss 升高 **0.037**,64 倍长度升高 **0.219 ± 0.063**;
  正弦位置编码的 Transformer 出训练长度后崩到约 4.64(≈随机水平;只有 8 条序列的测量)。
- 消融:分层半衰期初始化(+0.051)、可学习 λ(+0.028)、多头(1 头 +0.028)、去掉位置编码
  (+0.061)有明确作用;槽数 4~32、写强度门、写入竞争在该规模下**无显著差异**。
- 精确回忆:**无结论**(学习率配置问题),不能用来比较架构。

**本仓库不含训练权重**:项目里另一个 1.4M 参数的模型(内部名 ZeroX)及其语料、训练运行
都不在本次发布范围内。

许可证:Apache-2.0。设计文档中文原文见 [`docs/ZeroPoint.md`](docs/ZeroPoint.md),
英文版见 [`docs/ZeroPoint_EN.md`](docs/ZeroPoint_EN.md)。