fastembed-haystack 0.0.5__tar.gz → 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (23) hide show
  1. {fastembed_haystack-0.0.5 → fastembed_haystack-0.1.0}/.gitignore +1 -0
  2. {fastembed_haystack-0.0.5 → fastembed_haystack-0.1.0}/PKG-INFO +29 -4
  3. {fastembed_haystack-0.0.5 → fastembed_haystack-0.1.0}/README.md +25 -0
  4. {fastembed_haystack-0.0.5/example → fastembed_haystack-0.1.0/examples}/example.py +1 -1
  5. fastembed_haystack-0.1.0/examples/sparse_example.py +32 -0
  6. {fastembed_haystack-0.0.5 → fastembed_haystack-0.1.0}/pydoc/config.yml +3 -0
  7. {fastembed_haystack-0.0.5 → fastembed_haystack-0.1.0}/pyproject.toml +9 -12
  8. fastembed_haystack-0.1.0/src/haystack_integrations/components/embedders/fastembed/__init__.py +14 -0
  9. fastembed_haystack-0.1.0/src/haystack_integrations/components/embedders/fastembed/embedding_backend/fastembed_backend.py +109 -0
  10. {fastembed_haystack-0.0.5 → fastembed_haystack-0.1.0}/src/haystack_integrations/components/embedders/fastembed/fastembed_document_embedder.py +19 -15
  11. fastembed_haystack-0.1.0/src/haystack_integrations/components/embedders/fastembed/fastembed_sparse_document_embedder.py +160 -0
  12. fastembed_haystack-0.1.0/src/haystack_integrations/components/embedders/fastembed/fastembed_sparse_text_embedder.py +117 -0
  13. {fastembed_haystack-0.0.5 → fastembed_haystack-0.1.0}/src/haystack_integrations/components/embedders/fastembed/fastembed_text_embedder.py +19 -14
  14. {fastembed_haystack-0.0.5 → fastembed_haystack-0.1.0}/tests/test_fastembed_document_embedder.py +1 -1
  15. fastembed_haystack-0.1.0/tests/test_fastembed_sparse_document_embedder.py +283 -0
  16. fastembed_haystack-0.1.0/tests/test_fastembed_sparse_text_embedder.py +220 -0
  17. {fastembed_haystack-0.0.5 → fastembed_haystack-0.1.0}/tests/test_fastembed_text_embedder.py +0 -10
  18. fastembed_haystack-0.0.5/src/haystack_integrations/components/embedders/fastembed/__init__.py +0 -7
  19. fastembed_haystack-0.0.5/src/haystack_integrations/components/embedders/fastembed/embedding_backend/fastembed_backend.py +0 -45
  20. {fastembed_haystack-0.0.5 → fastembed_haystack-0.1.0}/LICENSE.txt +0 -0
  21. {fastembed_haystack-0.0.5 → fastembed_haystack-0.1.0}/src/haystack_integrations/components/embedders/fastembed/embedding_backend/__init__.py +0 -0
  22. {fastembed_haystack-0.0.5 → fastembed_haystack-0.1.0}/tests/__init__.py +0 -0
  23. {fastembed_haystack-0.0.5 → fastembed_haystack-0.1.0}/tests/test_fastembed_backend.py +0 -0
@@ -134,3 +134,4 @@ dmypy.json
134
134
 
135
135
  # Docs generation artifacts
136
136
  _readme_*.md
137
+ .idea
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.3
2
2
  Name: fastembed-haystack
3
- Version: 0.0.5
3
+ Version: 0.1.0
4
4
  Summary: Haystack 2.x component to embed strings and Documents using fastembed embedding model
5
5
  Project-URL: Source, https://github.com/deepset-ai/haystack-core-integrations
6
6
  Project-URL: Documentation, https://github.com/deepset-ai/haystack-core-integrations/blob/main/integrations/fastembed/README.md
@@ -18,8 +18,8 @@ Classifier: Programming Language :: Python :: 3.12
18
18
  Classifier: Programming Language :: Python :: Implementation :: CPython
19
19
  Classifier: Programming Language :: Python :: Implementation :: PyPy
20
20
  Requires-Python: >=3.8
21
- Requires-Dist: fastembed>=0.2
22
- Requires-Dist: haystack-ai
21
+ Requires-Dist: fastembed>=0.2.5
22
+ Requires-Dist: haystack-ai>=2.0.1
23
23
  Description-Content-Type: text/markdown
