Repository navigation
RemexIndex puts a sentence-transformers model and a bit width in front of the quantizer, for single-vector and late-interaction models alike. Centered codes now also read correctly at a lower Matryoshka precision, so a centered index encoded once at 8 bits can be served at 4, 2 or 1.
from sentence_transformers import SentenceTransformer, MultiVectorEncoder
from remex import RemexIndex
index = RemexIndex(SentenceTransformer("all-MiniLM-L6-v2"), bits=4)
index.add(docs)
index.search("query", top_k=10) # [{'corpus_id': ..., 'score': ...}, ...]
# late interaction: one code per token, MaxSim scoring
index = RemexIndex(MultiVectorEncoder("perplexity-ai/pplx-embed-v2-late-0.6b"), bits=2, center=True)Added
remex.RemexIndex: reads the dimension andsimilarity_fn_nameoff the model, encodes throughencode_document/encode_query, returnsutil.semantic_search-shaped hits, and saves to one.npzthat is also a plainCompressedVectorscontainer plus the seed.center=Trueuses the first batch's mean;low_memory=Truescores without a float32 cache. On 10,000 Natural Questions answers with all-MiniLM-L6-v2, recall@10 against float32util.semantic_searchis 0.860 / 0.948 / 0.992 at 2 / 4 / 8 bits (bench/st_eval.py).- Late interaction:
maxsim/meanmaxsimmodels (sentence-transformers'MultiVectorEncoder) get one code per token and MaxSim scoring. On BEIR SciFact with pplx-embed-v2-late-0.6b, centered 2-bit codes score nDCG@10 0.786 against 0.780 for float32 (writeup). remex.semantic_search_remex: the same search behindsemantic_search_faiss's signature.pip install "remex[sentence-transformers]"; sentence-transformers stays optional and models are duck-typed.
Fixed
- Centered codes read at a lower precision decoded at the wrong length. The stored length is now re-solved per precision. On pplx-embed-v2-late-0.6b tokens, a 1-bit read of a centered 8-bit code went from nDCG@10 0.527 to 0.765 (a direct 1-bit encode scores 0.765). Full-precision decodes are bit-identical to 1.1.0.
Full notes in CHANGELOG.md.