ConceptsINTERNALS.md

Bi-encoder vs cross-encoder

Two ways to use a neural model to match a query to documents. Bi-encoders find candidates fast, and cross-encoders re-rank a short list.

  • A bi-encoder reads the query and each document separately.
  • So it can read every document once, ahead of time, and save the result.
  • A cross-encoder reads the query and one document together.
  • So it must run once for every document, on every search.

Try this: drag N up to a million, then press Run a search a few times.

Try it

This page needs JavaScript.

What just happened

No model ran here. The page only counts how often each kind of model would have to run. That count is the whole difference.

Where you meet it

A search app has a million documents. It cannot read them all with a slow model on every search. So it uses a fast first step to find about a hundred candidates, then a slow, careful model to put those hundred in order. This is called retrieve and rerank.

Where it breaks

The cross-encoder cannot search a big collection. Its cost grows with every document, and nothing can be saved. The bi-encoder is quick, but its document vector is made before the query exists. The text “The hotel has no pool” becomes one vector that has to serve a search about pools, a search about prices and a search about noise. Pick how many top results the cross-encoder rereads.

This page counts work. It does not say which model is more accurate on your data. For that you need graded searches and a measure like nDCG.

Check yourself

A new document is added to the collection. What must each system do before the next search?

The bi-encoder must read the new document once and save its vector. The cross-encoder needs nothing in advance, because it never saved anything. It just reads the new document along with the query when the search runs.

You will run one search over 1,000 documents, once. Which system does fewer model passes?

The cross-encoder: 1,000 passes against 1,001 for the bi-encoder, which spends 1,000 saving the vectors and 1 on the query. Saving only pays back from the second search. That is the “Start over” then “Run a search” experiment above.

Why can't a cross-encoder save a vector for each document?

From the first layer on, each document word looks at the query words. Nothing the model computes for the document is independent of the query, so there is nothing to compute early and reuse.

Used in

Go deeper