This model is a lightweight, 32 million parameter ColBERT with a projection dimension of 64. It is built on top of Ettin-32M, meaning it benefits from all of ModernBERT's architectural efficiencies. Despite this extreme efficiency, it is the best-performer "edge-sized" retriever, outperforming ColBERTv2 and many models with over 10 times more parameters. It can create multi-vector representations for documents of up to 32,000 tokens and is fully compatible with the PyLate library.
This model can be used with Sentence Transformers as a multi-vector (ColBERT-style late interaction) retriever via the MultiVectorEncoder:
pip install "sentence-transformers>=6.0.0"
from sentence_transformers import MultiVectorEncoder
model = MultiVectorEncoder("mixedbread-ai/mxbai-edge-colbert-v0-32m")
query = "Which planet is known as the Red Planet?"
documents = [
"Venus is often called Earth's twin because of its similar size and proximity.",
"Mars, known for its reddish appearance, is often referred to as the Red Planet.",
"Jupiter, the largest planet in our solar system, has a prominent red spot.",
"Saturn, famous for its rings, is sometimes mistaken for the Red Planet.",
]
query_embeddings = model.encode_query(query)
document_embeddings = model.encode_document(documents)
print(query_embeddings.shape, document_embeddings[0].shape)
# (12, 64) (18, 64)
# MaxSim late-interaction scoring (higher is more relevant)
scores = model.similarity(query_embeddings, document_embeddings)
print(scores)
# tensor([[11.2081, 11.5308, 11.4104, 11.4756]])
Once installed, the model is immediately ready to use to generate representations and index documents:
from pylate import indexes, models, retrieve
# Step 1: Load the model
model = models.ColBERT(
model_name_or_path="mixedbread-ai/mxbai-edge-colbert-v0-32m",
)
# Step 2: Initialize an index (here, PLAID, for larger document collections)
index = indexes.PLAID(
index_folder="pylate-index",
index_name="index",
override=True, # This overwrites the existing index if any
)
# Step 3: Encode your documents
documents_ids = ["1", "2", "3"]
documents = ["document 1 text", "document 2 text", "document 3 text"]
documents_embeddings = model.encode(
documents,
batch_size=32,
is_query=False, # Ensure that it is set to False to indicate that these are documents, not queries
show_progress_bar=True,
)
# Step 4: Add document embeddings to the index by providing embeddings and corresponding ids
index.add_documents(
documents_ids=documents_ids,
documents_embeddings=documents_embeddings,
)
That's all you need to do to encode a full collection! Your documents are indexed and ready to be queried:
# Step 5.1: Initialize the ColBERT retriever
retriever = retrieve.ColBERT(index=index)
# Step 2: Encode the queries
queries_embeddings = model.encode(
["query for document 3", "query for document 1"],
batch_size=32,
is_query=True, # # Ensure that it is set to False to indicate that these are queries
show_progress_bar=True,
)
# Step 3: Retrieve top-k documents
scores = retriever.retrieve(
queries_embeddings=queries_embeddings,
k=10, # Retrieve the top 10 matches for each query
)
Thanks to its extreme parameter efficiency, this model is particularly well-suited to being used as a re-ranker following an even more lightweight first stage retrieval, such as static embeding models. Re-ranking is just as straigthforward:
If you use our model, please cite the associated tech report:
@misc{takehi2025fantasticsmallretrieverstrain,
title={Fantastic (small) Retrievers and How to Train Them: mxbai-edge-colbert-v0 Tech Report},
author={Rikiya Takehi and Benjamin Clavié and Sean Lee and Aamir Shakir},
year={2025},
eprint={2510.14880},
archivePrefix={arXiv},
primaryClass={cs.IR},
url={https://arxiv.org/abs/2510.14880},
}
If you specifically use its projection heads, or discuss their effect, please cite our report on using different projections for ColBERT models:
@misc{clavie2025simpleprojectionvariantsimprove,
title={Simple Projection Variants Improve ColBERT Performance},
author={Benjamin Clavié and Sean Lee and Rikiya Takehi and Aamir Shakir and Makoto P. Kato},
year={2025},
eprint={2510.12327},
archivePrefix={arXiv},
primaryClass={cs.IR},
url={https://arxiv.org/abs/2510.12327},
}
Finally, if you use PyLate in your work, please cite PyLate itself:
@misc{PyLate,
title={PyLate: Flexible Training and Retrieval for Late Interaction Models},
author={Chaffin, Antoine and Sourty, Raphaël},
url={https://github.com/lightonai/pylate},
year={2024}
}
Files
19 files · 300 MBWeights 131 MB (safetensors). Sizes and sha256 from the signed manifest.
import os
os.environ["HF_ENDPOINT"] = "https://freeweights.allternit.com"
from transformers import AutoModel, AutoTokenizer
tok = AutoTokenizer.from_pretrained("mixedbread-ai/mxbai-edge-colbert-v0-32m", revision="bb13a29ec9b1e7edd4ba8f7a0776c48b55cbad66")
model = AutoModel.from_pretrained("mixedbread-ai/mxbai-edge-colbert-v0-32m", revision="bb13a29ec9b1e7edd4ba8f7a0776c48b55cbad66", device_map="auto")
sentence-transformersEmbed text with sentence-transformers.
import os
os.environ["HF_ENDPOINT"] = "https://freeweights.allternit.com"
from sentence_transformers import SentenceTransformer
model = SentenceTransformer("mixedbread-ai/mxbai-edge-colbert-v0-32m", revision="bb13a29ec9b1e7edd4ba8f7a0776c48b55cbad66")
vectors = model.encode(["Hello"])