A tiny CPU-first, in-memory vector search library in C++ with Python bindings.
- Overview
- Features
- Applications
- Getting Started
- Examples
- Benchmarks
- Status
- Roadmap
- License
- Disclosure
Spheni is a C++ library with Python bindings to search for points in space that are close to a given query point. The aim is to build-and-document the architectural and performance improvements over time.
- Indexes: Flat, IVF
- Metrics: Cosine, L2
- Storage: F32, INT8
- Ops: add, search, search_batch, train, save, load
Check out the API Reference (Python) for full details.
Spheni manages the low-level indexing and storage of CLIP-generated embeddings to enable vector similarity calculations. It compares the mathematical representation of a text query against the indexed image vectors to find the best semantic matches.
It retrieves relevant lines based on meaning rather than exact keywords. It embeds text once and uses Spheni for fast, offline vector search.
Git clone and navigate into the root directory. Have CMake, pybind11 and OpenMP installed.
Build from the repo root:
./build_spheni.sh --python --install ./distand then link with your C++/Python projects.
Check out the full guide.
C++:
#include "spheni/engine.h"
#include <vector>
int main() {
spheni::IndexSpec spec(3, spheni::Metric::L2, spheni::IndexKind::Flat, false);
spheni::Engine engine(spec);
std::vector<float> data = {1,0,0, 0,1,0, 0,0,1};
engine.add(data);
std::vector<float> query = {0.1f, 0.9f, 0.0f};
auto hits = engine.search(query, 1);
}Python:
import numpy as np
import spheni
spec = spheni.IndexSpec(4, spheni.Metric.L2, spheni.IndexKind.Flat)
engine = spheni.Engine(spec)
base = np.random.rand(10, 4).astype(np.float32)
engine.add(base)
query = np.random.rand(4).astype(np.float32)
results = engine.search(query, 3)
for hit in results:
print(f"ID: {hit.id}, Score: {hit.score}")IVF achieves ~97% Recall@10 with ~12x higher throughput than brute force and stable tail latency. INT8 quantization reduces memory by ~73% with negligible accuracy loss, and OpenMP parallelism adds ~2.4x more throughput.
Read the full benchmark report.
Spheni is usable for experimentation and benchmarking, but not production-ready.
Current limitations:
- No SIMD kernels
- No deletion or updates
- Limited parameter validation
- IVF uses brute-force centroid assignment
Short term:
- Parameter validation + explicit error handling [partially done]
- Expose IVF training state
- Improve IVF memory locality
- Flat index optimizations
Longer term:
- SIMD kernels
- Multithreading (just query search)
- Persistence
- Quantized storage (INT8 : Scalar Quantization)
- Additional ANN structures
- FAISS: ArXiv Paper
- Near Neighbor Search in Large Metric Spaces
- The Binary Vector as the Basis of an Inverted Index File
Apache 2.0
I couldn't find any solid resources showing how to structure vector search lib end-to-end, so I relied on a few community discussions (viz. this reddit thread) and read some ANN literature from the 20th century.
I also used Claude in a "whiteboard" mode to reason about design decisions. Serialization, bindings, and exception-handling code were Codex-generated and then manually reviewed.