24
24
 
25
25
  # fastembed-haystack
@@ -67,6 +67,31 @@ doc = Document(content="fastembed is supported by and maintained by Qdrant.", me
67
67
  result = embedder.run(documents=[doc])
68
68
  ```
69
69
 
70
+ You can use `FastembedSparseTextEmbedder` and `FastembedSparseDocumentEmbedder` by importing as:
71
+
72
+ ```python
73
+ from haystack_integrations.components.embedders.fastembed import FastembedSparseTextEmbedder
74
+
75
+ text = "fastembed is supported by and maintained by Qdrant."
76
+ text_embedder = FastembedSparseTextEmbedder(
77
+ model="prithvida/Splade_PP_en_v1"
78
+ )
79
+ text_embedder.warm_up()
80
+ embedding = text_embedder.run(text)["embedding"]
81
+ ```
82
+
83
+ ```python
84
+ from haystack_integrations.components.embedders.fastembed import FastembedSparseDocumentEmbedder
85
+ from haystack.dataclasses import Document
86
+
87
+ embedder = FastembedSparseDocumentEmbedder(
88
+ model="prithvida/Splade_PP_en_v1",
89
+ )
90
+ embedder.warm_up()
91
+ doc = Document(content="fastembed is supported by and maintained by Qdrant.", meta={"long_answer": "no",})
92
+ result = embedder.run(documents=[doc])
93
+ ```
94
+
70
95
  ## License
71
96
 
72
97
  `fastembed-haystack` is distributed under the terms of the [Apache-2.0](https://spdx.org/licenses/Apache-2.0.html) license.
@@ -43,6 +43,31 @@ doc = Document(content="fastembed is supported by and maintained by Qdrant.", me
43
43
  result = embedder.run(documents=[doc])
44
44
  ```
45
45
 
46
+ You can use `FastembedSparseTextEmbedder` and `FastembedSparseDocumentEmbedder` by importing as:
47
+
48
+ ```python
49
+ from haystack_integrations.components.embedders.fastembed import FastembedSparseTextEmbedder
50
+
51
+ text = "fastembed is supported by and maintained by Qdrant."
52
+ text_embedder = FastembedSparseTextEmbedder(
53
+ model="prithvida/Splade_PP_en_v1"
54
+ )
55
+ text_embedder.warm_up()
56
+ embedding = text_embedder.run(text)["embedding"]
57
+ ```
58
+
59
+ ```python
60
+ from haystack_integrations.components.embedders.fastembed import FastembedSparseDocumentEmbedder
61
+ from haystack.dataclasses import Document
62
+
63
+ embedder = FastembedSparseDocumentEmbedder(
64
+ model="prithvida/Splade_PP_en_v1",
65
+ )
66
+ embedder.warm_up()
67
+ doc = Document(content="fastembed is supported by and maintained by Qdrant.", meta={"long_answer": "no",})
68
+ result = embedder.run(documents=[doc])
69
+ ```
70
+
46
71
  ## License
47
72
 
48
73
  `fastembed-haystack` is distributed under the terms of the [Apache-2.0](https://spdx.org/licenses/Apache-2.0.html) license.
@@ -26,7 +26,7 @@ query = "Who supports fastembed?"
26
26
 
27
27
  result = query_pipeline.run({"text_embedder": {"text": query}})
28
28
 
29
- print(result["retriever"]["documents"][0]) # noqa: T201
29
+ print(result["retriever"]["documents"][0])
30
30
 
31
31
  # Document(id=...,
32
32
  # content: 'fastembed is supported by and maintained by Qdrant.',
@@ -0,0 +1,32 @@
1
+ # Currently, this example shows how to use the FastembedSparseDocumentEmbedder component to embed a list of documents.
2
+
3
+ # TODO: Once we have a proper SparseEmbeddingRetriever, we should replace this naive example with a more realistic one,
4
+ # involving indexing and retrieval of documents.
5
+
6
+ from haystack import Document
7
+ from haystack_integrations.components.embedders.fastembed import FastembedSparseDocumentEmbedder
8
+
9
+ document_list = [
10
+ Document(
11
+ content="Oxidative stress generated within inflammatory joints can produce autoimmune phenomena and joint destruction. Radical species with oxidative activity, including reactive nitrogen species, represent mediators of inflammation and cartilage damage.",
12
+ meta={
13
+ "pubid": "25,445,628",
14
+ "long_answer": "yes",
15
+ },
16
+ ),
17
+ Document(
18
+ content="Plasma levels of pancreatic polypeptide (PP) rise upon food intake. Although other pancreatic islet hormones, such as insulin and glucagon, have been extensively investigated, PP secretion and actions are still poorly understood.",
19
+ meta={
20
+ "pubid": "25,445,712",
21
+ "long_answer": "yes",
22
+ },
23
+ ),
24
+ ]
25
+
26
+ document_embedder = FastembedSparseDocumentEmbedder()
27
+ document_embedder.warm_up()
28
+ documents_with_embeddings = document_embedder.run(document_list)["documents"]
29
+
30
+ for doc in documents_with_embeddings:
31
+ print(f"Document Text: {doc.content}")
32
+ print(f"Document Sparse Embedding: {doc.sparse_embedding.to_dict()}")
@@ -5,6 +5,8 @@ loaders:
5
5
  [
6
6
  "haystack_integrations.components.embedders.fastembed.fastembed_document_embedder",
7
7
  "haystack_integrations.components.embedders.fastembed.fastembed_text_embedder",
8
+ "haystack_integrations.components.embedders.fastembed.fastembed_sparse_document_embedder",
9
+ "haystack_integrations.components.embedders.fastembed.fastembed_sparse_text_embedder"
8
10
  ]
9
11
  ignore_when_discovered: ["__init__"]
10
12
  processors:
@@ -24,6 +26,7 @@ renderer:
24
26
  order: 80
25
27
  markdown:
26
28
  descriptive_class_title: false
29
+ classdef_code_block: false
27
30
  descriptive_module_title: true
28
31
  add_method_class_prefix: true
29
32
  add_member_class_prefix: false
@@ -25,8 +25,8 @@ classifiers = [
25
25
  "Programming Language :: Python :: Implementation :: PyPy",
26
26
  ]
27
27
  dependencies = [
28
- "haystack-ai",
29
- "fastembed>=0.2",
28
+ "haystack-ai>=2.0.1",
29
+ "fastembed>=0.2.5",
30
30
  ]
31
31
 
32
32
  [project.urls]
@@ -95,12 +95,12 @@ all = [
95
95
  ]
96
96
 
97
97
  [tool.black]
98
- target-version = ["py37"]
98
+ target-version = ["py38"]
99
99
  line-length = 120
100
100
  skip-string-normalization = true
101
101
 
102
102
  [tool.ruff]
103
- target-version = "py37"
103
+ target-version = "py38"
104
104
  line-length = 120
105
105
  select = [
106
106
  "A",
@@ -155,19 +155,16 @@ ban-relative-imports = "parents"
155
155
  # Tests can use magic values, assertions, and relative imports
156
156
  "tests/**/*" = ["PLR2004", "S101", "TID252"]
157
157
  # examples can contain "print" commands
158
- "examples/**/*" = ["T201"]
158
+ "examples/**/*" = ["T201", "E501"]
159
159
 
160
160
  [tool.coverage.run]
161
- source_pkgs = ["src", "tests"]
161
+ source = ["haystack_integrations"]
162
162
  branch = true
163
- parallel = true
164
-
165
-
166
- [tool.coverage.paths]
167
- fastembed_haystack = ["src/haystack_integrations", "*/fastembed-haystack/src"]
168
- tests = ["tests", "*/fastembed-haystack/tests"]
163
+ parallel = false
169
164
 
170
165
  [tool.coverage.report]
166
+ omit = ["*/tests/*", "*/__init__.py"]
167
+ show_missing=true
171
168
  exclude_lines = [
172
169
  "no cov",
173
170
  "if __name__ == .__main__.:",
@@ -0,0 +1,14 @@
1
+ # SPDX-FileCopyrightText: 2024-present deepset GmbH <info@deepset.ai>
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+ from .fastembed_document_embedder import FastembedDocumentEmbedder
5
+ from .fastembed_sparse_document_embedder import FastembedSparseDocumentEmbedder
6
+ from .fastembed_sparse_text_embedder import FastembedSparseTextEmbedder
7
+ from .fastembed_text_embedder import FastembedTextEmbedder
8
+
9
+ __all__ = [
10
+ "FastembedDocumentEmbedder",
11
+ "FastembedTextEmbedder",
12
+ "FastembedSparseDocumentEmbedder",
13
+ "FastembedSparseTextEmbedder",
14
+ ]
@@ -0,0 +1,109 @@
1
+ from typing import ClassVar, Dict, List, Optional
2
+
3
+ from haystack.dataclasses.sparse_embedding import SparseEmbedding
4
+ from tqdm import tqdm
5
+
6
+ from fastembed import TextEmbedding
7
+ from fastembed.sparse.sparse_text_embedding import SparseTextEmbedding
8
+
9
+
10
+ class _FastembedEmbeddingBackendFactory:
11
+ """
12
+ Factory class to create instances of fastembed embedding backends.
13
+ """
14
+
15
+ _instances: ClassVar[Dict[str, "_FastembedEmbeddingBackend"]] = {}
16
+
17
+ @staticmethod
18
+ def get_embedding_backend(
19
+ model_name: str,
20
+ cache_dir: Optional[str] = None,
21
+ threads: Optional[int] = None,
22
+ ):
23
+ embedding_backend_id = f"{model_name}{cache_dir}{threads}"
24
+
25
+ if embedding_backend_id in _FastembedEmbeddingBackendFactory._instances:
26
+ return _FastembedEmbeddingBackendFactory._instances[embedding_backend_id]
27
+
28
+ embedding_backend = _FastembedEmbeddingBackend(model_name=model_name, cache_dir=cache_dir, threads=threads)
29
+ _FastembedEmbeddingBackendFactory._instances[embedding_backend_id] = embedding_backend
30
+ return embedding_backend
31
+
32
+
33
+ class _FastembedEmbeddingBackend:
34
+ """
35
+ Class to manage fastembed embeddings.
36
+ """
37
+
38
+ def __init__(
39
+ self,
40
+ model_name: str,
41
+ cache_dir: Optional[str] = None,
42
+ threads: Optional[int] = None,
43
+ ):
44
+ self.model = TextEmbedding(model_name=model_name, cache_dir=cache_dir, threads=threads)
45
+
46
+ def embed(self, data: List[str], progress_bar=True, **kwargs) -> List[List[float]]:
47
+ # the embed method returns a Iterable[np.ndarray], so we convert it to a list of lists
48
+ embeddings = []
49
+ embeddings_iterable = self.model.embed(data, **kwargs)
50
+ for np_array in tqdm(
51
+ embeddings_iterable, disable=not progress_bar, desc="Calculating embeddings", total=len(data)
52
+ ):
53
+ embeddings.append(np_array.tolist())
54
+ return embeddings
55
+
56
+
57
+ class _FastembedSparseEmbeddingBackendFactory:
58
+ """
59
+ Factory class to create instances of fastembed sparse embedding backends.
60
+ """
61
+
62
+ _instances: ClassVar[Dict[str, "_FastembedSparseEmbeddingBackend"]] = {}
63
+
64
+ @staticmethod
65
+ def get_embedding_backend(
66
+ model_name: str,
67
+ cache_dir: Optional[str] = None,
68
+ threads: Optional[int] = None,
69
+ ):
70
+ embedding_backend_id = f"{model_name}{cache_dir}{threads}"
71
+
72
+ if embedding_backend_id in _FastembedSparseEmbeddingBackendFactory._instances:
73
+ return _FastembedSparseEmbeddingBackendFactory._instances[embedding_backend_id]
74
+
75
+ embedding_backend = _FastembedSparseEmbeddingBackend(
76
+ model_name=model_name, cache_dir=cache_dir, threads=threads
77
+ )
78
+ _FastembedSparseEmbeddingBackendFactory._instances[embedding_backend_id] = embedding_backend
79
+ return embedding_backend
80
+
81
+
82
+ class _FastembedSparseEmbeddingBackend:
83
+ """
84
+ Class to manage fastembed sparse embeddings.
85
+ """
86
+
87
+ def __init__(
88
+ self,
89
+ model_name: str,
90
+ cache_dir: Optional[str] = None,
91
+ threads: Optional[int] = None,
92
+ ):
93
+ self.model = SparseTextEmbedding(model_name=model_name, cache_dir=cache_dir, threads=threads)
94
+
95
+ def embed(self, data: List[List[str]], progress_bar=True, **kwargs) -> List[SparseEmbedding]:
96
+ # The embed method returns a Iterable[SparseEmbedding], so we convert to Haystack SparseEmbedding type.
97
+ # Each SparseEmbedding contains an `indices` key containing a list of int and
98
+ # an `values` key containing a list of floats.
99
+
100
+ sparse_embeddings = []
101
+ sparse_embeddings_iterable = self.model.embed(data, **kwargs)
102
+ for sparse_embedding in tqdm(
103
+ sparse_embeddings_iterable, disable=not progress_bar, desc="Calculating sparse embeddings", total=len(data)
104
+ ):
105
+ sparse_embeddings.append(
106
+ SparseEmbedding(indices=sparse_embedding.indices.tolist(), values=sparse_embedding.values.tolist())
107
+ )
108
+
109
+ return sparse_embeddings
@@ -8,7 +8,7 @@ from .embedding_backend.fastembed_backend import _FastembedEmbeddingBackendFacto
8
8
  @component
9
9
  class FastembedDocumentEmbedder:
10
10
  """
11
- A component for computing Document embeddings using Fastembed embedding models.
11
+ FastembedDocumentEmbedder computes Document embeddings using Fastembed embedding models.
12
12
  The embedding of each Document is stored in the `embedding` field of the Document.
13
13
 
14
14
  Usage example:
@@ -48,6 +48,7 @@ class FastembedDocumentEmbedder:
48
48
  print(f"Document Text: {result['documents'][0].content}")
49
49
  print(f"Document Embedding: {result['documents'][0].embedding}")
50
50
  print(f"Embedding Dimension: {len(result['documents'][0].embedding)}")
51
+ ```
51
52
  """ # noqa: E501
52
53
 
53
54
  def __init__(
@@ -67,11 +68,11 @@ class FastembedDocumentEmbedder:
67
68
  Create an FastembedDocumentEmbedder component.
68
69
 
69
70
  :param model: Local path or name of the model in Hugging Face's model hub,
70
- such as ``'BAAI/bge-small-en-v1.5'``.
71
- :param cache_dir (str, optional): The path to the cache directory.
71
+ such as `BAAI/bge-small-en-v1.5`.
72
+ :param cache_dir: The path to the cache directory.
72
73
  Can be set using the `FASTEMBED_CACHE_PATH` env variable.
73
74
  Defaults to `fastembed_cache` in the system's temp directory.
74
- :param threads (int, optional): The number of threads single onnxruntime session can use. Defaults to None.
75
+ :param threads: The number of threads single onnxruntime session can use. Defaults to None.
75
76
  :param prefix: A string to add to the beginning of each text.
76
77
  :param suffix: A string to add to the end of each text.
77
78
  :param batch_size: Number of strings to encode at once.
@@ -97,7 +98,9 @@ class FastembedDocumentEmbedder:
97
98
 
98
99
  def to_dict(self) -> Dict[str, Any]:
99
100
  """
100
- Serialize this component to a dictionary.
101
+ Serializes the component to a dictionary.
102
+ :returns:
103
+ Dictionary with serialized data.
101
104
  """
102
105
  return default_to_dict(
103
106
  self,
@@ -115,7 +118,7 @@ class FastembedDocumentEmbedder:
115
118
 
116
119
  def warm_up(self):
117
120
  """
118
- Load the embedding backend.
121
+ Initializes the component.
119
122
  """
120
123
  if not hasattr(self, "embedding_backend"):
121
124
  self.embedding_backend = _FastembedEmbeddingBackendFactory.get_embedding_backend(
@@ -128,18 +131,21 @@ class FastembedDocumentEmbedder:
128
131
  meta_values_to_embed = [
129
132
  str(doc.meta[key]) for key in self.meta_fields_to_embed if key in doc.meta and doc.meta[key] is not None
130
133
  ]
131
- text_to_embed = [
132
- self.prefix + self.embedding_separator.join([*meta_values_to_embed, doc.content or ""]) + self.suffix,
133
- ]
134
+ text_to_embed = (
135
+ self.prefix + self.embedding_separator.join([*meta_values_to_embed, doc.content or ""]) + self.suffix
136
+ )
134
137
 
135
- texts_to_embed.append(text_to_embed[0])
138
+ texts_to_embed.append(text_to_embed)
136
139
  return texts_to_embed
137
140
 
138
141
  @component.output_types(documents=List[Document])
139
142
  def run(self, documents: List[Document]):
140
143
  """
141
- Embed a list of Documents.
142
- The embedding of each Document is stored in the `embedding` field of the Document.
144
+ Embeds a list of Documents.
145
+
146
+ :param documents: List of Documents to embed.
147
+ :returns: A dictionary with the following keys:
148
+ - `documents`: List of Documents with each Document's `embedding` field set to the computed embeddings.
143
149
  """
144
150
  if not isinstance(documents, list) or documents and not isinstance(documents[0], Document):
145
151
  msg = (
@@ -151,13 +157,11 @@ class FastembedDocumentEmbedder:
151
157
  msg = "The embedding model has not been loaded. Please call warm_up() before running."
152
158
  raise RuntimeError(msg)
153
159
 
154
- # TODO: once non textual Documents are properly supported, we should also prepare them for embedding here
155
-
156
160
  texts_to_embed = self._prepare_texts_to_embed(documents=documents)
157
161
  embeddings = self.embedding_backend.embed(
158
162
  texts_to_embed,
159
163
  batch_size=self.batch_size,
160
- show_progress_bar=self.progress_bar,
164
+ progress_bar=self.progress_bar,
161
165
  parallel=self.parallel,
162
166
  )
163
167
 
@@ -0,0 +1,160 @@
1
+ from typing import Any, Dict, List, Optional
2
+
3
+ from haystack import Document, component, default_to_dict
4
+
5
+ from .embedding_backend.fastembed_backend import _FastembedSparseEmbeddingBackendFactory
6
+
7
+
8
+ @component
9
+ class FastembedSparseDocumentEmbedder:
10
+ """
11
+ FastembedSparseDocumentEmbedder computes Document embeddings using Fastembed sparse models.
12
+
13
+ Usage example:
14
+ ```python
15
+ # To use this component, install the "fastembed-haystack" package.
16
+ # pip install fastembed-haystack
17
+
18
+ from haystack_integrations.components.embedders.fastembed import FastembedSparseDocumentEmbedder
19
+ from haystack.dataclasses import Document
20
+
21
+ doc_embedder = FastembedSparseDocumentEmbedder(
22
+ model="prithvida/Splade_PP_en_v1",
23
+ batch_size=32,
24
+ )
25
+
26
+ doc_embedder.warm_up()
27
+
28
+ # Text taken from PubMed QA Dataset (https://huggingface.co/datasets/pubmed_qa)
29
+ document_list = [
30
+ Document(
31
+ content="Oxidative stress generated within inflammatory joints can produce autoimmune phenomena and joint destruction. Radical species with oxidative activity, including reactive nitrogen species, represent mediators of inflammation and cartilage damage.",
32
+ meta={
33
+ "pubid": "25,445,628",
34
+ "long_answer": "yes",
35
+ },
36
+ ),
37
+ Document(
38
+ content="Plasma levels of pancreatic polypeptide (PP) rise upon food intake. Although other pancreatic islet hormones, such as insulin and glucagon, have been extensively investigated, PP secretion and actions are still poorly understood.",
39
+ meta={
40
+ "pubid": "25,445,712",
41
+ "long_answer": "yes",
42
+ },
43
+ ),
44
+ ]
45
+
46
+ result = doc_embedder.run(document_list)
47
+ print(f"Document Text: {result['documents'][0].content}")
48
+ print(f"Document Embedding: {result['documents'][0].sparse_embedding}")
49
+ print(f"Embedding Dimension: {len(result['documents'][0].sparse_embedding)}")
50
+ ```
51
+ """ # noqa: E501
52
+
53
+ def __init__(
54
+ self,
55
+ model: str = "prithvida/Splade_PP_en_v1",
56
+ cache_dir: Optional[str] = None,
57
+ threads: Optional[int] = None,
58
+ batch_size: int = 32,
59
+ progress_bar: bool = True,
60
+ parallel: Optional[int] = None,
61
+ meta_fields_to_embed: Optional[List[str]] = None,
62
+ embedding_separator: str = "\n",
63
+ ):
64
+ """
65
+ Create an FastembedDocumentEmbedder component.
66
+
67
+ :param model: Local path or name of the model in Hugging Face's model hub,
68
+ such as `prithvida/Splade_PP_en_v1`.
69
+ :param cache_dir: The path to the cache directory.
70
+ Can be set using the `FASTEMBED_CACHE_PATH` env variable.
71
+ Defaults to `fastembed_cache` in the system's temp directory.
72
+ :param threads: The number of threads single onnxruntime session can use.
73
+ :param batch_size: Number of strings to encode at once.
74
+ :param progress_bar: If `True`, displays progress bar during embedding.
75
+ :param parallel:
76
+ If > 1, data-parallel encoding will be used, recommended for offline encoding of large datasets.
77
+ If 0, use all available cores.
78
+ If None, don't use data-parallel processing, use default onnxruntime threading instead.
79
+ :param meta_fields_to_embed: List of meta fields that should be embedded along with the Document content.
80
+ :param embedding_separator: Separator used to concatenate the meta fields to the Document content.
81
+ """
82
+
83
+ self.model_name = model
84
+ self.cache_dir = cache_dir
85
+ self.threads = threads
86
+ self.batch_size = batch_size
87
+ self.progress_bar = progress_bar
88
+ self.parallel = parallel
89
+ self.meta_fields_to_embed = meta_fields_to_embed or []
90
+ self.embedding_separator = embedding_separator
91
+
92
+ def to_dict(self) -> Dict[str, Any]:
93
+ """
94
+ Serializes the component to a dictionary.
95
+ :returns:
96
+ Dictionary with serialized data.
97
+ """
98
+ return default_to_dict(
99
+ self,
100
+ model=self.model_name,
101
+ cache_dir=self.cache_dir,
102
+ threads=self.threads,
103
+ batch_size=self.batch_size,
104
+ progress_bar=self.progress_bar,
105
+ parallel=self.parallel,
106
+ meta_fields_to_embed=self.meta_fields_to_embed,
107
+ embedding_separator=self.embedding_separator,
108
+ )
109
+
110
+ def warm_up(self):
111
+ """
112
+ Initializes the component.
113
+ """
114
+ if not hasattr(self, "embedding_backend"):
115
+ self.embedding_backend = _FastembedSparseEmbeddingBackendFactory.get_embedding_backend(
116
+ model_name=self.model_name, cache_dir=self.cache_dir, threads=self.threads
117
+ )
118
+
119
+ def _prepare_texts_to_embed(self, documents: List[Document]) -> List[str]:
120
+ texts_to_embed = []
121
+ for doc in documents:
122
+ meta_values_to_embed = [
123
+ str(doc.meta[key]) for key in self.meta_fields_to_embed if key in doc.meta and doc.meta[key] is not None
124
+ ]
125
+ text_to_embed = self.embedding_separator.join([*meta_values_to_embed, doc.content or ""])
126
+
127
+ texts_to_embed.append(text_to_embed)
128
+ return texts_to_embed
129
+
130
+ @component.output_types(documents=List[Document])
131
+ def run(self, documents: List[Document]):
132
+ """
133
+ Embeds a list of Documents.
134
+
135
+ :param documents: List of Documents to embed.
136
+ :returns: A dictionary with the following keys:
137
+ - `documents`: List of Documents with each Document's `sparse_embedding`
138
+ field set to the computed embeddings.
139
+ """
140
+ if not isinstance(documents, list) or documents and not isinstance(documents[0], Document):
141
+ msg = (
142
+ "FastembedSparseDocumentEmbedder expects a list of Documents as input. "
143
+ "In case you want to embed a list of strings, please use the FastembedTextEmbedder."
144
+ )
145
+ raise TypeError(msg)
146
+ if not hasattr(self, "embedding_backend"):
147
+ msg = "The embedding model has not been loaded. Please call warm_up() before running."
148
+ raise RuntimeError(msg)
149
+
150
+ texts_to_embed = self._prepare_texts_to_embed(documents=documents)
151
+ embeddings = self.embedding_backend.embed(
152
+ texts_to_embed,
153
+ batch_size=self.batch_size,
154
+ show_progress_bar=self.progress_bar,
155
+ parallel=self.parallel,
156
+ )
157
+
158
+ for doc, emb in zip(documents, embeddings):
159
+ doc.sparse_embedding = emb
160
+ return {"documents": documents}