vectordb-bench 0.0.14__py3-none-any.whl → 0.0.15__py3-none-any.whl
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.
- vectordb_bench/__init__.py +14 -13
- vectordb_bench/backend/clients/__init__.py +13 -0
- vectordb_bench/backend/clients/api.py +2 -0
- vectordb_bench/backend/clients/pgdiskann/cli.py +99 -0
- vectordb_bench/backend/clients/pgdiskann/config.py +145 -0
- vectordb_bench/backend/clients/pgdiskann/pgdiskann.py +350 -0
- vectordb_bench/backend/clients/pgvector/cli.py +47 -1
- vectordb_bench/backend/clients/pgvector/config.py +28 -5
- vectordb_bench/backend/clients/pgvector/pgvector.py +113 -64
- vectordb_bench/backend/clients/weaviate_cloud/weaviate_cloud.py +1 -1
- vectordb_bench/cli/vectordbbench.py +2 -0
- vectordb_bench/frontend/components/run_test/caseSelector.py +6 -0
- vectordb_bench/frontend/config/dbCaseConfigs.py +109 -2
- vectordb_bench/models.py +6 -0
- {vectordb_bench-0.0.14.dist-info → vectordb_bench-0.0.15.dist-info}/METADATA +7 -2
- {vectordb_bench-0.0.14.dist-info → vectordb_bench-0.0.15.dist-info}/RECORD +20 -17
- {vectordb_bench-0.0.14.dist-info → vectordb_bench-0.0.15.dist-info}/WHEEL +1 -1
- {vectordb_bench-0.0.14.dist-info → vectordb_bench-0.0.15.dist-info}/LICENSE +0 -0
- {vectordb_bench-0.0.14.dist-info → vectordb_bench-0.0.15.dist-info}/entry_points.txt +0 -0
- {vectordb_bench-0.0.14.dist-info → vectordb_bench-0.0.15.dist-info}/top_level.txt +0 -0
@@ -4,6 +4,8 @@ import click
|
|
4
4
|
import os
|
5
5
|
from pydantic import SecretStr
|
6
6
|
|
7
|
+
from vectordb_bench.backend.clients.api import MetricType
|
8
|
+
|
7
9
|
from ....cli.cli import (
|
8
10
|
CommonTypedDict,
|
9
11
|
HNSWFlavor1,
|
@@ -16,6 +18,13 @@ from ....cli.cli import (
|
|
16
18
|
from vectordb_bench.backend.clients import DB
|
17
19
|
|
18
20
|
|
21
|
+
|
22
|
+
def set_default_quantized_fetch_limit(ctx, param, value):
|
23
|
+
if ctx.params.get("reranking") and value is None:
|
24
|
+
# ef_search is the default value for quantized_fetch_limit as it's bound by ef_search.
|
25
|
+
return ctx.params["ef_search"]
|
26
|
+
return value
|
27
|
+
|
19
28
|
class PgVectorTypedDict(CommonTypedDict):
|
20
29
|
user_name: Annotated[
|
21
30
|
str, click.option("--user-name", type=str, help="Db username", required=True)
|
@@ -61,11 +70,45 @@ class PgVectorTypedDict(CommonTypedDict):
|
|
61
70
|
Optional[str],
|
62
71
|
click.option(
|
63
72
|
"--quantization-type",
|
64
|
-
type=click.Choice(["none", "halfvec"]),
|
73
|
+
type=click.Choice(["none", "bit", "halfvec"]),
|
65
74
|
help="quantization type for vectors",
|
66
75
|
required=False,
|
67
76
|
),
|
68
77
|
]
|
78
|
+
reranking: Annotated[
|
79
|
+
Optional[bool],
|
80
|
+
click.option(
|
81
|
+
"--reranking/--skip-reranking",
|
82
|
+
type=bool,
|
83
|
+
help="Enable reranking for HNSW search for binary quantization",
|
84
|
+
default=False,
|
85
|
+
),
|
86
|
+
]
|
87
|
+
reranking_metric: Annotated[
|
88
|
+
Optional[str],
|
89
|
+
click.option(
|
90
|
+
"--reranking-metric",
|
91
|
+
type=click.Choice(
|
92
|
+
[metric.value for metric in MetricType if metric.value not in ["HAMMING", "JACCARD"]]
|
93
|
+
),
|
94
|
+
help="Distance metric for reranking",
|
95
|
+
default="COSINE",
|
96
|
+
show_default=True,
|
97
|
+
),
|
98
|
+
]
|
99
|
+
quantized_fetch_limit: Annotated[
|
100
|
+
Optional[int],
|
101
|
+
click.option(
|
102
|
+
"--quantized-fetch-limit",
|
103
|
+
type=int,
|
104
|
+
help="Limit of fetching quantized vector ranked by distance for reranking \
|
105
|
+
-- bound by ef_search",
|
106
|
+
required=False,
|
107
|
+
callback=set_default_quantized_fetch_limit,
|
108
|
+
)
|
109
|
+
]
|
110
|
+
|
111
|
+
|
69
112
|
|
70
113
|
class PgVectorIVFFlatTypedDict(PgVectorTypedDict, IVFFlatTypedDict):
|
71
114
|
...
|
@@ -126,6 +169,9 @@ def PgVectorHNSW(
|
|
126
169
|
maintenance_work_mem=parameters["maintenance_work_mem"],
|
127
170
|
max_parallel_workers=parameters["max_parallel_workers"],
|
128
171
|
quantization_type=parameters["quantization_type"],
|
172
|
+
reranking=parameters["reranking"],
|
173
|
+
reranking_metric=parameters["reranking_metric"],
|
174
|
+
quantized_fetch_limit=parameters["quantized_fetch_limit"],
|
129
175
|
),
|
130
176
|
**parameters,
|
131
177
|
)
|
@@ -65,6 +65,10 @@ class PgVectorIndexConfig(BaseModel, DBCaseConfig):
|
|
65
65
|
elif self.metric_type == MetricType.IP:
|
66
66
|
return "halfvec_ip_ops"
|
67
67
|
return "halfvec_cosine_ops"
|
68
|
+
elif self.quantization_type == "bit":
|
69
|
+
if self.metric_type == MetricType.JACCARD:
|
70
|
+
return "bit_jaccard_ops"
|
71
|
+
return "bit_hamming_ops"
|
68
72
|
else:
|
69
73
|
if self.metric_type == MetricType.L2:
|
70
74
|
return "vector_l2_ops"
|
@@ -73,11 +77,16 @@ class PgVectorIndexConfig(BaseModel, DBCaseConfig):
|
|
73
77
|
return "vector_cosine_ops"
|
74
78
|
|
75
79
|
def parse_metric_fun_op(self) -> LiteralString:
|
76
|
-
if self.
|
77
|
-
|
78
|
-
|
79
|
-
return "
|
80
|
-
|
80
|
+
if self.quantization_type == "bit":
|
81
|
+
if self.metric_type == MetricType.JACCARD:
|
82
|
+
return "<%>"
|
83
|
+
return "<~>"
|
84
|
+
else:
|
85
|
+
if self.metric_type == MetricType.L2:
|
86
|
+
return "<->"
|
87
|
+
elif self.metric_type == MetricType.IP:
|
88
|
+
return "<#>"
|
89
|
+
return "<=>"
|
81
90
|
|
82
91
|
def parse_metric_fun_str(self) -> str:
|
83
92
|
if self.metric_type == MetricType.L2:
|
@@ -85,6 +94,14 @@ class PgVectorIndexConfig(BaseModel, DBCaseConfig):
|
|
85
94
|
elif self.metric_type == MetricType.IP:
|
86
95
|
return "max_inner_product"
|
87
96
|
return "cosine_distance"
|
97
|
+
|
98
|
+
def parse_reranking_metric_fun_op(self) -> LiteralString:
|
99
|
+
if self.reranking_metric == MetricType.L2:
|
100
|
+
return "<->"
|
101
|
+
elif self.reranking_metric == MetricType.IP:
|
102
|
+
return "<#>"
|
103
|
+
return "<=>"
|
104
|
+
|
88
105
|
|
89
106
|
@abstractmethod
|
90
107
|
def index_param(self) -> PgVectorIndexParam:
|
@@ -195,6 +212,9 @@ class PgVectorHNSWConfig(PgVectorIndexConfig):
|
|
195
212
|
maintenance_work_mem: Optional[str] = None
|
196
213
|
max_parallel_workers: Optional[int] = None
|
197
214
|
quantization_type: Optional[str] = None
|
215
|
+
reranking: Optional[bool] = None
|
216
|
+
quantized_fetch_limit: Optional[int] = None
|
217
|
+
reranking_metric: Optional[str] = None
|
198
218
|
|
199
219
|
def index_param(self) -> PgVectorIndexParam:
|
200
220
|
index_parameters = {"m": self.m, "ef_construction": self.ef_construction}
|
@@ -214,6 +234,9 @@ class PgVectorHNSWConfig(PgVectorIndexConfig):
|
|
214
234
|
def search_param(self) -> PgVectorSearchParam:
|
215
235
|
return {
|
216
236
|
"metric_fun_op": self.parse_metric_fun_op(),
|
237
|
+
"reranking": self.reranking,
|
238
|
+
"reranking_metric_fun_op": self.parse_reranking_metric_fun_op(),
|
239
|
+
"quantized_fetch_limit": self.quantized_fetch_limit,
|
217
240
|
}
|
218
241
|
|
219
242
|
def session_param(self) -> PgVectorSessionCommands:
|
@@ -11,7 +11,7 @@ from pgvector.psycopg import register_vector
|
|
11
11
|
from psycopg import Connection, Cursor, sql
|
12
12
|
|
13
13
|
from ..api import VectorDB
|
14
|
-
from .config import PgVectorConfigDict, PgVectorIndexConfig
|
14
|
+
from .config import PgVectorConfigDict, PgVectorIndexConfig, PgVectorHNSWConfig
|
15
15
|
|
16
16
|
log = logging.getLogger(__name__)
|
17
17
|
|
@@ -87,6 +87,92 @@ class PgVector(VectorDB):
|
|
87
87
|
assert cursor is not None, "Cursor is not initialized"
|
88
88
|
|
89
89
|
return conn, cursor
|
90
|
+
|
91
|
+
def _generate_search_query(self, filtered: bool=False) -> sql.Composed:
|
92
|
+
index_param = self.case_config.index_param()
|
93
|
+
reranking = self.case_config.search_param()["reranking"]
|
94
|
+
column_name = (
|
95
|
+
sql.SQL("binary_quantize({0})").format(sql.Identifier("embedding"))
|
96
|
+
if index_param["quantization_type"] == "bit"
|
97
|
+
else sql.SQL("embedding")
|
98
|
+
)
|
99
|
+
search_vector = (
|
100
|
+
sql.SQL("binary_quantize({0})").format(sql.Placeholder())
|
101
|
+
if index_param["quantization_type"] == "bit"
|
102
|
+
else sql.Placeholder()
|
103
|
+
)
|
104
|
+
|
105
|
+
# The following sections assume that the quantization_type value matches the quantization function name
|
106
|
+
if index_param["quantization_type"] != None:
|
107
|
+
if index_param["quantization_type"] == "bit" and reranking:
|
108
|
+
# Embeddings needs to be passed to binary_quantize function if quantization_type is bit
|
109
|
+
search_query = sql.Composed(
|
110
|
+
[
|
111
|
+
sql.SQL(
|
112
|
+
"""
|
113
|
+
SELECT i.id
|
114
|
+
FROM (
|
115
|
+
SELECT id, embedding {reranking_metric_fun_op} %s::vector AS distance
|
116
|
+
FROM public.{table_name} {where_clause}
|
117
|
+
ORDER BY {column_name}::{quantization_type}({dim})
|
118
|
+
"""
|
119
|
+
).format(
|
120
|
+
table_name=sql.Identifier(self.table_name),
|
121
|
+
column_name=column_name,
|
122
|
+
reranking_metric_fun_op=sql.SQL(self.case_config.search_param()["reranking_metric_fun_op"]),
|
123
|
+
quantization_type=sql.SQL(index_param["quantization_type"]),
|
124
|
+
dim=sql.Literal(self.dim),
|
125
|
+
where_clause=sql.SQL("WHERE id >= %s") if filtered else sql.SQL(""),
|
126
|
+
),
|
127
|
+
sql.SQL(self.case_config.search_param()["metric_fun_op"]),
|
128
|
+
sql.SQL(
|
129
|
+
"""
|
130
|
+
{search_vector}
|
131
|
+
LIMIT {quantized_fetch_limit}
|
132
|
+
) i
|
133
|
+
ORDER BY i.distance
|
134
|
+
LIMIT %s::int
|
135
|
+
"""
|
136
|
+
).format(
|
137
|
+
search_vector=search_vector,
|
138
|
+
quantized_fetch_limit=sql.Literal(
|
139
|
+
self.case_config.search_param()["quantized_fetch_limit"]
|
140
|
+
),
|
141
|
+
),
|
142
|
+
]
|
143
|
+
)
|
144
|
+
else:
|
145
|
+
search_query = sql.Composed(
|
146
|
+
[
|
147
|
+
sql.SQL(
|
148
|
+
"SELECT id FROM public.{table_name} {where_clause} ORDER BY {column_name}::{quantization_type}({dim}) "
|
149
|
+
).format(
|
150
|
+
table_name=sql.Identifier(self.table_name),
|
151
|
+
column_name=column_name,
|
152
|
+
quantization_type=sql.SQL(index_param["quantization_type"]),
|
153
|
+
dim=sql.Literal(self.dim),
|
154
|
+
where_clause=sql.SQL("WHERE id >= %s") if filtered else sql.SQL(""),
|
155
|
+
),
|
156
|
+
sql.SQL(self.case_config.search_param()["metric_fun_op"]),
|
157
|
+
sql.SQL(" {search_vector} LIMIT %s::int").format(search_vector=search_vector),
|
158
|
+
]
|
159
|
+
)
|
160
|
+
else:
|
161
|
+
search_query = sql.Composed(
|
162
|
+
[
|
163
|
+
sql.SQL(
|
164
|
+
"SELECT id FROM public.{table_name} {where_clause} ORDER BY embedding "
|
165
|
+
).format(
|
166
|
+
table_name=sql.Identifier(self.table_name),
|
167
|
+
where_clause=sql.SQL("WHERE id >= %s") if filtered else sql.SQL(""),
|
168
|
+
),
|
169
|
+
sql.SQL(self.case_config.search_param()["metric_fun_op"]),
|
170
|
+
sql.SQL(" %s::vector LIMIT %s::int"),
|
171
|
+
]
|
172
|
+
)
|
173
|
+
|
174
|
+
return search_query
|
175
|
+
|
90
176
|
|
91
177
|
@contextmanager
|
92
178
|
def init(self) -> Generator[None, None, None]:
|
@@ -112,63 +198,8 @@ class PgVector(VectorDB):
|
|
112
198
|
self.cursor.execute(command)
|
113
199
|
self.conn.commit()
|
114
200
|
|
115
|
-
|
116
|
-
|
117
|
-
if index_param["quantization_type"] != None:
|
118
|
-
self._filtered_search = sql.Composed(
|
119
|
-
[
|
120
|
-
sql.SQL(
|
121
|
-
"SELECT id FROM public.{table_name} WHERE id >= %s ORDER BY embedding::{quantization_type}({dim}) "
|
122
|
-
).format(
|
123
|
-
table_name=sql.Identifier(self.table_name),
|
124
|
-
quantization_type=sql.SQL(index_param["quantization_type"]),
|
125
|
-
dim=sql.Literal(self.dim),
|
126
|
-
),
|
127
|
-
sql.SQL(self.case_config.search_param()["metric_fun_op"]),
|
128
|
-
sql.SQL(" %s::{quantization_type}({dim}) LIMIT %s::int").format(
|
129
|
-
quantization_type=sql.SQL(index_param["quantization_type"]),
|
130
|
-
dim=sql.Literal(self.dim),
|
131
|
-
),
|
132
|
-
]
|
133
|
-
)
|
134
|
-
else:
|
135
|
-
self._filtered_search = sql.Composed(
|
136
|
-
[
|
137
|
-
sql.SQL(
|
138
|
-
"SELECT id FROM public.{table_name} WHERE id >= %s ORDER BY embedding "
|
139
|
-
).format(table_name=sql.Identifier(self.table_name)),
|
140
|
-
sql.SQL(self.case_config.search_param()["metric_fun_op"]),
|
141
|
-
sql.SQL(" %s::vector LIMIT %s::int"),
|
142
|
-
]
|
143
|
-
)
|
144
|
-
|
145
|
-
if index_param["quantization_type"] != None:
|
146
|
-
self._unfiltered_search = sql.Composed(
|
147
|
-
[
|
148
|
-
sql.SQL(
|
149
|
-
"SELECT id FROM public.{table_name} ORDER BY embedding::{quantization_type}({dim}) "
|
150
|
-
).format(
|
151
|
-
table_name=sql.Identifier(self.table_name),
|
152
|
-
quantization_type=sql.SQL(index_param["quantization_type"]),
|
153
|
-
dim=sql.Literal(self.dim),
|
154
|
-
),
|
155
|
-
sql.SQL(self.case_config.search_param()["metric_fun_op"]),
|
156
|
-
sql.SQL(" %s::{quantization_type}({dim}) LIMIT %s::int").format(
|
157
|
-
quantization_type=sql.SQL(index_param["quantization_type"]),
|
158
|
-
dim=sql.Literal(self.dim),
|
159
|
-
),
|
160
|
-
]
|
161
|
-
)
|
162
|
-
else:
|
163
|
-
self._unfiltered_search = sql.Composed(
|
164
|
-
[
|
165
|
-
sql.SQL("SELECT id FROM public.{} ORDER BY embedding ").format(
|
166
|
-
sql.Identifier(self.table_name)
|
167
|
-
),
|
168
|
-
sql.SQL(self.case_config.search_param()["metric_fun_op"]),
|
169
|
-
sql.SQL(" %s::vector LIMIT %s::int"),
|
170
|
-
]
|
171
|
-
)
|
201
|
+
self._filtered_search = self._generate_search_query(filtered=True)
|
202
|
+
self._unfiltered_search = self._generate_search_query()
|
172
203
|
|
173
204
|
try:
|
174
205
|
yield
|
@@ -306,12 +337,17 @@ class PgVector(VectorDB):
|
|
306
337
|
if index_param["quantization_type"] != None:
|
307
338
|
index_create_sql = sql.SQL(
|
308
339
|
"""
|
309
|
-
CREATE INDEX IF NOT EXISTS {index_name} ON public.{table_name}
|
310
|
-
USING {index_type} ((
|
340
|
+
CREATE INDEX IF NOT EXISTS {index_name} ON public.{table_name}
|
341
|
+
USING {index_type} (({column_name}::{quantization_type}({dim})) {embedding_metric})
|
311
342
|
"""
|
312
343
|
).format(
|
313
344
|
index_name=sql.Identifier(self._index_name),
|
314
345
|
table_name=sql.Identifier(self.table_name),
|
346
|
+
column_name=(
|
347
|
+
sql.SQL("binary_quantize({0})").format(sql.Identifier("embedding"))
|
348
|
+
if index_param["quantization_type"] == "bit"
|
349
|
+
else sql.Identifier("embedding")
|
350
|
+
),
|
315
351
|
index_type=sql.Identifier(index_param["index_type"]),
|
316
352
|
# This assumes that the quantization_type value matches the quantization function name
|
317
353
|
quantization_type=sql.SQL(index_param["quantization_type"]),
|
@@ -406,15 +442,28 @@ class PgVector(VectorDB):
|
|
406
442
|
assert self.conn is not None, "Connection is not initialized"
|
407
443
|
assert self.cursor is not None, "Cursor is not initialized"
|
408
444
|
|
445
|
+
index_param = self.case_config.index_param()
|
446
|
+
search_param = self.case_config.search_param()
|
409
447
|
q = np.asarray(query)
|
410
448
|
if filters:
|
411
449
|
gt = filters.get("id")
|
412
|
-
|
450
|
+
if index_param["quantization_type"] == "bit" and search_param["reranking"]:
|
451
|
+
result = self.cursor.execute(
|
452
|
+
self._filtered_search, (q, gt, q, k), prepare=True, binary=True
|
453
|
+
)
|
454
|
+
else:
|
455
|
+
result = self.cursor.execute(
|
413
456
|
self._filtered_search, (gt, q, k), prepare=True, binary=True
|
414
|
-
|
457
|
+
)
|
458
|
+
|
415
459
|
else:
|
416
|
-
|
460
|
+
if index_param["quantization_type"] == "bit" and search_param["reranking"]:
|
461
|
+
result = self.cursor.execute(
|
462
|
+
self._unfiltered_search, (q, q, k), prepare=True, binary=True
|
463
|
+
)
|
464
|
+
else:
|
465
|
+
result = self.cursor.execute(
|
417
466
|
self._unfiltered_search, (q, k), prepare=True, binary=True
|
418
|
-
|
467
|
+
)
|
419
468
|
|
420
469
|
return [int(i[0]) for i in result.fetchall()]
|
@@ -23,7 +23,7 @@ class WeaviateCloud(VectorDB):
|
|
23
23
|
**kwargs,
|
24
24
|
):
|
25
25
|
"""Initialize wrapper around the weaviate vector database."""
|
26
|
-
db_config.update("auth_client_secret"
|
26
|
+
db_config.update({"auth_client_secret": weaviate.AuthApiKey(api_key=db_config.get("auth_client_secret"))})
|
27
27
|
self.db_config = db_config
|
28
28
|
self.case_config = db_case_config
|
29
29
|
self.collection_name = collection_name
|
@@ -1,6 +1,7 @@
|
|
1
1
|
from ..backend.clients.pgvector.cli import PgVectorHNSW
|
2
2
|
from ..backend.clients.pgvecto_rs.cli import PgVectoRSHNSW, PgVectoRSIVFFlat
|
3
3
|
from ..backend.clients.pgvectorscale.cli import PgVectorScaleDiskAnn
|
4
|
+
from ..backend.clients.pgdiskann.cli import PgDiskAnn
|
4
5
|
from ..backend.clients.redis.cli import Redis
|
5
6
|
from ..backend.clients.memorydb.cli import MemoryDB
|
6
7
|
from ..backend.clients.test.cli import Test
|
@@ -22,6 +23,7 @@ cli.add_command(ZillizAutoIndex)
|
|
22
23
|
cli.add_command(MilvusAutoIndex)
|
23
24
|
cli.add_command(AWSOpenSearch)
|
24
25
|
cli.add_command(PgVectorScaleDiskAnn)
|
26
|
+
cli.add_command(PgDiskAnn)
|
25
27
|
|
26
28
|
|
27
29
|
if __name__ == "__main__":
|
@@ -110,6 +110,12 @@ def caseConfigSetting(st, dbToCaseClusterConfigs, uiCaseItem: UICaseItem, active
|
|
110
110
|
value=config.inputConfig["value"],
|
111
111
|
help=config.inputHelp,
|
112
112
|
)
|
113
|
+
elif config.inputType == InputType.Bool:
|
114
|
+
caseConfig[config.label] = column.checkbox(
|
115
|
+
config.displayLabel if config.displayLabel else config.label.value,
|
116
|
+
value=config.inputConfig["value"],
|
117
|
+
help=config.inputHelp,
|
118
|
+
)
|
113
119
|
k += 1
|
114
120
|
if k == 0:
|
115
121
|
columns[1].write("Auto")
|
@@ -3,7 +3,7 @@ import typing
|
|
3
3
|
from pydantic import BaseModel
|
4
4
|
from vectordb_bench.backend.cases import CaseLabel, CaseType
|
5
5
|
from vectordb_bench.backend.clients import DB
|
6
|
-
from vectordb_bench.backend.clients.api import IndexType
|
6
|
+
from vectordb_bench.backend.clients.api import IndexType, MetricType
|
7
7
|
from vectordb_bench.frontend.components.custom.getCustomConfig import get_custom_configs
|
8
8
|
|
9
9
|
from vectordb_bench.models import CaseConfig, CaseConfigParamType
|
@@ -149,6 +149,7 @@ class InputType(IntEnum):
|
|
149
149
|
Number = 20002
|
150
150
|
Option = 20003
|
151
151
|
Float = 20004
|
152
|
+
Bool = 20005
|
152
153
|
|
153
154
|
|
154
155
|
class CaseConfigInput(BaseModel):
|
@@ -180,6 +181,16 @@ CaseConfigParamInput_IndexType = CaseConfigInput(
|
|
180
181
|
},
|
181
182
|
)
|
182
183
|
|
184
|
+
CaseConfigParamInput_IndexType_PgDiskANN = CaseConfigInput(
|
185
|
+
label=CaseConfigParamType.IndexType,
|
186
|
+
inputHelp="Select Index Type",
|
187
|
+
inputType=InputType.Option,
|
188
|
+
inputConfig={
|
189
|
+
"options": [
|
190
|
+
IndexType.DISKANN.value,
|
191
|
+
],
|
192
|
+
},
|
193
|
+
)
|
183
194
|
|
184
195
|
CaseConfigParamInput_IndexType_PgVectorScale = CaseConfigInput(
|
185
196
|
label=CaseConfigParamType.IndexType,
|
@@ -205,6 +216,42 @@ CaseConfigParamInput_storage_layout = CaseConfigInput(
|
|
205
216
|
},
|
206
217
|
)
|
207
218
|
|
219
|
+
CaseConfigParamInput_max_neighbors = CaseConfigInput(
|
220
|
+
label=CaseConfigParamType.max_neighbors,
|
221
|
+
inputType=InputType.Number,
|
222
|
+
inputConfig={
|
223
|
+
"min": 10,
|
224
|
+
"max": 300,
|
225
|
+
"value": 32,
|
226
|
+
},
|
227
|
+
isDisplayed=lambda config: config.get(CaseConfigParamType.IndexType, None)
|
228
|
+
== IndexType.DISKANN.value,
|
229
|
+
)
|
230
|
+
|
231
|
+
CaseConfigParamInput_l_value_ib = CaseConfigInput(
|
232
|
+
label=CaseConfigParamType.l_value_ib,
|
233
|
+
inputType=InputType.Number,
|
234
|
+
inputConfig={
|
235
|
+
"min": 10,
|
236
|
+
"max": 300,
|
237
|
+
"value": 50,
|
238
|
+
},
|
239
|
+
isDisplayed=lambda config: config.get(CaseConfigParamType.IndexType, None)
|
240
|
+
== IndexType.DISKANN.value,
|
241
|
+
)
|
242
|
+
|
243
|
+
CaseConfigParamInput_l_value_is = CaseConfigInput(
|
244
|
+
label=CaseConfigParamType.l_value_is,
|
245
|
+
inputType=InputType.Number,
|
246
|
+
inputConfig={
|
247
|
+
"min": 10,
|
248
|
+
"max": 300,
|
249
|
+
"value": 40,
|
250
|
+
},
|
251
|
+
isDisplayed=lambda config: config.get(CaseConfigParamType.IndexType, None)
|
252
|
+
== IndexType.DISKANN.value,
|
253
|
+
)
|
254
|
+
|
208
255
|
CaseConfigParamInput_num_neighbors = CaseConfigInput(
|
209
256
|
label=CaseConfigParamType.num_neighbors,
|
210
257
|
inputType=InputType.Number,
|
@@ -773,7 +820,7 @@ CaseConfigParamInput_QuantizationType_PgVector = CaseConfigInput(
|
|
773
820
|
label=CaseConfigParamType.quantizationType,
|
774
821
|
inputType=InputType.Option,
|
775
822
|
inputConfig={
|
776
|
-
"options": ["none", "halfvec"],
|
823
|
+
"options": ["none", "bit", "halfvec"],
|
777
824
|
},
|
778
825
|
isDisplayed=lambda config: config.get(CaseConfigParamType.IndexType, None)
|
779
826
|
in [
|
@@ -819,6 +866,46 @@ CaseConfigParamInput_ZillizLevel = CaseConfigInput(
|
|
819
866
|
},
|
820
867
|
)
|
821
868
|
|
869
|
+
CaseConfigParamInput_reranking_PgVector = CaseConfigInput(
|
870
|
+
label=CaseConfigParamType.reranking,
|
871
|
+
inputType=InputType.Bool,
|
872
|
+
displayLabel="Enable Reranking",
|
873
|
+
inputHelp="Enable if you want to use reranking while performing \
|
874
|
+
similarity search in binary quantization",
|
875
|
+
inputConfig={
|
876
|
+
"value": False,
|
877
|
+
},
|
878
|
+
isDisplayed=lambda config: config.get(CaseConfigParamType.quantizationType, None)
|
879
|
+
== "bit"
|
880
|
+
)
|
881
|
+
|
882
|
+
CaseConfigParamInput_quantized_fetch_limit_PgVector = CaseConfigInput(
|
883
|
+
label=CaseConfigParamType.quantizedFetchLimit,
|
884
|
+
displayLabel="Quantized vector fetch limit",
|
885
|
+
inputHelp="Limit top-k vectors using the quantized vector comparison --bound by ef_search",
|
886
|
+
inputType=InputType.Number,
|
887
|
+
inputConfig={
|
888
|
+
"min": 20,
|
889
|
+
"max": 1000,
|
890
|
+
"value": 200,
|
891
|
+
},
|
892
|
+
isDisplayed=lambda config: config.get(CaseConfigParamType.quantizationType, None)
|
893
|
+
== "bit" and config.get(CaseConfigParamType.reranking, False)
|
894
|
+
)
|
895
|
+
|
896
|
+
|
897
|
+
CaseConfigParamInput_reranking_metric_PgVector = CaseConfigInput(
|
898
|
+
label=CaseConfigParamType.rerankingMetric,
|
899
|
+
inputType=InputType.Option,
|
900
|
+
inputConfig={
|
901
|
+
"options": [
|
902
|
+
metric.value for metric in MetricType if metric.value not in ["HAMMING", "JACCARD"]
|
903
|
+
],
|
904
|
+
},
|
905
|
+
isDisplayed=lambda config: config.get(CaseConfigParamType.quantizationType, None)
|
906
|
+
== "bit" and config.get(CaseConfigParamType.reranking, False)
|
907
|
+
)
|
908
|
+
|
822
909
|
MilvusLoadConfig = [
|
823
910
|
CaseConfigParamInput_IndexType,
|
824
911
|
CaseConfigParamInput_M,
|
@@ -896,6 +983,9 @@ PgVectorPerformanceConfig = [
|
|
896
983
|
CaseConfigParamInput_QuantizationType_PgVector,
|
897
984
|
CaseConfigParamInput_maintenance_work_mem_PgVector,
|
898
985
|
CaseConfigParamInput_max_parallel_workers_PgVector,
|
986
|
+
CaseConfigParamInput_reranking_PgVector,
|
987
|
+
CaseConfigParamInput_reranking_metric_PgVector,
|
988
|
+
CaseConfigParamInput_quantized_fetch_limit_PgVector,
|
899
989
|
]
|
900
990
|
|
901
991
|
PgVectoRSLoadingConfig = [
|
@@ -942,6 +1032,19 @@ PgVectorScalePerformanceConfig = [
|
|
942
1032
|
CaseConfigParamInput_query_search_list_size,
|
943
1033
|
]
|
944
1034
|
|
1035
|
+
PgDiskANNLoadConfig = [
|
1036
|
+
CaseConfigParamInput_IndexType_PgDiskANN,
|
1037
|
+
CaseConfigParamInput_max_neighbors,
|
1038
|
+
CaseConfigParamInput_l_value_ib,
|
1039
|
+
]
|
1040
|
+
|
1041
|
+
PgDiskANNPerformanceConfig = [
|
1042
|
+
CaseConfigParamInput_IndexType_PgDiskANN,
|
1043
|
+
CaseConfigParamInput_max_neighbors,
|
1044
|
+
CaseConfigParamInput_l_value_ib,
|
1045
|
+
CaseConfigParamInput_l_value_is,
|
1046
|
+
]
|
1047
|
+
|
945
1048
|
CASE_CONFIG_MAP = {
|
946
1049
|
DB.Milvus: {
|
947
1050
|
CaseLabel.Load: MilvusLoadConfig,
|
@@ -974,4 +1077,8 @@ CASE_CONFIG_MAP = {
|
|
974
1077
|
CaseLabel.Load: PgVectorScaleLoadingConfig,
|
975
1078
|
CaseLabel.Performance: PgVectorScalePerformanceConfig,
|
976
1079
|
},
|
1080
|
+
DB.PgDiskANN: {
|
1081
|
+
CaseLabel.Load: PgDiskANNLoadConfig,
|
1082
|
+
CaseLabel.Performance: PgDiskANNPerformanceConfig,
|
1083
|
+
},
|
977
1084
|
}
|
vectordb_bench/models.py
CHANGED
@@ -47,6 +47,9 @@ class CaseConfigParamType(Enum):
|
|
47
47
|
probes = "probes"
|
48
48
|
quantizationType = "quantization_type"
|
49
49
|
quantizationRatio = "quantization_ratio"
|
50
|
+
reranking = "reranking"
|
51
|
+
rerankingMetric = "reranking_metric"
|
52
|
+
quantizedFetchLimit = "quantized_fetch_limit"
|
50
53
|
m = "m"
|
51
54
|
nbits = "nbits"
|
52
55
|
intermediate_graph_degree = "intermediate_graph_degree"
|
@@ -64,6 +67,9 @@ class CaseConfigParamType(Enum):
|
|
64
67
|
max_parallel_workers = "max_parallel_workers"
|
65
68
|
storage_layout = "storage_layout"
|
66
69
|
num_neighbors = "num_neighbors"
|
70
|
+
max_neighbors = "max_neighbors"
|
71
|
+
l_value_ib = "l_value_ib"
|
72
|
+
l_value_is = "l_value_is"
|
67
73
|
search_list_size = "search_list_size"
|
68
74
|
max_alpha = "max_alpha"
|
69
75
|
num_dimensions = "num_dimensions"
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: vectordb-bench
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.15
|
4
4
|
Summary: VectorDBBench is not just an offering of benchmark results for mainstream vector databases and cloud services, it's your go-to tool for the ultimate performance and cost-effectiveness comparison. Designed with ease-of-use in mind, VectorDBBench is devised to help users, even non-professionals, reproduce results or test new systems, making the hunt for the optimal choice amongst a plethora of cloud services and open-source vector databases a breeze.
|
5
5
|
Author-email: XuanYang-cn <xuan.yang@zilliz.com>
|
6
6
|
Project-URL: repository, https://github.com/zilliztech/VectorDBBench
|
@@ -49,6 +49,10 @@ Provides-Extra: elastic
|
|
49
49
|
Requires-Dist: elasticsearch; extra == "elastic"
|
50
50
|
Provides-Extra: memorydb
|
51
51
|
Requires-Dist: memorydb; extra == "memorydb"
|
52
|
+
Provides-Extra: pgdiskann
|
53
|
+
Requires-Dist: psycopg; extra == "pgdiskann"
|
54
|
+
Requires-Dist: psycopg-binary; extra == "pgdiskann"
|
55
|
+
Requires-Dist: pgvector; extra == "pgdiskann"
|
52
56
|
Provides-Extra: pgvecto_rs
|
53
57
|
Requires-Dist: pgvecto-rs[psycopg3]>=0.2.2; extra == "pgvecto-rs"
|
54
58
|
Provides-Extra: pgvector
|
@@ -112,6 +116,7 @@ All the database client supported
|
|
112
116
|
| pgvector | `pip install vectordb-bench[pgvector]` |
|
113
117
|
| pgvecto.rs | `pip install vectordb-bench[pgvecto_rs]` |
|
114
118
|
| pgvectorscale | `pip install vectordb-bench[pgvectorscale]` |
|
119
|
+
| pgdiskann | `pip install vectordb-bench[pgdiskann]` |
|
115
120
|
| redis | `pip install vectordb-bench[redis]` |
|
116
121
|
| memorydb | `pip install vectordb-bench[memorydb]` |
|
117
122
|
| chromadb | `pip install vectordb-bench[chromadb]` |
|
@@ -191,7 +196,7 @@ Options:
|
|
191
196
|
--m INTEGER hnsw m
|
192
197
|
--ef-construction INTEGER hnsw ef-construction
|
193
198
|
--ef-search INTEGER hnsw ef-search
|
194
|
-
--quantization-type [none|halfvec]
|
199
|
+
--quantization-type [none|bit|halfvec]
|
195
200
|
quantization type for vectors
|
196
201
|
--custom-case-name TEXT Custom case name i.e. PerformanceCase1536D50K
|
197
202
|
--custom-case-description TEXT Custom name description
|