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
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.(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__isNone).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