Repository navigation
Conversation
|
Pushed a073842, which keeps each candidate's similarity to the selection as a running maximum. The rerank recomputed every remaining candidate's distance to every result already selected at each step, about 285,000 distance computations for The picks are unchanged: 20 queries over 5,000 cosine vectors of 768 dimensions, with This branch also conflicts with main now. I can rebase it if you'd like to take it. |
Add Maximal Marginal Relevance (MMR) support to vec0 virtual table. When mmr_lambda is provided in a KNN query, candidates are over-fetched and then greedily re-selected to balance relevance against diversity. API: WHERE embedding MATCH ? AND k = 10 AND mmr_lambda = 0.7 - mmr_lambda range [0.0, 1.0]: 1.0 = pure relevance, 0.0 = pure diversity - Over-fetch factor: 5x (capped at k_max=4096) - Supports float32, int8, and bit vector types - All distance metrics (L2, cosine, L1, hamming) - Zero impact when mmr_lambda is not provided
9 test functions covering: - Cosine diversity (baseline vs lambda=1.0, 0.5, 0.0) - L2 distance metric compatibility - Int8 vector element type - Cluster monopoly breaking - Composition with distance constraints - Composition with partition keys - Edge cases (k=1, k=0) - Error handling (invalid lambda range) - Insert guard for hidden column
The copy-back loop iterated k_target times, but the greedy selection loop can terminate early via `if (best_idx < 0) break`, leaving the tail of out_rowids/out_distances uninitialized. Add an n_selected counter and out_n_selected output parameter so only actually-selected entries are copied back. The caller now sets k_used = n_selected instead of k_used = k_original. Credit: mceachen (vlasky#6)
The relevance term was already normalized to [0,1] via max_dist, but the diversity term used raw distances (1 - d). For cosine this is fine since values are bounded [0,1], but for L2 and L1 the two terms operated on different scales, making mmr_lambda behave unpredictably. Normalize the diversity term the same way (d / max_dist) so both terms are on a consistent [0,1] scale regardless of distance metric. Ported from vlasky/sqlite-vec@8d4ef9e.
…ximum vec0_mmr_rerank recomputed, at every selection step, each remaining candidate's distance to every result already selected: about k^2/2 times the candidate count, near 285,000 distance computations for k = 50 over the 250 candidates that lambda's overfetch gives. max_sim[i] now holds candidate i's highest similarity to the selection and is raised against each new selection alone, so a step measures each remaining candidate once. A maximum over the selected results is the same however it is accumulated, and the distances are computed with the same arguments in the same order, so the picks are unchanged: 20 queries over 5,000 cosine vectors of 768 dimensions (k from 20 to 100, lambda from 0.3 to 0.7) return identical rowids before and after, in 410 ms against 9.8 s in total. The MMR snapshot tests pass unchanged.
|
Rebased onto main (v0.1.10-alpha.4), which conflicted with the branch. The |
refs #266
Adds Maximal Marginal Relevance reranking to
vec0KNN queries. Whenmmr_lambdais provided, candidates are over-fetched and then greedily re-selected to balance relevance against diversity.distancecolumn for pagination/custom thresholds #165 / WIP: Support constaints ondistancecolumn in KNN queries, for pagination and range queries #166) and partition keysTests
9 pytest + syrupy snapshot tests covering:
All 158 existing tests pass (+ 8 skipped). Verified in both aarch64 and x86_64 VMs.