fastembed 0.3.2__tar.gz → 0.3.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 (41) hide show
  1. {fastembed-0.3.2 → fastembed-0.3.4}/PKG-INFO +3 -2
  2. {fastembed-0.3.2 → fastembed-0.3.4}/README.md +2 -2
  3. {fastembed-0.3.2 → fastembed-0.3.4}/fastembed/common/model_management.py +40 -36
  4. {fastembed-0.3.2 → fastembed-0.3.4}/fastembed/image/image_embedding.py +2 -2
  5. {fastembed-0.3.2 → fastembed-0.3.4}/fastembed/image/onnx_embedding.py +29 -4
  6. {fastembed-0.3.2 → fastembed-0.3.4}/fastembed/sparse/bm25.py +3 -2
  7. {fastembed-0.3.2 → fastembed-0.3.4}/fastembed/sparse/bm42.py +1 -0
  8. {fastembed-0.3.2 → fastembed-0.3.4}/fastembed/text/onnx_embedding.py +6 -32
  9. fastembed-0.3.4/fastembed/text/pooled_embedding.py +87 -0
  10. fastembed-0.3.2/fastembed/text/jina_onnx_embedding.py → fastembed-0.3.4/fastembed/text/pooled_normalized_embedding.py +18 -16
  11. {fastembed-0.3.2 → fastembed-0.3.4}/fastembed/text/text_embedding.py +4 -4
  12. {fastembed-0.3.2 → fastembed-0.3.4}/pyproject.toml +1 -1
  13. fastembed-0.3.2/fastembed/text/mini_lm_embedding.py +0 -58
  14. {fastembed-0.3.2 → fastembed-0.3.4}/LICENSE +0 -0
  15. {fastembed-0.3.2 → fastembed-0.3.4}/fastembed/__init__.py +0 -0
  16. {fastembed-0.3.2 → fastembed-0.3.4}/fastembed/common/__init__.py +0 -0
  17. {fastembed-0.3.2 → fastembed-0.3.4}/fastembed/common/onnx_model.py +0 -0
  18. {fastembed-0.3.2 → fastembed-0.3.4}/fastembed/common/preprocessor_utils.py +0 -0
  19. {fastembed-0.3.2 → fastembed-0.3.4}/fastembed/common/types.py +0 -0
  20. {fastembed-0.3.2 → fastembed-0.3.4}/fastembed/common/utils.py +0 -0
  21. {fastembed-0.3.2 → fastembed-0.3.4}/fastembed/embedding.py +0 -0
  22. {fastembed-0.3.2 → fastembed-0.3.4}/fastembed/image/__init__.py +0 -0
  23. {fastembed-0.3.2 → fastembed-0.3.4}/fastembed/image/image_embedding_base.py +0 -0
  24. {fastembed-0.3.2 → fastembed-0.3.4}/fastembed/image/onnx_image_model.py +0 -0
  25. {fastembed-0.3.2 → fastembed-0.3.4}/fastembed/image/transform/functional.py +0 -0
  26. {fastembed-0.3.2 → fastembed-0.3.4}/fastembed/image/transform/operators.py +0 -0
  27. {fastembed-0.3.2 → fastembed-0.3.4}/fastembed/late_interaction/__init__.py +0 -0
  28. {fastembed-0.3.2 → fastembed-0.3.4}/fastembed/late_interaction/colbert.py +0 -0
  29. {fastembed-0.3.2 → fastembed-0.3.4}/fastembed/late_interaction/late_interaction_embedding_base.py +0 -0
  30. {fastembed-0.3.2 → fastembed-0.3.4}/fastembed/late_interaction/late_interaction_text_embedding.py +0 -0
  31. {fastembed-0.3.2 → fastembed-0.3.4}/fastembed/parallel_processor.py +0 -0
  32. {fastembed-0.3.2 → fastembed-0.3.4}/fastembed/sparse/__init__.py +0 -0
  33. {fastembed-0.3.2 → fastembed-0.3.4}/fastembed/sparse/sparse_embedding_base.py +0 -0
  34. {fastembed-0.3.2 → fastembed-0.3.4}/fastembed/sparse/sparse_text_embedding.py +0 -0
  35. {fastembed-0.3.2 → fastembed-0.3.4}/fastembed/sparse/splade_pp.py +0 -0
  36. {fastembed-0.3.2 → fastembed-0.3.4}/fastembed/sparse/utils/tokenizer.py +0 -0
  37. {fastembed-0.3.2 → fastembed-0.3.4}/fastembed/text/__init__.py +0 -0
  38. {fastembed-0.3.2 → fastembed-0.3.4}/fastembed/text/clip_embedding.py +0 -0
  39. {fastembed-0.3.2 → fastembed-0.3.4}/fastembed/text/e5_onnx_embedding.py +0 -0
  40. {fastembed-0.3.2 → fastembed-0.3.4}/fastembed/text/onnx_text_model.py +0 -0
  41. {fastembed-0.3.2 → fastembed-0.3.4}/fastembed/text/text_embedding_base.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fastembed
