File size: 3,271 Bytes
78bc0e4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
---
license: mit
tags:
- web-ttt
- test-time-training
- in-browser
- webgpu
- associative-memory
- minilm
- transformers-js
library_name: transformers.js
---

# web-TTT — a browser-native, test-time-TRAINABLE memory

A tiny method + toolkit for an associative memory that **learns from use, entirely in the browser** — no server, no API, no backend. To our knowledge, the first published browser-trainable **TTT (test-time training)** memory.

It is the memory layer behind a fully in-browser AI companion, extracted here as a clean, reusable method you can drop onto **any** corpus (it does **not** contain anyone's private data — just the process + a generic demo).

## The idea

- **Embed** each fact with `Xenova/all-MiniLM-L6-v2` (via [transformers.js](https://github.com/huggingface/transformers.js)) → a 384-d vector.
- **Recall** a query as `score(fact) = cosine( normalize(W · embed(query)) , fact_vec )`, top-K — where **W** is a learnable 384×384 projection matrix (identity at first).
- **Train at test time:** clicking a result runs ~25 steps of cross-entropy gradient descent on **W**, pulling that query toward that fact. The matrix learns which queries should surface which memories — **on the user's device, in the browser.** `W` persists in `localStorage`, so the memory keeps what you taught it across sessions.

That's the whole thing: a frozen embedder + a small matrix you train by example, live, client-side. It runs on WebGPU/WASM and needs nothing but a browser.

## Files

- `web-ttt.js` — the toolkit (ES module). `WebTTT` class: `init()`, `load(corpus)`, `recall(query, k)`, `teach(query, targetIndex)`, `exportW()/importW()/resetW()`.
- `demo/index.html` + `demo/facts.json` — a working demo on a generic corpus.

## Quick start

```js
import { WebTTT } from "./web-ttt.js";

const ttt = new WebTTT({ storageKey: "my_ttt" });
await ttt.init();                                   // loads MiniLM (CDN by default)
await ttt.load([
  { key: "the sun", text: "The Sun is the star at the center of the Solar System." },
  { key: "the moon", text: "The Moon is Earth's only natural satellite." },
]);

const hits = await ttt.recall("what's at the center of the solar system?", 3);
// → [{ key: "the sun", score: 0.6x, index: 0, ... }, ...]

await ttt.teach("center of the solar system", 0);   // reinforce: 25-step W update, persists
```

Run the demo: serve the folder over `http://localhost` (WebGPU/transformers.js need a real origin, not `file://`) and open `demo/index.html` in Chrome/Edge/Brave.

### Fully offline

Pass local asset paths to `init()`:

```js
await ttt.init({
  transformersUrl: "./vendor/transformers/transformers.min.js",
  localModelPath: "./models/",          // contains Xenova/all-MiniLM-L6-v2
  wasmPaths: "./vendor/transformers/",  // ort-wasm*.wasm
});
```

## Format / publishing your own TTT

A "trained TTT" is just: your corpus (`[{key, text}]`), optionally the precomputed 384-d `vec` per fact, and the learned `W` (384×384, from `exportW()`). Ship those three and any browser can load and keep training it. That's the publishable artifact — **the method, on your data, your choice.**

## License

MIT. The embedder (`Xenova/all-MiniLM-L6-v2`) and transformers.js carry their own licenses.