fastembed 0.2.6__tar.gz → 0.2.7__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.
- {fastembed-0.2.6 → fastembed-0.2.7}/PKG-INFO +34 -10
- {fastembed-0.2.6 → fastembed-0.2.7}/README.md +33 -8
- {fastembed-0.2.6 → fastembed-0.2.7}/fastembed/__init__.py +6 -1
- fastembed-0.2.7/fastembed/common/__init__.py +3 -0
- {fastembed-0.2.6 → fastembed-0.2.7}/fastembed/common/model_management.py +30 -21
- {fastembed-0.2.6 → fastembed-0.2.7}/fastembed/common/onnx_model.py +35 -6
- {fastembed-0.2.6 → fastembed-0.2.7}/fastembed/sparse/sparse_embedding_base.py +1 -0
- {fastembed-0.2.6 → fastembed-0.2.7}/fastembed/sparse/sparse_text_embedding.py +6 -2
- {fastembed-0.2.6 → fastembed-0.2.7}/fastembed/sparse/splade_pp.py +17 -9
- {fastembed-0.2.6 → fastembed-0.2.7}/fastembed/text/e5_onnx_embedding.py +3 -0
- {fastembed-0.2.6 → fastembed-0.2.7}/fastembed/text/jina_onnx_embedding.py +2 -0
- {fastembed-0.2.6 → fastembed-0.2.7}/fastembed/text/onnx_embedding.py +87 -34
- {fastembed-0.2.6 → fastembed-0.2.7}/fastembed/text/text_embedding.py +6 -2
- {fastembed-0.2.6 → fastembed-0.2.7}/fastembed/text/text_embedding_base.py +1 -0
- {fastembed-0.2.6 → fastembed-0.2.7}/pyproject.toml +2 -2
- fastembed-0.2.6/fastembed/image/__init__.py +0 -0
- {fastembed-0.2.6 → fastembed-0.2.7}/LICENSE +0 -0
- {fastembed-0.2.6 → fastembed-0.2.7}/fastembed/common/models.py +0 -0
- {fastembed-0.2.6 → fastembed-0.2.7}/fastembed/common/utils.py +0 -0
- {fastembed-0.2.6 → fastembed-0.2.7}/fastembed/embedding.py +0 -0
- {fastembed-0.2.6/fastembed/common → fastembed-0.2.7/fastembed/image}/__init__.py +0 -0
- {fastembed-0.2.6 → fastembed-0.2.7}/fastembed/parallel_processor.py +0 -0
- {fastembed-0.2.6 → fastembed-0.2.7}/fastembed/sparse/__init__.py +0 -0
- {fastembed-0.2.6 → fastembed-0.2.7}/fastembed/text/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: fastembed
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.7
|
|
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
|
|
@@ -22,7 +22,7 @@ Requires-Dist: numpy (>=1.26) ; python_version >= "3.12"
|
|
|
22
22
|
Requires-Dist: onnx (>=1.15.0,<2.0.0)
|
|
23
23
|
Requires-Dist: onnxruntime (>=1.17.0,<2.0.0)
|
|
24
24
|
Requires-Dist: requests (>=2.31,<3.0)
|
|
25
|
-
Requires-Dist: tokenizers (>=0.15
|
|
25
|
+
Requires-Dist: tokenizers (>=0.15,<0.16)
|
|
26
26
|
Requires-Dist: tqdm (>=4.66,<5.0)
|
|
27
27
|
Project-URL: Repository, https://github.com/qdrant/fastembed
|
|
28
28
|
Description-Content-Type: text/markdown
|
|
@@ -31,7 +31,7 @@ Description-Content-Type: text/markdown
|
|
|
31
31
|
|
|
32
32
|
FastEmbed is a lightweight, fast, Python library built for embedding generation. We [support popular text models](https://qdrant.github.io/fastembed/examples/Supported_Models/). Please [open a GitHub issue](https://github.com/qdrant/fastembed/issues/new) if you want us to add a new model.
|
|
33
33
|
|
|
34
|
-
The default text embedding (`TextEmbedding`) model is Flag Embedding, presented in the [MTEB](https://huggingface.co/spaces/mteb/leaderboard) leaderboard. It supports "query" and "passage" prefixes for the input text. Here is an example for [Retrieval Embedding Generation](https://qdrant.github.io/fastembed/
|
|
34
|
+
The default text embedding (`TextEmbedding`) model is Flag Embedding, presented in the [MTEB](https://huggingface.co/spaces/mteb/leaderboard) leaderboard. It supports "query" and "passage" prefixes for the input text. Here is an example for [Retrieval Embedding Generation](https://qdrant.github.io/fastembed/qdrant/Retrieval_with_FastEmbed/) and how to use [FastEmbed with Qdrant](https://qdrant.github.io/fastembed/qdrant/Usage_With_Qdrant/).
|
|
35
35
|
|
|
36
36
|
## 📈 Why FastEmbed?
|
|
37
37
|
|
|
@@ -43,12 +43,18 @@ The default text embedding (`TextEmbedding`) model is Flag Embedding, presented
|
|
|
43
43
|
|
|
44
44
|
## 🚀 Installation
|
|
45
45
|
|
|
46
|
-
To install the FastEmbed library, pip works:
|
|
46
|
+
To install the FastEmbed library, pip works best. You can install it with or without GPU support:
|
|
47
47
|
|
|
48
48
|
```bash
|
|
49
49
|
pip install fastembed
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
+
### ⚡️ With GPU
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
pip install fastembed-gpu
|
|
56
|
+
```
|
|
57
|
+
|
|
52
58
|
## 📖 Quickstart
|
|
53
59
|
|
|
54
60
|
```python
|
|
@@ -71,6 +77,23 @@ embeddings_list = list(embedding_model.embed(documents))
|
|
|
71
77
|
len(embeddings_list[0]) # Vector of 384 dimensions
|
|
72
78
|
```
|
|
73
79
|
|
|
80
|
+
### ⚡️ FastEmbed on a GPU
|
|
81
|
+
|
|
82
|
+
FastEmbed supports running on GPU devices. It requires installation of the `fastembed-gpu` package.
|
|
83
|
+
Make sure not to have the `fastembed` package installed, as it might interfere with the `fastembed-gpu` package.
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
pip install fastembed-gpu
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
from fastembed import TextEmbedding
|
|
91
|
+
|
|
92
|
+
embedding_model = TextEmbedding(model_name="BAAI/bge-small-en-v1.5", providers=["CUDAExecutionProvider"])
|
|
93
|
+
print("The model BAAI/bge-small-en-v1.5 is ready to use on a GPU.")
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
|
|
74
97
|
## Usage with Qdrant
|
|
75
98
|
|
|
76
99
|
Installation with Qdrant Client in Python:
|
|
@@ -79,7 +102,13 @@ Installation with Qdrant Client in Python:
|
|
|
79
102
|
pip install qdrant-client[fastembed]
|
|
80
103
|
```
|
|
81
104
|
|
|
82
|
-
|
|
105
|
+
or
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
pip install qdrant-client[fastembed-gpu]
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
You might have to use quotes ```pip install 'qdrant-client[fastembed]'``` on zsh.
|
|
83
112
|
|
|
84
113
|
```python
|
|
85
114
|
from qdrant_client import QdrantClient
|
|
@@ -115,8 +144,3 @@ search_result = client.query(
|
|
|
115
144
|
)
|
|
116
145
|
print(search_result)
|
|
117
146
|
```
|
|
118
|
-
|
|
119
|
-
#### Similar Work
|
|
120
|
-
|
|
121
|
-
Ilyas M. wrote about using [FlagEmbeddings with Optimum](https://twitter.com/IlysMoutawwakil/status/1705215192425288017) over CUDA.
|
|
122
|
-
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
FastEmbed is a lightweight, fast, Python library built for embedding generation. We [support popular text models](https://qdrant.github.io/fastembed/examples/Supported_Models/). Please [open a GitHub issue](https://github.com/qdrant/fastembed/issues/new) if you want us to add a new model.
|
|
4
4
|
|
|
5
|
-
The default text embedding (`TextEmbedding`) model is Flag Embedding, presented in the [MTEB](https://huggingface.co/spaces/mteb/leaderboard) leaderboard. It supports "query" and "passage" prefixes for the input text. Here is an example for [Retrieval Embedding Generation](https://qdrant.github.io/fastembed/
|
|
5
|
+
The default text embedding (`TextEmbedding`) model is Flag Embedding, presented in the [MTEB](https://huggingface.co/spaces/mteb/leaderboard) leaderboard. It supports "query" and "passage" prefixes for the input text. Here is an example for [Retrieval Embedding Generation](https://qdrant.github.io/fastembed/qdrant/Retrieval_with_FastEmbed/) and how to use [FastEmbed with Qdrant](https://qdrant.github.io/fastembed/qdrant/Usage_With_Qdrant/).
|
|
6
6
|
|
|
7
7
|
## 📈 Why FastEmbed?
|
|
8
8
|
|
|
@@ -14,12 +14,18 @@ The default text embedding (`TextEmbedding`) model is Flag Embedding, presented
|
|
|
14
14
|
|
|
15
15
|
## 🚀 Installation
|
|
16
16
|
|
|
17
|
-
To install the FastEmbed library, pip works:
|
|
17
|
+
To install the FastEmbed library, pip works best. You can install it with or without GPU support:
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
20
|
pip install fastembed
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
+
### ⚡️ With GPU
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
pip install fastembed-gpu
|
|
27
|
+
```
|
|
28
|
+
|
|
23
29
|
## 📖 Quickstart
|
|
24
30
|
|
|
25
31
|
```python
|
|
@@ -42,6 +48,23 @@ embeddings_list = list(embedding_model.embed(documents))
|
|
|
42
48
|
len(embeddings_list[0]) # Vector of 384 dimensions
|
|
43
49
|
```
|
|
44
50
|
|
|
51
|
+
### ⚡️ FastEmbed on a GPU
|
|
52
|
+
|
|
53
|
+
FastEmbed supports running on GPU devices. It requires installation of the `fastembed-gpu` package.
|
|
54
|
+
Make sure not to have the `fastembed` package installed, as it might interfere with the `fastembed-gpu` package.
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
pip install fastembed-gpu
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
```python
|
|
61
|
+
from fastembed import TextEmbedding
|
|
62
|
+
|
|
63
|
+
embedding_model = TextEmbedding(model_name="BAAI/bge-small-en-v1.5", providers=["CUDAExecutionProvider"])
|
|
64
|
+
print("The model BAAI/bge-small-en-v1.5 is ready to use on a GPU.")
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
|
|
45
68
|
## Usage with Qdrant
|
|
46
69
|
|
|
47
70
|
Installation with Qdrant Client in Python:
|
|
@@ -50,7 +73,13 @@ Installation with Qdrant Client in Python:
|
|
|
50
73
|
pip install qdrant-client[fastembed]
|
|
51
74
|
```
|
|
52
75
|
|
|
53
|
-
|
|
76
|
+
or
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
pip install qdrant-client[fastembed-gpu]
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
You might have to use quotes ```pip install 'qdrant-client[fastembed]'``` on zsh.
|
|
54
83
|
|
|
55
84
|
```python
|
|
56
85
|
from qdrant_client import QdrantClient
|
|
@@ -85,8 +114,4 @@ search_result = client.query(
|
|
|
85
114
|
query_text="This is a query document"
|
|
86
115
|
)
|
|
87
116
|
print(search_result)
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
#### Similar Work
|
|
91
|
-
|
|
92
|
-
Ilyas M. wrote about using [FlagEmbeddings with Optimum](https://twitter.com/IlysMoutawwakil/status/1705215192425288017) over CUDA.
|
|
117
|
+
```
|
|
@@ -3,5 +3,10 @@ import importlib.metadata
|
|
|
3
3
|
from fastembed.text import TextEmbedding
|
|
4
4
|
from fastembed.sparse import SparseTextEmbedding, SparseEmbedding
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
try:
|
|
7
|
+
version = importlib.metadata.version("fastembed")
|
|
8
|
+
except importlib.metadata.PackageNotFoundError as _:
|
|
9
|
+
version = importlib.metadata.version("fastembed-gpu")
|
|
10
|
+
|
|
11
|
+
__version__ = version
|
|
7
12
|
__all__ = ["TextEmbedding", "SparseTextEmbedding", "SparseEmbedding"]
|
|
@@ -11,23 +11,6 @@ from tqdm import tqdm
|
|
|
11
11
|
from loguru import logger
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
def locate_model_file(model_dir: Path, file_names: List[str]) -> Path:
|
|
15
|
-
"""
|
|
16
|
-
Find model path for both TransformerJS style `onnx` subdirectory structure and direct model weights structure used
|
|
17
|
-
by Optimum and Qdrant
|
|
18
|
-
"""
|
|
19
|
-
if not model_dir.is_dir():
|
|
20
|
-
raise ValueError(f"Provided model path '{model_dir}' is not a directory.")
|
|
21
|
-
|
|
22
|
-
for file_name in file_names:
|
|
23
|
-
file_paths = [path for path in model_dir.rglob(file_name) if path.is_file()]
|
|
24
|
-
|
|
25
|
-
if file_paths:
|
|
26
|
-
return file_paths[0]
|
|
27
|
-
|
|
28
|
-
raise ValueError(f"Could not find either of {', '.join(file_names)} in {model_dir}")
|
|
29
|
-
|
|
30
|
-
|
|
31
14
|
class ModelManagement:
|
|
32
15
|
@classmethod
|
|
33
16
|
def list_supported_models(cls) -> List[Dict[str, Any]]:
|
|
@@ -104,21 +87,36 @@ class ModelManagement:
|
|
|
104
87
|
|
|
105
88
|
@classmethod
|
|
106
89
|
def download_files_from_huggingface(
|
|
107
|
-
cls,
|
|
90
|
+
cls,
|
|
91
|
+
hf_source_repo: str,
|
|
92
|
+
cache_dir: Optional[str] = None,
|
|
93
|
+
extra_patterns: Optional[List[str]] = None,
|
|
94
|
+
**kwargs,
|
|
108
95
|
) -> str:
|
|
109
96
|
"""
|
|
110
97
|
Downloads a model from HuggingFace Hub.
|
|
111
98
|
Args:
|
|
112
99
|
hf_source_repo (str): Name of the model on HuggingFace Hub, e.g. "qdrant/all-MiniLM-L6-v2-onnx".
|
|
113
100
|
cache_dir (Optional[str]): The path to the cache directory.
|
|
101
|
+
extra_patterns (Optional[List[str]]): extra patterns to allow in the snapshot download, typically
|
|
102
|
+
includes the required model files.
|
|
114
103
|
Returns:
|
|
115
104
|
Path: The path to the model directory.
|
|
116
105
|
"""
|
|
106
|
+
allow_patterns = [
|
|
107
|
+
"config.json",
|
|
108
|
+
"tokenizer.json",
|
|
109
|
+
"tokenizer_config.json",
|
|
110
|
+
"special_tokens_map.json",
|
|
111
|
+
]
|
|
112
|
+
if extra_patterns is not None:
|
|
113
|
+
allow_patterns.extend(extra_patterns)
|
|
117
114
|
|
|
118
115
|
return snapshot_download(
|
|
119
116
|
repo_id=hf_source_repo,
|
|
120
|
-
|
|
117
|
+
allow_patterns=allow_patterns,
|
|
121
118
|
cache_dir=cache_dir,
|
|
119
|
+
local_files_only=kwargs.get("local_files_only", False),
|
|
122
120
|
)
|
|
123
121
|
|
|
124
122
|
@classmethod
|
|
@@ -175,6 +173,9 @@ class ModelManagement:
|
|
|
175
173
|
|
|
176
174
|
model_tar_gz = Path(cache_dir) / f"{fast_model_name}.tar.gz"
|
|
177
175
|
|
|
176
|
+
if model_tar_gz.exists():
|
|
177
|
+
model_tar_gz.unlink()
|
|
178
|
+
|
|
178
179
|
cls.download_file_from_gcs(
|
|
179
180
|
source_url,
|
|
180
181
|
output_path=str(model_tar_gz),
|
|
@@ -190,7 +191,7 @@ class ModelManagement:
|
|
|
190
191
|
return model_dir
|
|
191
192
|
|
|
192
193
|
@classmethod
|
|
193
|
-
def download_model(cls, model: Dict[str, Any], cache_dir: Path) -> Path:
|
|
194
|
+
def download_model(cls, model: Dict[str, Any], cache_dir: Path, **kwargs) -> Path:
|
|
194
195
|
"""
|
|
195
196
|
Downloads a model from HuggingFace Hub or Google Cloud Storage.
|
|
196
197
|
|
|
@@ -219,9 +220,17 @@ class ModelManagement:
|
|
|
219
220
|
url_source = model.get("sources", {}).get("url")
|
|
220
221
|
|
|
221
222
|
if hf_source:
|
|
223
|
+
extra_patterns = [model["model_file"]]
|
|
224
|
+
extra_patterns.extend(model.get("additional_files", []))
|
|
225
|
+
|
|
222
226
|
try:
|
|
223
227
|
return Path(
|
|
224
|
-
cls.download_files_from_huggingface(
|
|
228
|
+
cls.download_files_from_huggingface(
|
|
229
|
+
hf_source,
|
|
230
|
+
cache_dir=str(cache_dir),
|
|
231
|
+
extra_patterns=extra_patterns,
|
|
232
|
+
local_files_only=kwargs.get("local_files_only", False),
|
|
233
|
+
)
|
|
225
234
|
)
|
|
226
235
|
except (EnvironmentError, RepositoryNotFoundError, ValueError) as e:
|
|
227
236
|
logger.error(
|
|
@@ -1,19 +1,33 @@
|
|
|
1
1
|
import os
|
|
2
2
|
from multiprocessing import get_all_start_methods
|
|
3
3
|
from pathlib import Path
|
|
4
|
-
from typing import
|
|
4
|
+
from typing import (
|
|
5
|
+
Any,
|
|
6
|
+
Dict,
|
|
7
|
+
Generic,
|
|
8
|
+
Iterable,
|
|
9
|
+
List,
|
|
10
|
+
Optional,
|
|
11
|
+
Tuple,
|
|
12
|
+
Type,
|
|
13
|
+
TypeVar,
|
|
14
|
+
Union,
|
|
15
|
+
Sequence,
|
|
16
|
+
)
|
|
5
17
|
|
|
6
18
|
import numpy as np
|
|
7
19
|
import onnxruntime as ort
|
|
8
20
|
|
|
9
|
-
from fastembed.common.model_management import locate_model_file
|
|
10
21
|
from fastembed.common.models import load_tokenizer
|
|
11
22
|
from fastembed.common.utils import iter_batch
|
|
12
23
|
from fastembed.parallel_processor import ParallelWorkerPool, Worker
|
|
13
24
|
|
|
25
|
+
|
|
14
26
|
# Holds type of the embedding result
|
|
15
27
|
T = TypeVar("T")
|
|
16
28
|
|
|
29
|
+
OnnxProvider = Union[str, Tuple[str, Dict[Any, Any]]]
|
|
30
|
+
|
|
17
31
|
|
|
18
32
|
class OnnxModel(Generic[T]):
|
|
19
33
|
@classmethod
|
|
@@ -34,11 +48,26 @@ class OnnxModel(Generic[T]):
|
|
|
34
48
|
"""
|
|
35
49
|
return onnx_input
|
|
36
50
|
|
|
37
|
-
def load_onnx_model(
|
|
38
|
-
|
|
51
|
+
def load_onnx_model(
|
|
52
|
+
self,
|
|
53
|
+
model_dir: Path,
|
|
54
|
+
model_file: str,
|
|
55
|
+
threads: Optional[int],
|
|
56
|
+
providers: Optional[Sequence[OnnxProvider]] = None,
|
|
57
|
+
) -> None:
|
|
58
|
+
model_path = model_dir / model_file
|
|
39
59
|
|
|
40
60
|
# List of Execution Providers: https://onnxruntime.ai/docs/execution-providers
|
|
41
|
-
|
|
61
|
+
|
|
62
|
+
onnx_providers = ["CPUExecutionProvider"] if providers is None else list(providers)
|
|
63
|
+
available_providers = ort.get_available_providers()
|
|
64
|
+
for provider in onnx_providers:
|
|
65
|
+
# check providers available
|
|
66
|
+
provider_name = provider if isinstance(provider, str) else provider[0]
|
|
67
|
+
if provider_name not in available_providers:
|
|
68
|
+
raise ValueError(
|
|
69
|
+
f"Provider {provider_name} is not available. Available providers: {available_providers}"
|
|
70
|
+
)
|
|
42
71
|
|
|
43
72
|
so = ort.SessionOptions()
|
|
44
73
|
so.graph_optimization_level = ort.GraphOptimizationLevel.ORT_ENABLE_ALL
|
|
@@ -47,7 +76,7 @@ class OnnxModel(Generic[T]):
|
|
|
47
76
|
so.intra_op_num_threads = threads
|
|
48
77
|
so.inter_op_num_threads = threads
|
|
49
78
|
|
|
50
|
-
self.tokenizer = load_tokenizer(model_dir=model_dir
|
|
79
|
+
self.tokenizer = load_tokenizer(model_dir=model_dir)
|
|
51
80
|
self.model = ort.InferenceSession(
|
|
52
81
|
str(model_path), providers=onnx_providers, sess_options=so
|
|
53
82
|
)
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
from typing import List, Type, Dict, Any, Union, Iterable, Optional
|
|
1
|
+
from typing import List, Type, Dict, Any, Union, Iterable, Optional, Sequence
|
|
2
2
|
|
|
3
|
+
from fastembed.common import OnnxProvider
|
|
3
4
|
from fastembed.sparse.sparse_embedding_base import SparseTextEmbeddingBase, SparseEmbedding
|
|
4
5
|
from fastembed.sparse.splade_pp import SpladePP
|
|
5
6
|
|
|
@@ -42,6 +43,7 @@ class SparseTextEmbedding(SparseTextEmbeddingBase):
|
|
|
42
43
|
model_name: str,
|
|
43
44
|
cache_dir: Optional[str] = None,
|
|
44
45
|
threads: Optional[int] = None,
|
|
46
|
+
providers: Optional[Sequence[OnnxProvider]] = None,
|
|
45
47
|
**kwargs,
|
|
46
48
|
):
|
|
47
49
|
super().__init__(model_name, cache_dir, threads, **kwargs)
|
|
@@ -49,7 +51,9 @@ class SparseTextEmbedding(SparseTextEmbeddingBase):
|
|
|
49
51
|
for EMBEDDING_MODEL_TYPE in self.EMBEDDINGS_REGISTRY:
|
|
50
52
|
supported_models = EMBEDDING_MODEL_TYPE.list_supported_models()
|
|
51
53
|
if any(model_name.lower() == model["model"].lower() for model in supported_models):
|
|
52
|
-
self.model = EMBEDDING_MODEL_TYPE(
|
|
54
|
+
self.model = EMBEDDING_MODEL_TYPE(
|
|
55
|
+
model_name, cache_dir, threads, providers=providers, **kwargs
|
|
56
|
+
)
|
|
53
57
|
return
|
|
54
58
|
|
|
55
59
|
raise ValueError(
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
from typing import Any, Dict, Iterable, List, Optional, Tuple, Union, Type
|
|
1
|
+
from typing import Any, Dict, Iterable, List, Optional, Tuple, Union, Type, Sequence
|
|
2
2
|
|
|
3
3
|
import numpy as np
|
|
4
4
|
|
|
5
|
-
from fastembed.common.onnx_model import EmbeddingWorker, OnnxModel
|
|
5
|
+
from fastembed.common.onnx_model import EmbeddingWorker, OnnxModel, OnnxProvider
|
|
6
6
|
from fastembed.common.utils import define_cache_dir
|
|
7
7
|
from fastembed.sparse.sparse_embedding_base import SparseEmbedding, SparseTextEmbeddingBase
|
|
8
8
|
|
|
@@ -15,6 +15,7 @@ supported_splade_models = [
|
|
|
15
15
|
"sources": {
|
|
16
16
|
"hf": "Qdrant/SPLADE_PP_en_v1",
|
|
17
17
|
},
|
|
18
|
+
"model_file": "model.onnx",
|
|
18
19
|
},
|
|
19
20
|
{
|
|
20
21
|
"model": "prithivida/Splade_PP_en_v1",
|
|
@@ -24,6 +25,7 @@ supported_splade_models = [
|
|
|
24
25
|
"sources": {
|
|
25
26
|
"hf": "Qdrant/SPLADE_PP_en_v1",
|
|
26
27
|
},
|
|
28
|
+
"model_file": "model.onnx",
|
|
27
29
|
},
|
|
28
30
|
]
|
|
29
31
|
|
|
@@ -61,6 +63,7 @@ class SpladePP(SparseTextEmbeddingBase, OnnxModel[SparseEmbedding]):
|
|
|
61
63
|
model_name: str,
|
|
62
64
|
cache_dir: Optional[str] = None,
|
|
63
65
|
threads: Optional[int] = None,
|
|
66
|
+
providers: Optional[Sequence[OnnxProvider]] = None,
|
|
64
67
|
**kwargs,
|
|
65
68
|
):
|
|
66
69
|
"""
|
|
@@ -77,14 +80,19 @@ class SpladePP(SparseTextEmbeddingBase, OnnxModel[SparseEmbedding]):
|
|
|
77
80
|
|
|
78
81
|
super().__init__(model_name, cache_dir, threads, **kwargs)
|
|
79
82
|
|
|
80
|
-
|
|
81
|
-
|
|
83
|
+
model_description = self._get_model_description(model_name)
|
|
84
|
+
cache_dir = define_cache_dir(cache_dir)
|
|
82
85
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
+
model_dir = self.download_model(
|
|
87
|
+
model_description, cache_dir, local_files_only=self._local_files_only
|
|
88
|
+
)
|
|
86
89
|
|
|
87
|
-
self.load_onnx_model(
|
|
90
|
+
self.load_onnx_model(
|
|
91
|
+
model_dir=model_dir,
|
|
92
|
+
model_file=model_description["model_file"],
|
|
93
|
+
threads=threads,
|
|
94
|
+
providers=providers,
|
|
95
|
+
)
|
|
88
96
|
|
|
89
97
|
def embed(
|
|
90
98
|
self,
|
|
@@ -110,7 +118,7 @@ class SpladePP(SparseTextEmbeddingBase, OnnxModel[SparseEmbedding]):
|
|
|
110
118
|
"""
|
|
111
119
|
yield from self._embed_documents(
|
|
112
120
|
model_name=self.model_name,
|
|
113
|
-
cache_dir=str(self.
|
|
121
|
+
cache_dir=str(self.cache_dir),
|
|
114
122
|
documents=documents,
|
|
115
123
|
batch_size=batch_size,
|
|
116
124
|
parallel=parallel,
|
|
@@ -15,6 +15,8 @@ supported_multilingual_e5_models = [
|
|
|
15
15
|
"url": "https://storage.googleapis.com/qdrant-fastembed/fast-multilingual-e5-large.tar.gz",
|
|
16
16
|
"hf": "qdrant/multilingual-e5-large-onnx",
|
|
17
17
|
},
|
|
18
|
+
"model_file": "model.onnx",
|
|
19
|
+
"additional_files": ["model.onnx_data"],
|
|
18
20
|
},
|
|
19
21
|
{
|
|
20
22
|
"model": "sentence-transformers/paraphrase-multilingual-mpnet-base-v2",
|
|
@@ -24,6 +26,7 @@ supported_multilingual_e5_models = [
|
|
|
24
26
|
"sources": {
|
|
25
27
|
"hf": "xenova/paraphrase-multilingual-mpnet-base-v2",
|
|
26
28
|
},
|
|
29
|
+
"model_file": "onnx/model.onnx",
|
|
27
30
|
},
|
|
28
31
|
]
|
|
29
32
|
|
|
@@ -13,6 +13,7 @@ supported_jina_models = [
|
|
|
13
13
|
"description": "English embedding model supporting 8192 sequence length",
|
|
14
14
|
"size_in_GB": 0.52,
|
|
15
15
|
"sources": {"hf": "xenova/jina-embeddings-v2-base-en"},
|
|
16
|
+
"model_file": "onnx/model.onnx",
|
|
16
17
|
},
|
|
17
18
|
{
|
|
18
19
|
"model": "jinaai/jina-embeddings-v2-small-en",
|
|
@@ -20,6 +21,7 @@ supported_jina_models = [
|
|
|
20
21
|
"description": "English embedding model supporting 8192 sequence length",
|
|
21
22
|
"size_in_GB": 0.12,
|
|
22
23
|
"sources": {"hf": "xenova/jina-embeddings-v2-small-en"},
|
|
24
|
+
"model_file": "onnx/model.onnx",
|
|
23
25
|
},
|
|
24
26
|
]
|
|
25
27
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
from typing import Dict, Optional, Tuple, Union, Iterable, Type, List, Any
|
|
1
|
+
from typing import Dict, Optional, Tuple, Union, Iterable, Type, List, Any, Sequence
|
|
2
2
|
|
|
3
3
|
import numpy as np
|
|
4
4
|
|
|
5
|
-
from fastembed.common.onnx_model import OnnxModel, EmbeddingWorker
|
|
5
|
+
from fastembed.common.onnx_model import OnnxModel, EmbeddingWorker, OnnxProvider
|
|
6
6
|
from fastembed.common.models import normalize
|
|
7
7
|
from fastembed.common.utils import define_cache_dir
|
|
8
8
|
from fastembed.text.text_embedding_base import TextEmbeddingBase
|
|
@@ -16,6 +16,7 @@ supported_onnx_models = [
|
|
|
16
16
|
"sources": {
|
|
17
17
|
"url": "https://storage.googleapis.com/qdrant-fastembed/fast-bge-base-en.tar.gz",
|
|
18
18
|
},
|
|
19
|
+
"model_file": "model_optimized.onnx",
|
|
19
20
|
},
|
|
20
21
|
{
|
|
21
22
|
"model": "BAAI/bge-base-en-v1.5",
|
|
@@ -26,6 +27,7 @@ supported_onnx_models = [
|
|
|
26
27
|
"url": "https://storage.googleapis.com/qdrant-fastembed/fast-bge-base-en-v1.5.tar.gz",
|
|
27
28
|
"hf": "qdrant/bge-base-en-v1.5-onnx-q",
|
|
28
29
|
},
|
|
30
|
+
"model_file": "model_optimized.onnx",
|
|
29
31
|
},
|
|
30
32
|
{
|
|
31
33
|
"model": "BAAI/bge-large-en-v1.5",
|
|
@@ -35,6 +37,7 @@ supported_onnx_models = [
|
|
|
35
37
|
"sources": {
|
|
36
38
|
"hf": "qdrant/bge-large-en-v1.5-onnx",
|
|
37
39
|
},
|
|
40
|
+
"model_file": "model.onnx",
|
|
38
41
|
},
|
|
39
42
|
{
|
|
40
43
|
"model": "BAAI/bge-small-en",
|
|
@@ -44,18 +47,8 @@ supported_onnx_models = [
|
|
|
44
47
|
"sources": {
|
|
45
48
|
"url": "https://storage.googleapis.com/qdrant-fastembed/BAAI-bge-small-en.tar.gz",
|
|
46
49
|
},
|
|
50
|
+
"model_file": "model_optimized.onnx",
|
|
47
51
|
},
|
|
48
|
-
# {
|
|
49
|
-
# "model": "BAAI/bge-small-en",
|
|
50
|
-
# "dim": 384,
|
|
51
|
-
# "description": "Fast English model",
|
|
52
|
-
# "size_in_GB": 0.2,
|
|
53
|
-
# "hf_sources": [],
|
|
54
|
-
# "compressed_url_sources": [
|
|
55
|
-
# "https://storage.googleapis.com/qdrant-fastembed/fast-bge-small-en.tar.gz",
|
|
56
|
-
# "https://storage.googleapis.com/qdrant-fastembed/BAAI-bge-small-en.tar.gz"
|
|
57
|
-
# ]
|
|
58
|
-
# },
|
|
59
52
|
{
|
|
60
53
|
"model": "BAAI/bge-small-en-v1.5",
|
|
61
54
|
"dim": 384,
|
|
@@ -64,6 +57,7 @@ supported_onnx_models = [
|
|
|
64
57
|
"sources": {
|
|
65
58
|
"hf": "qdrant/bge-small-en-v1.5-onnx-q",
|
|
66
59
|
},
|
|
60
|
+
"model_file": "model_optimized.onnx",
|
|
67
61
|
},
|
|
68
62
|
{
|
|
69
63
|
"model": "BAAI/bge-small-zh-v1.5",
|
|
@@ -73,6 +67,7 @@ supported_onnx_models = [
|
|
|
73
67
|
"sources": {
|
|
74
68
|
"url": "https://storage.googleapis.com/qdrant-fastembed/fast-bge-small-zh-v1.5.tar.gz",
|
|
75
69
|
},
|
|
70
|
+
"model_file": "model_optimized.onnx",
|
|
76
71
|
},
|
|
77
72
|
{
|
|
78
73
|
"model": "sentence-transformers/all-MiniLM-L6-v2",
|
|
@@ -83,6 +78,7 @@ supported_onnx_models = [
|
|
|
83
78
|
"url": "https://storage.googleapis.com/qdrant-fastembed/sentence-transformers-all-MiniLM-L6-v2.tar.gz",
|
|
84
79
|
"hf": "qdrant/all-MiniLM-L6-v2-onnx",
|
|
85
80
|
},
|
|
81
|
+
"model_file": "model.onnx",
|
|
86
82
|
},
|
|
87
83
|
{
|
|
88
84
|
"model": "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2",
|
|
@@ -92,6 +88,7 @@ supported_onnx_models = [
|
|
|
92
88
|
"sources": {
|
|
93
89
|
"hf": "qdrant/paraphrase-multilingual-MiniLM-L12-v2-onnx-Q",
|
|
94
90
|
},
|
|
91
|
+
"model_file": "model_optimized.onnx",
|
|
95
92
|
},
|
|
96
93
|
{
|
|
97
94
|
"model": "nomic-ai/nomic-embed-text-v1",
|
|
@@ -101,6 +98,7 @@ supported_onnx_models = [
|
|
|
101
98
|
"sources": {
|
|
102
99
|
"hf": "nomic-ai/nomic-embed-text-v1",
|
|
103
100
|
},
|
|
101
|
+
"model_file": "onnx/model.onnx",
|
|
104
102
|
},
|
|
105
103
|
{
|
|
106
104
|
"model": "nomic-ai/nomic-embed-text-v1.5",
|
|
@@ -110,6 +108,17 @@ supported_onnx_models = [
|
|
|
110
108
|
"sources": {
|
|
111
109
|
"hf": "nomic-ai/nomic-embed-text-v1.5",
|
|
112
110
|
},
|
|
111
|
+
"model_file": "onnx/model.onnx",
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"model": "nomic-ai/nomic-embed-text-v1.5-Q",
|
|
115
|
+
"dim": 768,
|
|
116
|
+
"description": "Quantized 8192 context length english model",
|
|
117
|
+
"size_in_GB": 0.13,
|
|
118
|
+
"sources": {
|
|
119
|
+
"hf": "nomic-ai/nomic-embed-text-v1.5",
|
|
120
|
+
},
|
|
121
|
+
"model_file": "onnx/model_quantized.onnx",
|
|
113
122
|
},
|
|
114
123
|
{
|
|
115
124
|
"model": "thenlper/gte-large",
|
|
@@ -119,20 +128,8 @@ supported_onnx_models = [
|
|
|
119
128
|
"sources": {
|
|
120
129
|
"hf": "qdrant/gte-large-onnx",
|
|
121
130
|
},
|
|
131
|
+
"model_file": "model.onnx",
|
|
122
132
|
},
|
|
123
|
-
# {
|
|
124
|
-
# "model": "sentence-transformers/all-MiniLM-L6-v2",
|
|
125
|
-
# "dim": 384,
|
|
126
|
-
# "description": "Sentence Transformer model, MiniLM-L6-v2",
|
|
127
|
-
# "size_in_GB": 0.09,
|
|
128
|
-
# "hf_sources": [
|
|
129
|
-
# "qdrant/all-MiniLM-L6-v2-onnx"
|
|
130
|
-
# ],
|
|
131
|
-
# "compressed_url_sources": [
|
|
132
|
-
# "https://storage.googleapis.com/qdrant-fastembed/fast-all-MiniLM-L6-v2.tar.gz",
|
|
133
|
-
# "https://storage.googleapis.com/qdrant-fastembed/sentence-transformers-all-MiniLM-L6-v2.tar.gz"
|
|
134
|
-
# ]
|
|
135
|
-
# }
|
|
136
133
|
{
|
|
137
134
|
"model": "mixedbread-ai/mxbai-embed-large-v1",
|
|
138
135
|
"dim": 1024,
|
|
@@ -141,6 +138,57 @@ supported_onnx_models = [
|
|
|
141
138
|
"sources": {
|
|
142
139
|
"hf": "mixedbread-ai/mxbai-embed-large-v1",
|
|
143
140
|
},
|
|
141
|
+
"model_file": "onnx/model.onnx",
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
"model": "snowflake/snowflake-arctic-embed-xs",
|
|
145
|
+
"dim": 384,
|
|
146
|
+
"description": "Based on all-MiniLM-L6-v2 model with only 22m parameters, ideal for latency/TCO budgets.",
|
|
147
|
+
"size_in_GB": 0.09,
|
|
148
|
+
"sources": {
|
|
149
|
+
"hf": "snowflake/snowflake-arctic-embed-xs",
|
|
150
|
+
},
|
|
151
|
+
"model_file": "onnx/model.onnx",
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
"model": "snowflake/snowflake-arctic-embed-s",
|
|
155
|
+
"dim": 384,
|
|
156
|
+
"description": "Based on infloat/e5-small-unsupervised, does not trade off retrieval accuracy for its small size.",
|
|
157
|
+
"size_in_GB": 0.13,
|
|
158
|
+
"sources": {
|
|
159
|
+
"hf": "snowflake/snowflake-arctic-embed-s",
|
|
160
|
+
},
|
|
161
|
+
"model_file": "onnx/model.onnx",
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
"model": "snowflake/snowflake-arctic-embed-m",
|
|
165
|
+
"dim": 768,
|
|
166
|
+
"description": "Based on intfloat/e5-base-unsupervised model, provides the best retrieval without slowing down inference.",
|
|
167
|
+
"size_in_GB": 0.43,
|
|
168
|
+
"sources": {
|
|
169
|
+
"hf": "Snowflake/snowflake-arctic-embed-m",
|
|
170
|
+
},
|
|
171
|
+
"model_file": "onnx/model.onnx",
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
"model": "snowflake/snowflake-arctic-embed-m-long",
|
|
175
|
+
"dim": 768,
|
|
176
|
+
"description": "Based on nomic-ai/nomic-embed-text-v1-unsupervised model, 8192 context-length model",
|
|
177
|
+
"size_in_GB": 0.54,
|
|
178
|
+
"sources": {
|
|
179
|
+
"hf": "snowflake/snowflake-arctic-embed-m-long",
|
|
180
|
+
},
|
|
181
|
+
"model_file": "onnx/model.onnx",
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
"model": "snowflake/snowflake-arctic-embed-l",
|
|
185
|
+
"dim": 1024,
|
|
186
|
+
"description": "Based on intfloat/e5-large-unsupervised, large model for most accurate retrieval.",
|
|
187
|
+
"size_in_GB": 1.02,
|
|
188
|
+
"sources": {
|
|
189
|
+
"hf": "snowflake/snowflake-arctic-embed-l",
|
|
190
|
+
},
|
|
191
|
+
"model_file": "onnx/model.onnx",
|
|
144
192
|
},
|
|
145
193
|
]
|
|
146
194
|
|
|
@@ -163,6 +211,7 @@ class OnnxTextEmbedding(TextEmbeddingBase, OnnxModel[np.ndarray]):
|
|
|
163
211
|
model_name: str = "BAAI/bge-small-en-v1.5",
|
|
164
212
|
cache_dir: Optional[str] = None,
|
|
165
213
|
threads: Optional[int] = None,
|
|
214
|
+
providers: Optional[Sequence[OnnxProvider]] = None,
|
|
166
215
|
**kwargs,
|
|
167
216
|
):
|
|
168
217
|
"""
|
|
@@ -179,14 +228,18 @@ class OnnxTextEmbedding(TextEmbeddingBase, OnnxModel[np.ndarray]):
|
|
|
179
228
|
|
|
180
229
|
super().__init__(model_name, cache_dir, threads, **kwargs)
|
|
181
230
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
self._max_length = 512
|
|
231
|
+
model_description = self._get_model_description(model_name)
|
|
232
|
+
cache_dir = define_cache_dir(cache_dir)
|
|
233
|
+
model_dir = self.download_model(
|
|
234
|
+
model_description, cache_dir, local_files_only=self._local_files_only
|
|
235
|
+
)
|
|
188
236
|
|
|
189
|
-
self.load_onnx_model(
|
|
237
|
+
self.load_onnx_model(
|
|
238
|
+
model_dir=model_dir,
|
|
239
|
+
model_file=model_description["model_file"],
|
|
240
|
+
threads=threads,
|
|
241
|
+
providers=providers,
|
|
242
|
+
)
|
|
190
243
|
|
|
191
244
|
def embed(
|
|
192
245
|
self,
|
|
@@ -212,7 +265,7 @@ class OnnxTextEmbedding(TextEmbeddingBase, OnnxModel[np.ndarray]):
|
|
|
212
265
|
"""
|
|
213
266
|
yield from self._embed_documents(
|
|
214
267
|
model_name=self.model_name,
|
|
215
|
-
cache_dir=str(self.
|
|
268
|
+
cache_dir=str(self.cache_dir),
|
|
216
269
|
documents=documents,
|
|
217
270
|
batch_size=batch_size,
|
|
218
271
|
parallel=parallel,
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
from typing import Any, Dict, Iterable, List, Optional, Type, Union
|
|
1
|
+
from typing import Any, Dict, Iterable, List, Optional, Type, Union, Sequence
|
|
2
2
|
|
|
3
3
|
import numpy as np
|
|
4
4
|
|
|
5
|
+
from fastembed.common import OnnxProvider
|
|
5
6
|
from fastembed.text.e5_onnx_embedding import E5OnnxEmbedding
|
|
6
7
|
from fastembed.text.jina_onnx_embedding import JinaOnnxEmbedding
|
|
7
8
|
from fastembed.text.onnx_embedding import OnnxTextEmbedding
|
|
@@ -49,6 +50,7 @@ class TextEmbedding(TextEmbeddingBase):
|
|
|
49
50
|
model_name: str = "BAAI/bge-small-en-v1.5",
|
|
50
51
|
cache_dir: Optional[str] = None,
|
|
51
52
|
threads: Optional[int] = None,
|
|
53
|
+
providers: Optional[Sequence[OnnxProvider]] = None,
|
|
52
54
|
**kwargs,
|
|
53
55
|
):
|
|
54
56
|
super().__init__(model_name, cache_dir, threads, **kwargs)
|
|
@@ -56,7 +58,9 @@ class TextEmbedding(TextEmbeddingBase):
|
|
|
56
58
|
for EMBEDDING_MODEL_TYPE in self.EMBEDDINGS_REGISTRY:
|
|
57
59
|
supported_models = EMBEDDING_MODEL_TYPE.list_supported_models()
|
|
58
60
|
if any(model_name.lower() == model["model"].lower() for model in supported_models):
|
|
59
|
-
self.model = EMBEDDING_MODEL_TYPE(
|
|
61
|
+
self.model = EMBEDDING_MODEL_TYPE(
|
|
62
|
+
model_name, cache_dir, threads, providers=providers, **kwargs
|
|
63
|
+
)
|
|
60
64
|
return
|
|
61
65
|
|
|
62
66
|
raise ValueError(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "fastembed"
|
|
3
|
-
version = "0.2.
|
|
3
|
+
version = "0.2.7"
|
|
4
4
|
description = "Fast, light, accurate library built for retrieval embedding generation"
|
|
5
5
|
authors = ["NirantK <nirant.bits@gmail.com>"]
|
|
6
6
|
license = "Apache License"
|
|
@@ -16,7 +16,7 @@ onnx = "^1.15.0"
|
|
|
16
16
|
onnxruntime = "^1.17.0"
|
|
17
17
|
tqdm = "^4.66"
|
|
18
18
|
requests = "^2.31"
|
|
19
|
-
tokenizers = "^0.15
|
|
19
|
+
tokenizers = "^0.15"
|
|
20
20
|
huggingface-hub = "^0.20"
|
|
21
21
|
loguru = "^0.7.2"
|
|
22
22
|
numpy = [
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|