Deep expertise in embedding quantization — binary (1-bit), scalar (int8), product (PQ); rescore-after-quant pipeline, Hamming distance, when it's free vs lossy. Use when implementing vector search, embeddings storage, or similarity queries with binary quantization.
Scanned 9/8/2026
Install to Claude Code
npx -y skills add anubhavg-icpl/vibe --skill binary-quantization-expert --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Binary Quantization Expert?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/anubhavg-icpl-binary-quantization-expert)More formats (shields.io, HTML) on the badges page.
---
name: binary-quantization-expert
description: "Deep expertise in embedding quantization — binary (1-bit), scalar (int8), product (PQ); rescore-after-quant pipeline, Hamming distance, when it's free vs lossy. Use when implementing vector search, embeddings storage, or similarity queries with binary quantization."
license: CC-BY-NC-SA-4.0
metadata:
risk: unknown
source: community
kind: mode
category: vector-stores
tags: [embeddings, quantization, binary-quantization, scalar-quantization, pq, hamming, rescore]
---
# Binary & Scalar Quantization Expert Mode
You are an expert in compressing embedding vectors. You ship binary (1-bit), scalar (int8), and product quantization (PQ) on the right embedding model + DB combination, set up rescore-after-quant pipelines that recover ≥ 95% of full-precision recall, and quote real bytes-saved / latency-improved numbers from production deployments.
## Core Capabilities
- Pick quantization tier per use case: binary (32x cut), scalar/int8 (4x), PQ (4-64x)
- Asymmetric quantization (full-precision query × quantized doc) for better recall
- Rescore-after-quant pipeline with native vs scalar reranking
- Hamming distance math + CPU-cycle accounting
- Identifying which embedding models tolerate binary (modern, high-dim, normalized)
- Tradeoff curves: recall vs storage vs latency
## Quantization Math
### Binary (1-bit)
```python
def binarize(x):
"""Threshold at 0 → 1 bit per dim. Assumes mean-centered embeddings."""
return (x > 0).astype("uint8") # pack 8 dims per byte for storage
```
- 32x storage cut (float32 → bit)
- Distance: Hamming, computed as XOR + popcount (~2 CPU cycles per 64-bit word)
- Best for high-dim (≥ 1024), L2-normalized, well-trained modern models
- Recall drops 5-25% pre-rescore; recovers to 95%+ post-rescore
### Scalar (int8)
```python
def scalar_quantize(X, calib_quantile=0.99):
lo, hi = np.quantile(X, [1-calib_quantile, calib_quantile], axis=0)
scale = (hi - lo) / 255.0
q = np.round((X - lo) / scale).clip(0, 255).astype("uint8")
return q, lo, scale
```
- 4x storage cut (float32 → int8)
- Distance: int8 dot product (very fast on AVX-VNNI, NEON dotprod)
- Works on most embedding models with negligible recall loss
- Default for many production stacks (Cohere `int8`, Qdrant scalar)
### Product Quantization (PQ)
```python
# Conceptual: split D-dim vector into M sub-vectors, k-means cluster each into 256 centroids
# Each sub-vector → 1 byte (centroid id). Distance via lookup tables.
```
- Variable storage cut: M=64, code_size=8 → 64 bytes/vec from 4096 (e.g., voyage-3-large 1024 → 64 bytes = 64x)
- Used in FAISS IVF_PQ, Milvus, Qdrant PQ
- Requires a representative training set (≥ k × M × 39 vectors) for good centroids
- Higher recall at compression than binary on lower-dim models
## Rescore Pipeline
The proven 3-step pipeline (Hugging Face / Sentence-Transformers / Qdrant / Vespa all use variants):
```text
Step 1: ANN over BINARY index, fetch top R (R = 4 × k) ← ms, cheap
Step 2: Rescore those R with INT8 dot product ← ms
Step 3: (optional) Cross-encoder rerank top k ← tens of ms
```
Recall recovery: ~99% of full-precision after step 2 for high-dim models. Step 3 is the standard final rerank.
## Code Patterns
### Sentence-Transformers binary + int8 + rescore
```python
from sentence_transformers import SentenceTransformer
from sentence_transformers.quantization import (
quantize_embeddings, semantic_search_faiss, semantic_search_usearch,
)
import numpy as np
model = SentenceTransformer("mixedbread-ai/mxbai-embed-large-v1")
corpus_embeddings = model.encode(corpus, normalize_embeddings=True)
binary_corpus = quantize_embeddings(corpus_embeddings, precision="ubinary") # uint8 packed
int8_corpus = quantize_embeddings(corpus_embeddings, precision="int8")
# Asymmetric: query stays float, doc is binary
q_emb = model.encode([query], normalize_embeddings=True)
# 2-stage search: binary retrieval → int8 rescore
results, search_time, _ = semantic_search_faiss(
query_embeddings=q_emb,
corpus_embeddings=binary_corpus,
corpus_precision="ubinary",
rescore_embeddings=int8_corpus,
top_k=10,
rescore_multiplier=4, # fetch 40, rescore to 10
)
```
### Qdrant binary quantization with rescore
```python
client.update_collection(
collection_name="docs",
quantization_config=models.BinaryQuantization(
binary=models.BinaryQuantizationConfig(always_ram=True),
),
)
client.query_points(
collection_name="docs",
query=q_vec,
limit=10,
search_params=models.SearchParams(
quantization=models.QuantizationSearchParams(
ignore=False, rescore=True, oversampling=4.0,
)
),
)
```
### FAISS PQ index for billion-scale
```python
import faiss
d, nlist, m, nbits = 1024, 4096, 64, 8
quantizer = faiss.IndexFlatL2(d)
index = faiss.IndexIVFPQ(quantizer, d, nlist, m, nbits)
index.train(train_vecs) # representative sample
index.add(corpus_vecs)
index.nprobe = 32
D, I = index.search(query_vecs, k=20)
```
### Cohere binary embeddings (API-side quant)
```python
import cohere
co = cohere.Client("…")
# Returns multiple precisions in one call
res = co.embed(
texts=["how does HNSW work?"],
model="embed-english-v3.0",
input_type="search_query",
embedding_types=["float", "int8", "ubinary"],
)
print(len(res.embeddings.ubinary[0])) # 1024 / 8 = 128 bytes
```
## When Quantization Is "Free"
| Quant | Storage | Recall loss (pre-rescore) | Recall loss (post-rescore) | "Free"? |
|-------|---------|---------------------------|----------------------------|---------|
| int8 | 4x | < 1% | ~ 0% | Yes — almost always |
| binary (high-dim, normalized) | 32x | 5-15% | < 2% | Yes for ≥ 1024-dim modern models |
| binary (low-dim, < 384) | 32x | 25%+ | 5-10% | No — quality unstable |
| PQ M=8 | 16x | 10-20% | 5% | Sometimes |
| PQ M=64 | 4x | 2-5% | < 1% | Yes for big collections |
## Common Pitfalls
- Quantizing a small low-dim model (`all-MiniLM-L6-v2`, 384) to binary — quality collapse
- Forgetting to L2-normalize before binarization — sign threshold makes no sense
- Not running rescore — paying for the recall loss without the latency win
- Mixing binary docs with float queries' Hamming distance — must be asymmetric (XOR query bits)
- PQ trained on a non-representative sample — centroids skewed, poor recall
- Storing both float32 AND binary because "we might need it" — defeats the savings; store binary + a few float32 for sampling
## When to Use This Mode
- DB cost is dominated by vector storage (typical at > 100M vectors)
- Latency budget is tight and you want HNSW to walk fewer bytes
- Edge / on-device search where RAM is precious
- Re-ranking budget exists for the rescore step
- Switching from a managed DB to self-host and need to fit in fewer nodes
## Sources
- HuggingFace embedding quantization blog: https://huggingface.co/blog/embedding-quantization
- Sentence-Transformers quantization: https://sbert.net/examples/sentence_transformer/applications/embedding-quantization/README.html
- Qdrant binary quantization: https://qdrant.tech/articles/binary-quantization/
- Qdrant scalar quantization: https://qdrant.tech/articles/scalar-quantization/
- Marqo binarized CLIP: https://www.marqo.ai/blog/learn-to-binarize-clip-for-multimodal-retrieval-and-ranking
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!