Skip to main content

One-shot attractor memory for LLMs — vector-search accuracy at 98% fewer tokens.

Project description

slate-memory

One-shot attractor memory for LLMs. Vector-search accuracy at 98% fewer tokens.

The number

Setup Accuracy Cost per 1k queries Latency
haiku + slate 100% $0.10 0.6s
opus + full context 100% $64.04 1.7s
opus bare 0% $0.19 1.2s
haiku bare 0% $0.04 0.7s

A cheap model with slate-memory ties the most expensive model with the entire corpus in context — at 1/640th the cost. Both models score 0% without memory (facts are synthetic, unknowable parametrically). Benchmark: N=25 questions, K=600 stored facts, hermetic SDK calls. Full methodology and reproduction scripts in slate-bench.

How it works

Slate-memory is a modern Hopfield network (Ramsauer et al. 2020) — the same math as transformer attention, but used as a memory instead of a layer. Embeddings are sign-projected onto 10,000 bipolar cells (SimHash) and stored one-shot. On recall, the query settles into the nearest stored attractor via softmax-weighted feedback. Two cycles. No training. No index. No database.

The attractor dynamics error-correct: noisy, partial, or corrupted queries converge to the exact stored pattern. Verified at 20,000 stored patterns with 25% corruption.

Install

pip install slate-memory

For the built-in embedder convenience wrapper:

pip install slate-memory[embed]

Quick start

from slate_memory import SlateBank
import numpy as np

# Your embeddings (384-dim for MiniLM, 1536 for OpenAI, etc.)
bank = SlateBank(dim=384)

# Commit facts one-shot
bank.commit(embed("The capital of France is Paris"), {"text": "Paris is the capital of France", "id": "fact-1"})
bank.commit(embed("Python was created by Guido van Rossum"), {"text": "Guido created Python", "id": "fact-2"})

# Recall — even from a noisy or partial query
winner, ranked, confidence, cycles = bank.recall(embed("What's the capital of France?"))
print(winner)  # {"text": "Paris is the capital of France", "id": "fact-1"}
print(f"Confidence: {confidence:.3f}, settled in {cycles} cycles")

With sentence-transformers

from slate_memory import SlateBank
from sentence_transformers import SentenceTransformer

model = SentenceTransformer("all-MiniLM-L6-v2")
bank = SlateBank(dim=384)

# Commit
texts = ["The Earth orbits the Sun", "Water boils at 100°C", "Light travels at 299,792 km/s"]
for text in texts:
    bank.commit(model.encode(text), {"text": text})

# Recall
query = model.encode("what temperature does water boil")
winner, ranked, confidence, cycles = bank.recall(query)
print(winner["text"])  # "Water boils at 100°C"

With OpenAI embeddings

from slate_memory import SlateBank
from openai import OpenAI

client = OpenAI()
bank = SlateBank(dim=1536)  # text-embedding-3-small

def embed(text):
    return client.embeddings.create(input=text, model="text-embedding-3-small").data[0].embedding

bank.commit(embed("Revenue was $4.2M in Q3"), {"text": "Q3 revenue: $4.2M"})
winner, _, conf, _ = bank.recall(embed("how much revenue in Q3"))

Persistence

# Save
bank.save("./my_memory")

# Load
bank2 = SlateBank(dim=384)
n = bank2.load("./my_memory")
print(f"Loaded {n} patterns")

The entire memory is two files: patterns.npy (the attractor states) and meta.json (your metadata). No server. No database. Copy them anywhere.

Trust signals

confidence measures how deeply recall settled — not whether the winner is right. Settling reaches the bottom of some attractor at ~1.0 whether or not it's the right one (correct-vs-wrong AUC 0.10 in the limits battery). For trust decisions, ask for signals:

