Antivision · Latent Rehearsal
14

Consulted
memory

Chapter 11 measured that a memory vector persists, but dilutes: the whole past is worth less than each half. LeCun asks for something else — a memory that is consulted, and survives the window and the session. Here it becomes a bank of abstract states read by attention, with a quantized vector index (turbovec) keeping the bank on disk.

Chapter 14 Prerequisite: 11 (the summed memory) and 13 (memory-dropout)

1 What the summed memory does not do

The memory of chapter 11 is one vector m per sequence, updated at every block that leaves the window: m ← m + f([m ; sblock]). It persists — prediction with the memory of the right text gains +0.019 over the memory of another text, even a whole window later. But the same table showed the limit: "long" (A+B) errs 0.181, worse than "recent" (B only, 0.173) and than "old only" (A only, 0.174). A vector of fixed capacity does not accumulate: each new block overwrites part of the previous one. The more past, the less of each piece.

LeCun describes another piece. The talk: "you may have to combine this with the content of a memory to get a complete idea of the state of the world". The interview: systems with "persistent memory, of the type that we have". And the architecture slide has the memory as a module consulted by the world model, not as a running sum. Chapter 11 left this written as an open question: "the consulted memory, not just summed, requires attention over a bank of abstract states, and is another piece". This is the piece.

2 The piece: bank + attention

Every block of 8 tokens that leaves the window is abstracted by the same level-2 encoder (abstrair()) and stored, not summed. The bank is the set S = {s1, …, sn} of those states. The world model consults the bank with a key projected from the current state, and reads the result by attention:

q = Wq zt / √d   rt = softmax(q · ST) S   Pred(zt, at[, ζ][, m], rt) → zt+1

Three decisions, all inherited from what was already measured. The encoder receives no gradient through the bank (only Wq and the world model learn to consult it; the same rule as the summed memory, for the same reason: otherwise the encoder hides the target in the bank). Training uses the double windows of chapter 11: the training bank is the blocks of the contiguous past, and the attention is exact over them (at most 32 states). And a bank-dropout of 0.5 is built in — the lesson of chapter 13: half the batches with r = 0, so the predictor works when the bank is empty, which is the case for every short prompt.

The measure is chapter 11's, transposed: bank_gain = MSE(bank of another text) − MSE(right bank), with the MSE of the empty bank alongside. Zero means the attention finds nothing useful in the past.

3 Why a vector index, and why turbovec

In training the bank fits in one matrix multiplication. On the bench it does not: the bank grows with every block generated or read, session after session, and the interview's promise is that it is not erased. One million blocks (eight million tokens read) are 256 million floats — a gigabyte in fp32, and an exact attention over a million states at every token. What the attention actually needs are the k largest logits q · sj; the rest of the softmax is negligible. And "the k largest inner products with a query" is exactly what a vector index returns.

turbovec is a Rust index with Python bindings implementing TurboQuant (Google Research, 2025): each vector is normalized, goes through a fixed random rotation (which makes every coordinate approximately Beta-distributed, with the same distribution in all dimensions), is quantized per coordinate with a 4-bit Lloyd-Max codebook (16 levels) and bit-packed — 256 dimensions become 128 bytes, eight times less than fp32 — and one scalar per vector corrects the bias of the estimated inner product. Search runs in SIMD over the codes, with no training step and no parameter tuning: the bank ingests online, one block at a time, which is the bench's regime. Saving is incremental (sync writes only what changed since the last time), which makes persistence cost milliseconds per generation. What it does not return are the vectors — only ids and scores — so the fp32 states live in a file alongside, and the attention is done over the k actually retrieved.

What the index changes, for the bank of 256-dimensional states of this round. Exact search is what the attention would do without an index.
exact search (numpy)turbovec, 4 bits
bytes per state in the index1,024128
one million blocks1.0 GB128 MB (+ 1.0 GB of states on disk, only the k read)
cost per queryproduct with the whole bankSIMD search over codes; top-k
index training step—none (fixed rotation + precomputed codebook)
persistencerewrite everythingincremental, durable at any byte
the attention usesall statesthe k retrieved, in fp32

The simplest alternative would be to keep everything in RAM and search exactly; it stays available as a fallback (same API, without turbovec installed) and is the reference for measuring what quantization costs in recall — the question section 5 leaves open.

4 The round

Round wm1n2bco-sz1, on the same budget as the others: hierarchy with the raw mean (the honest abstraction of chapter 11), SigReg-z, bank with dropout 0.5, without the summed memory (to measure the piece alone). Three questions: does the bank carry the past (gain > 0)? is the whole past worth more than each half (what the vector could not do)? and does the rudder govern on this map, with the bank empty — which is the condition of chapter 12?

Persistence, model/memory.py: 32 sequences of 3 × 256 tokens, prediction in the third window, the bank built from A, B or A+B. Alongside, the summed memory (round wm1n2mem-sz1, chapter 11) for comparison.
Source of the pastsummed memory (mem)consulted bank (bco)gain vs other (bco)
zero / empty0.2200.1748+0.0023
other (A+B from another text)0.1930.17710
recent (B only)0.1730.1736+0.0035
long (A+B)0.1810.1736+0.0036
old only (A only)0.1740.1738+0.0033
The cost, the gain and the rudder (report.py, modes.py γ = 0.1, "futebol10" head + real state, judge reg1-lat1o).
Roundvalidationcostmap gainmemory / bank gainfreehead + real stategoverns?
wm1n2mem-sz1 (summed)5.6801+7.77%+0.93+0.0140.3430.258no
wm1n2mem-sz1-md0.5 (summed + dropout)5.6109+6.46%+0.92+0.0020.2240.301yes
wm1n2bco-sz1 (consulted)5.7695+9.73%+0.87+0.00360.3600.272no

The bank solves the dilution that was the summed memory's defect. In chapter 11, "long" (A+B) erred 0.181, worse than "recent" (B only, 0.173): the more past, the less of each piece, because a fixed-capacity vector overwrites itself. In the consulted bank, "long" errs 0.1736 — exactly equal to "recent", and slightly better than "old only" (0.1738). Storing instead of summing removes dilution by construction: the old block is still there, intact, and attention picks. It is what the slide's architecture predicted and the summation did not deliver.

And the bank carries little. Its gain over another text's memory is +0.0036, against chapter 11's +0.014 for the summed memory and +0.002 for the summed one with dropout. The cause is the same as in both earlier cases, and it is in the recipe: bank-dropout of 0.5 teaches the predictor to work without a bank, and it learns not to depend on one. The difference is that here the dropout was mandatory — every short prompt starts with an empty bank — so the trade-off is not a calibration error but the shape of the problem. The round with lower dropout is the missing test.

The rudder does not govern on this map (0.272 with head and real state against 0.360 free), and the cost to the generator is the family's highest, +9.73%. Summing up: consulted memory delivers what it promised on persistence — it does not dilute — and delivers nothing else. Under chapter 13 §12.3's noise ruler, +9.73% is indistinguishable from the same map's +9.55% without a bank: the bank is free and carries almost nothing. It stays on the bench as infrastructure, with the quantised on-disk index ready for a large bank, and the dropout question open.

How to read

The bank passes if "long" beats "recent" and "old only" — the attention chooses within the whole past instead of diluting it — and if "empty" stays neutral (the dropout did its job). If the bank's gain is zero, the attention found no structure in the past 256 tokens away; the next ruler is the same experiment with a longer past (the bench already builds one). If the cost to the generator is higher than the summed memory's, the attention is charging; what is compared then is gain per point of cost.

5 On the bench

Open questions