Implementation:Neuml Txtai Similarity
| Knowledge Sources | |
|---|---|
| Domains | Text_Similarity, NLP |
| Last Updated | 2026-02-09 00:00 GMT |
Overview
Multi-method text similarity computation pipeline supporting zero-shot, cross-encoder, and late interaction scoring modes.
Description
The Similarity class extends Labels to compute similarity scores between a query and a list of candidate texts. It provides a unified interface over three distinct similarity computation strategies:
- Zero-shot classification (default): Uses the parent
Labelspipeline to score texts against the query as a candidate label. This inverts the typical classification pattern -- the query becomes a label and each text becomes an input to classify. The resulting scores are transposed and sorted by descending similarity.
- Cross-encoder (
crossencode=True): Loads aCrossEncodermodel that jointly encodes query-text pairs to produce a single relevance score. Cross-encoders are generally more accurate than bi-encoders but cannot pre-encode documents independently.
- Late interaction (
lateencode=True): Delegates to aLateEncoderinstance that computes token-level maximum similarity (ColBERT-style). This preserves more fine-grained matching information than single-vector approaches.
The constructor's branching logic determines which backend is initialized. When lateencode=True, only the LateEncoder is created and the parent Labels constructor is skipped entirely. When crossencode=True, the parent constructor is called with dynamic=False to load a text-classification pipeline, then wrapped in a CrossEncoder. Otherwise, the parent constructor runs normally for zero-shot classification.
Usage
Use this pipeline to compute semantic similarity between a query and a set of candidate texts. Choose the backend based on the accuracy/speed tradeoff: zero-shot for convenience with no specialized model, cross-encoder for highest accuracy at slower speed, or late interaction for token-level matching with moderate speed. The Similarity pipeline is the core scoring component used by the Reranker pipeline.
Code Reference
Source Location
- Repository: txtai
- File:
src/python/txtai/pipeline/text/similarity.py - Lines: L1-83
Class Definition
class Similarity(Labels):
"""
Computes similarity between query and list of text using a transformers model.
"""
Constructor Signature
def __init__(self, path=None, quantize=False, gpu=True, model=None, dynamic=True,
crossencode=False, lateencode=False, **kwargs):
Call Signature
def __call__(self, query, texts, multilabel=True, **kwargs):
Import
from txtai.pipeline import Similarity
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| query | str or list | Yes | Query text or list of query texts. For zero-shot mode, the query is used as a candidate label for the Labels pipeline. A single string is handled natively; a list enables batch scoring.
|
| texts | list of str | Yes | List of candidate texts to score against the query. |
| multilabel | bool or None | No | Controls score normalization. True: scores are independent (default). False: scores normalized to sum to 1. None: raw scores.
|
| kwargs | dict | No | Additional keyword arguments passed to the parent Labels.__call__ method.
|
Outputs
| Name | Type | Description |
|---|---|---|
| results | list of tuple | If query is a string, returns a 1D list of (id, score) tuples sorted by highest score, where id is the index in texts. If query is a list, returns a 2D list with one row per query.
|
Key Methods
__call__(query, texts, multilabel=True, **kwargs)
The call method dispatches to the appropriate backend:
# Cross-encoder path
if self.crossencoder:
return self.crossencoder(query, texts, multilabel)
# Late interaction path
if self.lateencoder:
return self.lateencoder(query, texts)
# Zero-shot path: invert labels and texts
scores = super().__call__(texts, [query] if isinstance(query, str) else query, multilabel, **kwargs)
For the zero-shot path, the method performs a matrix transposition to convert from "text x label" scores to "query x text" scores, then sorts by descending score.
encode(data, category)
def encode(self, data, category):
Delegates to self.lateencoder.encode() when late interaction is enabled; otherwise returns the data unchanged. This method provides a consistent encoding interface used by the Reranker and other pipelines.
Constructor Branching Logic
| Mode | Condition | Behavior |
|---|---|---|
| Late interaction | lateencode=True |
Creates LateEncoder(path, gpu, **kwargs). Parent constructor is not called.
|
| Cross-encoder | crossencode=True |
Calls parent with dynamic=False to load a text-classification pipeline, then wraps it in CrossEncoder(model=self.pipeline).
|
| Zero-shot | Default | Calls parent normally (dynamic=True), loading a zero-shot-classification pipeline.
|
Inheritance Chain
Similarity -> Labels -> HFPipeline -> Tensors -> Pipeline
Similarity inherits the full zero-shot classification pipeline from Labels and adds cross-encoder and late interaction modes as alternatives.
Usage Examples
Zero-Shot Similarity (Default)
from txtai.pipeline import Similarity
# Default zero-shot similarity
similarity = Similarity()
# Score texts against a query
results = similarity("feel good story", [
"Maine moose are getting ticks at an alarming rate",
"North Atlantic whale population high",
"Boy scouts donate food to local food bank"
])
# Results: [(2, 0.89), (1, 0.08), (0, 0.03)]
for idx, score in results:
print(f"Text {idx}: {score:.4f}")
Cross-Encoder Similarity
from txtai.pipeline import Similarity
# Load a cross-encoder model for precise scoring
similarity = Similarity("cross-encoder/ms-marco-MiniLM-L-6-v2", crossencode=True)
results = similarity("What is Python?", [
"Python is a programming language created by Guido van Rossum",
"A python is a large constricting snake",
"Java is another popular language"
])
for idx, score in results:
print(f"Text {idx}: {score:.4f}")
Late Interaction Similarity
from txtai.pipeline import Similarity
# Load with ColBERT-style late interaction scoring
similarity = Similarity(lateencode=True)
results = similarity("machine learning algorithms", [
"Supervised learning requires labeled training data",
"The restaurant serves excellent pasta",
"Random forests are ensemble learning methods"
])
for idx, score in results:
print(f"Text {idx}: {score:.4f}")
Batch Queries
from txtai.pipeline import Similarity
similarity = Similarity()
texts = ["Climate change effects", "New smartphone release", "Stock market trends"]
queries = ["environmental science", "technology gadgets"]
results = similarity(queries, texts)
# Returns a 2D list: one row of (id, score) per query
for i, row in enumerate(results):
print(f"Query {i}: {[(idx, f'{score:.3f}') for idx, score in row]}")