Description of the Bug
The current Reranker.rerank() implementation modifies the input document dictionaries in-place when assigning the rerank_score. If the original document list or its dictionary references are reused across multiple requests or application pipelines, this permanently alters the source data, causing unintended side effects (data mutation bug).
Additionally, neither the singleton get_reranker() initialization nor the lazy model loader _load_model() are thread-safe or async-safe. Under concurrent load (e.g., inside an asynchronous framework like FastAPI or under multiple worker threads), the model can be triggered to load multiple times simultaneously, leading to redundant CPU/GPU memory utilization or outright crashes.
Steps to Reproduce
Pass a static list of document dictionaries to rerank().
Inspect the original document list after the function completes; notice that the dictionaries have been altered to include the "rerank_score" key.
Call get_reranker() concurrently using multiple Python threads before the model finishes loading to observe race conditions during model initialization.
Expected Behavior
The rerank() method should return a fresh list containing shallow/deep copies of the dictionaries, leaving the user's original input objects completely pristine.
Thread locks (threading.Lock) should gate the lazy loader and singleton instantiation to guarantee the heavy model weights are loaded into memory exactly once.
Screenshots / Logs
No response
Environment
=
GSSoC '26
Description of the Bug
The current Reranker.rerank() implementation modifies the input document dictionaries in-place when assigning the rerank_score. If the original document list or its dictionary references are reused across multiple requests or application pipelines, this permanently alters the source data, causing unintended side effects (data mutation bug).
Additionally, neither the singleton get_reranker() initialization nor the lazy model loader _load_model() are thread-safe or async-safe. Under concurrent load (e.g., inside an asynchronous framework like FastAPI or under multiple worker threads), the model can be triggered to load multiple times simultaneously, leading to redundant CPU/GPU memory utilization or outright crashes.
Steps to Reproduce
Pass a static list of document dictionaries to rerank().
Inspect the original document list after the function completes; notice that the dictionaries have been altered to include the "rerank_score" key.
Call get_reranker() concurrently using multiple Python threads before the model finishes loading to observe race conditions during model initialization.
Expected Behavior
The rerank() method should return a fresh list containing shallow/deep copies of the dictionaries, leaving the user's original input objects completely pristine.
Thread locks (threading.Lock) should gate the lazy loader and singleton instantiation to guarantee the heavy model weights are loaded into memory exactly once.
Screenshots / Logs
No response
Environment
=
GSSoC '26