--- draft: false title: "Static Embeddings: should you pay attention?" slug: static-embeddings short_description: "Static embeddings are a thing back! Is the encoding speedup worth a try? We checked that!" description: "Static embeddings are a thing back! Is the encoding speedup worth a try? We checked that!" preview_image: /blog/static-embeddings/preview.png date: 2025-01-17T09:13:00.000Z author: Kacper Ćukawski featured: false --- In the world of resource-constrained computing, a quiet revolution is taking place. While transformers dominate leaderboards with their impressive capabilities, static embeddings are making an unexpected comeback, offering remarkable speed improvements with surprisingly small quality trade-offs. **We evaluated how Qdrant users can benefit from this renaissance, and the results are promising**. ## What makes static embeddings different? Transformers are often seen as the only way to go when it comes to embeddings. The use of attention mechanisms helps to capture the relationships between the input tokens, so each token gets a vector representation that is context-aware and defined not only by the token itself but also by the surrounding tokens. Transformer-based models easily beat the quality of the older methods, such as word2vec or GloVe, which could only create a single vector embedding per each word. As a result, the word "bank" would have identical representation in the context of "river bank" and "financial institution".  Transformer-based models would represent the word "bank" differently in each of the contexts. However, transformers come with a cost. They are computationally expensive and usually require a lot of memory, although the embeddings models usually have fewer parameters than the Large Language Models. Still, GPUs are preferred to be used, even for inference. Static embeddings are still a thing, though! [MinishLab](https://minishlab.github.io/) introduced their [model2vec technique](https://huggingface.co/blog/Pringled/model2vec) in October 2024, achieving a remarkable 15x reduction in model size and up to 500x speed increase while maintaining impressive performance levels. Their idea was to distill the knowledge from the transformer-based sentence transformer and create a static embedding model that would be much faster and less memory-consuming. This introduction seems to be a catalyst for the static embeddings renaissance, as we can see static embeddings to be integrated even into popular [Sentence Transformers](https://www.sbert.net/) library. The [recent blog post on the Hugging Face blog](https://huggingface.co/blog/static-embeddings) by [Tom Aarsen](https://www.tomaarsen.com) reveals how to train a static embedding model using Sentence Transformers and still get up to 85% of transformer-level quality at a fraction of computational cost. The blog post also introduces an embedding model for English text retrieval, which is called `static-retrieval-mrl-en-v1`. ## Static embeddings in Qdrant From the vector database perspective, static embeddings are not different from any other embedding models. They are dense vectors after all, and you can simply store them in a Qdrant collection. Here is how you do it with the `sentence-transformers/static-retrieval-mrl-en-v1` model: ```python import uuid from sentence_transformers import SentenceTransformer from qdrant_client import QdrantClient, models # The model produces vectors of size 1024 model = SentenceTransformer( "sentence-transformers/static-retrieval-mrl-en-v1" ) # Let's assume we have a collection "my_collection" # with a single vector called "static" client = QdrantClient("http://localhost:6333") # Calling the sentence transformer model to encode # the text is not different compared to any other model client.upsert( "my_collection", points=[ models.PointStruct( id=uuid.uuid4().hex, vector=model.encode("Hello, world!"), payload={"static": "Hello, world!"}, ) ] ) ``` The retrieval is not going to be any faster just because you use static embeddings. However, **you will experience a huge speedup in creating the vectors from your data**, what is usually a bottleneck. The Hugging Face blog post mentions that the model might be even up to 400x faster on a CPU than the state-of-the-art embedding model. We didn't perform any proper benchmarking of the encoding speed, but one of the experiments done on `TREC-COVID` dataset from [BeIR](https://github.com/beir-cellar/beir) shows that we can **encode and fully index 171K documents in Qdrant in around 7.5 minutes**. All of it done on a consumer-grade laptop, without GPU acceleration. ## Quantization of the static embeddings What can actually make the retrieval faster is the use of Matryoshka Embeddings, as the `static-retrieval-mrl-en-v1` model was trained with that technique in mind. However, that's not the only way to speed up search. Quantization methods are really popular among our users, and we were curious to check if they might be applied to the static embeddings with the same success. We took the `static-retrieval-mrl-en-v1` model and tested it on various subsets of [BeIR](https://github.com/beir-cellar/beir) with and without Binary Quantization, to see how much if affects the retrieval quality. The results are really promising, as shown in our NDCG@10 measurements (a metric that evaluates the ranking quality of search results, with higher scores indicating better performance):
| NDCG@10 | ||
|---|---|---|
| Dataset | Original vectors | Binary Quantization, no rescoring |
| SciFact | 0.59348 | 0.54195 |
| TREC-COVID | 0.4428 | 0.44185 |
| ArguAna | 0.44393 | 0.42164 |
| NFCorpus | 0.30045 | 0.28027 |