3
- Version: 0.3.2
3
+ Version: 0.3.4
4
4
  Summary: Fast, light, accurate library built for retrieval embedding generation
5
5
  Home-page: https://github.com/qdrant/fastembed
6
6
  License: Apache License
@@ -43,7 +43,7 @@ The default text embedding (`TextEmbedding`) model is Flag Embedding, presented
43
43
 
44
44
  2. Fast: FastEmbed is designed for speed. We use the ONNX Runtime, which is faster than PyTorch. We also use data-parallelism for encoding large datasets.
45
45
 
46
- 3. Accurate: FastEmbed is better than OpenAI Ada-002. We also [supported](https://qdrant.github.io/fastembed/examples/Supported_Models/) an ever expanding set of models, including a few multilingual models.
46
+ 3. Accurate: FastEmbed is better than OpenAI Ada-002. We also [support](https://qdrant.github.io/fastembed/examples/Supported_Models/) an ever expanding set of models, including a few multilingual models.
47
47
 
48
48
  ## 🚀 Installation
49
49
 
@@ -243,3 +243,4 @@ search_result = client.query(
243
243
  )
244
244
  print(search_result)
245
245
  ```
246
+
@@ -10,7 +10,7 @@ The default text embedding (`TextEmbedding`) model is Flag Embedding, presented
10
10
 
11
11
  2. Fast: FastEmbed is designed for speed. We use the ONNX Runtime, which is faster than PyTorch. We also use data-parallelism for encoding large datasets.
12
12
 
13
- 3. Accurate: FastEmbed is better than OpenAI Ada-002. We also [supported](https://qdrant.github.io/fastembed/examples/Supported_Models/) an ever expanding set of models, including a few multilingual models.
13
+ 3. Accurate: FastEmbed is better than OpenAI Ada-002. We also [support](https://qdrant.github.io/fastembed/examples/Supported_Models/) an ever expanding set of models, including a few multilingual models.
14
14
 
15
15
  ## 🚀 Installation
16
16
 
@@ -209,4 +209,4 @@ search_result = client.query(
209
209
  query_text="This is a query document"
210
210
  )
211
211
  print(search_result)
212
- ```
212
+ ```
@@ -1,4 +1,5 @@
1
1
  import os
2
+ import time
2
3
  import shutil
3
4
  import tarfile
4
5
  from pathlib import Path
@@ -42,9 +43,7 @@ class ModelManagement:
42
43
  raise ValueError(f"Model {model_name} is not supported in {cls.__name__}.")
43
44
 
44
45
  @classmethod
45
- def download_file_from_gcs(
46
- cls, url: str, output_path: str, show_progress: bool = True
47
- ) -> str:
46
+ def download_file_from_gcs(cls, url: str, output_path: str, show_progress: bool = True) -> str:
48
47
  """
49
48
  Downloads a file from Google Cloud Storage.
50
49
 
@@ -73,9 +72,7 @@ class ModelManagement:
73
72
 
74
73
  # Warn if the total size is zero
75
74
  if total_size_in_bytes == 0:
76
- print(
77
- f"Warning: Content-length header is missing or zero in the response from {url}."
78
- )
75
+ print(f"Warning: Content-length header is missing or zero in the response from {url}.")
79
76
 
80
77
  show_progress = total_size_in_bytes and show_progress
81
78
 
@@ -163,9 +160,7 @@ class ModelManagement:
163
160
  return cache_dir
164
161
 
165
162
  @classmethod
166
- def retrieve_model_gcs(
167
- cls, model_name: str, source_url: str, cache_dir: str
168
- ) -> Path:
163
+ def retrieve_model_gcs(cls, model_name: str, source_url: str, cache_dir: str) -> Path:
169
164
  fast_model_name = f"fast-{model_name.split('/')[-1]}"
170
165
 
171
166
  cache_tmp_dir = Path(cache_dir) / "tmp"
@@ -191,12 +186,8 @@ class ModelManagement:
191
186
  output_path=str(model_tar_gz),
192
187
  )
193
188
 
194
- cls.decompress_to_cache(
195
- targz_path=str(model_tar_gz), cache_dir=str(cache_tmp_dir)
196
- )
197
- assert (
198
- model_tmp_dir.exists()
199
- ), f"Could not find {model_tmp_dir} in {cache_tmp_dir}"
189
+ cls.decompress_to_cache(targz_path=str(model_tar_gz), cache_dir=str(cache_tmp_dir))
190
+ assert model_tmp_dir.exists(), f"Could not find {model_tmp_dir} in {cache_tmp_dir}"
200
191
 
201
192
  model_tar_gz.unlink()
202
193
  # Rename from tmp to final name is atomic
@@ -205,7 +196,7 @@ class ModelManagement:
205
196
  return model_dir
206
197
 
207
198
  @classmethod
208
- def download_model(cls, model: Dict[str, Any], cache_dir: Path, **kwargs) -> Path:
199
+ def download_model(cls, model: Dict[str, Any], cache_dir: Path, retries=3, **kwargs) -> Path:
209
200
  """
210
201
  Downloads a model from HuggingFace Hub or Google Cloud Storage.
211
202
 
@@ -225,6 +216,7 @@ class ModelManagement:
225
216
  }
226
217
  ```
227
218
  cache_dir (str): The path to the cache directory.
219
+ retries: (int): The number of times to retry (including the first attempt)
228
220
 
229
221
  Returns:
230
222
  Path: The path to the downloaded model directory.
@@ -233,26 +225,38 @@ class ModelManagement:
233
225
  hf_source = model.get("sources", {}).get("hf")
234
226
  url_source = model.get("sources", {}).get("url")
235
227
 
236
- if hf_source:
237
- extra_patterns = [model["model_file"]]
238
- extra_patterns.extend(model.get("additional_files", []))
239
-
240
- try:
241
- return Path(
242
- cls.download_files_from_huggingface(
243
- hf_source,
244
- cache_dir=str(cache_dir),
245
- extra_patterns=extra_patterns,
246
- local_files_only=kwargs.get("local_files_only", False),
228
+ sleep = 3.0
229
+ while retries > 0:
230
+ retries -= 1
231
+
232
+ if hf_source:
233
+ extra_patterns = [model["model_file"]]
234
+ extra_patterns.extend(model.get("additional_files", []))
235
+
236
+ try:
237
+ return Path(
238
+ cls.download_files_from_huggingface(
239
+ hf_source,
240
+ cache_dir=str(cache_dir),
241
+ extra_patterns=extra_patterns,
242
+ local_files_only=kwargs.get("local_files_only", False),
243
+ )
247
244
  )
248
- )
249
- except (EnvironmentError, RepositoryNotFoundError, ValueError) as e:
250
- logger.error(
251
- f"Could not download model from HuggingFace: {e}"
252
- "Falling back to other sources."
253
- )
254
-
255
- if url_source:
256
- return cls.retrieve_model_gcs(model["model"], url_source, str(cache_dir))
245
+ except (EnvironmentError, RepositoryNotFoundError, ValueError) as e:
246
+ logger.error(
247
+ f"Could not download model from HuggingFace: {e} "
248
+ "Falling back to other sources."
249
+ )
250
+ if url_source:
251
+ try:
252
+ return cls.retrieve_model_gcs(model["model"], url_source, str(cache_dir))
253
+ except Exception:
254
+ logger.error(f"Could not download model from url: {url_source}")
255
+
256
+ logger.error(
257
+ f"Could not download model from either source, sleeping for {sleep} seconds, {retries} retries left."
258
+ )
259
+ time.sleep(sleep)
260
+ sleep *= 3
257
261
 
258
262
  raise ValueError(f"Could not download model {model['model']} from any source.")
@@ -65,8 +65,8 @@ class ImageEmbedding(ImageEmbeddingBase):
65
65
  return
66
66
 
67
67
  raise ValueError(
68
- f"Model {model_name} is not supported in TextEmbedding."
69
- "Please check the supported models using `TextEmbedding.list_supported_models()`"
68
+ f"Model {model_name} is not supported in ImageEmbedding."
69
+ "Please check the supported models using `ImageEmbedding.list_supported_models()`"
70
70
  )
71
71
 
72
72
  def embed(
@@ -29,9 +29,28 @@ supported_onnx_models = [
29
29
  },
30
30
  "model_file": "model.onnx",
31
31
  },
32
+ {
33
+ "model": "Qdrant/Unicom-ViT-B-16",
34
+ "dim": 768,
35
+ "description": "Unicom Unicom-ViT-B-16 from open-metric-learning",
36
+ "size_in_GB": 0.82,
37
+ "sources": {
38
+ "hf": "Qdrant/Unicom-ViT-B-16",
39
+ },
40
+ "model_file": "model.onnx",
41
+ },
42
+ {
43
+ "model": "Qdrant/Unicom-ViT-B-32",
44
+ "dim": 512,
45
+ "description": "Unicom Unicom-ViT-B-32 from open-metric-learning",
46
+ "size_in_GB": 0.48,
47
+ "sources": {
48
+ "hf": "Qdrant/Unicom-ViT-B-32",
49
+ },
50
+ "model_file": "model.onnx",
51
+ },
32
52
  ]
33
53
 
34
-
35
54
  class OnnxImageEmbedding(ImageEmbeddingBase, OnnxImageModel[np.ndarray]):
36
55
  def __init__(
37
56
  self,
@@ -122,10 +141,16 @@ class OnnxImageEmbedding(ImageEmbeddingBase, OnnxImageModel[np.ndarray]):
122
141
 
123
142
  return onnx_input
124
143
 
125
- def _post_process_onnx_output(self, output: OnnxOutputContext) -> Iterable[np.ndarray]:
144
+ def _post_process_onnx_output(
145
+ self, output: OnnxOutputContext
146
+ ) -> Iterable[np.ndarray]:
126
147
  return normalize(output.model_output).astype(np.float32)
127
148
 
128
149
 
129
150
  class OnnxImageEmbeddingWorker(ImageEmbeddingWorker):
130
- def init_embedding(self, model_name: str, cache_dir: str, **kwargs) -> OnnxImageEmbedding:
131
- return OnnxImageEmbedding(model_name=model_name, cache_dir=cache_dir, threads=1, **kwargs)
151
+ def init_embedding(
152
+ self, model_name: str, cache_dir: str, **kwargs
153
+ ) -> OnnxImageEmbedding:
154
+ return OnnxImageEmbedding(
155
+ model_name=model_name, cache_dir=cache_dir, threads=1, **kwargs
156
+ )
@@ -27,6 +27,7 @@ supported_bm25_models = [
27
27
  },
28
28
  "model_file": "mock.file", # bm25 does not require a model, so we just use a mock
29
29
  "additional_files": ["stopwords.txt"],
30
+ "requires_idf": True,
30
31
  },
31
32
  ]
32
33
 
@@ -250,8 +251,8 @@ class Bm25(SparseTextEmbeddingBase):
250
251
  tokens = self.tokenizer.tokenize(text)
251
252
  stemmed_tokens = self._stem(tokens)
252
253
  token_ids = np.array(
253
- [self.compute_token_id(token) for token in stemmed_tokens],
254
- dtype=np.float32,
254
+ list(set(self.compute_token_id(token) for token in stemmed_tokens)),
255
+ dtype=np.int32,
255
256
  )
256
257
  values = np.ones_like(token_ids)
257
258
  yield SparseEmbedding(indices=token_ids, values=values)
@@ -27,6 +27,7 @@ supported_bm42_models = [
27
27
  },
28
28
  "model_file": "model.onnx",
29
29
  "additional_files": ["stopwords.txt"],
30
+ "requires_idf": True,
30
31
  },
