vectordb-bench 0.0.7__py3-none-any.whl → 0.0.9__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/backend/clients/__init__.py +4 -4
- vectordb_bench/backend/clients/api.py +1 -0
- vectordb_bench/backend/clients/milvus/milvus.py +2 -3
- vectordb_bench/backend/clients/pgvecto_rs/config.py +44 -32
- vectordb_bench/backend/clients/pgvecto_rs/pgvecto_rs.py +16 -16
- vectordb_bench/backend/clients/pgvector/config.py +178 -24
- vectordb_bench/backend/clients/pgvector/pgvector.py +244 -70
- vectordb_bench/backend/clients/qdrant_cloud/config.py +19 -6
- vectordb_bench/backend/clients/qdrant_cloud/qdrant_cloud.py +11 -7
- vectordb_bench/backend/runner/serial_runner.py +0 -2
- vectordb_bench/backend/task_runner.py +1 -1
- vectordb_bench/frontend/components/run_test/caseSelector.py +6 -3
- vectordb_bench/frontend/const/dbCaseConfigs.py +128 -3
- vectordb_bench/models.py +6 -3
- vectordb_bench/results/PgVector/result_20230727_standard_pgvector.json +8 -0
- vectordb_bench/results/PgVector/result_20230808_standard_pgvector.json +9 -3
- vectordb_bench/results/ZillizCloud/{result_20240105_beta_202401_zillizcloud.json → result_20240105_standard_202401_zillizcloud.json} +365 -41
- vectordb_bench/results/getLeaderboardData.py +1 -1
- vectordb_bench/results/leaderboard.json +1 -1
- {vectordb_bench-0.0.7.dist-info → vectordb_bench-0.0.9.dist-info}/METADATA +4 -3
- {vectordb_bench-0.0.7.dist-info → vectordb_bench-0.0.9.dist-info}/RECORD +25 -25
- {vectordb_bench-0.0.7.dist-info → vectordb_bench-0.0.9.dist-info}/LICENSE +0 -0
- {vectordb_bench-0.0.7.dist-info → vectordb_bench-0.0.9.dist-info}/WHEEL +0 -0
- {vectordb_bench-0.0.7.dist-info → vectordb_bench-0.0.9.dist-info}/entry_points.txt +0 -0
- {vectordb_bench-0.0.7.dist-info → vectordb_bench-0.0.9.dist-info}/top_level.txt +0 -0
@@ -1,25 +1,36 @@
|
|
1
1
|
"""Wrapper around the Pgvector vector database over VectorDB"""
|
2
2
|
|
3
|
-
import io
|
4
3
|
import logging
|
4
|
+
import pprint
|
5
5
|
from contextlib import contextmanager
|
6
|
-
from typing import Any
|
7
|
-
import pandas as pd
|
8
|
-
import psycopg2
|
9
|
-
import psycopg2.extras
|
6
|
+
from typing import Any, Generator, Optional, Tuple, Sequence
|
10
7
|
|
11
|
-
|
8
|
+
import numpy as np
|
9
|
+
import psycopg
|
10
|
+
from pgvector.psycopg import register_vector
|
11
|
+
from psycopg import Connection, Cursor, sql
|
12
|
+
|
13
|
+
from ..api import VectorDB
|
14
|
+
from .config import PgVectorConfigDict, PgVectorIndexConfig
|
15
|
+
|
16
|
+
log = logging.getLogger(__name__)
|
12
17
|
|
13
|
-
log = logging.getLogger(__name__)
|
14
18
|
|
15
19
|
class PgVector(VectorDB):
|
16
|
-
"""
|
20
|
+
"""Use psycopg instructions"""
|
21
|
+
|
22
|
+
conn: psycopg.Connection[Any] | None = None
|
23
|
+
cursor: psycopg.Cursor[Any] | None = None
|
24
|
+
|
25
|
+
# TODO add filters support
|
26
|
+
_unfiltered_search: sql.Composed
|
27
|
+
|
17
28
|
def __init__(
|
18
29
|
self,
|
19
30
|
dim: int,
|
20
|
-
db_config:
|
21
|
-
db_case_config:
|
22
|
-
collection_name: str = "
|
31
|
+
db_config: PgVectorConfigDict,
|
32
|
+
db_case_config: PgVectorIndexConfig,
|
33
|
+
collection_name: str = "pg_vector_collection",
|
23
34
|
drop_old: bool = False,
|
24
35
|
**kwargs,
|
25
36
|
):
|
@@ -29,44 +40,89 @@ class PgVector(VectorDB):
|
|
29
40
|
self.table_name = collection_name
|
30
41
|
self.dim = dim
|
31
42
|
|
32
|
-
self._index_name = "
|
43
|
+
self._index_name = "pgvector_index"
|
33
44
|
self._primary_field = "id"
|
34
45
|
self._vector_field = "embedding"
|
35
46
|
|
36
47
|
# construct basic units
|
37
|
-
self.conn =
|
38
|
-
|
39
|
-
self.cursor = self.conn.cursor()
|
40
|
-
|
48
|
+
self.conn, self.cursor = self._create_connection(**self.db_config)
|
49
|
+
|
41
50
|
# create vector extension
|
42
|
-
self.cursor.execute(
|
51
|
+
self.cursor.execute("CREATE EXTENSION IF NOT EXISTS vector")
|
43
52
|
self.conn.commit()
|
44
|
-
|
45
|
-
|
46
|
-
|
53
|
+
|
54
|
+
log.info(f"{self.name} config values: {self.db_config}\n{self.case_config}")
|
55
|
+
if not any(
|
56
|
+
(
|
57
|
+
self.case_config.create_index_before_load,
|
58
|
+
self.case_config.create_index_after_load,
|
59
|
+
)
|
60
|
+
):
|
61
|
+
err = f"{self.name} config must create an index using create_index_before_load and/or create_index_after_load"
|
62
|
+
log.error(err)
|
63
|
+
raise RuntimeError(
|
64
|
+
f"{err}\n{pprint.pformat(self.db_config)}\n{pprint.pformat(self.case_config)}"
|
65
|
+
)
|
66
|
+
|
67
|
+
if drop_old:
|
47
68
|
# self.pg_table.drop(pg_engine, checkfirst=True)
|
48
69
|
self._drop_index()
|
49
70
|
self._drop_table()
|
50
71
|
self._create_table(dim)
|
51
|
-
self.
|
52
|
-
|
72
|
+
if self.case_config.create_index_before_load:
|
73
|
+
self._create_index()
|
74
|
+
|
53
75
|
self.cursor.close()
|
54
76
|
self.conn.close()
|
55
77
|
self.cursor = None
|
56
78
|
self.conn = None
|
57
79
|
|
80
|
+
@staticmethod
|
81
|
+
def _create_connection(**kwargs) -> Tuple[Connection, Cursor]:
|
82
|
+
conn = psycopg.connect(**kwargs)
|
83
|
+
register_vector(conn)
|
84
|
+
conn.autocommit = False
|
85
|
+
cursor = conn.cursor()
|
86
|
+
|
87
|
+
assert conn is not None, "Connection is not initialized"
|
88
|
+
assert cursor is not None, "Cursor is not initialized"
|
89
|
+
|
90
|
+
return conn, cursor
|
91
|
+
|
58
92
|
@contextmanager
|
59
|
-
def init(self) -> None:
|
93
|
+
def init(self) -> Generator[None, None, None]:
|
60
94
|
"""
|
61
95
|
Examples:
|
62
96
|
>>> with self.init():
|
63
97
|
>>> self.insert_embeddings()
|
64
98
|
>>> self.search_embedding()
|
65
99
|
"""
|
66
|
-
|
67
|
-
self.conn.
|
68
|
-
|
69
|
-
|
100
|
+
|
101
|
+
self.conn, self.cursor = self._create_connection(**self.db_config)
|
102
|
+
|
103
|
+
# index configuration may have commands defined that we should set during each client session
|
104
|
+
session_options: Sequence[dict[str, Any]] = self.case_config.session_param()["session_options"]
|
105
|
+
|
106
|
+
if len(session_options) > 0:
|
107
|
+
for setting in session_options:
|
108
|
+
command = sql.SQL("SET {setting_name} " + "= {val};").format(
|
109
|
+
setting_name=sql.Identifier(setting['parameter']['setting_name']),
|
110
|
+
val=sql.Identifier(str(setting['parameter']['val'])),
|
111
|
+
)
|
112
|
+
log.debug(command.as_string(self.cursor))
|
113
|
+
self.cursor.execute(command)
|
114
|
+
self.conn.commit()
|
115
|
+
|
116
|
+
self._unfiltered_search = sql.Composed(
|
117
|
+
[
|
118
|
+
sql.SQL("SELECT id FROM public.{} ORDER BY embedding ").format(
|
119
|
+
sql.Identifier(self.table_name)
|
120
|
+
),
|
121
|
+
sql.SQL(self.case_config.search_param()["metric_fun_op"]),
|
122
|
+
sql.SQL(" %s::vector LIMIT %s::int"),
|
123
|
+
]
|
124
|
+
)
|
125
|
+
|
70
126
|
try:
|
71
127
|
yield
|
72
128
|
finally:
|
@@ -74,54 +130,170 @@ class PgVector(VectorDB):
|
|
74
130
|
self.conn.close()
|
75
131
|
self.cursor = None
|
76
132
|
self.conn = None
|
77
|
-
|
133
|
+
|
78
134
|
def _drop_table(self):
|
79
135
|
assert self.conn is not None, "Connection is not initialized"
|
80
136
|
assert self.cursor is not None, "Cursor is not initialized"
|
81
|
-
|
82
|
-
|
137
|
+
log.info(f"{self.name} client drop table : {self.table_name}")
|
138
|
+
|
139
|
+
self.cursor.execute(
|
140
|
+
sql.SQL("DROP TABLE IF EXISTS public.{table_name}").format(
|
141
|
+
table_name=sql.Identifier(self.table_name)
|
142
|
+
)
|
143
|
+
)
|
83
144
|
self.conn.commit()
|
84
|
-
|
145
|
+
|
85
146
|
def ready_to_load(self):
|
86
147
|
pass
|
87
148
|
|
88
149
|
def optimize(self):
|
89
|
-
|
90
|
-
|
150
|
+
self._post_insert()
|
151
|
+
|
91
152
|
def _post_insert(self):
|
92
153
|
log.info(f"{self.name} post insert before optimize")
|
93
|
-
self.
|
94
|
-
|
154
|
+
if self.case_config.create_index_after_load:
|
155
|
+
self._drop_index()
|
156
|
+
self._create_index()
|
95
157
|
|
96
|
-
def ready_to_search(self):
|
97
|
-
pass
|
98
|
-
|
99
158
|
def _drop_index(self):
|
100
159
|
assert self.conn is not None, "Connection is not initialized"
|
101
160
|
assert self.cursor is not None, "Cursor is not initialized"
|
102
|
-
|
103
|
-
|
161
|
+
log.info(f"{self.name} client drop index : {self._index_name}")
|
162
|
+
|
163
|
+
drop_index_sql = sql.SQL("DROP INDEX IF EXISTS {index_name}").format(
|
164
|
+
index_name=sql.Identifier(self._index_name)
|
165
|
+
)
|
166
|
+
log.debug(drop_index_sql.as_string(self.cursor))
|
167
|
+
self.cursor.execute(drop_index_sql)
|
104
168
|
self.conn.commit()
|
105
|
-
|
169
|
+
|
170
|
+
def _set_parallel_index_build_param(self):
|
171
|
+
assert self.conn is not None, "Connection is not initialized"
|
172
|
+
assert self.cursor is not None, "Cursor is not initialized"
|
173
|
+
|
174
|
+
index_param = self.case_config.index_param()
|
175
|
+
|
176
|
+
if index_param["maintenance_work_mem"] is not None:
|
177
|
+
self.cursor.execute(
|
178
|
+
sql.SQL("SET maintenance_work_mem TO {};").format(
|
179
|
+
index_param["maintenance_work_mem"]
|
180
|
+
)
|
181
|
+
)
|
182
|
+
self.cursor.execute(
|
183
|
+
sql.SQL("ALTER USER {} SET maintenance_work_mem TO {};").format(
|
184
|
+
sql.Identifier(self.db_config["user"]),
|
185
|
+
index_param["maintenance_work_mem"],
|
186
|
+
)
|
187
|
+
)
|
188
|
+
self.conn.commit()
|
189
|
+
|
190
|
+
if index_param["max_parallel_workers"] is not None:
|
191
|
+
self.cursor.execute(
|
192
|
+
sql.SQL("SET max_parallel_maintenance_workers TO '{}';").format(
|
193
|
+
index_param["max_parallel_workers"]
|
194
|
+
)
|
195
|
+
)
|
196
|
+
self.cursor.execute(
|
197
|
+
sql.SQL(
|
198
|
+
"ALTER USER {} SET max_parallel_maintenance_workers TO '{}';"
|
199
|
+
).format(
|
200
|
+
sql.Identifier(self.db_config["user"]),
|
201
|
+
index_param["max_parallel_workers"],
|
202
|
+
)
|
203
|
+
)
|
204
|
+
self.cursor.execute(
|
205
|
+
sql.SQL("SET max_parallel_workers TO '{}';").format(
|
206
|
+
index_param["max_parallel_workers"]
|
207
|
+
)
|
208
|
+
)
|
209
|
+
self.cursor.execute(
|
210
|
+
sql.SQL(
|
211
|
+
"ALTER USER {} SET max_parallel_workers TO '{}';"
|
212
|
+
).format(
|
213
|
+
sql.Identifier(self.db_config["user"]),
|
214
|
+
index_param["max_parallel_workers"],
|
215
|
+
)
|
216
|
+
)
|
217
|
+
self.cursor.execute(
|
218
|
+
sql.SQL(
|
219
|
+
"ALTER TABLE {} SET (parallel_workers = {});"
|
220
|
+
).format(
|
221
|
+
sql.Identifier(self.table_name),
|
222
|
+
index_param["max_parallel_workers"],
|
223
|
+
)
|
224
|
+
)
|
225
|
+
self.conn.commit()
|
226
|
+
|
227
|
+
results = self.cursor.execute(
|
228
|
+
sql.SQL("SHOW max_parallel_maintenance_workers;")
|
229
|
+
).fetchall()
|
230
|
+
results.extend(
|
231
|
+
self.cursor.execute(sql.SQL("SHOW max_parallel_workers;")).fetchall()
|
232
|
+
)
|
233
|
+
results.extend(
|
234
|
+
self.cursor.execute(sql.SQL("SHOW maintenance_work_mem;")).fetchall()
|
235
|
+
)
|
236
|
+
log.info(f"{self.name} parallel index creation parameters: {results}")
|
237
|
+
|
106
238
|
def _create_index(self):
|
107
239
|
assert self.conn is not None, "Connection is not initialized"
|
108
240
|
assert self.cursor is not None, "Cursor is not initialized"
|
109
|
-
|
241
|
+
log.info(f"{self.name} client create index : {self._index_name}")
|
242
|
+
|
110
243
|
index_param = self.case_config.index_param()
|
111
|
-
self.
|
244
|
+
self._set_parallel_index_build_param()
|
245
|
+
options = []
|
246
|
+
for option in index_param["index_creation_with_options"]:
|
247
|
+
if option['val'] is not None:
|
248
|
+
options.append(
|
249
|
+
sql.SQL("{option_name} = {val}").format(
|
250
|
+
option_name=sql.Identifier(option['option_name']),
|
251
|
+
val=sql.Identifier(str(option['val'])),
|
252
|
+
)
|
253
|
+
)
|
254
|
+
if any(options):
|
255
|
+
with_clause = sql.SQL("WITH ({});").format(sql.SQL(", ").join(options))
|
256
|
+
else:
|
257
|
+
with_clause = sql.Composed(())
|
258
|
+
|
259
|
+
index_create_sql = sql.SQL(
|
260
|
+
"CREATE INDEX IF NOT EXISTS {index_name} ON public.{table_name} USING {index_type} (embedding {embedding_metric})"
|
261
|
+
).format(
|
262
|
+
index_name=sql.Identifier(self._index_name),
|
263
|
+
table_name=sql.Identifier(self.table_name),
|
264
|
+
index_type=sql.Identifier(index_param["index_type"]),
|
265
|
+
embedding_metric=sql.Identifier(index_param["metric"]),
|
266
|
+
)
|
267
|
+
index_create_sql_with_with_clause = (
|
268
|
+
index_create_sql + with_clause
|
269
|
+
).join(" ")
|
270
|
+
log.debug(index_create_sql_with_with_clause.as_string(self.cursor))
|
271
|
+
self.cursor.execute(index_create_sql_with_with_clause)
|
112
272
|
self.conn.commit()
|
113
|
-
|
114
|
-
def _create_table(self, dim
|
273
|
+
|
274
|
+
def _create_table(self, dim: int):
|
115
275
|
assert self.conn is not None, "Connection is not initialized"
|
116
276
|
assert self.cursor is not None, "Cursor is not initialized"
|
117
|
-
|
277
|
+
|
118
278
|
try:
|
279
|
+
log.info(f"{self.name} client create table : {self.table_name}")
|
280
|
+
|
119
281
|
# create table
|
120
|
-
self.cursor.execute(
|
121
|
-
|
282
|
+
self.cursor.execute(
|
283
|
+
sql.SQL(
|
284
|
+
"CREATE TABLE IF NOT EXISTS public.{table_name} (id BIGINT PRIMARY KEY, embedding vector({dim}));"
|
285
|
+
).format(table_name=sql.Identifier(self.table_name), dim=dim)
|
286
|
+
)
|
287
|
+
self.cursor.execute(
|
288
|
+
sql.SQL(
|
289
|
+
"ALTER TABLE public.{table_name} ALTER COLUMN embedding SET STORAGE PLAIN;"
|
290
|
+
).format(table_name=sql.Identifier(self.table_name))
|
291
|
+
)
|
122
292
|
self.conn.commit()
|
123
293
|
except Exception as e:
|
124
|
-
log.warning(
|
294
|
+
log.warning(
|
295
|
+
f"Failed to create pgvector table: {self.table_name} error: {e}"
|
296
|
+
)
|
125
297
|
raise e from None
|
126
298
|
|
127
299
|
def insert_embeddings(
|
@@ -129,31 +301,35 @@ class PgVector(VectorDB):
|
|
129
301
|
embeddings: list[list[float]],
|
130
302
|
metadata: list[int],
|
131
303
|
**kwargs: Any,
|
132
|
-
) ->
|
304
|
+
) -> Tuple[int, Optional[Exception]]:
|
133
305
|
assert self.conn is not None, "Connection is not initialized"
|
134
306
|
assert self.cursor is not None, "Cursor is not initialized"
|
135
307
|
|
136
308
|
try:
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
309
|
+
metadata_arr = np.array(metadata)
|
310
|
+
embeddings_arr = np.array(embeddings)
|
311
|
+
|
312
|
+
with self.cursor.copy(
|
313
|
+
sql.SQL("COPY public.{table_name} FROM STDIN (FORMAT BINARY)").format(
|
314
|
+
table_name=sql.Identifier(self.table_name)
|
315
|
+
)
|
316
|
+
) as copy:
|
317
|
+
copy.set_types(["bigint", "vector"])
|
318
|
+
for i, row in enumerate(metadata_arr):
|
319
|
+
copy.write_row((row, embeddings_arr[i]))
|
146
320
|
self.conn.commit()
|
147
|
-
|
321
|
+
|
148
322
|
if kwargs.get("last_batch"):
|
149
323
|
self._post_insert()
|
150
|
-
|
324
|
+
|
151
325
|
return len(metadata), None
|
152
326
|
except Exception as e:
|
153
|
-
log.warning(
|
327
|
+
log.warning(
|
328
|
+
f"Failed to insert data into pgvector table ({self.table_name}), error: {e}"
|
329
|
+
)
|
154
330
|
return 0, e
|
155
331
|
|
156
|
-
def search_embedding(
|
332
|
+
def search_embedding(
|
157
333
|
self,
|
158
334
|
query: list[float],
|
159
335
|
k: int = 100,
|
@@ -163,11 +339,9 @@ class PgVector(VectorDB):
|
|
163
339
|
assert self.conn is not None, "Connection is not initialized"
|
164
340
|
assert self.cursor is not None, "Cursor is not initialized"
|
165
341
|
|
166
|
-
|
167
|
-
self.cursor.execute(
|
168
|
-
|
169
|
-
|
170
|
-
result = self.cursor.fetchall()
|
342
|
+
# TODO add filters support
|
343
|
+
result = self.cursor.execute(
|
344
|
+
self._unfiltered_search, (query, k), prepare=True, binary=True
|
345
|
+
)
|
171
346
|
|
172
|
-
return [int(i[0]) for i in result]
|
173
|
-
|
347
|
+
return [int(i[0]) for i in result.fetchall()]
|
@@ -1,18 +1,31 @@
|
|
1
1
|
from pydantic import BaseModel, SecretStr
|
2
2
|
|
3
3
|
from ..api import DBConfig, DBCaseConfig, MetricType
|
4
|
+
from pydantic import validator
|
4
5
|
|
5
|
-
|
6
|
+
# Allowing `api_key` to be left empty, to ensure compatibility with the open-source Qdrant.
|
6
7
|
class QdrantConfig(DBConfig):
|
7
8
|
url: SecretStr
|
8
9
|
api_key: SecretStr
|
9
10
|
|
10
11
|
def to_dict(self) -> dict:
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
api_key = self.api_key.get_secret_value()
|
13
|
+
if len(api_key) > 0:
|
14
|
+
return {
|
15
|
+
"url": self.url.get_secret_value(),
|
16
|
+
"api_key": self.api_key.get_secret_value(),
|
17
|
+
"prefer_grpc": True,
|
18
|
+
}
|
19
|
+
else:
|
20
|
+
return {"url": self.url.get_secret_value(),}
|
21
|
+
|
22
|
+
@validator("*")
|
23
|
+
def not_empty_field(cls, v, field):
|
24
|
+
if field.name in ["api_key", "db_label"]:
|
25
|
+
return v
|
26
|
+
if isinstance(v, (str, SecretStr)) and len(v) == 0:
|
27
|
+
raise ValueError("Empty string!")
|
28
|
+
return v
|
16
29
|
|
17
30
|
class QdrantIndexConfig(BaseModel, DBCaseConfig):
|
18
31
|
metric_type: MetricType | None = None
|
@@ -43,8 +43,7 @@ class QdrantCloud(VectorDB):
|
|
43
43
|
if drop_old:
|
44
44
|
log.info(f"QdrantCloud client drop_old collection: {self.collection_name}")
|
45
45
|
tmp_client.delete_collection(self.collection_name)
|
46
|
-
|
47
|
-
self._create_collection(dim, tmp_client)
|
46
|
+
self._create_collection(dim, tmp_client)
|
48
47
|
tmp_client = None
|
49
48
|
|
50
49
|
@contextmanager
|
@@ -110,13 +109,18 @@ class QdrantCloud(VectorDB):
|
|
110
109
|
) -> (int, Exception):
|
111
110
|
"""Insert embeddings into Milvus. should call self.init() first"""
|
112
111
|
assert self.qdrant_client is not None
|
112
|
+
QDRANT_BATCH_SIZE = 500
|
113
113
|
try:
|
114
114
|
# TODO: counts
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
115
|
+
for offset in range(0, len(embeddings), QDRANT_BATCH_SIZE):
|
116
|
+
vectors = embeddings[offset: offset + QDRANT_BATCH_SIZE]
|
117
|
+
ids = metadata[offset: offset + QDRANT_BATCH_SIZE]
|
118
|
+
payloads=[{self._primary_field: v} for v in ids]
|
119
|
+
_ = self.qdrant_client.upsert(
|
120
|
+
collection_name=self.collection_name,
|
121
|
+
wait=True,
|
122
|
+
points=Batch(ids=ids, payloads=payloads, vectors=vectors),
|
123
|
+
)
|
120
124
|
except Exception as e:
|
121
125
|
log.info(f"Failed to insert data, {e}")
|
122
126
|
return 0, e
|
@@ -46,11 +46,9 @@ class SerialInsertRunner:
|
|
46
46
|
del(emb_np)
|
47
47
|
log.debug(f"batch dataset size: {len(all_embeddings)}, {len(all_metadata)}")
|
48
48
|
|
49
|
-
last_batch = self.dataset.data.size - count == len(all_metadata)
|
50
49
|
insert_count, error = self.db.insert_embeddings(
|
51
50
|
embeddings=all_embeddings,
|
52
51
|
metadata=all_metadata,
|
53
|
-
last_batch=last_batch,
|
54
52
|
)
|
55
53
|
if error is not None:
|
56
54
|
raise error
|
@@ -140,8 +140,8 @@ class CaseRunner(BaseModel):
|
|
140
140
|
)
|
141
141
|
|
142
142
|
self._init_search_runner()
|
143
|
-
m.recall, m.serial_latency_p99 = self._serial_search()
|
144
143
|
m.qps = self._conc_search()
|
144
|
+
m.recall, m.serial_latency_p99 = self._serial_search()
|
145
145
|
except Exception as e:
|
146
146
|
log.warning(f"Failed to run performance case, reason = {e}")
|
147
147
|
traceback.print_exc()
|
@@ -65,25 +65,28 @@ def caseConfigSetting(st, allCaseConfigs, case, activedDbList):
|
|
65
65
|
key = "%s-%s-%s" % (db, case, config.label.value)
|
66
66
|
if config.inputType == InputType.Text:
|
67
67
|
caseConfig[config.label] = column.text_input(
|
68
|
-
config.label.value,
|
68
|
+
config.displayLabel if config.displayLabel else config.label.value,
|
69
69
|
key=key,
|
70
|
+
help=config.inputHelp,
|
70
71
|
value=config.inputConfig["value"],
|
71
72
|
)
|
72
73
|
elif config.inputType == InputType.Option:
|
73
74
|
caseConfig[config.label] = column.selectbox(
|
74
|
-
config.label.value,
|
75
|
+
config.displayLabel if config.displayLabel else config.label.value,
|
75
76
|
config.inputConfig["options"],
|
76
77
|
key=key,
|
78
|
+
help=config.inputHelp,
|
77
79
|
)
|
78
80
|
elif config.inputType == InputType.Number:
|
79
81
|
caseConfig[config.label] = column.number_input(
|
80
|
-
config.label.value,
|
82
|
+
config.displayLabel if config.displayLabel else config.label.value,
|
81
83
|
# format="%d",
|
82
84
|
step=config.inputConfig.get("step", 1),
|
83
85
|
min_value=config.inputConfig["min"],
|
84
86
|
max_value=config.inputConfig["max"],
|
85
87
|
key=key,
|
86
88
|
value=config.inputConfig["value"],
|
89
|
+
help=config.inputHelp,
|
87
90
|
)
|
88
91
|
k += 1
|
89
92
|
if k == 0:
|