fastembed-gpu 0.3.4__tar.gz → 0.3.5__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_gpu-0.3.4 → fastembed_gpu-0.3.5}/PKG-INFO +9 -9
  2. {fastembed_gpu-0.3.4 → fastembed_gpu-0.3.5}/README.md +8 -8
  3. fastembed_gpu-0.3.5/fastembed/common/__init__.py +3 -0
  4. {fastembed_gpu-0.3.4 → fastembed_gpu-0.3.5}/fastembed/common/model_management.py +3 -1
  5. {fastembed_gpu-0.3.4 → fastembed_gpu-0.3.5}/fastembed/common/preprocessor_utils.py +11 -5
  6. {fastembed_gpu-0.3.4 → fastembed_gpu-0.3.5}/fastembed/common/types.py +3 -1
  7. {fastembed_gpu-0.3.4 → fastembed_gpu-0.3.5}/fastembed/image/onnx_embedding.py +8 -13
  8. {fastembed_gpu-0.3.4 → fastembed_gpu-0.3.5}/fastembed/image/onnx_image_model.py +12 -7
  9. {fastembed_gpu-0.3.4 → fastembed_gpu-0.3.5}/fastembed/late_interaction/colbert.py +11 -1
  10. {fastembed_gpu-0.3.4 → fastembed_gpu-0.3.5}/fastembed/sparse/bm25.py +43 -9
  11. {fastembed_gpu-0.3.4 → fastembed_gpu-0.3.5}/fastembed/sparse/sparse_text_embedding.py +10 -7
  12. {fastembed_gpu-0.3.4 → fastembed_gpu-0.3.5}/fastembed/sparse/splade_pp.py +0 -12
  13. {fastembed_gpu-0.3.4 → fastembed_gpu-0.3.5}/fastembed/text/clip_embedding.py +1 -1
  14. {fastembed_gpu-0.3.4 → fastembed_gpu-0.3.5}/fastembed/text/e5_onnx_embedding.py +2 -2
  15. {fastembed_gpu-0.3.4 → fastembed_gpu-0.3.5}/fastembed/text/onnx_embedding.py +16 -20
  16. {fastembed_gpu-0.3.4 → fastembed_gpu-0.3.5}/fastembed/text/pooled_embedding.py +3 -3
  17. {fastembed_gpu-0.3.4 → fastembed_gpu-0.3.5}/fastembed/text/pooled_normalized_embedding.py +12 -4
  18. {fastembed_gpu-0.3.4 → fastembed_gpu-0.3.5}/pyproject.toml +1 -1
  19. fastembed_gpu-0.3.4/fastembed/common/__init__.py +0 -3
  20. {fastembed_gpu-0.3.4 → fastembed_gpu-0.3.5}/LICENSE +0 -0
  21. {fastembed_gpu-0.3.4 → fastembed_gpu-0.3.5}/fastembed/__init__.py +0 -0
  22. {fastembed_gpu-0.3.4 → fastembed_gpu-0.3.5}/fastembed/common/onnx_model.py +0 -0
  23. {fastembed_gpu-0.3.4 → fastembed_gpu-0.3.5}/fastembed/common/utils.py +0 -0
  24. {fastembed_gpu-0.3.4 → fastembed_gpu-0.3.5}/fastembed/embedding.py +0 -0
  25. {fastembed_gpu-0.3.4 → fastembed_gpu-0.3.5}/fastembed/image/__init__.py +0 -0
  26. {fastembed_gpu-0.3.4 → fastembed_gpu-0.3.5}/fastembed/image/image_embedding.py +0 -0
  27. {fastembed_gpu-0.3.4 → fastembed_gpu-0.3.5}/fastembed/image/image_embedding_base.py +0 -0
  28. {fastembed_gpu-0.3.4 → fastembed_gpu-0.3.5}/fastembed/image/transform/functional.py +0 -0
  29. {fastembed_gpu-0.3.4 → fastembed_gpu-0.3.5}/fastembed/image/transform/operators.py +0 -0
  30. {fastembed_gpu-0.3.4 → fastembed_gpu-0.3.5}/fastembed/late_interaction/__init__.py +0 -0
  31. {fastembed_gpu-0.3.4 → fastembed_gpu-0.3.5}/fastembed/late_interaction/late_interaction_embedding_base.py +0 -0
  32. {fastembed_gpu-0.3.4 → fastembed_gpu-0.3.5}/fastembed/late_interaction/late_interaction_text_embedding.py +0 -0
  33. {fastembed_gpu-0.3.4 → fastembed_gpu-0.3.5}/fastembed/parallel_processor.py +0 -0
  34. {fastembed_gpu-0.3.4 → fastembed_gpu-0.3.5}/fastembed/sparse/__init__.py +0 -0
  35. {fastembed_gpu-0.3.4 → fastembed_gpu-0.3.5}/fastembed/sparse/bm42.py +0 -0
  36. {fastembed_gpu-0.3.4 → fastembed_gpu-0.3.5}/fastembed/sparse/sparse_embedding_base.py +0 -0
  37. {fastembed_gpu-0.3.4 → fastembed_gpu-0.3.5}/fastembed/sparse/utils/tokenizer.py +0 -0
  38. {fastembed_gpu-0.3.4 → fastembed_gpu-0.3.5}/fastembed/text/__init__.py +0 -0
  39. {fastembed_gpu-0.3.4 → fastembed_gpu-0.3.5}/fastembed/text/onnx_text_model.py +0 -0
  40. {fastembed_gpu-0.3.4 → fastembed_gpu-0.3.5}/fastembed/text/text_embedding.py +0 -0
  41. {fastembed_gpu-0.3.4 → fastembed_gpu-0.3.5}/fastembed/text/text_embedding_base.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fastembed-gpu