31
32
  ]
32
33
 
@@ -80,36 +80,6 @@ supported_onnx_models = [
80
80
  },
81
81
  "model_file": "model_optimized.onnx",
82
82
  },
83
- {
84
- "model": "nomic-ai/nomic-embed-text-v1",
85
- "dim": 768,
86
- "description": "8192 context length english model",
87
- "size_in_GB": 0.52,
88
- "sources": {
89
- "hf": "nomic-ai/nomic-embed-text-v1",
90
- },
91
- "model_file": "onnx/model.onnx",
92
- },
93
- {
94
- "model": "nomic-ai/nomic-embed-text-v1.5",
95
- "dim": 768,
96
- "description": "8192 context length english model",
97
- "size_in_GB": 0.52,
98
- "sources": {
99
- "hf": "nomic-ai/nomic-embed-text-v1.5",
100
- },
101
- "model_file": "onnx/model.onnx",
102
- },
103
- {
104
- "model": "nomic-ai/nomic-embed-text-v1.5-Q",
105
- "dim": 768,
106
- "description": "Quantized 8192 context length english model",
107
- "size_in_GB": 0.13,
108
- "sources": {
109
- "hf": "nomic-ai/nomic-embed-text-v1.5",
110
- },
111
- "model_file": "onnx/model_quantized.onnx",
112
- },
113
83
  {
114
84
  "model": "thenlper/gte-large",
115
85
  "dim": 1024,
@@ -274,7 +244,9 @@ class OnnxTextEmbedding(TextEmbeddingBase, OnnxTextModel[np.ndarray]):
274
244
  """
275
245
  return onnx_input
276
246
 
277
- def _post_process_onnx_output(self, output: OnnxOutputContext) -> Iterable[np.ndarray]:
247
+ def _post_process_onnx_output(
248
+ self, output: OnnxOutputContext
249
+ ) -> Iterable[np.ndarray]:
278
250
  embeddings = output.model_output
279
251
  return normalize(embeddings[:, 0]).astype(np.float32)
280
252
 
@@ -286,4 +258,6 @@ class OnnxTextEmbeddingWorker(TextEmbeddingWorker):
286
258
  cache_dir: str,
287
259
  **kwargs,
288
260
  ) -> OnnxTextEmbedding:
289
- return OnnxTextEmbedding(model_name=model_name, cache_dir=cache_dir, threads=1, **kwargs)
261
+ return OnnxTextEmbedding(
262
+ model_name=model_name, cache_dir=cache_dir, threads=1, **kwargs
263
+ )
@@ -0,0 +1,87 @@
1
+ from typing import Any, Dict, Iterable, List, Type
2
+
3
+ import numpy as np
4
+
5
+ from fastembed.common.onnx_model import OnnxOutputContext
6
+ from fastembed.common.utils import normalize
7
+ from fastembed.text.onnx_embedding import OnnxTextEmbedding, OnnxTextEmbeddingWorker
8
+ from fastembed.text.onnx_text_model import TextEmbeddingWorker
9
+
10
+ supported_pooled_models = [
11
+ {
12
+ "model": "nomic-ai/nomic-embed-text-v1.5",
13
+ "dim": 768,
14
+ "description": "8192 context length english model",
15
+ "size_in_GB": 0.52,
16
+ "sources": {
17
+ "hf": "nomic-ai/nomic-embed-text-v1.5",
18
+ },
19
+ "model_file": "onnx/model.onnx",
20
+ },
21
+ {
22
+ "model": "nomic-ai/nomic-embed-text-v1.5-Q",
23
+ "dim": 768,
24
+ "description": "Quantized 8192 context length english model",
25
+ "size_in_GB": 0.13,
26
+ "sources": {
27
+ "hf": "nomic-ai/nomic-embed-text-v1.5",
28
+ },
29
+ "model_file": "onnx/model_quantized.onnx",
30
+ },
31
+ {
32
+ "model": "nomic-ai/nomic-embed-text-v1",
33
+ "dim": 768,
34
+ "description": "8192 context length english model",
35
+ "size_in_GB": 0.52,
36
+ "sources": {
37
+ "hf": "nomic-ai/nomic-embed-text-v1",
38
+ },
39
+ "model_file": "onnx/model.onnx",
40
+ },
41
+ ]
42
+
43
+
44
+ class PooledEmbedding(OnnxTextEmbedding):
45
+ @classmethod
46
+ def _get_worker_class(cls) -> Type[TextEmbeddingWorker]:
47
+ return PooledEmbeddingWorker
48
+
49
+ @classmethod
50
+ def mean_pooling(
51
+ cls, model_output: np.ndarray, attention_mask: np.ndarray
52
+ ) -> np.ndarray:
53
+ token_embeddings = model_output
54
+ input_mask_expanded = np.expand_dims(attention_mask, axis=-1)
55
+ input_mask_expanded = np.tile(
56
+ input_mask_expanded, (1, 1, token_embeddings.shape[-1])
57
+ )
58
+ input_mask_expanded = input_mask_expanded.astype(float)
59
+ sum_embeddings = np.sum(token_embeddings * input_mask_expanded, axis=1)
60
+ sum_mask = np.sum(input_mask_expanded, axis=1)
61
+ pooled_embeddings = sum_embeddings / np.maximum(sum_mask, 1e-9)
62
+ return pooled_embeddings
63
+
64
+ @classmethod
65
+ def list_supported_models(cls) -> List[Dict[str, Any]]:
66
+ """Lists the supported models.
67
+
68
+ Returns:
69
+ List[Dict[str, Any]]: A list of dictionaries containing the model information.
70
+ """
71
+ return supported_pooled_models
72
+
73
+ def _post_process_onnx_output(
74
+ self, output: OnnxOutputContext
75
+ ) -> Iterable[np.ndarray]:
76
+ embeddings = output.model_output
77
+ attn_mask = output.attention_mask
78
+ return self.mean_pooling(embeddings, attn_mask).astype(np.float32)
79
+
80
+
81
+ class PooledEmbeddingWorker(OnnxTextEmbeddingWorker):
82
+ def init_embedding(
83
+ self, model_name: str, cache_dir: str, **kwargs
84
+ ) -> OnnxTextEmbedding:
85
+ return PooledEmbedding(
86
+ model_name=model_name, cache_dir=cache_dir, threads=1, **kwargs
87
+ )
@@ -6,8 +6,20 @@ from fastembed.common.onnx_model import OnnxOutputContext
6
6
  from fastembed.common.utils import normalize
7
7
  from fastembed.text.onnx_embedding import OnnxTextEmbedding, OnnxTextEmbeddingWorker
8
8
  from fastembed.text.onnx_text_model import TextEmbeddingWorker
9
+ from fastembed.text.pooled_embedding import PooledEmbedding
9
10
 
10
- supported_jina_models = [
11
+ supported_pooled_normalized_models = [
12
+ {
13
+ "model": "sentence-transformers/all-MiniLM-L6-v2",
14
+ "dim": 384,
15
+ "description": "Sentence Transformer model, MiniLM-L6-v2",
16
+ "size_in_GB": 0.09,
17
+ "sources": {
18
+ "url": "https://storage.googleapis.com/qdrant-fastembed/sentence-transformers-all-MiniLM-L6-v2.tar.gz",
19
+ "hf": "qdrant/all-MiniLM-L6-v2-onnx",
20
+ },
21
+ "model_file": "model.onnx",
22
+ },
11
23
  {
12
24
  "model": "jinaai/jina-embeddings-v2-base-en",
13
25
  "dim": 768,
@@ -35,20 +47,10 @@ supported_jina_models = [
35
47
  ]
36
48
 
37
49
 
38
- class JinaOnnxEmbedding(OnnxTextEmbedding):
50
+ class PooledNormalizedEmbedding(PooledEmbedding):
39
51
  @classmethod
40
52
  def _get_worker_class(cls) -> Type[TextEmbeddingWorker]:
41
- return JinaEmbeddingWorker
42
-
43
- @classmethod
44
- def mean_pooling(cls, model_output, attention_mask) -> np.ndarray:
45
- token_embeddings = model_output
46
- input_mask_expanded = (np.expand_dims(attention_mask, axis=-1)).astype(float)
47
-
48
- sum_embeddings = np.sum(token_embeddings * input_mask_expanded, axis=1)
49
- mask_sum = np.clip(np.sum(input_mask_expanded, axis=1), a_min=1e-9, a_max=None)
50
-
51
- return sum_embeddings / mask_sum
53
+ return PooledNormalizedEmbeddingWorker
52
54
 
53
55
  @classmethod
54
56
  def list_supported_models(cls) -> List[Dict[str, Any]]:
@@ -57,7 +59,7 @@ class JinaOnnxEmbedding(OnnxTextEmbedding):
57
59
  Returns:
58
60
  List[Dict[str, Any]]: A list of dictionaries containing the model information.
59
61
  """
60
- return supported_jina_models
62
+ return supported_pooled_normalized_models
61
63
 
62
64
  def _post_process_onnx_output(
63
65
  self, output: OnnxOutputContext
@@ -67,10 +69,10 @@ class JinaOnnxEmbedding(OnnxTextEmbedding):
67
69
  return normalize(self.mean_pooling(embeddings, attn_mask)).astype(np.float32)
68
70
 
69
71
 
70
- class JinaEmbeddingWorker(OnnxTextEmbeddingWorker):
72
+ class PooledNormalizedEmbeddingWorker(OnnxTextEmbeddingWorker):
71
73
  def init_embedding(
72
74
  self, model_name: str, cache_dir: str, **kwargs
73
75
  ) -> OnnxTextEmbedding:
74
- return JinaOnnxEmbedding(
76
+ return PooledNormalizedEmbedding(
75
77
  model_name=model_name, cache_dir=cache_dir, threads=1, **kwargs
76
78
  )
@@ -5,8 +5,8 @@ import numpy as np
5
5
  from fastembed.common import OnnxProvider
6
6
  from fastembed.text.clip_embedding import CLIPOnnxEmbedding
7
7
  from fastembed.text.e5_onnx_embedding import E5OnnxEmbedding
8
- from fastembed.text.jina_onnx_embedding import JinaOnnxEmbedding
9
- from fastembed.text.mini_lm_embedding import MiniLMOnnxEmbedding
8
+ from fastembed.text.pooled_normalized_embedding import PooledNormalizedEmbedding
9
+ from fastembed.text.pooled_embedding import PooledEmbedding
10
10
  from fastembed.text.onnx_embedding import OnnxTextEmbedding
11
11
  from fastembed.text.text_embedding_base import TextEmbeddingBase
12
12
 
@@ -15,9 +15,9 @@ class TextEmbedding(TextEmbeddingBase):
15
15
  EMBEDDINGS_REGISTRY: List[Type[TextEmbeddingBase]] = [
16
16
  OnnxTextEmbedding,
17
17
  E5OnnxEmbedding,
18
- JinaOnnxEmbedding,
19
18
  CLIPOnnxEmbedding,
20
- MiniLMOnnxEmbedding,
19
+ PooledNormalizedEmbedding,
20
+ PooledEmbedding,
21
21
  ]
22
22
 
23
23
  @classmethod
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "fastembed"
3
- version = "0.3.2"
3
+ version = "0.3.4"
4
4
  description = "Fast, light, accurate library built for retrieval embedding generation"
5
5
  authors = ["Qdrant Team <info@qdrant.tech>", "NirantK <nirant.bits@gmail.com>"]
6
6
  license = "Apache License"
@@ -1,58 +0,0 @@
1
- from typing import Any, Dict, Iterable, List, Type
2
-
3
- import numpy as np
4
-
5
- from fastembed.common.onnx_model import OnnxOutputContext
6
- from fastembed.common.utils import normalize
7
- from fastembed.text.onnx_embedding import OnnxTextEmbedding, OnnxTextEmbeddingWorker
8
- from fastembed.text.onnx_text_model import TextEmbeddingWorker
9
-
10
- supported_mini_lm_models = [
11
- {
12
- "model": "sentence-transformers/all-MiniLM-L6-v2",
13
- "dim": 384,
14
- "description": "Sentence Transformer model, MiniLM-L6-v2",
15
- "size_in_GB": 0.09,
16
- "sources": {
17
- "url": "https://storage.googleapis.com/qdrant-fastembed/sentence-transformers-all-MiniLM-L6-v2.tar.gz",
18
- "hf": "qdrant/all-MiniLM-L6-v2-onnx",
19
- },
20
- "model_file": "model.onnx",
21
- }
22
- ]
23
-
24
-
25
- class MiniLMOnnxEmbedding(OnnxTextEmbedding):
26
- @classmethod
27
- def _get_worker_class(cls) -> Type[TextEmbeddingWorker]:
28
- return MiniLMEmbeddingWorker
29
-
30
- @classmethod
31
- def mean_pooling(cls, model_output: np.ndarray, attention_mask: np.ndarray) -> np.ndarray:
32
- token_embeddings = model_output
33
- input_mask_expanded = np.expand_dims(attention_mask, axis=-1)
34
- input_mask_expanded = np.tile(input_mask_expanded, (1, 1, token_embeddings.shape[-1]))
35
- input_mask_expanded = input_mask_expanded.astype(float)
36
- sum_embeddings = np.sum(token_embeddings * input_mask_expanded, axis=1)
37
- sum_mask = np.sum(input_mask_expanded, axis=1)
38
- pooled_embeddings = sum_embeddings / np.maximum(sum_mask, 1e-9)
39
- return pooled_embeddings
40
-
41
- @classmethod
42
- def list_supported_models(cls) -> List[Dict[str, Any]]:
43
- """Lists the supported models.
44
-
45
- Returns:
46
- List[Dict[str, Any]]: A list of dictionaries containing the model information.
47
- """
48
- return supported_mini_lm_models
49
-
50
- def _post_process_onnx_output(self, output: OnnxOutputContext) -> Iterable[np.ndarray]:
51
- embeddings = output.model_output
52
- attn_mask = output.attention_mask
53
- return normalize(self.mean_pooling(embeddings, attn_mask)).astype(np.float32)
54
-
55
-
56
- class MiniLMEmbeddingWorker(OnnxTextEmbeddingWorker):
57
- def init_embedding(self, model_name: str, cache_dir: str, **kwargs) -> OnnxTextEmbedding:
58
- return MiniLMOnnxEmbedding(model_name=model_name, cache_dir=cache_dir, threads=1, **kwargs)
File without changes