Transformers.js
web-ttt
test-time-training
in-browser
webgpu
associative-memory
minilm
transformers-js
Instructions to use LJTSG/web-ttt with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers.js
How to use LJTSG/web-ttt with Transformers.js:
// β οΈ Unknown pipeline tag
| 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. | |