Commit graph

3 commits

Author SHA1 Message Date
Trevon
c26294a938
feat(topology): opt-in medoid representative and BQ rotation (#277)
* test(topology): characterize degree representatives and raw BQ sign bits

Pin the current behaviour before adding opt-in representative and BQ
rotation options:

- connected, louvain and kmeans engines on a skewed cluster (dense
  clique plus a weak-edge hub): medoid hash, score, extra routing
  representatives and roles;
- equal-degree ties go to the smaller document hash;
- the unrotated BinaryQuantizedIndex matches a raw-coordinate sign-bit
  reference, with and without a prefix dimension.

Signed-off-by: trvon <me@trevon.dev>

* feat(topology): add an opt-in medoid representative rule

topology.representative_rule = degree (default) | medoid selects how a
cluster's representative document is chosen. Degree keeps the max
within-cluster weighted degree. Medoid picks the member minimising
sum_j sqrt(max(0, 2(1 - cos))) over the other members.

- one shared helper, applyRepresentativeRule(), is called by the
  connected, louvain and kmeans engines after their unchanged degree
  choice; medoid falls back to it without usable geometry;
- clusters above 256 usable members are searched on a deterministic
  hash-ordered stride sample (kMedoidRepresentativeMaxMembers);
- ties within 1e-9 go to the smaller document hash;
- with medoid, farthest-first extra routing representatives are seeded
  from the medoid instead of the centroid;
- the rule is stored in the formerly reserved first header byte of the
  binary snapshot (0 = degree, so old snapshots keep their meaning) and
  extends the construction fingerprint only when it is not degree;
- search debug stats report topology_representative_rule.

Signed-off-by: trvon <me@trevon.dev>

* feat(topology): add an opt-in randomized Hadamard rotation for BQ routing

search.topology.bq_rotation = none (default) | fwht selects the rotation
applied before the centroid BQ shortlist takes sign bits. Raw-coordinate
sign bits make cos(pi * h / d) a poor estimate on anisotropic embeddings;
after x -> (1/sqrt(n)) H D [x; 0] every bit is a random hyperplane.

- RandomizedHadamardRotation in yams/vector: fixed splitmix64 sign
  diagonal plus an in-place FWHT, zero-padded to a power of two; Simeon's
  FWHT projection works on int32 sketches with row subsampling, so a
  small local transform is used instead;
- BinaryQuantizedIndex::build() takes the rotation and seed, rotates
  stored vectors before the prefix is taken, and rotates every float
  query itself, so centroids and queries always share one seed
  (kDefaultBinaryRotationSeed);
- the routing snapshot cache records bqRotation and bqRotationSeed and
  rebuilds the route index when either differs;
- the routing policy fingerprint changes only for a non-default rotation;
- search debug stats report topology_route_bq_rotation.

Signed-off-by: trvon <me@trevon.dev>

* test(bench): map representative rule and BQ rotation arm knobs

Harness-only env knobs written into the isolated benchmark config.toml,
so arms go through ConfigResolver like the other topology settings:

- YAMS_BENCH_TOPOLOGY_REPRESENTATIVE_RULE=degree|medoid
  -> [topology] representative_rule
- YAMS_BENCH_TOPOLOGY_BQ_ROTATION=none|fwht
  -> [search.topology] bq_rotation, next to bq_candidate_limit and
     bq_prefix_dim

The debug-file setup entry records the requested values; per-query
search_stats carry the effective topology_representative_rule and
topology_route_bq_rotation. Portability allowlist lines are shifted for
the inserted code.

Signed-off-by: trvon <me@trevon.dev>

---------

Signed-off-by: trvon <me@trevon.dev>
2026-10-08 14:30:27 -06:00
trvon
c3b667ee40
feat(retrieval): SGC topology smoothing, Matryoshka BQ prefix, and fragment outer-MaxSim
Implement three research-backed retrieval optimizations connecting
paperbridge literature findings with YAMS subsystems:

1. SGC Feature Smoothing (Proposal A):
   - Add sgcHops and sgcNormalize to TopologyBuildConfig.
   - Diffuse document embeddings across reciprocal nearest-neighbor graph
     edges prior to clustering, formalizing Lean SGC.lean.
   - Re-normalize diffused embeddings to preserve unit hypersphere metric geometry.
   - Wire into ConnectedComponent, Louvain, and KMeans topology engines.

2. Matryoshka Prefix Binary Quantization (Proposal C):
   - Add maxDimensions parameter to BinaryQuantizer::quantize and
     maxPrefixDimension to BinaryQuantizedIndex::build.
   - Support fast 64-bit word-aligned prefix Hamming shortlisting in
     SparseGuidedClusterRouter via bqPrefixDimension.

3. Fragment Outer-MaxSim Reranker (Proposal B):
   - Implement SimeonScoringMode { SingleVectorCosine, FragmentOuterMaxSim }
     in SimeonModelProvider.
   - Add extractDocumentFragments and late-interaction outer-MaxSim scoring
     inspired by ColBERTv2/PLAID/SPLATE to prevent relevance dilution in long docs.
   - Expose simeonRerankOuterMaxSim on SearchEngineConfig and ConfigResolver.
   - Add Catch2 test coverage and verify BEIR scifact benchmark metrics.

Signed-off-by: trvon <me@trevon.dev>
2026-09-22 07:37:35 -06:00
trvon
052031a484
feat(vector): binary quantization (BQ) pre-filter for cluster routing
- Add BinaryQuantizer and BinaryQuantizedIndex in include/yams/vector/binary_quantization.h
  and src/vector/binary_quantization.cpp implementing 1-bit sign quantization,
  packed 64-bit word storage, hardware popcount Hamming distance, and cosine
  similarity estimation.
- Integrate centroidBqIndex into SparseRouteIndex, constructing compact BQ
  centroids alongside dense ANN indices during SparseGuidedClusterRouter::buildRouteIndex.
- Add bqCandidateLimit to TopologyRouteRequest and tracking metrics (bqUsed,
  bqCandidates, bqDistanceEvaluations) to SparseRouteWork.
- Enable fast candidate pre-filtering in SparseGuidedClusterRouter::route with
  1-bit Hamming distance scans, providing sub-millisecond coarse candidate
  shortlisting and automatic fallback when the dense ANN index is omitted.
- Add Catch2 unit test suites in tests/unit/vector/binary_quantization_catch2_test.cpp
  and tests/unit/topology/topology_baseline_catch2_test.cpp.

Signed-off-by: trvon <me@trevon.dev>
2026-09-22 07:37:35 -06:00