barrel_rerank (barrel_rerank v1.0.0)

View Source

Async cross-encoder reranking server with request multiplexing

A gen_server that manages communication with a Python cross-encoder server. Supports concurrent requests by tracking request IDs and routing responses back to the correct callers.

Cross-encoders score query-document pairs directly, providing more accurate relevance scores than bi-encoder similarity for reranking candidate results.

Requirements

   pip install transformers torch

Usage

   %% Start the reranker
   {ok, Server} = barrel_rerank:start_link(#{}).
  
   %% Make concurrent rerank requests
   spawn(fun() -> barrel_rerank:rerank(Server, Query1, Docs1) end).
   spawn(fun() -> barrel_rerank:rerank(Server, Query2, Docs2) end).
  
   %% Stop when done
   barrel_rerank:stop(Server).

Request Multiplexing

Multiple Erlang processes can call rerank/3,4 concurrently. Each request is assigned a unique ID and sent to Python. The Python server includes the ID in its response, allowing this gen_server to route responses to the correct waiting callers.

Configuration

   Config = #{
       python => "python3",                               %% Python executable (fallback)
       model => "cross-encoder/ms-marco-MiniLM-L-6-v2",   %% Model name
       timeout => 120000                                  %% Timeout in ms
   }.

Managed Venv

The rerank server uses the managed venv from barrel_rerank_venv. Dependencies (transformers, torch, uvloop) are auto-installed when the application starts.

Supported Models

- "cross-encoder/ms-marco-MiniLM-L-6-v2" - Default, fast, good quality - "cross-encoder/ms-marco-MiniLM-L-12-v2" - Better quality, slower - "BAAI/bge-reranker-base" - Good quality - "BAAI/bge-reranker-large" - Best quality, slowest

Typical two-stage retrieval:

   %% Stage 1: Fast vector search (top 100)
   {ok, Candidates} = barrel_vectordb:search(Store, Query, #{k => 100}),
  
   %% Stage 2: Rerank top candidates
   Docs = [maps:get(text, C) || C <- Candidates],
   {ok, Ranked} = barrel_rerank:rerank(Server, Query, Docs),
  
   %% Get top 10 after reranking
   Top10Indices = [Idx || {Idx, _Score} <- lists:sublist(Ranked, 10)],
   Top10 = [lists:nth(Idx + 1, Candidates) || Idx <- Top10Indices].

Summary

Functions

Check if reranker is available.

Get model info.

Get model info with timeout.

Rerank documents by relevance to query. Returns list of {Index, Score} tuples sorted by score descending.

Rerank documents with options. Options: - top_k: Limit number of results returned - timeout: Override default timeout

Start the rerank server.

Stop the reranker and close the port.

Types

rerank_result/0

-type rerank_result() :: {Index :: non_neg_integer(), Score :: float()}.

Functions

available(Server)

-spec available(pid()) -> boolean().

Check if reranker is available.

handle_call(_, From, State)

handle_cast(Msg, State)

handle_info(Msg, State)

info(Server)

-spec info(pid()) -> {ok, map()} | {error, term()}.

Get model info.

info(Server, Timeout)

-spec info(pid(), timeout()) -> {ok, map()} | {error, term()}.

Get model info with timeout.

init(Config)

rerank(Server, Query, Documents)

-spec rerank(pid(), binary(), [binary()]) -> {ok, [rerank_result()]} | {error, term()}.

Rerank documents by relevance to query. Returns list of {Index, Score} tuples sorted by score descending.

rerank(Server, Query, Documents, Options)

-spec rerank(pid(), binary(), [binary()], map()) -> {ok, [rerank_result()]} | {error, term()}.

Rerank documents with options. Options: - top_k: Limit number of results returned - timeout: Override default timeout

start_link(Config)

-spec start_link(map()) -> {ok, pid()} | {error, term()}.

Start the rerank server.

stop(Server)

-spec stop(pid()) -> ok.

Stop the reranker and close the port.

terminate(Reason, State)