ColBERT and PLAID: Late Interaction Models That Make Neural Search Actually Fast
ColBERT and PLAID: Late Interaction Models That Make Neural Search Actually Fast
The dominant paradigm in neural search encodes entire documents into single dense vectors, then retrieves via approximate nearest neighbor (ANN) search. This is fast but lossy: compressing a 500-word document into one 768-dimensional vector discards fine-grained token interactions that matter for relevance. Cross-encoders solve this by jointly attending over query and document tokens, but they require running BERT inference per (query, document) pair at retrieval time, which is computationally infeasible for collections exceeding a few thousand documents.
ColBERT (Contextualized Late Interaction over BERT) introduced a third paradigm: late interaction. Rather than a single vector per document, ColBERT produces one embedding per token, then scores query-document relevance via cheap MaxSim operations over these token embeddings. ColBERT v2 and the PLAID engine made this practical at scale through aggressive compression and pruning, achieving sub-millisecond latency on million-document collections.
The Late Interaction Paradigm
In ColBERT, a query q with m tokens and a document d with n tokens produce embedding matrices Q ∈ ℝ^(m×dim) and D ∈ ℝ^(n×dim) respectively. The relevance score is computed as:
Score(q, d) = Σᵢ maxⱼ Qᵢ · DⱼᵀFor each query token embedding, find the maximum cosine similarity against all document token embeddings, then sum these maxima. This MaxSim operation captures fine-grained token-level matches while remaining decomposable: document embeddings can be precomputed and stored offline.
The key insight is that this is neither a bi-encoder (single vector per text) nor a cross-encoder (joint attention). The query and document encoders run independently, but scoring preserves token-level granularity. This yields relevance quality approaching cross-encoders while keeping document encoding offline.
ColBERT v2: Residual Compression
The naive ColBERT approach stores n full-precision vectors per document. For a collection of 10 million documents averaging 150 tokens each, that is 1.5 billion 128-dimensional vectors at 4 bytes per float: roughly 768 GB. Clearly impractical.
ColBERT v2 addresses this with residual compression. The approach:
- Centroid assignment: cluster all token embeddings into
kcentroids (typically 2^16 = 65,536) using k-means. - Residual quantization: for each token embedding, store the centroid ID (2 bytes) plus a quantized residual vector. The residual is the difference between the original embedding and its assigned centroid, compressed to 1-2 bits per dimension.
- Decompression at scoring time: reconstruct the approximate embedding as
centroid[id] + decompress(residual).
This reduces storage from 512 bytes per token (128 dims × 4 bytes) to roughly 18-34 bytes per token, a 15-28x compression ratio with minimal quality loss. The centroid structure also enables inverted-index-style candidate generation.
# Conceptual ColBERT v2 scoring with residual decompression
def score_document(query_embeddings, doc_centroid_ids, doc_residuals, centroids):
# Reconstruct document token embeddings from compressed representation
doc_embeddings = centroids[doc_centroid_ids] + decompress(doc_residuals)
# MaxSim: for each query token, find max similarity across doc tokens
similarities = query_embeddings @ doc_embeddings.T # (m, n) matrix
max_per_query_token = similarities.max(dim=1).values # (m,)
return max_per_query_token.sum()PLAID: Performance-optimized Late Interaction Driver
PLAID (2022-2023, Santhanam et al.) is the retrieval engine that makes ColBERT v2 practical for production workloads. It introduces a three-stage pipeline that progressively filters candidates:
Stage 1: Centroid Interaction
For each query token, compute its similarity against all centroids. Select the top-nprobe centroids per query token. The union of documents containing tokens assigned to these centroids forms the initial candidate set. This is essentially an inverted index lookup using centroid IDs as posting list keys.
This stage reduces the candidate pool from millions to tens of thousands with a few matrix multiplications.
Stage 2: Centroid-Based Approximate Scoring
For the candidate documents from Stage 1, compute an approximate score using only the centroid assignments (without decompressing residuals). Each document token's embedding is approximated by its centroid alone:
ApproxScore(q, d) = Σᵢ maxⱼ Qᵢ · centroid[doc_token_j_centroid]ᵀThis is extremely fast because centroid embeddings are already in memory. The top-k' candidates (typically a few hundred) pass to Stage 3.
Stage 3: Full Residual Decompression and Exact Scoring
Only for the final few hundred candidates, decompress the residual vectors and compute the full MaxSim score. This gives exact ColBERT v2 scores but only for a tiny fraction of the collection.
Latency Breakdown
On a single CPU thread with 8.8 million passages (MS MARCO):
| Stage | Candidates | Latency |
|---|---|---|
| Centroid interaction | Full collection → ~30K | ~2ms |
| Approximate scoring | 30K → 1K | ~3ms |
| Full decompression | 1K → final top-k | ~3ms |
| Total | ~8ms |
For comparison, a standard dense retriever with HNSW takes 5-15ms but produces significantly lower-quality results. A cross-encoder re-ranker over 1000 candidates takes 2-5 seconds.
Why This Matters: The Quality Gap
On MS MARCO passage ranking (MRR@10):
| Method | MRR@10 | Latency |
|---|---|---|
| BM25 | 0.187 | <1ms |
| Dense bi-encoder (DPR) | 0.311 | ~10ms |
| ColBERT v2 + PLAID | 0.397 | ~8ms |
| Cross-encoder (monoBERT) | 0.401 | ~3000ms |
ColBERT v2 closes 97% of the gap between dense bi-encoders and cross-encoders while maintaining latency comparable to ANN search. The token-level matching captures phenomena that single-vector representations miss: multi-aspect queries, rare terms, and negation.
The Deferred Computation Principle
The architectural elegance of late interaction lies in what it defers. Consider the information flow:
- Offline (indexing time): encode all document tokens through BERT. Compress and store.
- Online (query time): encode query tokens through BERT (fast, since queries are short). Then pure arithmetic: matrix multiplications and argmax operations.
No neural network runs at the query-document interaction stage. The "intelligence" is baked into the token embeddings during encoding; retrieval is pure linear algebra. This is why PLAID achieves single-digit millisecond latency despite operating over token-level representations.
JaColBERT and Multilingual Extensions
The late interaction paradigm generalizes across languages without architectural changes. JaColBERT (2024) demonstrated that training ColBERT on Japanese text with appropriate tokenization produces state-of-the-art Japanese retrieval without language-specific modifications. The MaxSim operation is language-agnostic, operating over whatever token embeddings the encoder produces.
This contrasts with sparse retrieval methods (BM25, SPLADE) that require language-specific stemming, tokenization, and stopword handling.
Practical Deployment Considerations
Memory footprint: ColBERT v2 with 2-bit residuals requires ~25 GB for 100M passages. Viable for single-machine deployment with commodity RAM.
GPU acceleration: the centroid interaction and approximate scoring stages are trivially parallelizable on GPU. PLAID on a single A100 achieves sub-millisecond latency for the full pipeline.
Index updates: unlike HNSW graphs that require expensive re-linking for insertions, ColBERT indices are append-friendly. New documents simply add entries to the centroid inverted lists. Periodic centroid retraining (offline) maintains quality as the distribution shifts.
Hybrid retrieval: PLAID can run as a first-stage retriever with a lightweight cross-encoder re-ranker on the final 10-50 results, achieving near-perfect relevance at under 100ms total latency.
Conclusion
ColBERT's late interaction paradigm resolves the fundamental tension in neural retrieval: you can have token-level matching granularity without the prohibitive cost of cross-attention at retrieval time. The PLAID engine's three-stage progressive filtering makes this practical, delivering cross-encoder-quality relevance at BM25-competitive latency. For anyone building search systems where relevance quality matters but latency budgets are tight, this architecture represents the current Pareto frontier.