winner, ranked, conf, cycles, sig = bank.recall(query, with_signals=True)
if sig["margin"] < 0.02:
    # thin margin: the winner is a guess, not a memory
    answer_i_dont_know()
  • margin — gap between the best and second-best overlap, computed before settling. The calibrated retrieval-quality signal (AUC 0.88): wide margin means a confident memory, thin margin means a guess.
  • familiarity — the best overlap itself. Low values flag out-of-domain queries (AUC 1.00); it does not reliably detect a plausible-but-absent fact (AUC ~0.62) — that's what margin is for.

Both come from work already done during recall — no extra cost.

API

SlateBank(dim, n_cells=10000, beta=60.0, distinctiveness=True, dedup_threshold=0.95, seed=7)

  • dim: Embedding dimensionality (must match your embedder)
  • n_cells: Bipolar cells in the attractor state. 10,000 is verified for up to 20k patterns
  • beta: Winner-take-all sharpness. 60.0 is benchmarked; don't change without reason
  • distinctiveness: Down-weight cells where all patterns agree. Essential for images; neutral for text
  • dedup_threshold: Refuse commits with overlap above this. 0.95 prevents near-duplicates
  • seed: RNG seed for the projection matrix. Same seed = same projections = portable patterns

bank.commit(embedding, meta) → (bool, str)

One-shot storage. Returns (True, "committed") or (False, "duplicate (...)").

bank.recall(embedding, top_k=3, max_cycles=5, with_scores=False, with_signals=False) → (winner, ranked, confidence, cycles[, signals])

Full attractor settle. Returns the winner's metadata, top-k ranked results, confidence score, and settle cycles. with_scores=True makes ranked a list of (meta, score) pairs (pre-settle overlaps). with_signals=True appends a fifth element {"familiarity", "margin"} — see Trust signals.

bank.remove(predicate) → int

Remove every pattern whose meta matches predicate(meta). For re-ingestion flows where a source document changed:

bank.remove(lambda m: m.get("chapter_id") == chapter_id)

bank.familiar(embedding) → (meta, score)

Quick overlap check without settling. Use for "have I seen this before?" checks.

bank.save(path) / bank.load(path)

Persist to / restore from a directory.

Benchmarks

Full retrieval benchmarks across 5 corruption conditions and 4 capacity levels show accuracy parity with exact cosine search (±1 point). The attractor substrate recalls 20,000 random patterns perfectly at 25% corruption. Capacity is limited by embedding discriminability (the embedder), not the attractor.

Honest limitations in software: per-query latency is ~35x slower than exact vector search (19ms vs 0.5ms at K=2000) because the projected patterns are 10,000-d vs 384-d. The speed case is the photonic implementation where recall is one pass of light — that's the roadmap, not the demo.

See slate-bench for full reproduction scripts and results.

License

Apache 2.0. Patent pending.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

slate_memory-0.2.0.tar.gz (16.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

slate_memory-0.2.0-py3-none-any.whl (12.9 kB view details)

Uploaded Python 3

File details

Details for the file slate_memory-0.2.0.tar.gz.

File metadata

  • Download URL: slate_memory-0.2.0.tar.gz
  • Upload date:
  • Size: 16.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for slate_memory-0.2.0.tar.gz
Algorithm Hash digest
SHA256 d2ece44588208bd91ad6d3a2b7efef301e643dc28638a7245e6c6b7c39d701a5
MD5 4a0c11c6b7b0d60c62ac61daad843c74
BLAKE2b-256 be1a34f254b43896a8fb50932a78472b36d3ac5d5b640277ca101714a1f8b57d

See more details on using hashes here.

File details

Details for the file slate_memory-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: slate_memory-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 12.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for slate_memory-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9404e4c5d67bea87f3cda0dc39d7095f3dd4d6467b1f603e982e62a9a5892574
MD5 d625f926011fc5921bbdffc1557719d6
BLAKE2b-256 954928e1ae53ecae5ecb7ee626823fce3be4edac35b5ffdcfd1819aa92ff4358

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page