Delta N-gram: Forward-Only Continual Writing into a Language Model's Native N-gram Memory
Organizations: Illinois Institute of Technology
Abstract
Our previous analysis found that a model's native hashed N-gram table is where continual updates disturb the base least, but its writes needed backpropagation and changed the pretrained table. We present Delta N-gram, a forward-only write path into that table. The pretrained table T^0 is never modified. Evidence is written into a sparse patch Δon the rows it addresses: a 4.1M-parameter writer emits a target and a gate per (position, hash head) event, and a block-averaged delta rule keeps each row a convex combination of its old value and the gated targets. The writer is trained offline on raw text with the pretraining objective; at use time writing takes forward passes only, and clearing Δrestores the original model. A 0.6B prototype trained to answer questions keeps 16/16 facts after a second write; online gradient writes keep 2--4/16. We study two writers: a plain writer that encodes evidence with the T^0-only model, and a delta writer that reads its current memory while encoding. On Qwen3.8-Flash-Next, the plain writer's memory is document-specific: on 64 held-out news events it lowers continuation NLL by 0.068 nats/token against empty memory and by 0.024 against another document's memory, and 0.063 and 0.013 after 16 intervening articles. The delta writer's memory is more document-specific and keeps more of it under distraction (70% vs 54%). Over 35,000 writes on our previous seven-task chain both writers stay stable and the delta writer drifts less (layer-2 math drift 176% vs 188%); later accuracy changes by -0.26/-0.52pp (-7.29pp for gradient updates) and small-k_i drift is 17.9/17.5% (39.2%). Acquisition is negative, and general-input drift reaches 32.8% (20.75%): format rows read by every example grow to 4--12 times their pretrained norm. Zeroing eight such rows removes over 98% of layer-2 drift on math inputs, together with their NLL gain.
Figures & tables
| In-context writes (linear attn., GDN, KDA) | Online LoRA | Gradient table edits [ 31 ] | Persistent memory block (MemT) | Delta N-gram | |
|---|---|---|---|---|---|
| Written state | sequence state | low-rank backbone increment | native N-gram table | added memory block (dense GDN-2 state) | sparse patch on the native N-gram table |
| Write signal | forward projection | backprop | backprop (Adam) | forward (GDN-2 update) | forward writer + D1 |
| Lifetime | cleared at sequence end | permanent | permanent | permanent | permanent (optional decay) |
| Pretrained parameters | unchanged | frozen; adapter separate | table overwritten | unchanged; module added | unchanged; fixed |
| Use-time cost | near zero | full backward per write; optimizer state per user | same | forward | one -only forward + 4M-param writer |
| Undo / per user | n/a | yes (adapter per user) | needs a copy of the table | yes (state per user) | clear ; sparse rows per user |
| Method | First | Retained | New |
|---|---|---|---|
| Forward writer + D1 | 16 | 16 | 15 |
| Online gradient writes (SparseAdam, lr 0.01) | 16 | 2 | 16 |
| Online gradient writes (SparseAdam, lr 0.05) | 16 | 4 | 16 |
| Full evidence in context | 16 | 16 | 14 |
| BM25 retrieval, top 2 | 16 | 16 | 14 |
| Distractors | self NLL | ||
|---|---|---|---|
| 0 | 0.0682 [0.0584, 0.0781] | 0.0244 [0.0166, 0.0326] | 1.7728 |
| 1 | 0.0658 [0.0562, 0.0754] | 0.0187 [0.0124, 0.0256] | 1.7751 |
| 4 | 0.0648 [0.0545, 0.0754] | 0.0167 [0.0113, 0.0226] | 1.7761 |
| 8 | 0.0659 [0.0561, 0.0761] | 0.0170 [0.0119, 0.0225] | 1.7750 |
| 16 | 0.0633 [0.0524, 0.0746] | 0.0133 [0.0077, 0.0194] | 1.7777 |
| Weights | Encoding | |||||
|---|---|---|---|---|---|---|
| main | -only | .0668 / .0234 | .0654 / .0179 | .0635 / .0168 | .0655 / .0163 | .0626 / .0127 |
| main | memory-aware | .0626 / .0270 | .0627 / .0206 | .0648 / .0172 | .0613 / .0152 | .0647 / .0122 |
| delta | -only | .0560 / .0315 | .0555 / .0296 | .0550 / .0271 | .0516 / .0249 | .0538 / .0219 |
| delta | memory-aware | .0517 / .0320 | .0522 / .0290 | .0520 / .0252 | .0492 / .0232 | .0538 / .0217 |
| Task | Plain writer | Delta writer | [ 31 ] N-gram |
| SME | 10 7 6 | 10 7 7 | 13 |
| NAV | 6 5 5 | 6 6 6 | 6 |
| HYE | 33 28 29 | 32 32 32 | 61 |
| AFB | 5 2 2 | 6 2 2 | 42 |
| SQI | 24 27 25 | 27 27 26 | 50 |
| MKD | 29 27 28 | 26 27 26 | 54 |
| Task | Head input | Layer 48 | Layer 9 | [ 31 ] N-gram |
|---|---|---|---|---|
| SME | 23.3% | 42.8% | 290% | 40.4% |
| NAV | 21.3% | 32.7% | 211% | 62.0% |
| HYE | 12.4% | 21.1% | 52% | 32.6% |
| AFB | 11.2% | 21.3% | 55% | 37.3% |
| SQI | 19.9% | 31.7% | 180% | 36.8% |
| MKD | 19.2% | 33.6% | 265% | 26.0% |
| Plain writer | Delta writer | |
| Math big , layer 2 | 188.0% | 175.7% |
| Math big , layer 2, after task 4 | 153.0% | 94.8% |
| Math big , layer 9 | 135.0% | 125.7% |
| Math big , layer 48 | 51.2% | 49.3% |
| Head big , math / code | 41.8% / 23.8% | 40.2% / 22.5% |
| Small at the head, mean of six tasks | 17.9% | 17.5% |
| Condition | F1 | Answer NLL |
|---|---|---|
| self (own dialogue in memory) | 0.44 | 4.034 |
| empty | 0.44 | 4.018 |
| donor (other dialogue in memory) | 0.44 | 4.049 |
| full context | 56.79 [55.33, 58.34] | — |
| self empty | 0 | [ , ] |
| self donor | 0 | [ , ] |
| State | Layer 2 | Layer 9 | Head input | Math NLL |
|---|---|---|---|---|
| Plain, task 1 | 197.7% 2.5% | 143.9% 3.9% | 42.5% 12.8% | 0.841 0.901 |
| Plain, task 7 | 188.0% 2.9% | 135.0% 5.1% | 41.8% 18.8% | 0.846 0.902 |
| Delta, task 1 | 182.3% 2.9% | 131.7% 4.6% | 40.6% 12.7% | 0.849 0.902 |
| Delta, task 7 | 175.7% 3.3% | 125.7% 5.7% | 40.2% 27.1% | 0.855 0.901 |
Persistent Memory for Language Models
Persistent memory for language models studies how models retain, update, and use information across interactions and beyond their context windows.
See all 272 papers