From a5a578c92ac43f5e305b97972985003bfaa64f01 Mon Sep 17 00:00:00 2001 From: Bogdan Kostic Date: Thu, 12 Feb 2026 15:57:16 +0100 Subject: [PATCH 1/7] Automatically call warm_up() if model is not loaded in FastembedRanker --- .../components/rankers/fastembed/ranker.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/integrations/fastembed/src/haystack_integrations/components/rankers/fastembed/ranker.py b/integrations/fastembed/src/haystack_integrations/components/rankers/fastembed/ranker.py index 6120bac4a3..11158371ad 100644 --- a/integrations/fastembed/src/haystack_integrations/components/rankers/fastembed/ranker.py +++ b/integrations/fastembed/src/haystack_integrations/components/rankers/fastembed/ranker.py @@ -177,8 +177,7 @@ def run(self, query: str, documents: list[Document], top_k: int | None = None) - raise ValueError(msg) if self._model is None: - msg = "The ranker model has not been loaded. Please call warm_up() before running." - raise RuntimeError(msg) + self.warm_up() fastembed_input_docs = self._prepare_fastembed_input_docs(documents) From 1cda1c19cb0c2203b99d683798f278622b33ada0 Mon Sep 17 00:00:00 2001 From: Bogdan Kostic Date: Thu, 12 Feb 2026 15:57:32 +0100 Subject: [PATCH 2/7] Remove explicit call to warm_up() in ranker_example.py --- integrations/fastembed/examples/ranker_example.py | 1 - 1 file changed, 1 deletion(-) diff --git a/integrations/fastembed/examples/ranker_example.py b/integrations/fastembed/examples/ranker_example.py index 593334e905..235fe4f814 100644 --- a/integrations/fastembed/examples/ranker_example.py +++ b/integrations/fastembed/examples/ranker_example.py @@ -11,7 +11,6 @@ ] ranker = FastembedRanker(model_name="Xenova/ms-marco-MiniLM-L-6-v2") -ranker.warm_up() reranked_documents = ranker.run(query=query, documents=documents)["documents"] From ce1e5da28ba593dcf105efa8d58dfa36dbc03a48 Mon Sep 17 00:00:00 2001 From: Bogdan Kostic Date: Thu, 12 Feb 2026 16:25:40 +0100 Subject: [PATCH 3/7] Add unit tests --- .../tests/test_fastembed_document_embedder.py | 14 ++++++++++++++ .../fastembed/tests/test_fastembed_ranker.py | 16 +++++++++++++++- .../test_fastembed_sparse_document_embedder.py | 13 +++++++++++++ .../tests/test_fastembed_sparse_text_embedder.py | 14 ++++++++++++++ .../tests/test_fastembed_text_embedder.py | 14 ++++++++++++++ 5 files changed, 70 insertions(+), 1 deletion(-) diff --git a/integrations/fastembed/tests/test_fastembed_document_embedder.py b/integrations/fastembed/tests/test_fastembed_document_embedder.py index 37a7a0c581..9b673f0f01 100644 --- a/integrations/fastembed/tests/test_fastembed_document_embedder.py +++ b/integrations/fastembed/tests/test_fastembed_document_embedder.py @@ -281,6 +281,20 @@ def test_embed_metadata(self): parallel=None, ) + def test_run_calls_warm_up(self): + embedder = FastembedDocumentEmbedder() + assert embedder.embedding_backend is None + + mock_backend = MagicMock() + mock_backend.embed.return_value = [[0.1, 0.2, 0.3]] + + with patch.object( + embedder, "warm_up", side_effect=lambda: setattr(embedder, "embedding_backend", mock_backend) + ) as mock_warm_up: + embedder.run(documents=[Document(content="test document")]) + + mock_warm_up.assert_called_once() + @pytest.mark.integration def test_run(self): embedder = FastembedDocumentEmbedder( diff --git a/integrations/fastembed/tests/test_fastembed_ranker.py b/integrations/fastembed/tests/test_fastembed_ranker.py index 0985762613..79fa527dda 100644 --- a/integrations/fastembed/tests/test_fastembed_ranker.py +++ b/integrations/fastembed/tests/test_fastembed_ranker.py @@ -2,7 +2,7 @@ # # SPDX-License-Identifier: Apache-2.0 -from unittest.mock import MagicMock +from unittest.mock import MagicMock, patch import numpy as np import pytest @@ -257,6 +257,20 @@ def test_embed_metadata(self): parallel=None, ) + def test_run_calls_warm_up(self): + """ + Unit test to check that warm_up is called when run is called for the first time. + """ + ranker = FastembedRanker() + + mock_model = MagicMock() + mock_model.rerank.return_value = [0.5] + + with patch.object(ranker, "warm_up", side_effect=lambda: setattr(ranker, "_model", mock_model)) as mock_warm_up: + ranker.run(query="test query", documents=[Document(content="test document")]) + + mock_warm_up.assert_called_once() + @pytest.mark.integration def test_run(self): ranker = FastembedRanker(model_name="Xenova/ms-marco-MiniLM-L-6-v2", top_k=2) diff --git a/integrations/fastembed/tests/test_fastembed_sparse_document_embedder.py b/integrations/fastembed/tests/test_fastembed_sparse_document_embedder.py index 0b58d818aa..87d1c75375 100644 --- a/integrations/fastembed/tests/test_fastembed_sparse_document_embedder.py +++ b/integrations/fastembed/tests/test_fastembed_sparse_document_embedder.py @@ -304,6 +304,19 @@ def test_init_with_model_kwargs_parameters(self): assert embedder.model_kwargs == bm25_config + def test_run_calls_warm_up(self): + embedder = FastembedSparseDocumentEmbedder() + + mock_backend = MagicMock() + mock_backend.embed.return_value = [{"indices": [0], "values": [0.5]}] + + with patch.object( + embedder, "warm_up", side_effect=lambda: setattr(embedder, "embedding_backend", mock_backend) + ) as mock_warm_up: + embedder.run(documents=[Document(content="test document")]) + + mock_warm_up.assert_called_once() + @pytest.mark.integration def test_run_with_model_kwargs(self): """ diff --git a/integrations/fastembed/tests/test_fastembed_sparse_text_embedder.py b/integrations/fastembed/tests/test_fastembed_sparse_text_embedder.py index c9e3f77130..bb16e24bed 100644 --- a/integrations/fastembed/tests/test_fastembed_sparse_text_embedder.py +++ b/integrations/fastembed/tests/test_fastembed_sparse_text_embedder.py @@ -224,6 +224,20 @@ def test_init_with_model_kwargs_parameters(self): assert embedder.model_kwargs == bm25_config + def test_run_calls_warm_up(self): + embedder = FastembedSparseTextEmbedder() + assert embedder.embedding_backend is None + + mock_backend = MagicMock() + mock_backend.embed.return_value = [[0.1, 0.2, 0.3]] + + with patch.object( + embedder, "warm_up", side_effect=lambda: setattr(embedder, "embedding_backend", mock_backend) + ) as mock_warm_up: + embedder.run(text="test text") + + mock_warm_up.assert_called_once() + @pytest.mark.integration def test_run_with_model_kwargs(self): """ diff --git a/integrations/fastembed/tests/test_fastembed_text_embedder.py b/integrations/fastembed/tests/test_fastembed_text_embedder.py index da969dffa8..52cc051327 100644 --- a/integrations/fastembed/tests/test_fastembed_text_embedder.py +++ b/integrations/fastembed/tests/test_fastembed_text_embedder.py @@ -202,6 +202,20 @@ def test_run_wrong_incorrect_format(self): with pytest.raises(TypeError, match="FastembedTextEmbedder expects a string as input"): embedder.run(text=list_integers_input) + def test_run_calls_warm_up(self): + embedder = FastembedTextEmbedder() + assert embedder.embedding_backend is None + + mock_backend = MagicMock() + mock_backend.embed.return_value = [[0.1, 0.2, 0.3]] + + with patch.object( + embedder, "warm_up", side_effect=lambda: setattr(embedder, "embedding_backend", mock_backend) + ) as mock_warm_up: + embedder.run(text="test text") + + mock_warm_up.assert_called_once() + @pytest.mark.integration def test_run(self): embedder = FastembedTextEmbedder( From 9aef38237876451ad8f7692009cfdb7292b84a81 Mon Sep 17 00:00:00 2001 From: Bogdan Kostic Date: Thu, 12 Feb 2026 16:40:35 +0100 Subject: [PATCH 4/7] Fix typing issue --- .../components/rankers/fastembed/ranker.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/integrations/fastembed/src/haystack_integrations/components/rankers/fastembed/ranker.py b/integrations/fastembed/src/haystack_integrations/components/rankers/fastembed/ranker.py index 11158371ad..6f28ddc58c 100644 --- a/integrations/fastembed/src/haystack_integrations/components/rankers/fastembed/ranker.py +++ b/integrations/fastembed/src/haystack_integrations/components/rankers/fastembed/ranker.py @@ -178,7 +178,8 @@ def run(self, query: str, documents: list[Document], top_k: int | None = None) - if self._model is None: self.warm_up() - + assert self._model is not None + fastembed_input_docs = self._prepare_fastembed_input_docs(documents) scores = list( From 88f136b454226db7c56f486e291c0e3dc9cfdd71 Mon Sep 17 00:00:00 2001 From: Bogdan Kostic Date: Thu, 12 Feb 2026 16:49:10 +0100 Subject: [PATCH 5/7] Fix tying --- .../components/rankers/fastembed/ranker.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/integrations/fastembed/src/haystack_integrations/components/rankers/fastembed/ranker.py b/integrations/fastembed/src/haystack_integrations/components/rankers/fastembed/ranker.py index 6f28ddc58c..26878387f4 100644 --- a/integrations/fastembed/src/haystack_integrations/components/rankers/fastembed/ranker.py +++ b/integrations/fastembed/src/haystack_integrations/components/rankers/fastembed/ranker.py @@ -178,12 +178,11 @@ def run(self, query: str, documents: list[Document], top_k: int | None = None) - if self._model is None: self.warm_up() - assert self._model is not None - + fastembed_input_docs = self._prepare_fastembed_input_docs(documents) scores = list( - self._model.rerank( + self._model.rerank( # type: ignore[union-attr] query=query, documents=fastembed_input_docs, batch_size=self.batch_size, From e704865f0367f84bea3c3ed8806aa92b68248687 Mon Sep 17 00:00:00 2001 From: Bogdan Kostic Date: Thu, 12 Feb 2026 17:02:57 +0100 Subject: [PATCH 6/7] Update docstrings --- .../embedders/fastembed/fastembed_document_embedder.py | 2 -- .../embedders/fastembed/fastembed_sparse_document_embedder.py | 2 -- .../embedders/fastembed/fastembed_sparse_text_embedder.py | 1 - .../components/embedders/fastembed/fastembed_text_embedder.py | 1 - 4 files changed, 6 deletions(-) diff --git a/integrations/fastembed/src/haystack_integrations/components/embedders/fastembed/fastembed_document_embedder.py b/integrations/fastembed/src/haystack_integrations/components/embedders/fastembed/fastembed_document_embedder.py index c10b05d8c3..b2c28918dc 100644 --- a/integrations/fastembed/src/haystack_integrations/components/embedders/fastembed/fastembed_document_embedder.py +++ b/integrations/fastembed/src/haystack_integrations/components/embedders/fastembed/fastembed_document_embedder.py @@ -29,8 +29,6 @@ class FastembedDocumentEmbedder: batch_size=256, ) - doc_embedder.warm_up() - # Text taken from PubMed QA Dataset (https://huggingface.co/datasets/pubmed_qa) document_list = [ Document( diff --git a/integrations/fastembed/src/haystack_integrations/components/embedders/fastembed/fastembed_sparse_document_embedder.py b/integrations/fastembed/src/haystack_integrations/components/embedders/fastembed/fastembed_sparse_document_embedder.py index f20ce84d20..5fda8ffbbe 100644 --- a/integrations/fastembed/src/haystack_integrations/components/embedders/fastembed/fastembed_sparse_document_embedder.py +++ b/integrations/fastembed/src/haystack_integrations/components/embedders/fastembed/fastembed_sparse_document_embedder.py @@ -28,8 +28,6 @@ class FastembedSparseDocumentEmbedder: batch_size=32, ) - sparse_doc_embedder.warm_up() - # Text taken from PubMed QA Dataset (https://huggingface.co/datasets/pubmed_qa) document_list = [ Document( diff --git a/integrations/fastembed/src/haystack_integrations/components/embedders/fastembed/fastembed_sparse_text_embedder.py b/integrations/fastembed/src/haystack_integrations/components/embedders/fastembed/fastembed_sparse_text_embedder.py index 8824458a05..437ad3c7f3 100644 --- a/integrations/fastembed/src/haystack_integrations/components/embedders/fastembed/fastembed_sparse_text_embedder.py +++ b/integrations/fastembed/src/haystack_integrations/components/embedders/fastembed/fastembed_sparse_text_embedder.py @@ -28,7 +28,6 @@ class FastembedSparseTextEmbedder: sparse_text_embedder = FastembedSparseTextEmbedder( model="prithivida/Splade_PP_en_v1" ) - sparse_text_embedder.warm_up() sparse_embedding = sparse_text_embedder.run(text)["sparse_embedding"] ``` diff --git a/integrations/fastembed/src/haystack_integrations/components/embedders/fastembed/fastembed_text_embedder.py b/integrations/fastembed/src/haystack_integrations/components/embedders/fastembed/fastembed_text_embedder.py index b6e24500f3..d593f2b9b3 100644 --- a/integrations/fastembed/src/haystack_integrations/components/embedders/fastembed/fastembed_text_embedder.py +++ b/integrations/fastembed/src/haystack_integrations/components/embedders/fastembed/fastembed_text_embedder.py @@ -24,7 +24,6 @@ class FastembedTextEmbedder: text_embedder = FastembedTextEmbedder( model="BAAI/bge-small-en-v1.5" ) - text_embedder.warm_up() embedding = text_embedder.run(text)["embedding"] ``` From c3ba2a00e14c7b7a26496ce134ebd5ca9b9a1be3 Mon Sep 17 00:00:00 2001 From: Bogdan Kostic Date: Fri, 13 Feb 2026 11:09:56 +0100 Subject: [PATCH 7/7] Remove explicit warm_up calls from integration tests --- .../fastembed/tests/test_fastembed_document_embedder.py | 1 - integrations/fastembed/tests/test_fastembed_ranker.py | 1 - .../fastembed/tests/test_fastembed_sparse_document_embedder.py | 2 -- .../fastembed/tests/test_fastembed_sparse_text_embedder.py | 1 - integrations/fastembed/tests/test_fastembed_text_embedder.py | 1 - 5 files changed, 6 deletions(-) diff --git a/integrations/fastembed/tests/test_fastembed_document_embedder.py b/integrations/fastembed/tests/test_fastembed_document_embedder.py index 9b673f0f01..61be6f4409 100644 --- a/integrations/fastembed/tests/test_fastembed_document_embedder.py +++ b/integrations/fastembed/tests/test_fastembed_document_embedder.py @@ -300,7 +300,6 @@ def test_run(self): embedder = FastembedDocumentEmbedder( model="BAAI/bge-small-en-v1.5", ) - embedder.warm_up() doc = Document(content="Parton energy loss in QCD matter") diff --git a/integrations/fastembed/tests/test_fastembed_ranker.py b/integrations/fastembed/tests/test_fastembed_ranker.py index 79fa527dda..3d78991def 100644 --- a/integrations/fastembed/tests/test_fastembed_ranker.py +++ b/integrations/fastembed/tests/test_fastembed_ranker.py @@ -274,7 +274,6 @@ def test_run_calls_warm_up(self): @pytest.mark.integration def test_run(self): ranker = FastembedRanker(model_name="Xenova/ms-marco-MiniLM-L-6-v2", top_k=2) - ranker.warm_up() query = "Who is maintaining Qdrant?" documents = [ diff --git a/integrations/fastembed/tests/test_fastembed_sparse_document_embedder.py b/integrations/fastembed/tests/test_fastembed_sparse_document_embedder.py index 87d1c75375..8b80b884f1 100644 --- a/integrations/fastembed/tests/test_fastembed_sparse_document_embedder.py +++ b/integrations/fastembed/tests/test_fastembed_sparse_document_embedder.py @@ -330,7 +330,6 @@ def test_run_with_model_kwargs(self): model="Qdrant/bm42-all-minilm-l6-v2-attentions", model_kwargs=bm42_config, ) - embedder.warm_up() doc = Document(content="Example content using BM42") @@ -349,7 +348,6 @@ def test_run(self): embedder = FastembedSparseDocumentEmbedder( model="prithivida/Splade_PP_en_v1", ) - embedder.warm_up() doc = Document(content="Parton energy loss in QCD matter") diff --git a/integrations/fastembed/tests/test_fastembed_sparse_text_embedder.py b/integrations/fastembed/tests/test_fastembed_sparse_text_embedder.py index bb16e24bed..0a7936dad6 100644 --- a/integrations/fastembed/tests/test_fastembed_sparse_text_embedder.py +++ b/integrations/fastembed/tests/test_fastembed_sparse_text_embedder.py @@ -272,7 +272,6 @@ def test_run(self): embedder = FastembedSparseTextEmbedder( model="prithivida/Splade_PP_en_v1", ) - embedder.warm_up() text = "Parton energy loss in QCD matter" diff --git a/integrations/fastembed/tests/test_fastembed_text_embedder.py b/integrations/fastembed/tests/test_fastembed_text_embedder.py index 52cc051327..008e905cab 100644 --- a/integrations/fastembed/tests/test_fastembed_text_embedder.py +++ b/integrations/fastembed/tests/test_fastembed_text_embedder.py @@ -221,7 +221,6 @@ def test_run(self): embedder = FastembedTextEmbedder( model="BAAI/bge-small-en-v1.5", ) - embedder.warm_up() text = "Parton energy loss in QCD matter"