Cross-Encoder Reranking
On this page
Cross-encoder reranking is an optional second-stage ranking technique that improves the relevance of documents returned by vector or hybrid search.
For more information about first-stage retrieval, refer to Working with Vector Data and Hybrid Search.
A typical pipeline is:
-
Retrieve candidate documents using vector or hybrid search.
-
Score each query-document pair with a cross-encoder.
-
Reorder the candidates based on their relevance scores.
This approach balances the efficiency of initial retrieval with the improved ranking accuracy of a cross-encoder.
Cross-Encoder Overview
Vector search uses embeddings generated by a bi-encoder model.
A cross-encoder, in contrast, processes the query and document together to evaluate their semantic relationship directly.
The main trade-off is performance.
Cross-Encoder Reranking Use Cases
Cross-encoder reranking is best suited to workloads where ranking quality is more important than minimizing latency.
-
User-facing search applications where high-quality results are a priority.
-
Retrieval-augmented generation (RAG) pipelines that require highly relevant context for downstream LLMs.
-
Complex semantic queries where more accurate relevance scoring improves the ordering of results.
Example Implementation
Cross-encoder reranking can be implemented in several ways, including external application code, external functions, or Wasm UDFs.
-
SingleStore performs vector search with embeddings generated by the BAAI/bge-large-en-v1.
5 bi-encoder model. -
Python scripts (
rerank_andexample. py compare_) apply the BAAI/bge-reranker-v2-m3 cross-encoder model to evaluate each query-document pair and rerank the retrieved candidates.search_ methods. py
To understand the core concept, consider this simplified reranking workflow:
query = "puzzle game with falling blocks"# Step 1: Encode query with bi-encoder (from get_candidates method)bi_encoder = SentenceTransformer("BAAI/bge-large-en-v1.5")query_embedding = bi_encoder.encode([query],normalize_embeddings=True,show_progress_bar=False,)[0]emb_json = json.dumps(query_embedding.tolist())# Step 2: Retrieve candidates from SingleStore using vector searchwith conn.cursor() as cur:cur.execute("""SELECTchunk_id,text,DOT_PRODUCT(embedding_1024, %s :> VECTOR(1024)) AS scoreFROM documentsORDER BY score DESCLIMIT %s""",(emb_json, 50),)candidates = cur.fetchall()# Step 3: Rerank with cross-encoder (from rerank method)cross_encoder = CrossEncoder("BAAI/bge-reranker-v2-m3")pairs = [[query, text] for _, text, _ in candidates]scores = cross_encoder.predict(pairs,batch_size=32,show_progress_bar=False,)# Step 4: Sort by cross-encoder scoresreranked = [(candidates[i][0], candidates[i][1], float(scores[i]))for i in range(len(candidates))]reranked.sort(key=lambda x: x[2], reverse=True)# reranked[0] is now the most relevant result
Note: Many cross-encoder models are available, and new models continue to improve on existing approaches.
Repository Structure
The full implementation is available in the cross-encoder-reranking-example repository.
-
Database setup
-
Document loading and embedding generation
-
Vector search
-
Cross-encoder reranking scripts
-
Before/after comparison examples
Refer to the repository README for setup and execution instructions.
Example Results
The repository example uses a test dataset of Wikipedia video game articles.
Query: puzzle game with falling blocks
Before reranking (vector search):
|
Rank |
Chunk |
Score |
Content |
|
1 |
362 |
0. |
Tetris generally has a consistent puzzle video game design. |
|
2 |
132 |
0. |
Minecraft is a three-dimensional sandbox video game that has no required goals to accomplish. |
|
3 |
375 |
0. |
See also: Brain Wall and Blokken, game shows based on Tetris. |
After reranking (cross-encoder):
|
Rank |
Chunk |
Score |
Content |
|
1 |
361 |
0. |
Tetris is a puzzle video game created by Alexey Pajitnov, a Soviet software engineer, in the mid-1980s. |
|
2 |
362 |
0. |
Tetris generally has a consistent puzzle video game design. |
|
3 |
376 |
0. |
Notes. |
Performance
Sample measurements on an Intel CPU with a 603-chunk dataset (from the example repository):
-
Retrieve top-50 candidates: ~0.
2s -
Rerank 50 candidates (CPU): ~25s
-
Model loading (first run only): ~7s
These measurements reflect the computational cost of CPU-based inference and are not representative of production deployments, where batching and GPU acceleration can substantially reduce latency.
Limitations
Cross-encoder reranking improves the ordering of retrieved results but does not improve recall.
-
Retrieve a larger candidate set
-
Use hybrid search to combine semantic and full-text search
-
Tune embeddings and retrieval parameters
Cross-encoder outputs should be interpreted as relative ranking signals within a single query, not as absolute relevance scores.
Related Topics
Last modified: