Skip to content

TQ loses to the FAISS PQ baseline on bimodal and one-hot-like coordinate distributions #310

Description

@RyanCodrai

Found by bug-hunt wave 11 (recall-quality lens). Severity: medium — the only regimes found where TQ is worse than the published baseline.

Same harness as the official recall suite, n=20,000, d=256, 300 queries, FAISS IndexPQ(m = d/4 @2bit, d/2 @4bit, nbits=8, METRIC_INNER_PRODUCT) — the exact baseline README §Recall uses.

data bits TQ R@1 FAISS R@1
bimodal (N(0,1) ± 3 per coord, normalized) 2 0.364 0.632
bimodal 4 0.772 0.900
one-hot + 0.01 noise 2 0.068 0.308
one-hot + 0.01 noise 4 0.174 0.324

(bimodal R10@10: 0.518 vs 0.721.)

This contradicts the README's "beats FAISS" framing, which is only ever evaluated on dense unimodal embeddings. One-hot data is tie-heavy so R@1 there is partly arbitrary, but the 4.5x gap vs PQ on identical data is not.

Diagnosis: TQ+ calibration maps the 5/95% quantiles onto a unimodal Beta (encode.rs:195-196), which is the wrong summary for a bimodal marginal. A user-applied dense random pre-rotation did not rescue either case (one-hot 2-bit: 0.080 raw → 0.060 pre-rotated), so this is the codebook/calibration, not rotation mixing.

For contrast, clustered data (50 clusters, σ=0.3) is brutal in absolute terms (2-bit R@1 0.080) but TQ beats FAISS there (0.026) — intrinsic difficulty, not a regression.

Also worth a doc note from the same audit: unnormalized input works correctly (norms are stored; MIPS on log-normally-scaled vectors gives 2-bit R@1 0.710, 4-bit 0.915, identical whether queries are normalized), but neither docs/api.md nor the docstrings state that inputs need not be normalized or that the metric is raw inner product rather than cosine (add.__doc__ is None).

And a measured non-issue: the calibration freeze (#284/#285) costs ≤2pp on real data — cross-corpus shift (openai→GloVe) 2-bit R@1 0.520 frozen vs 0.530 fresh; 4-bit frozen slightly ahead. The one case worth documenting is a tiny first add: first-add of 150 vectors gives 2-bit R@1 0.523 vs 0.603 with a 5,000-vector first add (~8pp) — i.e. "make your first add at least a few thousand vectors".

🤖 Generated with Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-human-decisionBlocked on a maintainer decision: scope, public claims, or dependency/release policy

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions