--- 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.