kumarakkiy's picture
Upload 143 files
4cdc522 verified
Raw
History Blame Contribute Delete
1.53 kB
"""Cross-encoder reranking via BAAI/bge-reranker-v2-m3.
Dense retrieval is great for recall but ranks by a single vector dot-product. A
cross-encoder reads (query, passage) **together** and scores true relevance — the single
biggest precision lever for cross-lingual search. We only score the top ~80 candidates,
so it's cheap. ``normalize=True`` squashes scores to 0..1 (sigmoid) for nice display.
"""
from __future__ import annotations
from typing import List, Optional
from app.config import Config, get_config
class Reranker:
def __init__(self, cfg: Optional[Config] = None):
self.cfg = cfg or get_config()
self._model = None
@property
def enabled(self) -> bool:
return bool(self.cfg.reranker["enabled"])
def _load(self):
if self._model is not None:
return self._model
from FlagEmbedding import FlagReranker
r = self.cfg.reranker
self._model = FlagReranker(r["model"], use_fp16=bool(r["use_fp16"]))
return self._model
def scores(self, query: str, passages: List[str]) -> List[float]:
"""Relevance score (0..1) for each passage against the query."""
if not passages:
return []
model = self._load()
pairs = [[query, p] for p in passages]
out = model.compute_score(
pairs, batch_size=self.cfg.reranker["batch_size"], normalize=True
)
if isinstance(out, (int, float)):
return [float(out)]
return [float(x) for x in out]