fluidlayer 2.0.0__tar.gz → 2.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/PKG-INFO +30 -31
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/README.md +28 -29
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/docs/BLOG.md +3 -4
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/docs/CHANGELOG.md +9 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/docs/COMPARISON.md +4 -4
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/docs/DESIGN_pinned_memory.md +11 -12
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/docs/FRAMEWORK.md +6 -2
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/docs/GETTING_STARTED.md +17 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/docs/GRAFT.md +12 -47
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/docs/MILESTONES.md +9 -16
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/docs/NEGATIVE-RESULTS.md +34 -87
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/docs/POSITIONING.md +9 -23
- fluidlayer-2.1.0/docs/PROCESS.md +347 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/docs/README.md +4 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/docs/REPRODUCING.md +40 -6
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/docs/TEN-MILLION.md +8 -2
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/docs/index.html +3 -3
- fluidlayer-2.1.0/examples/appkit/attach_layer.py +235 -0
- fluidlayer-2.1.0/examples/appkit/load_model.py +63 -0
- fluidlayer-2.1.0/experiments/e15_scale_model.py +317 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/experiments/e9_ten_million.py +96 -78
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/experiments/pretrain_prior.py +5 -3
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/fluidlayer/__init__.py +1 -1
- fluidlayer-2.1.0/fluidlayer/qwen2_model.py +156 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/fluidlayer.egg-info/PKG-INFO +30 -31
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/fluidlayer.egg-info/SOURCES.txt +6 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/pyproject.toml +2 -2
- fluidlayer-2.1.0/tests/test_qwen2_model.py +26 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/CITATION.cff +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/LICENSE +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/MANIFEST.in +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/Makefile +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/docs/API.md +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/docs/LIMITATION.md +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/examples/gate_demo.py +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/examples/graft_demo.py +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/examples/quickstart.py +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/experiments/e10_gate.py +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/experiments/e11_exact.py +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/experiments/e12_router.py +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/experiments/e13_knn_baseline.py +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/experiments/e14_real_gpt2.py +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/experiments/e1_prior_perplexity.py +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/experiments/e2_scaling.py +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/experiments/e4_gbalance.py +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/experiments/e5_graft.py +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/experiments/e6_graft.py +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/experiments/e6_real_corpus.py +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/experiments/e7_lossy_fix.py +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/experiments/gpu_graft.py +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/experiments/run_all.py +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/fluidlayer/autodiff.py +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/fluidlayer/blocks.py +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/fluidlayer/bpe.py +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/fluidlayer/data.py +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/fluidlayer/diffusion.py +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/fluidlayer/gpt2_model.py +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/fluidlayer/gpt2_tokenizer.py +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/fluidlayer/graft.py +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/fluidlayer/losses.py +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/fluidlayer/memory.py +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/fluidlayer/model.py +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/fluidlayer/optim.py +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/fluidlayer/py.typed +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/fluidlayer/sheaf.py +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/fluidlayer/topology.py +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/fluidlayer/torch_graft.py +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/fluidlayer.egg-info/dependency_links.txt +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/fluidlayer.egg-info/requires.txt +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/fluidlayer.egg-info/top_level.txt +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/fluidlayer_single.py +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/requirements.txt +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/run_without_pytest.py +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/selftest.py +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/setup.cfg +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/tests/conftest.py +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/tests/test_bpe.py +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/tests/test_graft.py +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/tests/test_memory.py +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/tests/test_selftest.py +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/tests/test_topology.py +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/tests/test_torch_parity.py +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/tools/_bundle_template.py +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/tools/bundle_single_file.py +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/tools/download_gpt2.py +0 -0
- {fluidlayer-2.0.0 → fluidlayer-2.1.0}/tools/fetch_pypi.py +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fluidlayer
|
|
3
|
-
Version: 2.
|
|
4
|
-
Summary: A research memory layer for language models
|
|
3
|
+
Version: 2.1.0
|
|
4
|
+
Summary: A research memory layer for language models with optional GPT-2 and Qwen2 adapters
|
|
5
5
|
Author: Kapil Dhinwa
|
|
6
6
|
License: MIT
|
|
7
7
|
Project-URL: Homepage, https://github.com/kapildhinwa2010-dev/fluidtech
|
|
@@ -216,14 +216,17 @@ Details: [`docs/TEN-MILLION.md`](docs/TEN-MILLION.md)
|
|
|
216
216
|
## The negative results
|
|
217
217
|
|
|
218
218
|
This is the part that makes the rest believable.
|
|
219
|
-
Eleven
|
|
219
|
+
Eleven negative or unexpected findings are documented. Most have checked-in
|
|
220
|
+
result files; the archived transformer and real-GPT-2 outputs are now
|
|
221
|
+
checked in. Their original model/script environments are not fully included,
|
|
222
|
+
so those historical runs cannot be independently repeated as-is.
|
|
220
223
|
|
|
221
224
|
| What we expected | What happened |
|
|
222
225
|
|---|---|
|
|
223
226
|
| The **topological** selection criterion picks the right facts | It does **not** — `0.000` precision vs `0.970` for plain geometric affinity. |
|
|
224
227
|
| `‖L·1‖∞` detects the frozen state | It does **not** — the frustration index does; the old claim is now a test case. |
|
|
225
228
|
| `λ₂` predicts long-context quality | Barely — Pearson `0.20`. |
|
|
226
|
-
| A transformer loses at some scale |
|
|
229
|
+
| A transformer loses at some scale | The archived run says it **wins**; see `results/train_results.json`. |
|
|
227
230
|
| A domain prior beats a frequency table | It helps (`−0.006 nats`) but a **unigram table wins 6× more**. |
|
|
228
231
|
| The diffusion tier is neutral on a frozen model | It **degrades** the model by **`+0.81 nats`** (fixed → `+0.0000`, but no upside either). |
|
|
229
232
|
| Training the layer helps | It **hurts** — the training-free identity map is better (`0.800 vs 0.650`). |
|
|
@@ -235,16 +238,18 @@ Read it: [`docs/NEGATIVE-RESULTS.md`](docs/NEGATIVE-RESULTS.md)
|
|
|
235
238
|
## The repository
|
|
236
239
|
|
|
237
240
|
```text
|
|
238
|
-
fluidlayer/ the package (
|
|
241
|
+
fluidlayer/ the package (NumPy core; optional PyTorch adapters)
|
|
239
242
|
graft.py the attachable memory layer
|
|
240
243
|
memory.py the frozen register (20 B per fact, bit-exact)
|
|
241
244
|
torch_graft.py the same layer in PyTorch, for a real LLM
|
|
242
245
|
gpt2_model.py a GPT-2 forward pass in PyTorch (no transformers needed)
|
|
243
246
|
gpt2_tokenizer.py the GPT-2 byte-level BPE, in pure Python
|
|
247
|
+
qwen2_model.py an optional PyTorch Qwen2 forward pass
|
|
244
248
|
sheaf.py topology.py diffusion.py blocks.py autodiff.py ...
|
|
245
249
|
|
|
246
250
|
experiments/ every measurement; each writes a JSON into results/
|
|
247
251
|
e14_real_gpt2.py the graft on a REAL pretrained GPT-2 (124M)
|
|
252
|
+
e15_scale_model.py the graft on Qwen2.5-0.5B
|
|
248
253
|
e13_knn_baseline.py the layer vs. the closest prior art (kNN-LM)
|
|
249
254
|
|
|
250
255
|
tools/ the artifact checker, bundler, checkpoint downloader,
|
|
@@ -253,7 +258,7 @@ fluidlayer/bpe.py the byte-level BPE tokenizer
|
|
|
253
258
|
|
|
254
259
|
tests/ the unit tests (pytest, or run them without it)
|
|
255
260
|
|
|
256
|
-
examples/ quickstart.py, graft_demo.py, gate_demo.py
|
|
261
|
+
examples/ quickstart.py, graft_demo.py, gate_demo.py, appkit/
|
|
257
262
|
|
|
258
263
|
docs/ the design docs, the API, the limits, the theory report
|
|
259
264
|
|
|
@@ -273,28 +278,20 @@ and [limitations](docs/LIMITATION.md).
|
|
|
273
278
|
|
|
274
279
|
---
|
|
275
280
|
|
|
276
|
-
##
|
|
281
|
+
## Real-model experiment status
|
|
277
282
|
|
|
278
|
-
GPT-2
|
|
283
|
+
The E14 GPT-2 experiment script, forward implementation, tokenizer, and
|
|
284
|
+
archived `results/e14_real_gpt2.json` are included. The checkpoint is not;
|
|
285
|
+
rerun E14 to independently reproduce the recorded measurements. See
|
|
286
|
+
[the reproduction guide](docs/REPRODUCING.md) for download and run commands.
|
|
279
287
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
On the real model, the classic kNN-LM interpolation beats the gated override by **8×** on perplexity — the opposite of the 131k-parameter model, where the gate won by **7.4×**.
|
|
289
|
-
The gate wins where the base model is weak; interpolation wins where it is strong.
|
|
290
|
-
The capability works on both.
|
|
291
|
-
|
|
292
|
-
The checkpoint, the forward pass and the tokenizer are all in this repository:
|
|
293
|
-
|
|
294
|
-
- [`fluidlayer/gpt2_model.py`](fluidlayer/gpt2_model.py)
|
|
295
|
-
- [`fluidlayer/gpt2_tokenizer.py`](fluidlayer/gpt2_tokenizer.py)
|
|
296
|
-
|
|
297
|
-
No `transformers` dependency, and the generation is verified coherent.
|
|
288
|
+
E15 adds a from-scratch Qwen2.5-0.5B forward implementation and app-kit
|
|
289
|
+
integration. Its archived run records bit-identical attachment, exact recall
|
|
290
|
+
of a planted fact 1,411 tokens back, and a best gated loss improvement of
|
|
291
|
+
`0.041` nats; the kNN-LM baseline improves loss by `0.274` nats, so this run
|
|
292
|
+
does not show the gate outperforming that baseline. The checkpoint is not
|
|
293
|
+
bundled. Reproduction requires the optional GPU dependencies and local model
|
|
294
|
+
weights; see [E15 instructions](docs/REPRODUCING.md#qwen2-scale-experiment-e15).
|
|
298
295
|
|
|
299
296
|
The Torch twin is now tested against the NumPy reference in [`tests/test_torch_parity.py`](tests/test_torch_parity.py): the two implementations must agree on the router, the store and the gated override.
|
|
300
297
|
|
|
@@ -314,7 +311,9 @@ claim or validate production-scale operation.
|
|
|
314
311
|
|
|
315
312
|
## A research prototype, honestly labelled
|
|
316
313
|
|
|
317
|
-
|
|
314
|
+
The core research experiments use small CPU models and character-level or
|
|
315
|
+
512-token subword corpora. E14 and E15 are separate pretrained-model
|
|
316
|
+
experiments; their checkpoints are not included.
|
|
318
317
|
|
|
319
318
|
The subword repeat is the closest thing to a realistic tokenizer in this repository.
|
|
320
319
|
The GPU run, [`experiments/gpu_graft.py`](experiments/gpu_graft.py), is written and has not been executed here.
|
|
@@ -370,7 +369,7 @@ A research memory layer with an operator-level stability bound, a bounded in-mem
|
|
|
370
369
|
## Origin and acknowledgments
|
|
371
370
|
|
|
372
371
|
The project began with the author's idea of flowing information through a
|
|
373
|
-
topological structure. The
|
|
374
|
-
|
|
375
|
-
decisions are documented alongside
|
|
376
|
-
reproduced.
|
|
372
|
+
topological structure. The author describes it as a school project and
|
|
373
|
+
credits AI assistance for implementation and repository organization. The
|
|
374
|
+
research decisions, measurements, and limitations are documented alongside
|
|
375
|
+
the code so the work can be evaluated and reproduced.
|
|
@@ -179,14 +179,17 @@ Details: [`docs/TEN-MILLION.md`](docs/TEN-MILLION.md)
|
|
|
179
179
|
## The negative results
|
|
180
180
|
|
|
181
181
|
This is the part that makes the rest believable.
|
|
182
|
-
Eleven
|
|
182
|
+
Eleven negative or unexpected findings are documented. Most have checked-in
|
|
183
|
+
result files; the archived transformer and real-GPT-2 outputs are now
|
|
184
|
+
checked in. Their original model/script environments are not fully included,
|
|
185
|
+
so those historical runs cannot be independently repeated as-is.
|
|
183
186
|
|
|
184
187
|
| What we expected | What happened |
|
|
185
188
|
|---|---|
|
|
186
189
|
| The **topological** selection criterion picks the right facts | It does **not** — `0.000` precision vs `0.970` for plain geometric affinity. |
|
|
187
190
|
| `‖L·1‖∞` detects the frozen state | It does **not** — the frustration index does; the old claim is now a test case. |
|
|
188
191
|
| `λ₂` predicts long-context quality | Barely — Pearson `0.20`. |
|
|
189
|
-
| A transformer loses at some scale |
|
|
192
|
+
| A transformer loses at some scale | The archived run says it **wins**; see `results/train_results.json`. |
|
|
190
193
|
| A domain prior beats a frequency table | It helps (`−0.006 nats`) but a **unigram table wins 6× more**. |
|
|
191
194
|
| The diffusion tier is neutral on a frozen model | It **degrades** the model by **`+0.81 nats`** (fixed → `+0.0000`, but no upside either). |
|
|
192
195
|
| Training the layer helps | It **hurts** — the training-free identity map is better (`0.800 vs 0.650`). |
|
|
@@ -198,16 +201,18 @@ Read it: [`docs/NEGATIVE-RESULTS.md`](docs/NEGATIVE-RESULTS.md)
|
|
|
198
201
|
## The repository
|
|
199
202
|
|
|
200
203
|
```text
|
|
201
|
-
fluidlayer/ the package (
|
|
204
|
+
fluidlayer/ the package (NumPy core; optional PyTorch adapters)
|
|
202
205
|
graft.py the attachable memory layer
|
|
203
206
|
memory.py the frozen register (20 B per fact, bit-exact)
|
|
204
207
|
torch_graft.py the same layer in PyTorch, for a real LLM
|
|
205
208
|
gpt2_model.py a GPT-2 forward pass in PyTorch (no transformers needed)
|
|
206
209
|
gpt2_tokenizer.py the GPT-2 byte-level BPE, in pure Python
|
|
210
|
+
qwen2_model.py an optional PyTorch Qwen2 forward pass
|
|
207
211
|
sheaf.py topology.py diffusion.py blocks.py autodiff.py ...
|
|
208
212
|
|
|
209
213
|
experiments/ every measurement; each writes a JSON into results/
|
|
210
214
|
e14_real_gpt2.py the graft on a REAL pretrained GPT-2 (124M)
|
|
215
|
+
e15_scale_model.py the graft on Qwen2.5-0.5B
|
|
211
216
|
e13_knn_baseline.py the layer vs. the closest prior art (kNN-LM)
|
|
212
217
|
|
|
213
218
|
tools/ the artifact checker, bundler, checkpoint downloader,
|
|
@@ -216,7 +221,7 @@ fluidlayer/bpe.py the byte-level BPE tokenizer
|
|
|
216
221
|
|
|
217
222
|
tests/ the unit tests (pytest, or run them without it)
|
|
218
223
|
|
|
219
|
-
examples/ quickstart.py, graft_demo.py, gate_demo.py
|
|
224
|
+
examples/ quickstart.py, graft_demo.py, gate_demo.py, appkit/
|
|
220
225
|
|
|
221
226
|
docs/ the design docs, the API, the limits, the theory report
|
|
222
227
|
|
|
@@ -236,28 +241,20 @@ and [limitations](docs/LIMITATION.md).
|
|
|
236
241
|
|
|
237
242
|
---
|
|
238
243
|
|
|
239
|
-
##
|
|
244
|
+
## Real-model experiment status
|
|
240
245
|
|
|
241
|
-
GPT-2
|
|
246
|
+
The E14 GPT-2 experiment script, forward implementation, tokenizer, and
|
|
247
|
+
archived `results/e14_real_gpt2.json` are included. The checkpoint is not;
|
|
248
|
+
rerun E14 to independently reproduce the recorded measurements. See
|
|
249
|
+
[the reproduction guide](docs/REPRODUCING.md) for download and run commands.
|
|
242
250
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
On the real model, the classic kNN-LM interpolation beats the gated override by **8×** on perplexity — the opposite of the 131k-parameter model, where the gate won by **7.4×**.
|
|
252
|
-
The gate wins where the base model is weak; interpolation wins where it is strong.
|
|
253
|
-
The capability works on both.
|
|
254
|
-
|
|
255
|
-
The checkpoint, the forward pass and the tokenizer are all in this repository:
|
|
256
|
-
|
|
257
|
-
- [`fluidlayer/gpt2_model.py`](fluidlayer/gpt2_model.py)
|
|
258
|
-
- [`fluidlayer/gpt2_tokenizer.py`](fluidlayer/gpt2_tokenizer.py)
|
|
259
|
-
|
|
260
|
-
No `transformers` dependency, and the generation is verified coherent.
|
|
251
|
+
E15 adds a from-scratch Qwen2.5-0.5B forward implementation and app-kit
|
|
252
|
+
integration. Its archived run records bit-identical attachment, exact recall
|
|
253
|
+
of a planted fact 1,411 tokens back, and a best gated loss improvement of
|
|
254
|
+
`0.041` nats; the kNN-LM baseline improves loss by `0.274` nats, so this run
|
|
255
|
+
does not show the gate outperforming that baseline. The checkpoint is not
|
|
256
|
+
bundled. Reproduction requires the optional GPU dependencies and local model
|
|
257
|
+
weights; see [E15 instructions](docs/REPRODUCING.md#qwen2-scale-experiment-e15).
|
|
261
258
|
|
|
262
259
|
The Torch twin is now tested against the NumPy reference in [`tests/test_torch_parity.py`](tests/test_torch_parity.py): the two implementations must agree on the router, the store and the gated override.
|
|
263
260
|
|
|
@@ -277,7 +274,9 @@ claim or validate production-scale operation.
|
|
|
277
274
|
|
|
278
275
|
## A research prototype, honestly labelled
|
|
279
276
|
|
|
280
|
-
|
|
277
|
+
The core research experiments use small CPU models and character-level or
|
|
278
|
+
512-token subword corpora. E14 and E15 are separate pretrained-model
|
|
279
|
+
experiments; their checkpoints are not included.
|
|
281
280
|
|
|
282
281
|
The subword repeat is the closest thing to a realistic tokenizer in this repository.
|
|
283
282
|
The GPU run, [`experiments/gpu_graft.py`](experiments/gpu_graft.py), is written and has not been executed here.
|
|
@@ -333,7 +332,7 @@ A research memory layer with an operator-level stability bound, a bounded in-mem
|
|
|
333
332
|
## Origin and acknowledgments
|
|
334
333
|
|
|
335
334
|
The project began with the author's idea of flowing information through a
|
|
336
|
-
topological structure. The
|
|
337
|
-
|
|
338
|
-
decisions are documented alongside
|
|
339
|
-
reproduced.
|
|
335
|
+
topological structure. The author describes it as a school project and
|
|
336
|
+
credits AI assistance for implementation and repository organization. The
|
|
337
|
+
research decisions, measurements, and limitations are documented alongside
|
|
338
|
+
the code so the work can be evaluated and reproduced.
|
|
@@ -85,10 +85,9 @@ suite.
|
|
|
85
85
|
λ₂ does not predict quality (pearson 0.20). The certificate is true
|
|
86
86
|
about the operator; it says nothing about the task. The claim was
|
|
87
87
|
weakened, not the data massaged.
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
which is the honest summary of the entire architecture.
|
|
88
|
+
Archived results record a transformer beating the fluid (2.6331 vs 2.7397
|
|
89
|
+
nats) and a 97.3 % mechanism result. The historical source scripts are not
|
|
90
|
+
included, so see N4 in `docs/NEGATIVE-RESULTS.md` for the reproduction caveat.
|
|
92
91
|
Grafted onto a frozen model, my own diffusion tier made the model
|
|
93
92
|
worse — +0.81 nats (ppl 13.3 -> 29.9) on real English. The cause is
|
|
94
93
|
structural: the persistent state sits outside the autodiff graph, so the
|
|
@@ -6,6 +6,15 @@ uses [Semantic Versioning](https://semver.org/).
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [2.1.0] - 2026-11-03
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Added the optional PyTorch Qwen2 adapter, E15 scale-model experiment,
|
|
14
|
+
archived measurements, and a runnable app-kit example.
|
|
15
|
+
- Categorized the new project-process, app-kit, experiment, and result files
|
|
16
|
+
into `docs/`, `examples/`, `experiments/`, and `results/`.
|
|
17
|
+
|
|
9
18
|
### Changed
|
|
10
19
|
|
|
11
20
|
- Improved the Markdown documentation structure, added a documentation
|
|
@@ -205,7 +205,7 @@ what makes per-user persistent memory economically possible at all.
|
|
|
205
205
|
| ---|---|---|---|---|---|---|---|---|---|
|
|
206
206
|
| exact needle at a position|✅|✅ recent|✅|❌|❌|❌|❌|✅|✅ pinned / L3|
|
|
207
207
|
| exact specific fact|✅|✅ recent|✅|❌|❌|❌|❌|✅|✅ pinned (20 B)|
|
|
208
|
-
| global gist / aggregate|✅|❌|✅|✅|✅|✅|❌|❌|✅ 97.3 %
|
|
208
|
+
| global gist / aggregate|✅|❌|✅|✅|✅|✅|❌|❌|✅ archived 97.3 % result (`results/mechanism.json`)|
|
|
209
209
|
| positional recall ( "3rd paragraph ")|✅|✅|✅|✅|❌|❌|❌|❌|❌|
|
|
210
210
|
| infinite stream / never re-encode|❌|✅|❌|❌|✅|✅|n/a|✅|✅|
|
|
211
211
|
| no "lost in the middle "|❌|❌|❌|❌|~ (no positions)|~|n/a|~|✅ (no positional decay)|
|
|
@@ -266,12 +266,12 @@ the measured semantic/local-geometric policy performed better.
|
|
|
266
266
|
KV bytes/token, KV @ctx, sessions that fit in VRAM, prefill FLOPs, crossover point
|
|
267
267
|
fluid read cost 16 KB = 0.009 µs; fluid compute = 384 flops/token/layer
|
|
268
268
|
our `selftest.py` → 50/50
|
|
269
|
-
mechanism test:
|
|
270
|
-
LM A/B:
|
|
269
|
+
mechanism test: archived result records 97.3 % sign accuracy; original source unavailable
|
|
270
|
+
LM A/B: archived result records transformer 2.6331 vs FluidLayer 2.7397; original training source unavailable
|
|
271
271
|
param-matched FLOPs: 1.10× cheaper @8K → 2.54× @128K
|
|
272
272
|
⚠️ PROJECTED — needs E1/E5 to become fact
|
|
273
273
|
that the 16 KB fluid carries long-range information at usable quality
|
|
274
|
-
that a real LLM actually routes to the fluid (the 97.3 %
|
|
274
|
+
that a real LLM actually routes to the fluid (the archived 97.3 % synthetic-task result does not establish real-model routing)
|
|
275
275
|
that topology picks the right facts to freeze
|
|
276
276
|
that pinned facts survive a real model's distribution shift
|
|
277
277
|
Every table above is a CONDITIONAL: "IF the fluid is usable, THEN this".
|
|
@@ -45,10 +45,9 @@ This is the entire design in one move:
|
|
|
45
45
|
FluidLayer stops being a memory. It becomes an index.
|
|
46
46
|
The memory moves to a write-once register; the fluid answers where, and
|
|
47
47
|
the register answers what.
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
We just gave it an exact value to point at.
|
|
48
|
+
The archived `results/mechanism.json` records a 97.3 % global-aggregation
|
|
49
|
+
result. Its original experiment source is not present, so the historical run
|
|
50
|
+
cannot be independently regenerated (see N4 in `docs/NEGATIVE-RESULTS.md`).
|
|
52
51
|
|
|
53
52
|
## 1. The impossibility, stated precisely
|
|
54
53
|
|
|
@@ -89,7 +88,7 @@ keep.
|
|
|
89
88
|
└──────────────────────────────────────────────────┘
|
|
90
89
|
Slot layout (20 B, as implemented):`key uint64 | val int32 | sig uint32 | anchor uint16 | meta uint16`.
|
|
91
90
|
The read path is three clean steps, each with a guarantee:
|
|
92
|
-
query h ──▶ L2 routes h → anchor a (
|
|
91
|
+
query h ──▶ L2 routes h → anchor a (approximate; archived score in results/mechanism.json)
|
|
93
92
|
anchor a → slot id s (exact: 1 byte)
|
|
94
93
|
L1[s] = (key, token_id) (exact: 4 bytes)
|
|
95
94
|
verify key matches h's context hash (fail-loud)
|
|
@@ -174,12 +173,12 @@ This is a testable prediction, and it is falsifiable.
|
|
|
174
173
|
Which tokens to freeze? The longest bars = the structural landmarks =
|
|
175
174
|
the tokens that carry the document's skeleton. Freeze those and you get
|
|
176
175
|
exact extraction of the load-bearing facts, not random trivia.
|
|
177
|
-
|
|
176
|
+
The theory suggests why diffusion can carry global aggregation: the
|
|
178
177
|
harmonic branch of `L` (its kernel) is the globally dominant H₀ mode —
|
|
179
|
-
and the global mean is the longest bar. The
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
178
|
+
and the global mean is the longest bar. The archived mechanism output records
|
|
179
|
+
a 97.3 % score, beating local aggregators (65.6 % / 71.0 %); its original
|
|
180
|
+
source is unavailable, so the run cannot be independently regenerated. The
|
|
181
|
+
v0.1 theory report and the mechanism experiment now have one
|
|
183
182
|
unified explanation. That is a real, publishable narrative.
|
|
184
183
|
|
|
185
184
|
## 5. Budget: the 3-D trade-off
|
|
@@ -366,8 +365,8 @@ P4 needs one GPU for a few hours.
|
|
|
366
365
|
|
|
367
366
|
Attention remembers by position. We remember by geometry. But geometry alone
|
|
368
367
|
smears: diffusion destroys exactness by construction. So we split the
|
|
369
|
-
memory. A 16 KB sheaf routes
|
|
370
|
-
|
|
368
|
+
memory. A 16 KB sheaf routes to an approximate landmark (the archived
|
|
369
|
+
mechanism result records 97.3 % sign accuracy) — and an append-only frozen register stores the exact token id
|
|
371
370
|
at 14 bytes per fact, 196,234× cheaper than a KV cache. Topology decides
|
|
372
371
|
which landmarks get exact storage, using the document's own persistence
|
|
373
372
|
diagram, at zero per-token cost. The model can promote a fact or recall one
|
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
> **Historical design note:** this is not a current implementation contract.
|
|
4
4
|
> For current behavior and limitations, see [the API reference](API.md) and
|
|
5
5
|
> [limitations](LIMITATION.md).
|
|
6
|
+
> Archived LM-comparison and mechanism-test JSON outputs are included under
|
|
7
|
+
> `results/`, but their original experiment source files are unavailable.
|
|
8
|
+
> Treat the numbers as historical snapshots, not independently rerunnable
|
|
9
|
+
> measurements.
|
|
6
10
|
|
|
7
11
|
A topological fluid architecture for sequence models: replace the
|
|
8
12
|
transformer's quadratic attention with a cellular-sheaf diffusion whose
|
|
@@ -345,8 +349,8 @@ fluidlayer/
|
|
|
345
349
|
losses.py CE (+ tensor variant), sheaf energy, band decorrelation
|
|
346
350
|
optim.py Adam (decoupled WD, clipping, cosine schedule)
|
|
347
351
|
data.py Gutenberg corpus + char tokenizer + synthetic fallback
|
|
348
|
-
selftest.py
|
|
349
|
-
train.py LM A/B + global-aggregation demo
|
|
352
|
+
selftest.py historical numerical checks
|
|
353
|
+
train.py historical LM A/B + global-aggregation demo (source unavailable; see archived results/)
|
|
350
354
|
|
|
351
355
|
### Run it
|
|
352
356
|
|
|
@@ -106,6 +106,23 @@ integration must handle the model's positional embeddings, attention masks,
|
|
|
106
106
|
device placement, session boundaries, and task-specific gain calibration.
|
|
107
107
|
Call `branch.reset()` when starting a new independent session.
|
|
108
108
|
|
|
109
|
+
## Run the GPT-2/Qwen2 app kit
|
|
110
|
+
|
|
111
|
+
The repository includes a standalone app kit that loads a local GPT-2 or
|
|
112
|
+
Qwen2 checkpoint and demonstrates attachment and recall:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
python -m pip install "fluidlayer[gpu]"
|
|
116
|
+
hf download Qwen/Qwen2.5-0.5B --local-dir models/qwen05b
|
|
117
|
+
python examples/appkit/attach_layer.py --model models/qwen05b
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
The Qwen2 forward implementation is in the published `fluidlayer` package;
|
|
121
|
+
the Qwen tokenizer is provided by the optional Transformers dependency.
|
|
122
|
+
Model weights are not bundled. This app kit is a research example, not a
|
|
123
|
+
production serving wrapper. See [the E15 result](../results/e15_scale_model.json)
|
|
124
|
+
and [reproduction guide](REPRODUCING.md#qwen2-scale-experiment-e15).
|
|
125
|
+
|
|
109
126
|
## Memory behavior and safety
|
|
110
127
|
|
|
111
128
|
The attachable store is bounded. Its reported 20-byte slot cost is a logical
|
|
@@ -516,56 +516,21 @@ size is decisive, and the honest reading is sharper than "we beat kNN-LM":
|
|
|
516
516
|
|
|
517
517
|
---
|
|
518
518
|
|
|
519
|
-
## ON A REAL PRETRAINED LLM (E14) —
|
|
519
|
+
## ON A REAL PRETRAINED LLM (E14) — archived result
|
|
520
520
|
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
(`fluidlayer/gpt2_model.py`, verified by generation).
|
|
521
|
+
The E14 script, GPT-2 forward implementation, tokenizer, and archived
|
|
522
|
+
`results/e14_real_gpt2.json` are present. The checkpoint must be downloaded
|
|
523
|
+
separately, so rerun E14 to reproduce the recorded measurements; see N11 in
|
|
524
|
+
[`NEGATIVE-RESULTS.md`](NEGATIVE-RESULTS.md).
|
|
526
525
|
|
|
527
|
-
|
|
526
|
+
To reproduce the run, install the optional dependencies, download GPT-2,
|
|
527
|
+
then run the experiment on the committed corpus:
|
|
528
528
|
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
### And the kNN-LM baseline, on the real model
|
|
536
|
-
|
|
537
|
-
| | val loss | ppl | Δ | token accuracy |
|
|
538
|
-
|---|---|---|---|---|
|
|
539
|
-
| the base GPT-2 | 4.0289 | 56.20 | – | 0.3073 |
|
|
540
|
-
| **kNN-LM, λ=0.9** | **3.8030** | **44.84** | **−0.2259** | 0.3029 |
|
|
541
|
-
| kNN-LM, λ=0.95 | 3.8052 | 44.94 | −0.2237 | 0.3091 |
|
|
542
|
-
| the layer (gated), gain 0.5 | 4.0019 | 54.70 | −0.0271 | 0.3104 |
|
|
543
|
-
| the layer (gated), gain 2 | 4.1965 | 66.46 | +0.1676 | 0.2982 |
|
|
544
|
-
|
|
545
|
-
> **The result that changes the claim.** On the *tiny* model the gate beat
|
|
546
|
-
> the kNN-LM interpolation by **7.4×**. On the **real** model the
|
|
547
|
-
> interpolation wins by **8×**. The reason is structural, not a bug: the
|
|
548
|
-
> interpolation is **bounded** — it can only shift probability mass by
|
|
549
|
-
> (1−λ), so a wrong retrieval can never take over — whereas the gate
|
|
550
|
-
> *can* take over, and on a strong model the base's own guess is usually
|
|
551
|
-
> better than the datastore's answer.
|
|
552
|
-
>
|
|
553
|
-
> **The gate wins where the base model is weak; the interpolation wins
|
|
554
|
-
> where the base model is strong.** The capability (E14c) works on both.
|
|
555
|
-
|
|
556
|
-
### One thing that had to be fixed to make it work on a real model
|
|
557
|
-
|
|
558
|
-
The gate was first formulated in probability space, `u = 1 − max p`. On
|
|
559
|
-
GPT-2 that needed a gain of 50+ and it wrecked the perplexity: GPT-2's
|
|
560
|
-
logits span ±20, while the tiny model's span ±2, so the same "gain" meant
|
|
561
|
-
something completely different. **The gate is now in logit space**,
|
|
562
|
-
`u = −log p_max` (how many nats the model is from being sure), which is
|
|
563
|
-
**scale-free**: the same gain works on both models.
|
|
564
|
-
|
|
565
|
-
→ `experiments/e14_real_gpt2.py`, `results/e14_real_gpt2.json`
|
|
566
|
-
(measured with torch 2.4.1+cpu; `python tools/download_gpt2.py --out models/gpt2`
|
|
567
|
-
fetches the checkpoint, and the forward pass + tokenizer are in this
|
|
568
|
-
repository — no `transformers` needed)
|
|
529
|
+
```bash
|
|
530
|
+
python -m pip install -e ".[gpu]"
|
|
531
|
+
python tools/download_gpt2.py --out models/gpt2
|
|
532
|
+
python experiments/e14_real_gpt2.py --corpus corpus.txt
|
|
533
|
+
```
|
|
569
534
|
|
|
570
535
|
---
|
|
571
536
|
|
|
@@ -157,26 +157,19 @@ is the contribution under a hard memory budget** — which is a narrower
|
|
|
157
157
|
claim than the project started with, and a defensible one.
|
|
158
158
|
→ `experiments/e13_knn_baseline.py`, `results/e13_knn.json`
|
|
159
159
|
|
|
160
|
-
## 16. A pretrained LLM
|
|
160
|
+
## 16. A pretrained LLM — unverified
|
|
161
161
|
|
|
162
|
-
The
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
pass and the tokenizer are all in this repository — no `transformers`
|
|
167
|
-
dependency, and the generation is verified coherent.
|
|
168
|
-
|
|
169
|
-
The honest caveat it forced: **the gate's advantage over the kNN-LM
|
|
170
|
-
interpolation reverses on a strong model** (the tiny model: the gate won by
|
|
171
|
-
7.4×; GPT-2: the interpolation wins by 8×). The gate wins where the base
|
|
172
|
-
model is weak. The capability works on both.
|
|
173
|
-
→ `experiments/e14_real_gpt2.py`, `results/e14_real_gpt2.json`
|
|
162
|
+
The E14 script, GPT-2 forward/tokenizer implementation, and archived
|
|
163
|
+
`results/e14_real_gpt2.json` are present. The checkpoint is not; rerun E14
|
|
164
|
+
to independently reproduce the recorded measurements.
|
|
165
|
+
→ `experiments/e14_real_gpt2.py`; see [reproduction instructions](REPRODUCING.md)
|
|
174
166
|
|
|
175
167
|
## 17. A repository a stranger can run in one minute
|
|
176
168
|
|
|
177
|
-
|
|
178
|
-
imports from an installed wheel.
|
|
179
|
-
|
|
169
|
+
Fresh clone → `python selftest.py` → **50/50**. `pip install .` → the public API
|
|
170
|
+
imports from an installed wheel. Reproducible experiments can be rerun with
|
|
171
|
+
`python experiments/run_all.py --full`; archived N4 results are preserved,
|
|
172
|
+
though their historical source script is unavailable.
|
|
180
173
|
→ `scripts/check_artifacts.sh` (the one-command audit)
|
|
181
174
|
|
|
182
175
|
## 18. The credibility milestone
|