3
- Version: 0.3.4
3
+ Version: 0.3.5
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
@@ -40,9 +40,9 @@ The default text embedding (`TextEmbedding`) model is Flag Embedding, presented
40
40
 
41
41
  1. Light: FastEmbed is a lightweight library with few external dependencies. We don't require a GPU and don't download GBs of PyTorch dependencies, and instead use the ONNX Runtime. This makes it a great candidate for serverless runtimes like AWS Lambda.
42
42
 
43
- 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.
43
+ 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.
44
44
 
45
- 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.
45
+ 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.
46
46
 
47
47
  ## 🚀 Installation
48
48
 
@@ -86,7 +86,7 @@ The list of all the available models can be found [here](https://qdrant.github.i
86
86
  from fastembed import TextEmbedding
87
87
 
88
88
  model = TextEmbedding(model_name="BAAI/bge-small-en-v1.5")
89
- embeddings = list(embedding_model.embed(documents))
89
+ embeddings = list(model.embed(documents))
90
90
 
91
91
  # [
92
92
  # array([-0.1115, 0.0097, 0.0052, 0.0195, ...], dtype=float32),
@@ -105,7 +105,7 @@ embeddings = list(embedding_model.embed(documents))
105
105
  from fastembed import SparseTextEmbedding
106
106
 
107
107
  model = SparseTextEmbedding(model_name="prithivida/Splade_PP_en_v1")
108
- embeddings = list(embedding_model.embed(documents))
108
+ embeddings = list(model.embed(documents))
109
109
 
110
110
  # [
111
111
  # SparseEmbedding(indices=[ 17, 123, 919, ... ], values=[0.71, 0.22, 0.39, ...]),
@@ -120,7 +120,7 @@ embeddings = list(embedding_model.embed(documents))
120
120
  from fastembed import SparseTextEmbedding
121
121
 
122
122
  model = SparseTextEmbedding(model_name="Qdrant/bm42-all-minilm-l6-v2-attentions")
123
- embeddings = list(embedding_model.embed(documents))
123
+ embeddings = list(model.embed(documents))
124
124
 
125
125
  # [
126
126
  # SparseEmbedding(indices=[ 17, 123, 919, ... ], values=[0.71, 0.22, 0.39, ...]),
@@ -136,7 +136,7 @@ embeddings = list(embedding_model.embed(documents))
136
136
  from fastembed import LateInteractionTextEmbedding
137
137
 
138
138
  model = LateInteractionTextEmbedding(model_name="colbert-ir/colbertv2.0")
139
- embeddings = list(embedding_model.embed(documents))
139
+ embeddings = list(model.embed(documents))
140
140
 
141
141
  # [
142
142
  # array([
@@ -161,7 +161,7 @@ images = [
161
161
  ]
162
162
 
163
163
  model = ImageEmbedding(model_name="Qdrant/clip-ViT-B-32-vision")
164
- embeddings = list(embedding_model.embed(images))
164
+ embeddings = list(model.embed(images))
165
165
 
166
166
  # [
167
167
  # array([-0.1115, 0.0097, 0.0052, 0.0195, ...], dtype=float32),
@@ -179,7 +179,7 @@ It requires installation of the `fastembed-gpu` package.
179
179
  pip install fastembed-gpu
180
180
  ```
181
181
 
182
- Check our [example](https://qdrant.github.io/fastembed/examples/FastEmbed_GPU/) for the detailed instructions and CUDA 12.x support.
182
+ Check our [example](https://qdrant.github.io/fastembed/examples/FastEmbed_GPU/) for detailed instructions and CUDA 12.x support.
183
183
 
184
184
  ```python
185
185
  from fastembed import TextEmbedding
@@ -8,9 +8,9 @@ The default text embedding (`TextEmbedding`) model is Flag Embedding, presented
8
8
 
9
9
  1. Light: FastEmbed is a lightweight library with few external dependencies. We don't require a GPU and don't download GBs of PyTorch dependencies, and instead use the ONNX Runtime. This makes it a great candidate for serverless runtimes like AWS Lambda.
10
10
 
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.
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 [support](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
 
@@ -54,7 +54,7 @@ The list of all the available models can be found [here](https://qdrant.github.i
54
54
  from fastembed import TextEmbedding
55
55
 
56
56
  model = TextEmbedding(model_name="BAAI/bge-small-en-v1.5")
57
- embeddings = list(embedding_model.embed(documents))
57
+ embeddings = list(model.embed(documents))
58
58
 
59
59
  # [
60
60
  # array([-0.1115, 0.0097, 0.0052, 0.0195, ...], dtype=float32),
@@ -73,7 +73,7 @@ embeddings = list(embedding_model.embed(documents))
73
73
  from fastembed import SparseTextEmbedding
74
74
 
75
75
  model = SparseTextEmbedding(model_name="prithivida/Splade_PP_en_v1")
76
- embeddings = list(embedding_model.embed(documents))
76
+ embeddings = list(model.embed(documents))
77
77
 
78
78
  # [
79
79
  # SparseEmbedding(indices=[ 17, 123, 919, ... ], values=[0.71, 0.22, 0.39, ...]),
@@ -88,7 +88,7 @@ embeddings = list(embedding_model.embed(documents))
88
88
  from fastembed import SparseTextEmbedding
89
89
 
90
90
  model = SparseTextEmbedding(model_name="Qdrant/bm42-all-minilm-l6-v2-attentions")
91
- embeddings = list(embedding_model.embed(documents))
91
+ embeddings = list(model.embed(documents))
92
92
 
93
93
  # [
94
94
  # SparseEmbedding(indices=[ 17, 123, 919, ... ], values=[0.71, 0.22, 0.39, ...]),
@@ -104,7 +104,7 @@ embeddings = list(embedding_model.embed(documents))
104
104
  from fastembed import LateInteractionTextEmbedding
105
105
 
106
106
  model = LateInteractionTextEmbedding(model_name="colbert-ir/colbertv2.0")
107
- embeddings = list(embedding_model.embed(documents))
107
+ embeddings = list(model.embed(documents))
108
108
 
109
109
  # [
110
110
  # array([
@@ -129,7 +129,7 @@ images = [
129
129
  ]
130
130
 
131
131
  model = ImageEmbedding(model_name="Qdrant/clip-ViT-B-32-vision")
132
- embeddings = list(embedding_model.embed(images))
132
+ embeddings = list(model.embed(images))
133
133
 
134
134
  # [
135
135
  # array([-0.1115, 0.0097, 0.0052, 0.0195, ...], dtype=float32),
@@ -147,7 +147,7 @@ It requires installation of the `fastembed-gpu` package.
147
147
  pip install fastembed-gpu
148
148
  ```
149
149
 
150
- Check our [example](https://qdrant.github.io/fastembed/examples/FastEmbed_GPU/) for the detailed instructions and CUDA 12.x support.
150
+ Check our [example](https://qdrant.github.io/fastembed/examples/FastEmbed_GPU/) for detailed instructions and CUDA 12.x support.
151
151
 
152
152
  ```python
153
153
  from fastembed import TextEmbedding
@@ -0,0 +1,3 @@
1
+ from fastembed.common.types import ImageInput, OnnxProvider, PathInput, PilInput
2
+
3
+ __all__ = ["OnnxProvider", "ImageInput", "PathInput", "PilInput"]
@@ -148,7 +148,9 @@ class ModelManagement:
148
148
  # Open the tar.gz file
149
149
  with tarfile.open(targz_path, "r:gz") as tar:
150
150
  # Extract all files into the cache directory
151
- tar.extractall(path=cache_dir)
151
+ tar.extractall(
152
+ path=cache_dir,
153
+ )
152
154
  except tarfile.TarError as e:
153
155
  # If any error occurs while opening or extracting the tar.gz file,
154
156
  # delete the cache directory (if it was created in this function)
@@ -1,7 +1,6 @@
1
1
  import json
2
2
  from pathlib import Path
3
3
  from typing import Tuple
4
-
5
4
  from tokenizers import AddedToken, Tokenizer
6
5
 
7
6
  from fastembed.image.transform.operators import Compose
@@ -18,7 +17,7 @@ def load_special_tokens(model_dir: Path) -> dict:
18
17
  return tokens_map
19
18
 
20
19
 
21
- def load_tokenizer(model_dir: Path, max_length: int = 512) -> Tuple[Tokenizer, dict]:
20
+ def load_tokenizer(model_dir: Path) -> Tuple[Tokenizer, dict]:
22
21
  config_path = model_dir / "config.json"
23
22
  if not config_path.exists():
24
23
  raise ValueError(f"Could not find config.json in {model_dir}")
@@ -36,13 +35,20 @@ def load_tokenizer(model_dir: Path, max_length: int = 512) -> Tuple[Tokenizer, d
36
35
 
37
36
  with open(str(tokenizer_config_path)) as tokenizer_config_file:
38
37
  tokenizer_config = json.load(tokenizer_config_file)
38
+ assert (
39
+ "model_max_length" in tokenizer_config or "max_length" in tokenizer_config
40
+ ), "Models without model_max_length or max_length are not supported."
41
+ if "model_max_length" not in tokenizer_config:
42
+ max_context = tokenizer_config["max_length"]
43
+ elif "max_length" not in tokenizer_config:
44
+ max_context = tokenizer_config["model_max_length"]
45
+ else:
46
+ max_context = min(tokenizer_config["model_max_length"], tokenizer_config["max_length"])
39
47
 
40
48
  tokens_map = load_special_tokens(model_dir)
41
49
 
42
50
  tokenizer = Tokenizer.from_file(str(tokenizer_path))
43
- tokenizer.enable_truncation(
44
- max_length=min(tokenizer_config["model_max_length"], max_length)
45
- )
51
+ tokenizer.enable_truncation(max_length=max_context)
46
52
  tokenizer.enable_padding(
47
53
  pad_id=config.get("pad_token_id", 0), pad_token=tokenizer_config["pad_token"]
48
54
  )
@@ -1,5 +1,6 @@
1
1
  import os
2
2
  import sys
3
+ from PIL import Image
3
4
  from typing import Any, Dict, Iterable, Tuple, Union
4
5
 
5
6
  if sys.version_info >= (3, 10):
@@ -9,6 +10,7 @@ else:
9
10
 
10
11
 
11
12
  PathInput: TypeAlias = Union[str, os.PathLike]
12
- ImageInput: TypeAlias = Union[PathInput, Iterable[PathInput]]
13
+ PilInput: TypeAlias = Union[Image.Image, Iterable[Image.Image]]
14
+ ImageInput: TypeAlias = Union[PathInput, Iterable[PathInput], PilInput]
13
15
 
14
16
  OnnxProvider: TypeAlias = Union[str, Tuple[str, Dict[Any, Any]]]
@@ -12,7 +12,7 @@ supported_onnx_models = [
12
12
  {
13
13
  "model": "Qdrant/clip-ViT-B-32-vision",
14
14
  "dim": 512,
15
- "description": "CLIP vision encoder based on ViT-B/32",
15
+ "description": "Image embeddings, Multimodal (text&image), 2021 year",
16
16
  "size_in_GB": 0.34,
17
17
  "sources": {
18
18
  "hf": "Qdrant/clip-ViT-B-32-vision",
@@ -22,7 +22,7 @@ supported_onnx_models = [
22
22
  {
23
23
  "model": "Qdrant/resnet50-onnx",
24
24
  "dim": 2048,
25
- "description": "ResNet-50 from `Deep Residual Learning for Image Recognition <https://arxiv.org/abs/1512.03385>`__.",
25
+ "description": "Image embeddings, Unimodal (image), 2016 year",
26
26
  "size_in_GB": 0.1,
27
27
  "sources": {
28
28
  "hf": "Qdrant/resnet50-onnx",
@@ -32,7 +32,7 @@ supported_onnx_models = [
32
32
  {
33
33
  "model": "Qdrant/Unicom-ViT-B-16",
34
34
  "dim": 768,
35
- "description": "Unicom Unicom-ViT-B-16 from open-metric-learning",
35
+ "description": "Image embeddings (more detailed than Unicom-ViT-B-32), Multimodal (text&image), 2023 year",
36
36
  "size_in_GB": 0.82,
37
37
  "sources": {
38
38
  "hf": "Qdrant/Unicom-ViT-B-16",
@@ -42,7 +42,7 @@ supported_onnx_models = [
42
42
  {
43
43
  "model": "Qdrant/Unicom-ViT-B-32",
44
44
  "dim": 512,
45
- "description": "Unicom Unicom-ViT-B-32 from open-metric-learning",
45
+ "description": "Image embeddings, Multimodal (text&image), 2023 year",
46
46
  "size_in_GB": 0.48,
47
47
  "sources": {
48
48
  "hf": "Qdrant/Unicom-ViT-B-32",
@@ -51,6 +51,7 @@ supported_onnx_models = [
51
51
  },
52
52
  ]
53
53
 
54
+
54
55
  class OnnxImageEmbedding(ImageEmbeddingBase, OnnxImageModel[np.ndarray]):
55
56
  def __init__(
56
57
  self,
@@ -141,16 +142,10 @@ class OnnxImageEmbedding(ImageEmbeddingBase, OnnxImageModel[np.ndarray]):
141
142
 
142
143
  return onnx_input
143
144
 
144
- def _post_process_onnx_output(
145
- self, output: OnnxOutputContext
146
- ) -> Iterable[np.ndarray]:
145
+ def _post_process_onnx_output(self, output: OnnxOutputContext) -> Iterable[np.ndarray]:
147
146
  return normalize(output.model_output).astype(np.float32)
148
147
 
149
148
 
150
149
  class OnnxImageEmbeddingWorker(ImageEmbeddingWorker):
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
- )
150
+ def init_embedding(self, model_name: str, cache_dir: str, **kwargs) -> OnnxImageEmbedding:
151
+ return OnnxImageEmbedding(model_name=model_name, cache_dir=cache_dir, threads=1, **kwargs)
@@ -7,7 +7,7 @@ from typing import Any, Dict, Iterable, List, Optional, Sequence, Tuple, Type
7
7
  import numpy as np
8
8
  from PIL import Image
9
9
 
10
- from fastembed.common import ImageInput, OnnxProvider, PathInput
10
+ from fastembed.common import ImageInput, OnnxProvider
11
11
  from fastembed.common.onnx_model import EmbeddingWorker, OnnxModel, OnnxOutputContext, T
12
12
  from fastembed.common.preprocessor_utils import load_preprocessor
13
13
  from fastembed.common.utils import iter_batch
@@ -54,9 +54,12 @@ class OnnxImageModel(OnnxModel[T]):
54
54
  def _build_onnx_input(self, encoded: np.ndarray) -> Dict[str, np.ndarray]:
55
55
  return {node.name: encoded for node in self.model.get_inputs()}
56
56
 
57
- def onnx_embed(self, images: List[PathInput], **kwargs) -> OnnxOutputContext:
57
+ def onnx_embed(self, images: List[ImageInput], **kwargs) -> OnnxOutputContext:
58
58
  with contextlib.ExitStack():
59
- image_files = [Image.open(image) for image in images]
59
+ image_files = [
60
+ Image.open(image) if not isinstance(image, Image.Image) else image
61
+ for image in images
62
+ ]
60
63
  encoded = self.processor(image_files)
61
64
  onnx_input = self._build_onnx_input(encoded)
62
65
  onnx_input = self._preprocess_onnx_input(onnx_input)
@@ -75,7 +78,11 @@ class OnnxImageModel(OnnxModel[T]):
75
78
  ) -> Iterable[T]:
76
79
  is_small = False
77
80
 
78
- if isinstance(images, str) or isinstance(images, Path):
81
+ if (
82
+ isinstance(images, str)
83
+ or isinstance(images, Path)
84
+ or (isinstance(images, Image.Image))
85
+ ):
79
86
  images = [images]
80
87
  is_small = True
81
88
 
@@ -90,9 +97,7 @@ class OnnxImageModel(OnnxModel[T]):
90
97
  for batch in iter_batch(images, batch_size):
91
98
  yield from self._post_process_onnx_output(self.onnx_embed(batch))
92
99
  else:
93
- start_method = (
94
- "forkserver" if "forkserver" in get_all_start_methods() else "spawn"
95
- )
100
+ start_method = "forkserver" if "forkserver" in get_all_start_methods() else "spawn"
96
101
  params = {"model_name": model_name, "cache_dir": cache_dir, **kwargs}
97
102
  pool = ParallelWorkerPool(
98
103
  parallel, self._get_worker_class(), start_method=start_method
@@ -22,7 +22,17 @@ supported_colbert_models = [
22
22
  "hf": "colbert-ir/colbertv2.0",
23
23
  },
24
24
  "model_file": "model.onnx",
25
- }
25
+ },
26
+ {
27
+ "model": "answerdotai/answerai-colbert-small-v1",
28
+ "dim": 96,
29
+ "description": "Text embeddings, Unimodal (text), Multilingual (~100 languages), 512 input tokens truncation, 2024 year",
30
+ "size_in_GB": 0.13,
31
+ "sources": {
32
+ "hf": "answerdotai/answerai-colbert-small-v1",
33
+ },
34
+ "model_file": "vespa_colbert.onnx",
35
+ },
26
36
  ]
27
37
 
28
38
 
@@ -17,6 +17,38 @@ from fastembed.sparse.sparse_embedding_base import (
17
17
  )
18
18
  from fastembed.sparse.utils.tokenizer import WordTokenizer
19
19
 
20
+ supported_languages = [
21
+ "arabic",
22
+ "azerbaijani",
23
+ "basque",
24
+ "bengali",
25
+ "catalan",
26
+ "chinese",
27
+ "danish",
28
+ "dutch",
29
+ "english",
30
+ "finnish",
31
+ "french",
32
+ "german",
33
+ "greek",
34
+ "hebrew",
35
+ "hinglish",
36
+ "hungarian",
37
+ "indonesian",
38
+ "italian",
39
+ "kazakh",
40
+ "nepali",
41
+ "norwegian",
42
+ "portuguese",
43
+ "romanian",
44
+ "russian",
45
+ "slovene",
46
+ "spanish",
47
+ "swedish",
48
+ "tajik",
49
+ "turkish",
50
+ ]
51
+
20
52
  supported_bm25_models = [
21
53
  {
22
54
  "model": "Qdrant/bm25",
@@ -26,15 +58,11 @@ supported_bm25_models = [
26
58
  "hf": "Qdrant/bm25",
27
59
  },
28
60
  "model_file": "mock.file", # bm25 does not require a model, so we just use a mock
29
- "additional_files": ["stopwords.txt"],
61
+ "additional_files": [f"{lang}.txt" for lang in supported_languages],
30
62
  "requires_idf": True,
31
63
  },
32
64
  ]
33
65
 
34
- MODEL_TO_LANGUAGE = {
35
- "Qdrant/bm25": "english",
36
- }
37
-
38
66
 
39
67
  class Bm25(SparseTextEmbeddingBase):
40
68
  """Implements traditional BM25 in a form of sparse embeddings.
@@ -71,10 +99,16 @@ class Bm25(SparseTextEmbeddingBase):
71
99
  k: float = 1.2,
72
100
  b: float = 0.75,
73
101
  avg_len: float = 256.0,
102
+ language: str = "english",
74
103
  **kwargs,
75
104
  ):
76
105
  super().__init__(model_name, cache_dir, **kwargs)
77
106
 
107
+ if language not in supported_languages:
108
+ raise ValueError(f"{language} language is not supported")
109
+ else:
110
+ self.language = language
111
+
78
112
  self.k = k
79
113
  self.b = b
80
114
  self.avg_len = avg_len
@@ -87,8 +121,8 @@ class Bm25(SparseTextEmbeddingBase):
87
121
  )
88
122
 
89
123
  self.punctuation = set(string.punctuation)
90
- self.stopwords = set(self._load_stopwords(model_dir))
91
- self.stemmer = get_stemmer(MODEL_TO_LANGUAGE[model_name])
124
+ self.stopwords = set(self._load_stopwords(model_dir, self.language))
125
+ self.stemmer = get_stemmer(language)
92
126
  self.tokenizer = WordTokenizer
93
127
 
94
128
  @classmethod
@@ -101,8 +135,8 @@ class Bm25(SparseTextEmbeddingBase):
101
135
  return supported_bm25_models
102
136
 
103
137
  @classmethod
104
- def _load_stopwords(cls, model_dir: Path) -> List[str]:
105
- stopwords_path = model_dir / "stopwords.txt"
138
+ def _load_stopwords(cls, model_dir: Path, language: str) -> List[str]:
139
+ stopwords_path = model_dir / f"{language}.txt"
106
140
  if not stopwords_path.exists():
107
141
  return []
108
142
 
@@ -8,6 +8,7 @@ from fastembed.sparse.sparse_embedding_base import (
8
8
  SparseTextEmbeddingBase,
9
9
  )
10
10
  from fastembed.sparse.splade_pp import SpladePP
11
+ import warnings
11
12
 
12
13
 
13
14
  class SparseTextEmbedding(SparseTextEmbeddingBase):
@@ -50,13 +51,17 @@ class SparseTextEmbedding(SparseTextEmbeddingBase):
50
51
  **kwargs,
51
52
  ):
52
53
  super().__init__(model_name, cache_dir, threads, **kwargs)
54
+ if model_name == "prithvida/Splade_PP_en_v1":
55
+ warnings.warn(
56
+ "The right spelling is prithivida/Splade_PP_en_v1. "
57
+ "Support of this name will be removed soon, please fix the model_name",
58
+ DeprecationWarning,
59
+ )
60
+ model_name = "prithivida/Splade_PP_en_v1"
53
61
 
54
62
  for EMBEDDING_MODEL_TYPE in self.EMBEDDINGS_REGISTRY:
55
63
  supported_models = EMBEDDING_MODEL_TYPE.list_supported_models()
56
- if any(
57
- model_name.lower() == model["model"].lower()
58
- for model in supported_models
59
- ):
64
+ if any(model_name.lower() == model["model"].lower() for model in supported_models):
60
65
  self.model = EMBEDDING_MODEL_TYPE(
61
66
  model_name,
62
67
  cache_dir,
@@ -95,9 +100,7 @@ class SparseTextEmbedding(SparseTextEmbeddingBase):
95
100
  """
96
101
  yield from self.model.embed(documents, batch_size, parallel, **kwargs)
97
102
 
98
- def query_embed(
99
- self, query: Union[str, Iterable[str]], **kwargs
100
- ) -> Iterable[SparseEmbedding]:
103
+ def query_embed(self, query: Union[str, Iterable[str]], **kwargs) -> Iterable[SparseEmbedding]:
101
104
  """
102
105
  Embeds queries
103
106
 
@@ -1,7 +1,6 @@
1
1
  from typing import Any, Dict, Iterable, List, Optional, Sequence, Type, Union
2
2
 
3
3
  import numpy as np
4
-
5
4
  from fastembed.common import OnnxProvider
6
5
  from fastembed.common.onnx_model import OnnxOutputContext
7
6
  from fastembed.common.utils import define_cache_dir
@@ -12,16 +11,6 @@ from fastembed.sparse.sparse_embedding_base import (
12
11
  from fastembed.text.onnx_text_model import OnnxTextModel, TextEmbeddingWorker
13
12
 
14
13
  supported_splade_models = [
15
- {
16
- "model": "prithvida/Splade_PP_en_v1",
17
- "vocab_size": 30522,
18
- "description": "Misspelled version of the model. Retained for backward compatibility. Independent Implementation of SPLADE++ Model for English",
19
- "size_in_GB": 0.532,
20
- "sources": {
21
- "hf": "Qdrant/SPLADE_PP_en_v1",
22
- },
23
- "model_file": "model.onnx",
24
- },
25
14
  {
26
15
  "model": "prithivida/Splade_PP_en_v1",
27
16
  "vocab_size": 30522,
@@ -78,7 +67,6 @@ class SpladePP(SparseTextEmbeddingBase, OnnxTextModel[SparseEmbedding]):
78
67
  Raises:
79
68
  ValueError: If the model_name is not in the format <org>/<model> e.g. BAAI/bge-base-en.
80
69
  """
81
-
82
70
  super().__init__(model_name, cache_dir, threads, **kwargs)
83
71
 
84
72
  model_description = self._get_model_description(model_name)
@@ -10,7 +10,7 @@ supported_clip_models = [
10
10
  {
11
11
  "model": "Qdrant/clip-ViT-B-32-text",
12
12
  "dim": 512,
13
- "description": "CLIP text encoder",
13
+ "description": "Text embeddings, Multimodal (text&image), English, 77 input tokens truncation, Prefixes for queries/documents: not necessary, 2021 year",
14
14
  "size_in_GB": 0.25,
15
15
  "sources": {
16
16
  "hf": "Qdrant/clip-ViT-B-32-text",
@@ -9,7 +9,7 @@ supported_multilingual_e5_models = [
9
9
  {
10
10
  "model": "intfloat/multilingual-e5-large",
11
11
  "dim": 1024,
12
- "description": "Multilingual model, e5-large. Recommend using this model for non-English languages",
12
+ "description": "Text embeddings, Unimodal (text), Multilingual (~100 languages), 512 input tokens truncation, Prefixes for queries/documents: necessary, 2024 year",
13
13
  "size_in_GB": 2.24,
14
14
  "sources": {
15
15
  "url": "https://storage.googleapis.com/qdrant-fastembed/fast-multilingual-e5-large.tar.gz",
@@ -21,7 +21,7 @@ supported_multilingual_e5_models = [
21
21
  {
22
22
  "model": "sentence-transformers/paraphrase-multilingual-mpnet-base-v2",
23
23
  "dim": 768,
24
- "description": "Sentence-transformers model for tasks like clustering or semantic search",
24
+ "description": "Text embeddings, Unimodal (text), Multilingual (~50 languages), 384 input tokens truncation, Prefixes for queries/documents: not necessary, 2021 year",
25
25
  "size_in_GB": 1.00,
26
26
  "sources": {
27
27
  "hf": "xenova/paraphrase-multilingual-mpnet-base-v2",
@@ -12,7 +12,7 @@ supported_onnx_models = [
12
12
  {
13
13
  "model": "BAAI/bge-base-en",
14
14
  "dim": 768,
15
- "description": "Base English model",
15
+ "description": "Text embeddings, Unimodal (text), English, 512 input tokens truncation, Prefixes for queries/documents: necessary, 2023 year",
16
16
  "size_in_GB": 0.42,
17
17
  "sources": {
18
18
  "url": "https://storage.googleapis.com/qdrant-fastembed/fast-bge-base-en.tar.gz",
@@ -22,7 +22,7 @@ supported_onnx_models = [
22
22
  {
23
23
  "model": "BAAI/bge-base-en-v1.5",
24
24
  "dim": 768,
25
- "description": "Base English model, v1.5",
25
+ "description": "Text embeddings, Unimodal (text), English, 512 input tokens truncation, Prefixes for queries/documents: not so necessary, 2023 year",
26
26
  "size_in_GB": 0.21,
27
27
  "sources": {
28
28
  "url": "https://storage.googleapis.com/qdrant-fastembed/fast-bge-base-en-v1.5.tar.gz",
@@ -33,7 +33,7 @@ supported_onnx_models = [
33
33
  {
34
34
  "model": "BAAI/bge-large-en-v1.5",
35
35
  "dim": 1024,
36
- "description": "Large English model, v1.5",
36
+ "description": "Text embeddings, Unimodal (text), English, 512 input tokens truncation, Prefixes for queries/documents: not so necessary, 2023 year",
37
37
  "size_in_GB": 1.20,
38
38
  "sources": {
39
39
  "hf": "qdrant/bge-large-en-v1.5-onnx",
@@ -43,7 +43,7 @@ supported_onnx_models = [
43
43
  {
44
44
  "model": "BAAI/bge-small-en",
45
45
  "dim": 384,
46
- "description": "Fast English model",
46
+ "description": "Text embeddings, Unimodal (text), English, 512 input tokens truncation, Prefixes for queries/documents: necessary, 2023 year",
47
47
  "size_in_GB": 0.13,
48
48
  "sources": {
49
49
  "url": "https://storage.googleapis.com/qdrant-fastembed/BAAI-bge-small-en.tar.gz",
@@ -53,7 +53,7 @@ supported_onnx_models = [
53
53
  {
54
54
  "model": "BAAI/bge-small-en-v1.5",
55
55
  "dim": 384,
56
- "description": "Fast and Default English model",
56
+ "description": "Text embeddings, Unimodal (text), English, 512 input tokens truncation, Prefixes for queries/documents: not so necessary, 2023 year",
57
57
  "size_in_GB": 0.067,
58
58
  "sources": {
59
59
  "hf": "qdrant/bge-small-en-v1.5-onnx-q",
@@ -63,7 +63,7 @@ supported_onnx_models = [
63
63
  {
64
64
  "model": "BAAI/bge-small-zh-v1.5",
65
65
  "dim": 512,
66
- "description": "Fast and recommended Chinese model",
66
+ "description": "Text embeddings, Unimodal (text), Chinese, 512 input tokens truncation, Prefixes for queries/documents: not so necessary, 2023 year",
67
67
  "size_in_GB": 0.09,
68
68
  "sources": {
69
69
  "url": "https://storage.googleapis.com/qdrant-fastembed/fast-bge-small-zh-v1.5.tar.gz",
@@ -73,7 +73,7 @@ supported_onnx_models = [
73
73
  {
74
74
  "model": "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2",
75
75
  "dim": 384,
76
- "description": "Sentence Transformer model, paraphrase-multilingual-MiniLM-L12-v2",
76
+ "description": "Text embeddings, Unimodal (text), Multilingual (~50 languages), 512 input tokens truncation, Prefixes for queries/documents: not necessary, 2019 year",
77
77
  "size_in_GB": 0.22,
78
78
  "sources": {
79
79
  "hf": "qdrant/paraphrase-multilingual-MiniLM-L12-v2-onnx-Q",
@@ -83,7 +83,7 @@ supported_onnx_models = [
83
83
  {
84
84
  "model": "thenlper/gte-large",
85
85
  "dim": 1024,
86
- "description": "Large general text embeddings model",
86
+ "description": "Text embeddings, Unimodal (text), English, 512 input tokens truncation, Prefixes for queries/documents: not necessary, 2023 year",
87
87
  "size_in_GB": 1.20,
88
88
  "sources": {
89
89
  "hf": "qdrant/gte-large-onnx",
@@ -93,7 +93,7 @@ supported_onnx_models = [
93
93
  {
94
94
  "model": "mixedbread-ai/mxbai-embed-large-v1",
95
95
  "dim": 1024,
96
- "description": "MixedBread Base sentence embedding model, does well on MTEB",
96
+ "description": "Text embeddings, Unimodal (text), English, 512 input tokens truncation, Prefixes for queries/documents: necessary, 2024 year",
97
97
  "size_in_GB": 0.64,
98
98
  "sources": {
99
99
  "hf": "mixedbread-ai/mxbai-embed-large-v1",
@@ -103,7 +103,7 @@ supported_onnx_models = [
103
103
  {
104
104
  "model": "snowflake/snowflake-arctic-embed-xs",
105
105
  "dim": 384,
106
- "description": "Based on all-MiniLM-L6-v2 model with only 22m parameters, ideal for latency/TCO budgets.",
106
+ "description": "Text embeddings, Unimodal (text), English, 512 input tokens truncation, Prefixes for queries/documents: necessary, 2024 year",
107
107
  "size_in_GB": 0.09,
108
108
  "sources": {
109
109
  "hf": "snowflake/snowflake-arctic-embed-xs",
@@ -113,7 +113,7 @@ supported_onnx_models = [
113
113
  {
114
114
  "model": "snowflake/snowflake-arctic-embed-s",
115
115
  "dim": 384,
116
- "description": "Based on infloat/e5-small-unsupervised, does not trade off retrieval accuracy for its small size.",
116
+ "description": "Text embeddings, Unimodal (text), English, 512 input tokens truncation, Prefixes for queries/documents: necessary, 2024 year",
117
117
  "size_in_GB": 0.13,
118
118
  "sources": {
119
119
  "hf": "snowflake/snowflake-arctic-embed-s",
@@ -123,7 +123,7 @@ supported_onnx_models = [
123
123
  {
124
124
  "model": "snowflake/snowflake-arctic-embed-m",
125
125
  "dim": 768,
126
- "description": "Based on intfloat/e5-base-unsupervised model, provides the best retrieval without slowing down inference.",
126
+ "description": "Text embeddings, Unimodal (text), English, 512 input tokens truncation, Prefixes for queries/documents: necessary, 2024 year",
127
127
  "size_in_GB": 0.43,
128
128
  "sources": {
129
129
  "hf": "Snowflake/snowflake-arctic-embed-m",
@@ -133,7 +133,7 @@ supported_onnx_models = [
133
133
  {
134
134
  "model": "snowflake/snowflake-arctic-embed-m-long",
135
135
  "dim": 768,
136
- "description": "Based on nomic-ai/nomic-embed-text-v1-unsupervised model, 8192 context-length model",
136
+ "description": "Text embeddings, Unimodal (text), English, 2048 input tokens truncation, Prefixes for queries/documents: necessary, 2024 year",
137
137
  "size_in_GB": 0.54,
138
138
  "sources": {
139
139
  "hf": "snowflake/snowflake-arctic-embed-m-long",
@@ -143,7 +143,7 @@ supported_onnx_models = [
143
143
  {
144
144
  "model": "snowflake/snowflake-arctic-embed-l",
145
145
  "dim": 1024,
146
- "description": "Based on intfloat/e5-large-unsupervised, large model for most accurate retrieval.",
146
+ "description": "Text embeddings, Unimodal (text), English, 512 input tokens truncation, Prefixes for queries/documents: necessary, 2024 year",
147
147
  "size_in_GB": 1.02,
148
148
  "sources": {
149
149
  "hf": "snowflake/snowflake-arctic-embed-l",
@@ -244,9 +244,7 @@ class OnnxTextEmbedding(TextEmbeddingBase, OnnxTextModel[np.ndarray]):
244
244
  """
245
245
  return onnx_input
246
246
 
247
- def _post_process_onnx_output(
248
- self, output: OnnxOutputContext
249
- ) -> Iterable[np.ndarray]:
247
+ def _post_process_onnx_output(self, output: OnnxOutputContext) -> Iterable[np.ndarray]:
250
248
  embeddings = output.model_output
251
249
  return normalize(embeddings[:, 0]).astype(np.float32)
252
250
 
@@ -258,6 +256,4 @@ class OnnxTextEmbeddingWorker(TextEmbeddingWorker):
258
256
  cache_dir: str,
259
257
  **kwargs,
260
258
  ) -> OnnxTextEmbedding:
261
- return OnnxTextEmbedding(
262
- model_name=model_name, cache_dir=cache_dir, threads=1, **kwargs
263
- )
259
+ return OnnxTextEmbedding(model_name=model_name, cache_dir=cache_dir, threads=1, **kwargs)
@@ -11,7 +11,7 @@ supported_pooled_models = [
11
11
  {
12
12
  "model": "nomic-ai/nomic-embed-text-v1.5",
13
13
  "dim": 768,
14
- "description": "8192 context length english model",
14
+ "description": "Text embeddings, Multimodal (text, image), English, 8192 input tokens truncation, Prefixes for queries/documents: necessary, 2024 year",
15
15
  "size_in_GB": 0.52,
16
16
  "sources": {
17
17
  "hf": "nomic-ai/nomic-embed-text-v1.5",
@@ -21,7 +21,7 @@ supported_pooled_models = [
21
21
  {
22
22
  "model": "nomic-ai/nomic-embed-text-v1.5-Q",
23
23
  "dim": 768,
24
- "description": "Quantized 8192 context length english model",
24
+ "description": "Text embeddings, Multimodal (text, image), English, 8192 input tokens truncation, Prefixes for queries/documents: necessary, 2024 year",
25
25
  "size_in_GB": 0.13,
26
26
  "sources": {
27
27
  "hf": "nomic-ai/nomic-embed-text-v1.5",
@@ -31,7 +31,7 @@ supported_pooled_models = [
31
31
  {
32
32
  "model": "nomic-ai/nomic-embed-text-v1",
33
33
  "dim": 768,
34
- "description": "8192 context length english model",
34
+ "description": "Text embeddings, Multimodal (text, image), English, 8192 input tokens truncation, Prefixes for queries/documents: necessary, 2024 year",
35
35
  "size_in_GB": 0.52,
36
36
  "sources": {
37
37
  "hf": "nomic-ai/nomic-embed-text-v1",
@@ -12,7 +12,7 @@ supported_pooled_normalized_models = [
12
12
  {
13
13
  "model": "sentence-transformers/all-MiniLM-L6-v2",
14
14
  "dim": 384,
15
- "description": "Sentence Transformer model, MiniLM-L6-v2",
15
+ "description": "Text embeddings, Unimodal (text), English, 256 input tokens truncation, Prefixes for queries/documents: not necessary, 2021 year",
16
16
  "size_in_GB": 0.09,
17
17
  "sources": {
18
18
  "url": "https://storage.googleapis.com/qdrant-fastembed/sentence-transformers-all-MiniLM-L6-v2.tar.gz",
@@ -23,7 +23,7 @@ supported_pooled_normalized_models = [
23
23
  {
24
24
  "model": "jinaai/jina-embeddings-v2-base-en",
25
25
  "dim": 768,
26
- "description": "English embedding model supporting 8192 sequence length",
26
+ "description": "Text embeddings, Unimodal (text), English, 8192 input tokens truncation, Prefixes for queries/documents: not necessary, 2023 year",
27
27
  "size_in_GB": 0.52,
28
28
  "sources": {"hf": "xenova/jina-embeddings-v2-base-en"},
29
29
  "model_file": "onnx/model.onnx",
@@ -31,7 +31,7 @@ supported_pooled_normalized_models = [
31
31
  {
32
32
  "model": "jinaai/jina-embeddings-v2-small-en",
33
33
  "dim": 512,
34
- "description": "English embedding model supporting 8192 sequence length",
34
+ "description": "Text embeddings, Unimodal (text), English, 8192 input tokens truncation, Prefixes for queries/documents: not necessary, 2023 year",
35
35
  "size_in_GB": 0.12,
36
36
  "sources": {"hf": "xenova/jina-embeddings-v2-small-en"},
37
37
  "model_file": "onnx/model.onnx",
@@ -39,11 +39,19 @@ supported_pooled_normalized_models = [
39
39
  {
40
40
  "model": "jinaai/jina-embeddings-v2-base-de",
41
41
  "dim": 768,
42
- "description": "German embedding model supporting 8192 sequence length",
42
+ "description": "Text embeddings, Unimodal (text), Multilingual (German, English), 8192 input tokens truncation, Prefixes for queries/documents: not necessary, 2024 year",
43
43
  "size_in_GB": 0.32,
44
44
  "sources": {"hf": "jinaai/jina-embeddings-v2-base-de"},
45
45
  "model_file": "onnx/model_fp16.onnx",
46
46
  },
47
+ {
48
+ "model": "jinaai/jina-embeddings-v2-base-code",
49
+ "dim": 768,
50
+ "description": "Text embeddings, Unimodal (text), Multilingual (English, 30 programming languages), 8192 input tokens truncation, Prefixes for queries/documents: not necessary, 2024 year",
51
+ "size_in_GB": 0.64,
52
+ "sources": {"hf": "jinaai/jina-embeddings-v2-base-code"},
53
+ "model_file": "onnx/model.onnx",
54
+ },
47
55
  ]
48
56
 
49
57
 
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "fastembed-gpu"
3
- version = "0.3.4"
3
+ version = "0.3.5"
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,3 +0,0 @@
1
- from fastembed.common.types import ImageInput, OnnxProvider, PathInput
2
-
3
- __all__ = ["OnnxProvider", "ImageInput", "PathInput"]
File without changes