Skip to content

research: scalar quantization with two-stage re-ranking in HNSW (nightly 2026-07-11)#660

Draft
ruvnet wants to merge 6 commits into
mainfrom
research/nightly/2026-07-11-sq-rerank-hnsw
Draft

research: scalar quantization with two-stage re-ranking in HNSW (nightly 2026-07-11)#660
ruvnet wants to merge 6 commits into
mainfrom
research/nightly/2026-07-11-sq-rerank-hnsw

Conversation

@ruvnet

@ruvnet ruvnet commented Jul 11, 2026

Copy link
Copy Markdown
Owner

Summary

Nightly research PR adding crates/ruvector-sq-hnsw: a pure-Rust, zero-dependency implementation of scalar quantization (SQ8 / SQ4) with two-stage full-precision re-ranking, composed with NSW and two-layer HNSW graph search.

  • ScalarQuantizer — trains in a single pass (no codebook), supports SQ8 (4× compression) and SQ4 (8× compression)
  • FlatExact — exact brute force, serves as ground truth
  • FlatSq8 — SQ8 scan + full-precision re-rank; achieves recall@10 = 1.000
  • GraphSq8 / GraphSq4 — NSW graph with seed-layer diverse entry points and multi-probe search; plateau ~0.80 recall at 128 dims (concentration of measure — documented)
  • SqHnsw2 — 2-layer HNSW: sparse Layer-1 (~n/l1_period nodes) provides geometrically diverse entries, dense Layer-0 beam-searched to ef=200 candidates, exact re-rank; achieves recall@10 = 0.937

All five variants implement the unified NnSearch trait. No external crate dependencies; compiles on any rustc stable target including WASM.

Benchmark results (n=10K, dims=128, k=10, 100 queries — x86_64 Linux)

Variant Mean(μs) QPS Mem(MB) Recall@10
FlatExact 1773 564 4.88 1.000
FlatSq8 2520 397 6.10 1.000
NSW-SQ8 5127 195 8.55 0.798
NSW-SQ4 6272 159 7.94 0.802
HNSW2-SQ8 3660 273 11.14 0.937

Files changed

  • crates/ruvector-sq-hnsw/ — new crate (src, tests, examples)
  • docs/adr/ADR-272-sq-rerank-hnsw.md — Architecture Decision Record
  • docs/research/nightly/2026-07-11-sq-rerank-hnsw/README.md — full research document
  • docs/research/nightly/2026-07-11-sq-rerank-hnsw/gist.md — SEO-optimised public article
  • Cargo.toml / Cargo.lock — workspace registration

Test plan

  • cargo test -p ruvector-sq-hnsw — 6 integration tests pass (recall thresholds enforced numerically)
  • cargo run --release -p ruvector-sq-hnsw --example benchmark — ACCEPTANCE: PASS
  • cargo fmt -p ruvector-sq-hnsw — clean formatting
  • Phase 2: SELECT-NEIGHBORS-HEURISTIC edge pruning, rayon parallel construction, serde serialization
  • Phase 3: wire as backend option in ruvector-core, MCP tool surface

ADR

ADR-272 — Status: Proposed

Key research finding

NSW recall has a hard ceiling (~0.80) for 128-dim Gaussian data due to concentration of measure. Hierarchical entry points (HNSW Layer-1) break this ceiling, achieving 0.937 recall@10 — a 17-point improvement. This ceiling and its root cause are documented as a first-class research contribution.


Generated by Claude Code

claude and others added 6 commits July 11, 2026 07:40
Register crates/ruvector-sq-hnsw in workspace members and update lock file.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01MQmLYEUQd8yNb4Xt7oXiTb
…nking

Implements five ANN variants sharing the NnSearch trait:
- FlatExact: exact brute force (ground truth)
- FlatSq8: SQ8 scan + full-precision re-rank (recall@10 = 1.000)
- GraphSq8/GraphSq4: NSW graph with seed layer + multi-probe search
- SqHnsw2: 2-layer HNSW with SQ8 distances + re-rank (recall@10 = 0.937)

ScalarQuantizer trains in one pass (no codebook), supports SQ8 and SQ4.
Zero external dependencies; compiles on any rustc stable target.
NSW recall ceiling (~0.80 at 128 dims) documented; HNSW2 breaks it.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01MQmLYEUQd8yNb4Xt7oXiTb
6 integration tests with real recall thresholds measured on Gaussian
corpus (N=2000, DIMS=64, K=10, Q=50 queries):
- flat_exact_returns_sorted_results (correctness)
- flat_sq8_recall_above_90pct (>=0.90)
- graph_sq8_recall_above_85pct (>=0.85)
- graph_sq4_recall_above_70pct (>=0.70)
- memory_estimates_are_positive (all variants)
- sq_hnsw2_recall_above_88pct (>=0.88)

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01MQmLYEUQd8yNb4Xt7oXiTb
Measures latency, QPS, memory, and recall@10 for all five variants at
n=10K, dims=128. Acceptance thresholds enforced: FlatSq8>=0.90,
NSW-SQ8>=0.70, NSW-SQ4>=0.60, HNSW2-SQ8>=0.88. Exits nonzero on fail.

Results from 2026-07-11 x86_64 Linux run:
  FlatExact  1773μs  564 QPS  4.88MB  1.000
  FlatSq8    2520μs  397 QPS  6.10MB  1.000
  NSW-SQ8    5127μs  195 QPS  8.55MB  0.798
  NSW-SQ4    6272μs  159 QPS  7.94MB  0.802
  HNSW2-SQ8  3660μs  273 QPS 11.14MB  0.937

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01MQmLYEUQd8yNb4Xt7oXiTb
…n HNSW

Architecture Decision Record covering: context (gap vs PQ-search),
decision (5-variant NnSearch trait hierarchy), consequences (4× SQ8
compression, 0.937 recall), tradeoffs (2.3× memory with re-rank),
alternatives, 3-phase implementation plan, benchmark evidence, failure
modes, security considerations, and migration path from flat/PQ index.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01MQmLYEUQd8yNb4Xt7oXiTb
Research document, SEO-optimised gist, and nightly survey for
ruvector-sq-hnsw. Covers SOTA survey (Qdrant, LanceDB, FAISS, ScaNN),
NSW recall ceiling analysis (concentration of measure at 128 dims),
HNSW2 architecture, 8 practical + 8 exotic applications, production
crate layout, and Phase 2-3 roadmap.

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01MQmLYEUQd8yNb4Xt7oXiTb
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants