fastembed-haystack 0.0.2__tar.gz → 0.0.4__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 (16) hide show
  1. {fastembed_haystack-0.0.2 → fastembed_haystack-0.0.4}/PKG-INFO +1 -1
  2. fastembed_haystack-0.0.4/example/example.py +33 -0
  3. {fastembed_haystack-0.0.2 → fastembed_haystack-0.0.4}/pydoc/config.yml +5 -5
  4. {fastembed_haystack-0.0.2 → fastembed_haystack-0.0.4}/src/haystack_integrations/components/embedders/fastembed/embedding_backend/fastembed_backend.py +2 -1
  5. {fastembed_haystack-0.0.2 → fastembed_haystack-0.0.4}/src/haystack_integrations/components/embedders/fastembed/fastembed_document_embedder.py +9 -1
  6. {fastembed_haystack-0.0.2 → fastembed_haystack-0.0.4}/src/haystack_integrations/components/embedders/fastembed/fastembed_text_embedder.py +10 -1
  7. {fastembed_haystack-0.0.2 → fastembed_haystack-0.0.4}/tests/test_fastembed_document_embedder.py +12 -1
  8. {fastembed_haystack-0.0.2 → fastembed_haystack-0.0.4}/tests/test_fastembed_text_embedder.py +11 -1
  9. {fastembed_haystack-0.0.2 → fastembed_haystack-0.0.4}/.gitignore +0 -0
  10. {fastembed_haystack-0.0.2 → fastembed_haystack-0.0.4}/LICENSE.txt +0 -0
  11. {fastembed_haystack-0.0.2 → fastembed_haystack-0.0.4}/README.md +0 -0
  12. {fastembed_haystack-0.0.2 → fastembed_haystack-0.0.4}/pyproject.toml +0 -0
  13. {fastembed_haystack-0.0.2 → fastembed_haystack-0.0.4}/src/haystack_integrations/components/embedders/fastembed/__init__.py +0 -0
  14. {fastembed_haystack-0.0.2 → fastembed_haystack-0.0.4}/src/haystack_integrations/components/embedders/fastembed/embedding_backend/__init__.py +0 -0
  15. {fastembed_haystack-0.0.2 → fastembed_haystack-0.0.4}/tests/__init__.py +0 -0
  16. {fastembed_haystack-0.0.2 → fastembed_haystack-0.0.4}/tests/test_fastembed_backend.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fastembed-haystack
3
- Version: 0.0.2
3
+ Version: 0.0.4
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
@@ -0,0 +1,33 @@
1
+ from haystack import Document, Pipeline
2
+ from haystack.components.retrievers.in_memory import InMemoryEmbeddingRetriever
3
+ from haystack.document_stores.in_memory import InMemoryDocumentStore
4
+ from haystack_integrations.components.embedders.fastembed import FastembedDocumentEmbedder, FastembedTextEmbedder
5
+
6
+ document_store = InMemoryDocumentStore(embedding_similarity_function="cosine")
7
+
8
+ documents = [
9
+ Document(content="My name is Wolfgang and I live in Berlin"),
10
+ Document(content="I saw a black horse running"),
11
+ Document(content="Germany has many big cities"),
12
+ Document(content="fastembed is supported by and maintained by Qdrant."),
13
+ ]
14
+
15
+ document_embedder = FastembedDocumentEmbedder()
16
+ document_embedder.warm_up()
17
+ documents_with_embeddings = document_embedder.run(documents)["documents"]
18
+ document_store.write_documents(documents_with_embeddings)
19
+
20
+ query_pipeline = Pipeline()
21
+ query_pipeline.add_component("text_embedder", FastembedTextEmbedder())
22
+ query_pipeline.add_component("retriever", InMemoryEmbeddingRetriever(document_store=document_store))
23
+ query_pipeline.connect("text_embedder.embedding", "retriever.query_embedding")
24
+
25
+ query = "Who supports fastembed?"
26
+
27
+ result = query_pipeline.run({"text_embedder": {"text": query}})
28
+
29
+ print(result["retriever"]["documents"][0]) # noqa: T201
30
+
31
+ # Document(id=...,
32
+ # content: 'fastembed is supported by and maintained by Qdrant.',
33
+ # score: 0.758..)
@@ -3,8 +3,8 @@ loaders:
3
3
  search_path: [../src]
4
4
  modules:
5
5
  [
6
- "haystack_integrations.components.embedders.fastembed",
7
- "haystack_integrations.components.embedders.fastembed.embedding_backend",
6
+ "haystack_integrations.components.embedders.fastembed.fastembed_document_embedder",
7
+ "haystack_integrations.components.embedders.fastembed.fastembed_text_embedder",
8
8
  ]
9
9
  ignore_when_discovered: ["__init__"]
10
10
  processors:
@@ -17,11 +17,11 @@ processors:
17
17
  - type: crossref
18
18
  renderer:
19
19
  type: haystack_pydoc_tools.renderers.ReadmePreviewRenderer
20
- excerpt: Embedders integration for Haystack
20
+ excerpt: FastEmbed integration for Haystack
21
21
  category_slug: haystack-integrations
22
- title: Embedders
22
+ title: FastEmbed
23
23
  slug: fastembed-embedders
24
- order: 300
24
+ order: 55
25
25
  markdown:
26
26
  descriptive_class_title: false
27
27
  descriptive_module_title: true
@@ -38,5 +38,6 @@ class _FastembedEmbeddingBackend:
38
38
  self.model = TextEmbedding(model_name=model_name)
39
39
 
40
40
  def embed(self, data: List[List[str]], **kwargs) -> List[List[float]]:
41
- embeddings = list(self.model.embed(data, **kwargs))
41
+ # the embed method returns a Iterable[np.ndarray], so we convert it to a list of lists
42
+ embeddings = [np_array.tolist() for np_array in self.model.embed(data, **kwargs)]
42
43
  return embeddings
@@ -57,6 +57,7 @@ class FastembedDocumentEmbedder:
57
57
  suffix: str = "",
58
58
  batch_size: int = 256,
59
59
  progress_bar: bool = True,
60
+ parallel: Optional[int] = None,
60
61
  meta_fields_to_embed: Optional[List[str]] = None,
61
62
  embedding_separator: str = "\n",
62
63
  ):
@@ -69,6 +70,10 @@ class FastembedDocumentEmbedder:
69
70
  :param suffix: A string to add to the end of each text.
70
71
  :param batch_size: Number of strings to encode at once.
71
72
  :param progress_bar: If true, displays progress bar during embedding.
73
+ :param parallel:
74
+ If > 1, data-parallel encoding will be used, recommended for offline encoding of large datasets.
75
+ If 0, use all available cores.
76
+ If None, don't use data-parallel processing, use default onnxruntime threading instead.
72
77
  :param meta_fields_to_embed: List of meta fields that should be embedded along with the Document content.
73
78
  :param embedding_separator: Separator used to concatenate the meta fields to the Document content.
74
79
  """
@@ -78,6 +83,7 @@ class FastembedDocumentEmbedder:
78
83
  self.suffix = suffix
79
84
  self.batch_size = batch_size
80
85
  self.progress_bar = progress_bar
86
+ self.parallel = parallel
81
87
  self.meta_fields_to_embed = meta_fields_to_embed or []
82
88
  self.embedding_separator = embedding_separator
83
89
 
@@ -92,6 +98,7 @@ class FastembedDocumentEmbedder:
92
98
  suffix=self.suffix,
93
99
  batch_size=self.batch_size,
94
100
  progress_bar=self.progress_bar,
101
+ parallel=self.parallel,
95
102
  meta_fields_to_embed=self.meta_fields_to_embed,
96
103
  embedding_separator=self.embedding_separator,
97
104
  )
@@ -139,9 +146,10 @@ class FastembedDocumentEmbedder:
139
146
  texts_to_embed,
140
147
  batch_size=self.batch_size,
141
148
  show_progress_bar=self.progress_bar,
149
+ parallel=self.parallel,
142
150
  )
143
151
 
144
152
  for doc, emb in zip(documents, embeddings):
145
- doc.embedding = list(emb)
153
+ doc.embedding = emb
146
154
 
147
155
  return {"documents": documents}
@@ -1,4 +1,4 @@
1
- from typing import Any, Dict, List
1
+ from typing import Any, Dict, List, Optional
2
2
 
3
3
  from haystack import component, default_to_dict
4
4
 
@@ -35,6 +35,7 @@ class FastembedTextEmbedder:
35
35
  suffix: str = "",
36
36
  batch_size: int = 256,
37
37
  progress_bar: bool = True,
38
+ parallel: Optional[int] = None,
38
39
  ):
39
40
  """
40
41
  Create a FastembedTextEmbedder component.
@@ -44,6 +45,11 @@ class FastembedTextEmbedder:
44
45
  :param batch_size: Number of strings to encode at once.
45
46
  :param prefix: A string to add to the beginning of each text.
46
47
  :param suffix: A string to add to the end of each text.
48
+ :param progress_bar: If true, displays progress bar during embedding.
49
+ :param parallel:
50
+ If > 1, data-parallel encoding will be used, recommended for offline encoding of large datasets.
51
+ If 0, use all available cores.
52
+ If None, don't use data-parallel processing, use default onnxruntime threading instead.
47
53
  """
48
54
 
49
55
  # TODO add parallel
@@ -53,6 +59,7 @@ class FastembedTextEmbedder:
53
59
  self.suffix = suffix
54
60
  self.batch_size = batch_size
55
61
  self.progress_bar = progress_bar
62
+ self.parallel = parallel
56
63
 
57
64
  def to_dict(self) -> Dict[str, Any]:
58
65
  """
@@ -65,6 +72,7 @@ class FastembedTextEmbedder:
65
72
  suffix=self.suffix,
66
73
  batch_size=self.batch_size,
67
74
  progress_bar=self.progress_bar,
75
+ parallel=self.parallel,
68
76
  )
69
77
 
70
78
  def warm_up(self):
@@ -93,6 +101,7 @@ class FastembedTextEmbedder:
93
101
  text_to_embed,
94
102
  batch_size=self.batch_size,
95
103
  show_progress_bar=self.progress_bar,
104
+ parallel=self.parallel,
96
105
  )[0]
97
106
  )
98
107
  return {"embedding": embedding}
@@ -19,6 +19,7 @@ class TestFastembedDocumentEmbedder:
19
19
  assert embedder.suffix == ""
20
20
  assert embedder.batch_size == 256
21
21
  assert embedder.progress_bar is True
22
+ assert embedder.parallel is None
22
23
  assert embedder.meta_fields_to_embed == []
23
24
  assert embedder.embedding_separator == "\n"
24
25
 
@@ -32,6 +33,7 @@ class TestFastembedDocumentEmbedder:
32
33
  suffix="suffix",
33
34
  batch_size=64,
34
35
  progress_bar=False,
36
+ parallel=1,
35
37
  meta_fields_to_embed=["test_field"],
36
38
  embedding_separator=" | ",
37
39
  )
@@ -40,6 +42,7 @@ class TestFastembedDocumentEmbedder:
40
42
  assert embedder.suffix == "suffix"
41
43
  assert embedder.batch_size == 64
42
44
  assert embedder.progress_bar is False
45
+ assert embedder.parallel == 1
43
46
  assert embedder.meta_fields_to_embed == ["test_field"]
44
47
  assert embedder.embedding_separator == " | "
45
48
 
@@ -57,6 +60,7 @@ class TestFastembedDocumentEmbedder:
57
60
  "suffix": "",
58
61
  "batch_size": 256,
59
62
  "progress_bar": True,
63
+ "parallel": None,
60
64
  "embedding_separator": "\n",
61
65
  "meta_fields_to_embed": [],
62
66
  },
@@ -72,6 +76,7 @@ class TestFastembedDocumentEmbedder:
72
76
  suffix="suffix",
73
77
  batch_size=64,
74
78
  progress_bar=False,
79
+ parallel=1,
75
80
  meta_fields_to_embed=["test_field"],
76
81
  embedding_separator=" | ",
77
82
  )
@@ -84,6 +89,7 @@ class TestFastembedDocumentEmbedder:
84
89
  "suffix": "suffix",
85
90
  "batch_size": 64,
86
91
  "progress_bar": False,
92
+ "parallel": 1,
87
93
  "meta_fields_to_embed": ["test_field"],
88
94
  "embedding_separator": " | ",
89
95
  },
@@ -101,6 +107,7 @@ class TestFastembedDocumentEmbedder:
101
107
  "suffix": "",
102
108
  "batch_size": 256,
103
109
  "progress_bar": True,
110
+ "parallel": None,
104
111
  "meta_fields_to_embed": [],
105
112
  "embedding_separator": "\n",
106
113
  },
@@ -111,6 +118,7 @@ class TestFastembedDocumentEmbedder:
111
118
  assert embedder.suffix == ""
112
119
  assert embedder.batch_size == 256
113
120
  assert embedder.progress_bar is True
121
+ assert embedder.parallel is None
114
122
  assert embedder.meta_fields_to_embed == []
115
123
  assert embedder.embedding_separator == "\n"
116
124
 
@@ -126,6 +134,7 @@ class TestFastembedDocumentEmbedder:
126
134
  "suffix": "suffix",
127
135
  "batch_size": 64,
128
136
  "progress_bar": False,
137
+ "parallel": 1,
129
138
  "meta_fields_to_embed": ["test_field"],
130
139
  "embedding_separator": " | ",
131
140
  },
@@ -136,6 +145,7 @@ class TestFastembedDocumentEmbedder:
136
145
  assert embedder.suffix == "suffix"
137
146
  assert embedder.batch_size == 64
138
147
  assert embedder.progress_bar is False
148
+ assert embedder.parallel == 1
139
149
  assert embedder.meta_fields_to_embed == ["test_field"]
140
150
  assert embedder.embedding_separator == " | "
141
151
 
@@ -232,6 +242,7 @@ class TestFastembedDocumentEmbedder:
232
242
  ],
233
243
  batch_size=256,
234
244
  show_progress_bar=True,
245
+ parallel=None,
235
246
  )
236
247
 
237
248
  @pytest.mark.integration
@@ -248,4 +259,4 @@ class TestFastembedDocumentEmbedder:
248
259
 
249
260
  assert isinstance(embedding, list)
250
261
  assert len(embedding) == 384
251
- assert all(isinstance(emb.item(), float) for emb in embedding)
262
+ assert all(isinstance(emb, float) for emb in embedding)
@@ -19,6 +19,7 @@ class TestFastembedTextEmbedder:
19
19
  assert embedder.suffix == ""
20
20
  assert embedder.batch_size == 256
21
21
  assert embedder.progress_bar is True
22
+ assert embedder.parallel is None
22
23
 
23
24
  def test_init_with_parameters(self):
24
25
  """
@@ -30,12 +31,14 @@ class TestFastembedTextEmbedder:
30
31
  suffix="suffix",
31
32
  batch_size=64,
32
33
  progress_bar=False,
34
+ parallel=1,
33
35
  )
34
36
  assert embedder.model_name == "BAAI/bge-small-en-v1.5"
35
37
  assert embedder.prefix == "prefix"
36
38
  assert embedder.suffix == "suffix"
37
39
  assert embedder.batch_size == 64
38
40
  assert embedder.progress_bar is False
41
+ assert embedder.parallel == 1
39
42
 
40
43
  def test_to_dict(self):
41
44
  """
@@ -51,6 +54,7 @@ class TestFastembedTextEmbedder:
51
54
  "suffix": "",
52
55
  "batch_size": 256,
53
56
  "progress_bar": True,
57
+ "parallel": None,
54
58
  },
55
59
  }
56
60
 
@@ -64,6 +68,7 @@ class TestFastembedTextEmbedder:
64
68
  suffix="suffix",
65
69
  batch_size=64,
66
70
  progress_bar=False,
71
+ parallel=1,
67
72
  )
68
73
  embedder_dict = embedder.to_dict()
69
74
  assert embedder_dict == {
@@ -74,6 +79,7 @@ class TestFastembedTextEmbedder:
74
79
  "suffix": "suffix",
75
80
  "batch_size": 64,
76
81
  "progress_bar": False,
82
+ "parallel": 1,
77
83
  },
78
84
  }
79
85
 
@@ -89,6 +95,7 @@ class TestFastembedTextEmbedder:
89
95
  "suffix": "",
90
96
  "batch_size": 256,
91
97
  "progress_bar": True,
98
+ "parallel": None,
92
99
  },
93
100
  }
94
101
  embedder = default_from_dict(FastembedTextEmbedder, embedder_dict)
@@ -97,6 +104,7 @@ class TestFastembedTextEmbedder:
97
104
  assert embedder.suffix == ""
98
105
  assert embedder.batch_size == 256
99
106
  assert embedder.progress_bar is True
107
+ assert embedder.parallel is None
100
108
 
101
109
  def test_from_dict_with_custom_init_parameters(self):
102
110
  """
@@ -110,6 +118,7 @@ class TestFastembedTextEmbedder:
110
118
  "suffix": "suffix",
111
119
  "batch_size": 64,
112
120
  "progress_bar": False,
121
+ "parallel": 1,
113
122
  },
114
123
  }
115
124
  embedder = default_from_dict(FastembedTextEmbedder, embedder_dict)
@@ -118,6 +127,7 @@ class TestFastembedTextEmbedder:
118
127
  assert embedder.suffix == "suffix"
119
128
  assert embedder.batch_size == 64
120
129
  assert embedder.progress_bar is False
130
+ assert embedder.parallel == 1
121
131
 
122
132
  @patch(
123
133
  "haystack_integrations.components.embedders.fastembed.fastembed_text_embedder._FastembedEmbeddingBackendFactory"
@@ -186,4 +196,4 @@ class TestFastembedTextEmbedder:
186
196
 
187
197
  assert isinstance(embedding, list)
188
198
  assert len(embedding) == 384
189
- assert all(isinstance(emb.item(), float) for emb in embedding)
199
+ assert all(isinstance(emb, float) for emb in embedding)