Two-Tower Retrieval Architectures
Two separately-weighted networks map a query and a candidate item into the same vector space, so ranking millions of candidates collapses into a fast dot-product lookup instead of running the full model on every pair.
Prerequisites: Siamese and Twin-Tower Networks, Learned Embeddings for Categorical Features
Given one query — say, a target factor exposure — and a universe of a million candidate stocks, how do you rank all million by relevance without running an expensive joint model on all million query-candidate pairs, every single time a query arrives? Comparing every pair directly is far too slow to do live. You need to do the expensive work once, in advance, and leave only a cheap operation for query time.
The analogy: two catalogs, one shelf coordinate system
A library keeps a subject catalog and a title catalog — built differently, indexed differently — but both ultimately point to the same physical shelf coordinates. Find a book's shelf number from either catalog and matching becomes trivial: just compare coordinates. A two-tower architecture builds exactly this: one tower encodes the query, a separately weighted tower encodes the item, and both are trained so their outputs land in the same shared vector space, even though the towers themselves can differ in architecture.
The mechanics
Query tower and item tower are trained jointly so that matching pairs score high on a dot product:
In words: the relevance of an item to a query is just how aligned their two vectors are — no joint computation between them at inference time. Crucially, because the item tower doesn't depend on the query, every item's embedding can be precomputed once and stored; only the query tower needs to run live, followed by a fast nearest-neighbor lookup.
Worked example 1: ranking three candidates
Query embedding . Three precomputed item embeddings: , , . Dot products: ; ; . Ranking: B (4) > C (3) > A (2) — pure arithmetic, no rerun of any network on the pair.
Worked example 2: why precomputation matters at scale
Suppose scoring one query-item pair with a full joint model costs 1 unit of compute, and the universe has candidates. A joint (cross-encoder) approach costs units per query. A two-tower approach precomputes all item embeddings once (a one-time -unit cost, amortized across all future queries), then each query costs only 1 unit to encode plus a cheap approximate-nearest-neighbor search — turning a per-query cost of a million units into a handful.
Two-tower architectures separate the expensive part (encoding items) from the cheap part (comparing them), by forcing query and item embeddings into a shared space where relevance collapses to a dot product — trading some accuracy against a full joint model for retrieval speed that scales to millions of candidates.
What this means in practice
In a factor-screening pipeline, the item tower can encode the entire investable universe overnight into stored vectors; at query time, only the query tower (e.g., encoding "target exposure profile") runs live, followed by an approximate-nearest-neighbor search over the precomputed vectors — the same pattern used by search engines and recommender systems to serve results in milliseconds.
Don't confuse two-tower retrieval with a cross-encoder, which feeds the query and item together into one joint network and is substantially more accurate because it can model interactions between them directly — but is far too slow to run over millions of candidates per query. The standard production pattern is to use a two-tower model for fast first-pass retrieval of a shortlist, then a cross-encoder to rerank only that shortlist.
Related concepts
Practice in interviews
Further reading
- Huang et al., Learning Deep Structured Semantic Models for Web Search (2013)