titans-unofficial
An unofficial PyTorch implementation of
Titans: Learning to Memorize at Test Time
(Behrouz, Zhong and Mirrokni).
Titans pairs attention, which acts as short-term memory, with a small neural network that serves as long-term memory. That network keeps learning while the model reads: it is updated by gradient descent on each token, with momentum and a forgetting term, at inference time as well as during training.
pip install titans-unofficial
import torch
from titans import TitansMAC
model = TitansMAC(d_model=128, n_layers=2, n_heads=4)
x = torch.randn(2, 300, 128) # (batch, sequence, d_model)
y = model(x) # same shape; the memory learns as it reads
The models work on embeddings, not token IDs, so they slot in where a transformer encoder stack would go. Add your own embedding layer and output head; the examples show how.
Variants
The paper describes three ways to connect the memory to attention. All three
share the same constructor arguments and the same forward(x, is_training=True).
| Class | Paper | How the memory is used |
|---|---|---|
TitansMAC |
§4.1 | Memory as context: what the memory recalls is prepended to each chunk |
TitansMAG |
§4.2 | Memory as gate: a learned gate mixes sliding-window attention with memory |
TitansMAL |
§4.3 | Memory as layer: every block runs attention, then memory, then the MLP |
from titans import TitansMAC, TitansMAG, TitansMAL
mac = TitansMAC(d_model=128, n_layers=2, n_heads=4, chunk_size=128)
mag = TitansMAG(d_model=128, n_layers=2, n_heads=4, window_size=128)
mal = TitansMAL(d_model=128, n_layers=2, n_heads=4, window_size=128)
| Argument | Default | Meaning |
|---|---|---|
d_model |
Width of the input and output embeddings | |
n_layers |
Number of attention blocks | |
n_heads |
Attention heads; must divide d_model |
|
memory_depth |
2 | Layers in the memory network |
persistent_tokens |
16 | Learned, input-independent tokens prepended to input |
window_size |
128 | Attention window (MAG, MAL); off by default in MAC |
chunk_size |
128 | Tokens per chunk (MAC only) |
dropout |
0.1 | Dropout rate |
Working with the memory
The memory is state that lives on the model and changes during forward.
y = model(x) # reads from memory and writes to it
y = model(x, is_training=False) # reads only; the memory stays as it is
model.reset_memory() # forget everything, e.g. between documents
model.to_device("cuda") # move the model together with its memory
is_training controls the memory only and is independent of model.train() and
model.eval(), which still switch dropout as usual. Leave it on at inference
time if you want the test-time learning the paper is about.
Differences from the paper
This is an alpha-stage reimplementation, and it departs from the paper in ways that matter if you plan to reproduce its results:
- One memory is shared by the whole batch and persists across
forwardcalls, so outputs depend on batch composition and call order. Use a batch size of 1 and callreset_memory()between sequences for clean behaviour. reset_memory()draws new random memory weights; it does not return to a learned starting point, so results after a reset are not reproducible without fixing the random seed.- The memory's key and value projections and its learning-rate, momentum and forgetting gates are not trained; they keep their initial values.
- In MAG and MAL, persistent tokens drop out of the attention window for
positions beyond
window_size. - MAC queries the memory with the average of a chunk, giving one recalled token per chunk.
These are tracked in the roadmap.
Examples
The example scripts are not part of the installed package. Run them from a clone:
git clone https://github.com/itsmesherry/titans-unofficial.git
cd titans-unofficial
pip install -e ".[examples]"
cd examples
python simple_example.py
| Script | What it shows |
|---|---|
simple_example.py |
A forward pass through each variant |
language_modeling.py |
A language model with token embeddings and text generation |
text_classification.py |
A classifier head, with a training and evaluation loop |
fine_tuning.py |
A longer training loop with evaluation and sample generation |
Citation
This repository is not affiliated with the authors. If you use it, cite the paper:
@article{behrouz2024titans,
title={Titans: Learning to Memorize at Test Time},
author={Behrouz, Ali and Zhong, Peilin and Mirrokni, Vahab},
journal={arXiv preprint arXiv:2501.00663},
year={2024}
}
Project
Metadata
Release files for titans-unofficial 1.1.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| titans_unofficial-1.1.4.tar.gz | 28.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| titans_unofficial-1.1.4-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 47.2 kB
Release files / titans_unofficial-1.1.4.tar.gz
| Download URL | titans_unofficial-1.1.4.tar.gz |
|---|---|
| Size | 28.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1bafe106030e78f5cf10f11f6e2f9ae5e64fc713d1bc52c66c31d50a50481b67
|
|
BLAKE2b-256 checksum How to use checksums |
ffa967a966695a6dcad53839b20b6b9c232088e05a3e33734b76977e7dbf5863
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.
Transparency logRelease files / titans_unofficial-1.1.4-py3-none-any.whl
| Download URL | titans_unofficial-1.1.4-py3-none-any.whl |
|---|---|
| Size | 18.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
16f6557a08ff2c28f5a50d1434773398adf2c62a28fce6ce00d336332efff70b
|
|
BLAKE2b-256 checksum How to use checksums |
fd2d62ebe7eaabbb5da1256907263068372c934ced94c1e0595edac248c16cc1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.
Transparency log