Apache-2.0 · v0.6.1 · runs on your machine
Search and memory that run entirely on your machine.
HMS is a local-first document search engine and a vector-symbolic associative memory in one store. Hybrid BM25 and exact-cosine retrieval, byte-offset hits, crash-safe persistence, and superposed memory you can bind, bundle and query. No service calls and no telemetry.
- Rust
- Python
- Node
Install, ingest, search
The code below is read from the quickstart examples that CI runs on every pull request.
cargo add holographic-memory --features security
// 1. Ingest. A store is a directory (`None` would use the current directory); it persists
// there and reopens with the same arguments.
let store_dir = tempfile::tempdir()?;
let hms = HmsCore::new(
DIMENSIONS,
Some(store_dir.path().display().to_string()),
None,
)?;
let start = Instant::now();
let inputs: Vec<DocumentInput> = corpus.iter().map(to_input).collect();
hms.memorize_documents(inputs)?;
println!(
"ingested {} documents in {:.1?}",
corpus.len(),
start.elapsed()
);
// Hits carry the passage and its byte range in the source text.
let hit = &hms.search_documents("asylum from persecution", &SearchOptions::default())?[0];
println!(
"\n{} bytes {}..{} score {:.3}: {}",
hit.document_id,
hit.start_byte,
hit.end_byte,
hit.score,
hit.text.as_deref().unwrap_or("")
);
The engine itself. Every other runtime is a surface over it.
pip install holographic-sdk
# 1. Ingest. The server keeps one store per tenant; you send the text and a vector per document.
docs = [
{"id": d["id"], "vector": toy_embed(d["text"]), "text": d["text"], "metadata": {"title": d["title"]}}
for d in corpus
]
client = HolographicClient(url=URL, api_key=API_KEY, tenant_id=tenant)
started = time.perf_counter()
client.add_documents(docs)
print(f"ingested {len(docs)} documents in {(time.perf_counter() - started) * 1000:.1f} ms")
# Hits carry the stored text, metadata and the exact cosine score.
top = client.query(toy_embed("asylum from persecution"), top_k=1)["matches"][0]
print(f"\n{top['id']} score {top['score']:.3f}: {top['text']}")
An HTTP client for hms-server. The holographic-vsa wheel is the quantized-phase substrate, a different package.
git clone https://github.com/writerslogic/holographic-memory
cd holographic-memory && npm ci --omit=optional && npm run build
// 1. Ingest. A store is a directory; it persists there and reopens with the same arguments.
const memory = new DocumentMemory(new HolographicMemorySystem(4096, mkdtempSync(join(tmpdir(), 'hms-quickstart-'))))
const started = performance.now()
await memory.ingest(corpus.map(toInput))
console.log(`ingested ${corpus.length} documents in ${(performance.now() - started).toFixed(1)} ms`)
// Hits carry the passage and its byte range in the source text.
const [hit] = await memory.search('asylum from persecution')
console.log(`\n${hit.documentId} bytes ${hit.startByte}..${hit.endByte} score ${hit.score.toFixed(3)}: ${hit.text}`)
Built from source with a Rust toolchain. The npm package is deprecated until the next release.
Measured, and traceable
Both results are read from committed files under benchmarks/results/ each time the site is built.
BEIR SciFact test split, 300 queries over 5,183 documents, MiniLM-L6-v2 embeddings (384 dimensions). The published BM25 figure (0.665, Thakur et al. 2021) is quoted from the BEIR paper, not re-run here.
Source: benchmarks/results/public_scifact.json · Apple M4 · benchmark page
- At recall@10 of 0.90: the fastest HMS configuration (HMS VGraph (8-bit codes, rerank)) ran at 4,409 QPS, slower than the fastest other system (SymphonyQG (qb=0), 5,913 QPS).
- Not reached at 0.90 by: SymphonyQG (qb=4).
- At recall@10 of 0.95: no HMS configuration reached it. Reached by: FAISS HNSW M=16, FAISS HNSW M=32, Lucene HNSW M=16, Lucene HNSW M=32, RaBitQ IVF 1+8, hnswlib M=16.
- † HMS VGraph (4-bit codes, rerank): opt-in encoding that ran at lower machine load than the other rows; the benchmark page treats it as unconfirmed.
Source: benchmarks/results/public_qgraph_nytimes-256-angular.json · Apple M4 · load gate met by 0 of 107 configurations (limit 3.0), so throughput is indicative · benchmark page
One engine, two layers
Document search is a conventional hybrid retriever. The vector-symbolic layer is the associative memory. Both sit on one crash-safe store. Module map →
Why holographic
A hologram stores the whole picture in every fragment. A hypervector memory does the same: many facts are superposed into one long vector, no single bit holds any one fact, and damage is spread thinly over all of them.
- Bind a key to a value with XOR. The result looks like neither, and binding again with the key gives the value back.
- Bundle many bound pairs by majority vote into one vector that stays a little similar to each of them.
- Resonate: unbind with a key and compare against known values. The right one stands out from the noise, even after you corrupt the memory.
The demo uses dense binary vectors so the algebra is easy to see. The engine uses sparse binary vectors, and its document search does not rank with hypervectors; the concepts page says exactly which parts do.
A memory in one vector
4,096 bits hold every key-value pair at once. Pick how many pairs, damage the memory, and ask for one value back.
Similarity of the unbound memory to each known value
What is being computed
Each key and each value is a random 4,096-bit vector. A pair is key XOR value. The memory is the bitwise majority of all pairs, then damage flips the chosen share of its bits. To ask, XOR the memory with a key and measure the fraction of matching bits against every value. Unrelated vectors match about half their bits, with a spread near 0.8 percentage points, so a match well above 0.5 is the stored value. More pairs shrink the signal; more damage shrinks it too. Past some point the answer is wrong, and the demo says so.
Retrieval quality on SciFact
| System | nDCG@10 | Recall@100 |
|---|---|---|
| HMS hybrid (BM25 + exact cosine) | 0.729 | 0.953 |
| HMS lexical (stemmed BM25) | 0.688 | 0.925 |
| HMS dense (exact cosine) | 0.645 | 0.925 |
| NumPy exact cosine, same embeddings | 0.645 | 0.925 |
| HMS sparse vector path | 0.470 | 0.779 |
Same embeddings for every dense row. The benchmark pages carry the full comparison, including where HMS loses. Source: benchmarks/results/public_scifact.json.
What is in the box
Hybrid search
Stemmed BM25 fused with exact cosine over embeddings you supply. Hits carry the passage and its byte range.
Vector-symbolic memory
Sparse binary hypervectors with bind, bundle and permute, a triple store with multi-hop queries, Hopfield cleanup and a resonator network.
Crash-safe storage
Atomic batches, a mmap segmented log with generations, and replay. A store is a directory.
Hardening you opt into
AES-256-GCM stores, signed audit logs, credential-gated agents and COSE/SCITT provenance behind Cargo features.
Local by construction
The engine makes no network calls and sends no telemetry. The optional HTTP server is yours to run.
Measured, including losses
Every number on this site traces to a committed results file, and the benchmark pages say where another system wins.
How to read this site¶
The document pipeline is conventional retrieval: stemmed BM25 fused with exact cosine over embeddings you supply. The vector-symbolic layer powers the meaning memory, composition and the experimental vector index. Where HMS loses to another system on a measured benchmark, the benchmark pages say so, and every number on this site traces to a committed file under benchmarks/results/.
New here? Start with the quickstart, then read what "holographic" means in this code. Looking something up? Use the search box, the glossary or the FAQ. The version selector in the header switches between latest (the newest tagged release that carries these docs), dev (the main branch) and each tagged release. How the site is built and checked is on its own page.