HyperFlow / backend /ml /colbert_reranker.py
Gaurav711's picture
deploy: revert to 733e96b
d491dc1
Raw
History Blame Contribute Delete
2.39 kB
import numpy as np
from typing import List, Dict, Any
class ColBERTReranker:
"""
ColBERT Late-Interaction MaxSim Reranker for Dish Semantic Search.
Calculates token-level late-interaction dot products between query token embeddings
and candidate dish token embeddings:
Score(Q, D) = sum_{i in Q} max_{j in D} (E_q(i) . E_d(j)^T)
"""
def __init__(self, dim: int = 32):
self.dim = dim
np.random.seed(42)
def _get_token_embeddings(self, text: str) -> np.ndarray:
"""Simulates token embedding vectors for input text using deterministic hashing."""
tokens = text.lower().split()
if not tokens:
return np.zeros((1, self.dim))
embeddings = []
for token in tokens:
# Deterministic pseudo-random seed per token string
token_hash = abs(hash(token)) % (2**31)
rng = np.random.RandomState(token_hash)
vec = rng.randn(self.dim)
vec /= np.linalg.norm(vec) + 1e-9
embeddings.append(vec)
return np.array(embeddings)
def score(self, query: str, document: str) -> float:
"""Calculates MaxSim late-interaction score between query and document text."""
Q = self._get_token_embeddings(query) # Shape: (N_q, dim)
D = self._get_token_embeddings(document) # Shape: (N_d, dim)
# Token-level similarity matrix: (N_q, N_d)
sim_matrix = np.dot(Q, D.T)
# MaxSim per query token, then sum over query tokens
max_sim_per_q_token = np.max(sim_matrix, axis=1)
total_score = float(np.sum(max_sim_per_q_token))
return round(total_score, 4)
def rerank(self, query: str, candidates: List[Dict[str, Any]], text_key: str = "name") -> List[Dict[str, Any]]:
"""Reranks candidate dictionary items by MaxSim score in descending order."""
if not candidates:
return []
scored = []
for item in candidates:
doc_text = item.get(text_key, "") + " " + item.get("description", "")
sc = self.score(query, doc_text)
item_copy = dict(item)
item_copy["colbert_score"] = sc
scored.append(item_copy)
scored.sort(key=lambda x: x["colbert_score"], reverse=True)
return scored
colbert_reranker = ColBERTReranker()