Skip to content

perf(vector/search): two-stage rerank exists only for HNSW; pipeline is hard-coded #650

Description

@mosuka

Round-3 perf push sub-issue (tracked under umbrella #536).

[L] Two-stage rerank exists only for HNSW; pipeline is hard-coded

  • Where: laurus/src/vector/index/hnsw/searcher.rs:493-522 implements Stage-2 inline.
    laurus/src/vector/index/flat/searcher.rs:31-37 and
    laurus/src/vector/index/ivf/searcher.rs:121-127 return NotImplemented when
    rerank_factor is set. No shared ReRankScorer trait.

  • Current behavior: Each searcher must reimplement rerank. Flat and IVF can't use the
    LRS1 sidecar even though the storage pool exists. 3+ stage chains (PQ → SQ → f32) are
    not expressible.

  • Why it might be a bottleneck / risk: Composable rerank is essential for FastScan-style
    3-stage pipelines (PQ initial → SQ verify → f32 final). The current code is locked to a
    single int8 → f32 path.

  • Reference precedent: Qdrant ReScorer trait pluggable per index; LanceDB IVF_PQ
    reranks against original f32 stored in the rowgroup; FAISS IndexRefine wraps any base
    index; Lucene 9.10 ScalarQuantizedVectorScorer with score() separate from rescore().

  • Data structure (proposed):

    trait RerankScorer: Send + Sync {
        fn prepare(&self, query: &[f32]) -> Self::Prepared;
        fn rescore(&self, prepared: &Self::Prepared, doc_id: u64) -> Option<f32>;
    }
    struct RerankPipeline {
        stages: Vec<Box<dyn RerankScorer>>,
        factors: Vec<usize>,           // top_k * f[0], then top_k * f[1], ...
    }
    // Each stage narrows the candidate set by factor[i]. Composable per index type.
    // Candidate buffer is SoA: (Vec<u64>, Vec<f32>) — not a tuple Vec.
    
  • Suggested direction: Generic RerankScorer trait + RerankPipeline. Implement
    Pq8Scorer, Pq4FastScanScorer, Sq8Scorer, F32Scorer. HNSW/Flat/IVF emit a
    candidate set and let the pipeline run.

  • Risk / scope: Large architectural. Removes duplication, unlocks 3+ stage rerank,
    normalises behaviour across index types.


ID: VS-07 — see ~/.claude/tasks/laurus/20260523_perf_round3_audit/task_list.md for the full Round-3 issue list.


Task list

This is now the umbrella for a 3-PR campaign (see the investigation/plan comment, 2026-08-02):

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions