vectordb-bench 0.0.25__py3-none-any.whl → 0.0.26__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.
@@ -16,10 +16,15 @@ class MetricType(str, Enum):
16
16
 
17
17
  class IndexType(str, Enum):
18
18
  HNSW = "HNSW"
19
+ HNSW_SQ = "HNSW_SQ"
20
+ HNSW_PQ = "HNSW_PQ"
21
+ HNSW_PRQ = "HNSW_PRQ"
19
22
  DISKANN = "DISKANN"
20
23
  STREAMING_DISKANN = "DISKANN"
21
24
  IVFFlat = "IVF_FLAT"
25
+ IVFPQ = "IVF_PQ"
22
26
  IVFSQ8 = "IVF_SQ8"
27
+ IVF_RABITQ = "IVF_RABITQ"
23
28
  Flat = "FLAT"
24
29
  AUTOINDEX = "AUTOINDEX"
25
30
  ES_HNSW = "hnsw"
@@ -31,6 +36,14 @@ class IndexType(str, Enum):
31
36
  SCANN = "scann"
32
37
 
33
38
 
39
+ class SQType(str, Enum):
40
+ SQ6 = "SQ6"
41
+ SQ8 = "SQ8"
42
+ BF16 = "BF16"
43
+ FP16 = "FP16"
44
+ FP32 = "FP32"
45
+
46
+
34
47
  class DBConfig(ABC, BaseModel):
35
48
  """DBConfig contains the connection info of vector database
36
49
 
@@ -5,8 +5,11 @@ from contextlib import contextmanager
5
5
  from typing import Any
6
6
 
7
7
  import clickhouse_connect
8
+ from clickhouse_connect.driver import Client
8
9
 
9
- from ..api import DBCaseConfig, VectorDB
10
+ from .. import IndexType
11
+ from ..api import VectorDB
12
+ from .config import ClickhouseConfigDict, ClickhouseIndexConfig
10
13
 
11
14
  log = logging.getLogger(__name__)
12
15
 
@@ -17,8 +20,8 @@ class Clickhouse(VectorDB):
17
20
  def __init__(
18
21
  self,
19
22
  dim: int,
20
- db_config: dict,
21
- db_case_config: DBCaseConfig,
23
+ db_config: ClickhouseConfigDict,
24
+ db_case_config: ClickhouseIndexConfig,
22
25
  collection_name: str = "CHVectorCollection",
23
26
  drop_old: bool = False,
24
27
  **kwargs,
@@ -28,29 +31,29 @@ class Clickhouse(VectorDB):
28
31
  self.table_name = collection_name
29
32
  self.dim = dim
30
33
 
34
+ self.index_param = self.case_config.index_param()
35
+ self.search_param = self.case_config.search_param()
36
+ self.session_param = self.case_config.session_param()
37
+
31
38
  self._index_name = "clickhouse_index"
32
39
  self._primary_field = "id"
33
40
  self._vector_field = "embedding"
34
41
 
35
42
  # construct basic units
36
- self.conn = clickhouse_connect.get_client(
37
- host=self.db_config["host"],
38
- port=self.db_config["port"],
39
- username=self.db_config["user"],
40
- password=self.db_config["password"],
41
- database=self.db_config["dbname"],
42
- )
43
+ self.conn = self._create_connection(**self.db_config, settings=self.session_param)
43
44
 
44
45
  if drop_old:
45
46
  log.info(f"Clickhouse client drop table : {self.table_name}")
46
47
  self._drop_table()
47
48
  self._create_table(dim)
49
+ if self.case_config.create_index_before_load:
50
+ self._create_index()
48
51
 
49
52
  self.conn.close()
50
53
  self.conn = None
51
54
 
52
55
  @contextmanager
53
- def init(self):
56
+ def init(self) -> None:
54
57
  """
55
58
  Examples:
56
59
  >>> with self.init():
@@ -58,13 +61,7 @@ class Clickhouse(VectorDB):
58
61
  >>> self.search_embedding()
59
62
  """
60
63
 
61
- self.conn = clickhouse_connect.get_client(
62
- host=self.db_config["host"],
63
- port=self.db_config["port"],
64
- username=self.db_config["user"],
65
- password=self.db_config["password"],
66
- database=self.db_config["dbname"],
67
- )
64
+ self.conn = self._create_connection(**self.db_config, settings=self.session_param)
68
65
 
69
66
  try:
70
67
  yield
@@ -72,10 +69,61 @@ class Clickhouse(VectorDB):
72
69
  self.conn.close()
73
70
  self.conn = None
74
71
 
72
+ def _create_connection(self, settings: dict | None, **kwargs) -> Client:
73
+ return clickhouse_connect.get_client(**self.db_config, settings=settings)
74
+
75
+ def _drop_index(self):
76
+ assert self.conn is not None, "Connection is not initialized"
77
+ try:
78
+ self.conn.command(
79
+ f'ALTER TABLE {self.db_config["database"]}.{self.table_name} DROP INDEX {self._index_name}'
80
+ )
81
+ except Exception as e:
82
+ log.warning(f"Failed to drop index on table {self.db_config['database']}.{self.table_name}: {e}")
83
+ raise e from None
84
+
75
85
  def _drop_table(self):
76
86
  assert self.conn is not None, "Connection is not initialized"
77
87
 
78
- self.conn.command(f'DROP TABLE IF EXISTS {self.db_config["dbname"]}.{self.table_name}')
88
+ try:
89
+ self.conn.command(f'DROP TABLE IF EXISTS {self.db_config["database"]}.{self.table_name}')
90
+ except Exception as e:
91
+ log.warning(f"Failed to drop table {self.db_config['database']}.{self.table_name}: {e}")
92
+ raise e from None
93
+
94
+ def _perfomance_tuning(self):
95
+ self.conn.command("SET materialize_skip_indexes_on_insert = 1")
96
+
97
+ def _create_index(self):
98
+ assert self.conn is not None, "Connection is not initialized"
99
+ try:
100
+ if self.index_param["index_type"] == IndexType.HNSW.value:
101
+ if (
102
+ self.index_param["quantization"]
103
+ and self.index_param["params"]["M"]
104
+ and self.index_param["params"]["efConstruction"]
105
+ ):
106
+ query = f"""
107
+ ALTER TABLE {self.db_config["database"]}.{self.table_name}
108
+ ADD INDEX {self._index_name} {self._vector_field}
109
+ TYPE vector_similarity('hnsw', '{self.index_param["metric_type"]}',
110
+ '{self.index_param["quantization"]}',
111
+ {self.index_param["params"]["M"]}, {self.index_param["params"]["efConstruction"]})
112
+ GRANULARITY {self.index_param["granularity"]}
113
+ """
114
+ else:
115
+ query = f"""
116
+ ALTER TABLE {self.db_config["database"]}.{self.table_name}
117
+ ADD INDEX {self._index_name} {self._vector_field}
118
+ TYPE vector_similarity('hnsw', '{self.index_param["metric_type"]}')
119
+ GRANULARITY {self.index_param["granularity"]}
120
+ """
121
+ self.conn.command(cmd=query)
122
+ else:
123
+ log.warning("HNSW is only avaliable method in clickhouse now")
124
+ except Exception as e:
125
+ log.warning(f"Failed to create Clickhouse vector index on table: {self.table_name} error: {e}")
126
+ raise e from None
79
127
 
80
128
  def _create_table(self, dim: int):
81
129
  assert self.conn is not None, "Connection is not initialized"
@@ -83,21 +131,22 @@ class Clickhouse(VectorDB):
83
131
  try:
84
132
  # create table
85
133
  self.conn.command(
86
- f'CREATE TABLE IF NOT EXISTS {self.db_config["dbname"]}.{self.table_name} \
87
- (id UInt32, embedding Array(Float64)) ENGINE = MergeTree() ORDER BY id;'
134
+ f'CREATE TABLE IF NOT EXISTS {self.db_config["database"]}.{self.table_name} '
135
+ f"({self._primary_field} UInt32, "
136
+ f'{self._vector_field} Array({self.index_param["vector_data_type"]}) CODEC(NONE), '
137
+ f"CONSTRAINT same_length CHECK length(embedding) = {dim}) "
138
+ f"ENGINE = MergeTree() "
139
+ f"ORDER BY {self._primary_field}"
88
140
  )
89
141
 
90
142
  except Exception as e:
91
143
  log.warning(f"Failed to create Clickhouse table: {self.table_name} error: {e}")
92
144
  raise e from None
93
145
 
94
- def ready_to_load(self):
95
- pass
96
-
97
146
  def optimize(self, data_size: int | None = None):
98
147
  pass
99
148
 
100
- def ready_to_search(self):
149
+ def _post_insert(self):
101
150
  pass
102
151
 
103
152
  def insert_embeddings(
@@ -105,7 +154,7 @@ class Clickhouse(VectorDB):
105
154
  embeddings: list[list[float]],
106
155
  metadata: list[int],
107
156
  **kwargs: Any,
108
- ) -> tuple[int, Exception]:
157
+ ) -> (int, Exception):
109
158
  assert self.conn is not None, "Connection is not initialized"
110
159
 
111
160
  try:
@@ -116,7 +165,7 @@ class Clickhouse(VectorDB):
116
165
  table=self.table_name,
117
166
  data=items,
118
167
  column_names=["id", "embedding"],
119
- column_type_names=["UInt32", "Array(Float64)"],
168
+ column_type_names=["UInt32", f'Array({self.index_param["vector_data_type"]})'],
120
169
  column_oriented=True,
121
170
  )
122
171
  return len(metadata), None
@@ -132,25 +181,52 @@ class Clickhouse(VectorDB):
132
181
  timeout: int | None = None,
133
182
  ) -> list[int]:
134
183
  assert self.conn is not None, "Connection is not initialized"
135
-
136
- index_param = self.case_config.index_param() # noqa: F841
137
- search_param = self.case_config.search_param()
138
-
139
- if filters:
140
- gt = filters.get("id")
141
- filter_sql = (
142
- f'SELECT id, {search_param["metric_type"]}(embedding,{query}) AS score ' # noqa: S608
143
- f'FROM {self.db_config["dbname"]}.{self.table_name} '
144
- f"WHERE id > {gt} "
145
- f"ORDER BY score LIMIT {k};"
146
- )
147
- result = self.conn.query(filter_sql).result_rows
184
+ parameters = {
185
+ "primary_field": self._primary_field,
186
+ "vector_field": self._vector_field,
187
+ "schema": self.db_config["database"],
188
+ "table": self.table_name,
189
+ "gt": filters.get("id"),
190
+ "k": k,
191
+ "metric_type": self.search_param["metric_type"],
192
+ "query": query,
193
+ }
194
+ if self.case_config.metric_type == "COSINE":
195
+ if filters:
196
+ result = self.conn.query(
197
+ "SELECT {primary_field:Identifier}, {vector_field:Identifier} "
198
+ "FROM {schema:Identifier}.{table:Identifier} "
199
+ "WHERE {primary_field:Identifier} > {gt:UInt32} "
200
+ "ORDER BY cosineDistance(embedding,{query:Array(Float64)}) "
201
+ "LIMIT {k:UInt32}",
202
+ parameters=parameters,
203
+ ).result_rows
204
+ return [int(row[0]) for row in result]
205
+
206
+ result = self.conn.query(
207
+ "SELECT {primary_field:Identifier}, {vector_field:Identifier} "
208
+ "FROM {schema:Identifier}.{table:Identifier} "
209
+ "ORDER BY cosineDistance(embedding,{query:Array(Float64)}) "
210
+ "LIMIT {k:UInt32}",
211
+ parameters=parameters,
212
+ ).result_rows
148
213
  return [int(row[0]) for row in result]
149
- else: # noqa: RET505
150
- select_sql = (
151
- f'SELECT id, {search_param["metric_type"]}(embedding,{query}) AS score ' # noqa: S608
152
- f'FROM {self.db_config["dbname"]}.{self.table_name} '
153
- f"ORDER BY score LIMIT {k};"
154
- )
155
- result = self.conn.query(select_sql).result_rows
214
+ if filters:
215
+ result = self.conn.query(
216
+ "SELECT {primary_field:Identifier}, {vector_field:Identifier} "
217
+ "FROM {schema:Identifier}.{table:Identifier} "
218
+ "WHERE {primary_field:Identifier} > {gt:UInt32} "
219
+ "ORDER BY L2Distance(embedding,{query:Array(Float64)}) "
220
+ "LIMIT {k:UInt32}",
221
+ parameters=parameters,
222
+ ).result_rows
156
223
  return [int(row[0]) for row in result]
224
+
225
+ result = self.conn.query(
226
+ "SELECT {primary_field:Identifier}, {vector_field:Identifier} "
227
+ "FROM {schema:Identifier}.{table:Identifier} "
228
+ "ORDER BY L2Distance(embedding,{query:Array(Float64)}) "
229
+ "LIMIT {k:UInt32}",
230
+ parameters=parameters,
231
+ ).result_rows
232
+ return [int(row[0]) for row in result]
@@ -1,29 +1,46 @@
1
+ from abc import abstractmethod
2
+ from typing import TypedDict
3
+
1
4
  from pydantic import BaseModel, SecretStr
2
5
 
3
6
  from ..api import DBCaseConfig, DBConfig, IndexType, MetricType
4
7
 
5
8
 
9
+ class ClickhouseConfigDict(TypedDict):
10
+ user: str
11
+ password: str
12
+ host: str
13
+ port: int
14
+ database: str
15
+ secure: bool
16
+
17
+
6
18
  class ClickhouseConfig(DBConfig):
7
19
  user_name: str = "clickhouse"
8
20
  password: SecretStr
9
21
  host: str = "localhost"
10
22
  port: int = 8123
11
23
  db_name: str = "default"
24
+ secure: bool = False
12
25
 
13
- def to_dict(self) -> dict:
26
+ def to_dict(self) -> ClickhouseConfigDict:
14
27
  pwd_str = self.password.get_secret_value()
15
28
  return {
16
29
  "host": self.host,
17
30
  "port": self.port,
18
- "dbname": self.db_name,
31
+ "database": self.db_name,
19
32
  "user": self.user_name,
20
33
  "password": pwd_str,
34
+ "secure": self.secure,
21
35
  }
22
36
 
23
37
 
24
- class ClickhouseIndexConfig(BaseModel):
38
+ class ClickhouseIndexConfig(BaseModel, DBCaseConfig):
25
39
 
26
40
  metric_type: MetricType | None = None
41
+ vector_data_type: str | None = "Float32" # Data type of vectors. Can be Float32 or Float64 or BFloat16
42
+ create_index_before_load: bool = True
43
+ create_index_after_load: bool = False
27
44
 
28
45
  def parse_metric(self) -> str:
29
46
  if not self.metric_type:
@@ -35,26 +52,38 @@ class ClickhouseIndexConfig(BaseModel):
35
52
  return "L2Distance"
36
53
  if self.metric_type == MetricType.COSINE:
37
54
  return "cosineDistance"
38
- msg = f"Not Support for {self.metric_type}"
39
- raise RuntimeError(msg)
40
- return None
55
+ return "cosineDistance"
56
+
57
+ @abstractmethod
58
+ def session_param(self):
59
+ pass
41
60
 
42
61
 
43
- class ClickhouseHNSWConfig(ClickhouseIndexConfig, DBCaseConfig):
44
- M: int | None
45
- efConstruction: int | None
62
+ class ClickhouseHNSWConfig(ClickhouseIndexConfig):
63
+ M: int | None # Default in clickhouse in 32
64
+ efConstruction: int | None # Default in clickhouse in 128
46
65
  ef: int | None = None
47
66
  index: IndexType = IndexType.HNSW
67
+ quantization: str | None = "bf16" # Default is bf16. Possible values are f64, f32, f16, bf16, or i8
68
+ granularity: int | None = 10_000_000 # Size of the index granules. By default, in CH it's equal 10.000.000
48
69
 
49
70
  def index_param(self) -> dict:
50
71
  return {
72
+ "vector_data_type": self.vector_data_type,
51
73
  "metric_type": self.parse_metric_str(),
52
74
  "index_type": self.index.value,
75
+ "quantization": self.quantization,
76
+ "granularity": self.granularity,
53
77
  "params": {"M": self.M, "efConstruction": self.efConstruction},
54
78
  }
55
79
 
56
80
  def search_param(self) -> dict:
57
81
  return {
58
- "met˝ric_type": self.parse_metric_str(),
82
+ "metric_type": self.parse_metric_str(),
59
83
  "params": {"ef": self.ef},
60
84
  }
85
+
86
+ def session_param(self) -> dict:
87
+ return {
88
+ "allow_experimental_vector_similarity_index": 1,
89
+ }
@@ -1,6 +1,6 @@
1
1
  from pydantic import BaseModel, SecretStr, validator
2
2
 
3
- from ..api import DBCaseConfig, DBConfig, IndexType, MetricType
3
+ from ..api import DBCaseConfig, DBConfig, IndexType, MetricType, SQType
4
4
 
5
5
 
6
6
  class MilvusConfig(DBConfig):
@@ -88,6 +88,88 @@ class HNSWConfig(MilvusIndexConfig, DBCaseConfig):
88
88
  }
89
89
 
90
90
 
91
+ class HNSWSQConfig(HNSWConfig, DBCaseConfig):
92
+ index: IndexType = IndexType.HNSW_SQ
93
+ sq_type: SQType = SQType.SQ8
94
+ refine: bool = True
95
+ refine_type: SQType = SQType.FP32
96
+ refine_k: float = 1
97
+
98
+ def index_param(self) -> dict:
99
+ return {
100
+ "metric_type": self.parse_metric(),
101
+ "index_type": self.index.value,
102
+ "params": {
103
+ "M": self.M,
104
+ "efConstruction": self.efConstruction,
105
+ "sq_type": self.sq_type.value,
106
+ "refine": self.refine,
107
+ "refine_type": self.refine_type.value,
108
+ },
109
+ }
110
+
111
+ def search_param(self) -> dict:
112
+ return {
113
+ "metric_type": self.parse_metric(),
114
+ "params": {"ef": self.ef, "refine_k": self.refine_k},
115
+ }
116
+
117
+
118
+ class HNSWPQConfig(HNSWConfig):
119
+ index: IndexType = IndexType.HNSW_PQ
120
+ m: int = 32
121
+ nbits: int = 8
122
+ refine: bool = True
123
+ refine_type: SQType = SQType.FP32
124
+ refine_k: float = 1
125
+
126
+ def index_param(self) -> dict:
127
+ return {
128
+ "metric_type": self.parse_metric(),
129
+ "index_type": self.index.value,
130
+ "params": {
131
+ "M": self.M,
132
+ "efConstruction": self.efConstruction,
133
+ "m": self.m,
134
+ "nbits": self.nbits,
135
+ "refine": self.refine,
136
+ "refine_type": self.refine_type.value,
137
+ },
138
+ }
139
+
140
+ def search_param(self) -> dict:
141
+ return {
142
+ "metric_type": self.parse_metric(),
143
+ "params": {"ef": self.ef, "refine_k": self.refine_k},
144
+ }
145
+
146
+
147
+ class HNSWPRQConfig(HNSWPQConfig):
148
+ index: IndexType = IndexType.HNSW_PRQ
149
+ nrq: int = 2
150
+
151
+ def index_param(self) -> dict:
152
+ return {
153
+ "metric_type": self.parse_metric(),
154
+ "index_type": self.index.value,
155
+ "params": {
156
+ "M": self.M,
157
+ "efConstruction": self.efConstruction,
158
+ "m": self.m,
159
+ "nbits": self.nbits,
160
+ "nrq": self.nrq,
161
+ "refine": self.refine,
162
+ "refine_type": self.refine_type.value,
163
+ },
164
+ }
165
+
166
+ def search_param(self) -> dict:
167
+ return {
168
+ "metric_type": self.parse_metric(),
169
+ "params": {"ef": self.ef, "refine_k": self.refine_k},
170
+ }
171
+
172
+
91
173
  class DISKANNConfig(MilvusIndexConfig, DBCaseConfig):
92
174
  search_list: int | None = None
93
175
  index: IndexType = IndexType.DISKANN
@@ -125,6 +207,27 @@ class IVFFlatConfig(MilvusIndexConfig, DBCaseConfig):
125
207
  }
126
208
 
127
209
 
210
+ class IVFPQConfig(MilvusIndexConfig, DBCaseConfig):
211
+ nlist: int
212
+ nprobe: int | None = None
213
+ m: int = 32
214
+ nbits: int = 8
215
+ index: IndexType = IndexType.IVFPQ
216
+
217
+ def index_param(self) -> dict:
218
+ return {
219
+ "metric_type": self.parse_metric(),
220
+ "index_type": self.index.value,
221
+ "params": {"nlist": self.nlist, "m": self.m, "nbits": self.nbits},
222
+ }
223
+
224
+ def search_param(self) -> dict:
225
+ return {
226
+ "metric_type": self.parse_metric(),
227
+ "params": {"nprobe": self.nprobe},
228
+ }
229
+
230
+
128
231
  class IVFSQ8Config(MilvusIndexConfig, DBCaseConfig):
129
232
  nlist: int
130
233
  nprobe: int | None = None
@@ -144,6 +247,31 @@ class IVFSQ8Config(MilvusIndexConfig, DBCaseConfig):
144
247
  }
145
248
 
146
249
 
250
+ class IVFRABITQConfig(IVFSQ8Config):
251
+ index: IndexType = IndexType.IVF_RABITQ
252
+ rbq_bits_query: int = 0 # 0, 1, 2, ..., 8
253
+ refine: bool = True
254
+ refine_type: SQType = SQType.FP32
255
+ refine_k: float = 1
256
+
257
+ def index_param(self) -> dict:
258
+ return {
259
+ "metric_type": self.parse_metric(),
260
+ "index_type": self.index.value,
261
+ "params": {
262
+ "nlist": self.nlist,
263
+ "refine": self.refine,
264
+ "refine_type": self.refine_type.value,
265
+ },
266
+ }
267
+
268
+ def search_param(self) -> dict:
269
+ return {
270
+ "metric_type": self.parse_metric(),
271
+ "params": {"nprobe": self.nprobe, "rbq_bits_query": self.rbq_bits_query, "refine_k": self.refine_k},
272
+ }
273
+
274
+
147
275
  class FLATConfig(MilvusIndexConfig, DBCaseConfig):
148
276
  index: IndexType = IndexType.Flat
149
277
 
@@ -285,9 +413,14 @@ class GPUCAGRAConfig(MilvusIndexConfig, DBCaseConfig):
285
413
  _milvus_case_config = {
286
414
  IndexType.AUTOINDEX: AutoIndexConfig,
287
415
  IndexType.HNSW: HNSWConfig,
416
+ IndexType.HNSW_SQ: HNSWSQConfig,
417
+ IndexType.HNSW_PQ: HNSWPQConfig,
418
+ IndexType.HNSW_PRQ: HNSWPRQConfig,
288
419
  IndexType.DISKANN: DISKANNConfig,
289
420
  IndexType.IVFFlat: IVFFlatConfig,
421
+ IndexType.IVFPQ: IVFPQConfig,
290
422
  IndexType.IVFSQ8: IVFSQ8Config,
423
+ IndexType.IVF_RABITQ: IVFRABITQConfig,
291
424
  IndexType.Flat: FLATConfig,
292
425
  IndexType.GPU_IVF_FLAT: GPUIVFFlatConfig,
293
426
  IndexType.GPU_IVF_PQ: GPUIVFPQConfig,
@@ -61,6 +61,7 @@ class Milvus(VectorDB):
61
61
  consistency_level="Session",
62
62
  )
63
63
 
64
+ log.info(f"{self.name} create index: index_params: {self.case_config.index_param()}")
64
65
  col.create_index(
65
66
  self._vector_field,
66
67
  self.case_config.index_param(),
@@ -71,7 +72,7 @@ class Milvus(VectorDB):
71
72
  connections.disconnect("default")
72
73
 
73
74
  @contextmanager
74
- def init(self) -> None:
75
+ def init(self):
75
76
  """
76
77
  Examples:
77
78
  >>> with self.init():
@@ -126,6 +127,7 @@ class Milvus(VectorDB):
126
127
  try:
127
128
  self.col.compact()
128
129
  self.col.wait_for_compaction_completed()
130
+ log.info("compactation completed. waiting for the rest of index buliding.")
129
131
  except Exception as e:
130
132
  log.warning(f"{self.name} compact error: {e}")
131
133
  if hasattr(e, "code"):
@@ -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, MetricType
6
+ from vectordb_bench.backend.clients.api import IndexType, MetricType, SQType
7
7
  from vectordb_bench.frontend.components.custom.getCustomConfig import get_custom_configs
8
8
 
9
9
  from vectordb_bench.models import CaseConfig, CaseConfigParamType
@@ -164,10 +164,14 @@ CaseConfigParamInput_IndexType = CaseConfigInput(
164
164
  inputConfig={
165
165
  "options": [
166
166
  IndexType.HNSW.value,
167
+ IndexType.HNSW_SQ.value,
168
+ IndexType.HNSW_PQ.value,
169
+ IndexType.HNSW_PRQ.value,
167
170
  IndexType.IVFFlat.value,
171
+ IndexType.IVFPQ.value,
168
172
  IndexType.IVFSQ8.value,
173
+ IndexType.IVF_RABITQ.value,
169
174
  IndexType.DISKANN.value,
170
- IndexType.STREAMING_DISKANN.value,
171
175
  IndexType.Flat.value,
172
176
  IndexType.AUTOINDEX.value,
173
177
  IndexType.GPU_IVF_FLAT.value,
@@ -346,9 +350,16 @@ CaseConfigParamInput_M = CaseConfigInput(
346
350
  "max": 64,
347
351
  "value": 30,
348
352
  },
349
- isDisplayed=lambda config: config.get(CaseConfigParamType.IndexType, None) == IndexType.HNSW.value,
353
+ isDisplayed=lambda config: config.get(CaseConfigParamType.IndexType, None)
354
+ in [
355
+ IndexType.HNSW.value,
356
+ IndexType.HNSW_SQ.value,
357
+ IndexType.HNSW_PQ.value,
358
+ IndexType.HNSW_PRQ.value,
359
+ ],
350
360
  )
351
361
 
362
+
352
363
  CaseConfigParamInput_m = CaseConfigInput(
353
364
  label=CaseConfigParamType.m,
354
365
  inputType=InputType.Number,
@@ -369,7 +380,62 @@ CaseConfigParamInput_EFConstruction_Milvus = CaseConfigInput(
369
380
  "max": 512,
370
381
  "value": 360,
371
382
  },
372
- isDisplayed=lambda config: config[CaseConfigParamType.IndexType] == IndexType.HNSW.value,
383
+ isDisplayed=lambda config: config[CaseConfigParamType.IndexType]
384
+ in [
385
+ IndexType.HNSW.value,
386
+ IndexType.HNSW_SQ.value,
387
+ IndexType.HNSW_PQ.value,
388
+ IndexType.HNSW_PRQ.value,
389
+ ],
390
+ )
391
+
392
+ CaseConfigParamInput_SQType = CaseConfigInput(
393
+ label=CaseConfigParamType.sq_type,
394
+ inputType=InputType.Option,
395
+ inputHelp="Scalar quantizer type.",
396
+ inputConfig={
397
+ "options": [SQType.SQ6.value, SQType.SQ8.value, SQType.BF16.value, SQType.FP16.value, SQType.FP32.value]
398
+ },
399
+ isDisplayed=lambda config: config.get(CaseConfigParamType.IndexType, None) in [IndexType.HNSW_SQ.value],
400
+ )
401
+
402
+ CaseConfigParamInput_Refine = CaseConfigInput(
403
+ label=CaseConfigParamType.refine,
404
+ inputType=InputType.Option,
405
+ inputHelp="Whether refined data is reserved during index building.",
406
+ inputConfig={"options": [True, False]},
407
+ isDisplayed=lambda config: config.get(CaseConfigParamType.IndexType, None)
408
+ in [IndexType.HNSW_SQ.value, IndexType.HNSW_PQ.value, IndexType.HNSW_PRQ.value, IndexType.IVF_RABITQ.value],
409
+ )
410
+
411
+ CaseConfigParamInput_RefineType = CaseConfigInput(
412
+ label=CaseConfigParamType.refine_type,
413
+ inputType=InputType.Option,
414
+ inputHelp="The data type of the refine index.",
415
+ inputConfig={
416
+ "options": [SQType.FP32.value, SQType.FP16.value, SQType.BF16.value, SQType.SQ8.value, SQType.SQ6.value]
417
+ },
418
+ isDisplayed=lambda config: config.get(CaseConfigParamType.IndexType, None)
419
+ in [IndexType.HNSW_SQ.value, IndexType.HNSW_PQ.value, IndexType.HNSW_PRQ.value, IndexType.IVF_RABITQ.value]
420
+ and config.get(CaseConfigParamType.refine, True),
421
+ )
422
+
423
+ CaseConfigParamInput_RefineK = CaseConfigInput(
424
+ label=CaseConfigParamType.refine_k,
425
+ inputType=InputType.Float,
426
+ inputHelp="The magnification factor of refine compared to k.",
427
+ inputConfig={"min": 1.0, "max": 10000.0, "value": 1.0},
428
+ isDisplayed=lambda config: config.get(CaseConfigParamType.IndexType, None)
429
+ in [IndexType.HNSW_SQ.value, IndexType.HNSW_PQ.value, IndexType.HNSW_PRQ.value, IndexType.IVF_RABITQ.value]
430
+ and config.get(CaseConfigParamType.refine, True),
431
+ )
432
+
433
+ CaseConfigParamInput_RBQBitsQuery = CaseConfigInput(
434
+ label=CaseConfigParamType.rbq_bits_query,
435
+ inputType=InputType.Number,
436
+ inputHelp="The magnification factor of refine compared to k.",
437
+ inputConfig={"min": 0, "max": 8, "value": 0},
438
+ isDisplayed=lambda config: config.get(CaseConfigParamType.IndexType, None) in [IndexType.IVF_RABITQ.value],
373
439
  )
374
440
 
375
441
  CaseConfigParamInput_EFConstruction_Weaviate = CaseConfigInput(
@@ -519,7 +585,13 @@ CaseConfigParamInput_EF_Milvus = CaseConfigInput(
519
585
  "max": MAX_STREAMLIT_INT,
520
586
  "value": 100,
521
587
  },
522
- isDisplayed=lambda config: config[CaseConfigParamType.IndexType] == IndexType.HNSW.value,
588
+ isDisplayed=lambda config: config[CaseConfigParamType.IndexType]
589
+ in [
590
+ IndexType.HNSW.value,
591
+ IndexType.HNSW_SQ.value,
592
+ IndexType.HNSW_PQ.value,
593
+ IndexType.HNSW_PRQ.value,
594
+ ],
523
595
  )
524
596
 
525
597
  CaseConfigParamInput_EF_Weaviate = CaseConfigInput(
@@ -560,7 +632,9 @@ CaseConfigParamInput_Nlist = CaseConfigInput(
560
632
  isDisplayed=lambda config: config.get(CaseConfigParamType.IndexType, None)
561
633
  in [
562
634
  IndexType.IVFFlat.value,
635
+ IndexType.IVFPQ.value,
563
636
  IndexType.IVFSQ8.value,
637
+ IndexType.IVF_RABITQ.value,
564
638
  IndexType.GPU_IVF_FLAT.value,
565
639
  IndexType.GPU_IVF_PQ.value,
566
640
  IndexType.GPU_BRUTE_FORCE.value,
@@ -578,7 +652,9 @@ CaseConfigParamInput_Nprobe = CaseConfigInput(
578
652
  isDisplayed=lambda config: config.get(CaseConfigParamType.IndexType, None)
579
653
  in [
580
654
  IndexType.IVFFlat.value,
655
+ IndexType.IVFPQ.value,
581
656
  IndexType.IVFSQ8.value,
657
+ IndexType.IVF_RABITQ.value,
582
658
  IndexType.GPU_IVF_FLAT.value,
583
659
  IndexType.GPU_IVF_PQ.value,
584
660
  IndexType.GPU_BRUTE_FORCE.value,
@@ -589,11 +665,12 @@ CaseConfigParamInput_M_PQ = CaseConfigInput(
589
665
  label=CaseConfigParamType.m,
590
666
  inputType=InputType.Number,
591
667
  inputConfig={
592
- "min": 0,
668
+ "min": 1,
593
669
  "max": 65536,
594
- "value": 0,
670
+ "value": 32,
595
671
  },
596
- isDisplayed=lambda config: config.get(CaseConfigParamType.IndexType, None) in [IndexType.GPU_IVF_PQ.value],
672
+ isDisplayed=lambda config: config.get(CaseConfigParamType.IndexType, None)
673
+ in [IndexType.GPU_IVF_PQ.value, IndexType.HNSW_PQ.value, IndexType.HNSW_PRQ.value, IndexType.IVFPQ.value],
597
674
  )
598
675
 
599
676
 
@@ -605,7 +682,20 @@ CaseConfigParamInput_Nbits_PQ = CaseConfigInput(
605
682
  "max": 65536,
606
683
  "value": 8,
607
684
  },
608
- isDisplayed=lambda config: config.get(CaseConfigParamType.IndexType, None) in [IndexType.GPU_IVF_PQ.value],
685
+ isDisplayed=lambda config: config.get(CaseConfigParamType.IndexType, None)
686
+ in [IndexType.GPU_IVF_PQ.value, IndexType.HNSW_PQ.value, IndexType.HNSW_PRQ.value, IndexType.IVFPQ.value],
687
+ )
688
+
689
+ CaseConfigParamInput_NRQ = CaseConfigInput(
690
+ label=CaseConfigParamType.nrq,
691
+ inputType=InputType.Number,
692
+ inputHelp="The number of residual subquantizers.",
693
+ inputConfig={
694
+ "min": 1,
695
+ "max": 16,
696
+ "value": 2,
697
+ },
698
+ isDisplayed=lambda config: config.get(CaseConfigParamType.IndexType, None) in [IndexType.HNSW_PRQ.value],
609
699
  )
610
700
 
611
701
  CaseConfigParamInput_intermediate_graph_degree = CaseConfigInput(
@@ -1186,6 +1276,10 @@ MilvusLoadConfig = [
1186
1276
  CaseConfigParamInput_graph_degree,
1187
1277
  CaseConfigParamInput_build_algo,
1188
1278
  CaseConfigParamInput_cache_dataset_on_device,
1279
+ CaseConfigParamInput_SQType,
1280
+ CaseConfigParamInput_Refine,
1281
+ CaseConfigParamInput_RefineType,
1282
+ CaseConfigParamInput_NRQ,
1189
1283
  ]
1190
1284
  MilvusPerformanceConfig = [
1191
1285
  CaseConfigParamInput_IndexType,
@@ -1197,6 +1291,8 @@ MilvusPerformanceConfig = [
1197
1291
  CaseConfigParamInput_Nprobe,
1198
1292
  CaseConfigParamInput_M_PQ,
1199
1293
  CaseConfigParamInput_Nbits_PQ,
1294
+ CaseConfigParamInput_RBQBitsQuery,
1295
+ CaseConfigParamInput_NRQ,
1200
1296
  CaseConfigParamInput_intermediate_graph_degree,
1201
1297
  CaseConfigParamInput_graph_degree,
1202
1298
  CaseConfigParamInput_itopk_size,
@@ -1207,6 +1303,10 @@ MilvusPerformanceConfig = [
1207
1303
  CaseConfigParamInput_build_algo,
1208
1304
  CaseConfigParamInput_cache_dataset_on_device,
1209
1305
  CaseConfigParamInput_refine_ratio,
1306
+ CaseConfigParamInput_SQType,
1307
+ CaseConfigParamInput_Refine,
1308
+ CaseConfigParamInput_RefineType,
1309
+ CaseConfigParamInput_RefineK,
1210
1310
  ]
1211
1311
 
1212
1312
  WeaviateLoadConfig = [
vectordb_bench/models.py CHANGED
@@ -55,6 +55,7 @@ class CaseConfigParamType(Enum):
55
55
  quantizedFetchLimit = "quantized_fetch_limit"
56
56
  m = "m"
57
57
  nbits = "nbits"
58
+ nrq = "nrq"
58
59
  intermediate_graph_degree = "intermediate_graph_degree"
59
60
  graph_degree = "graph_degree"
60
61
  itopk_size = "itopk_size"
@@ -65,6 +66,11 @@ class CaseConfigParamType(Enum):
65
66
  build_algo = "build_algo"
66
67
  cache_dataset_on_device = "cache_dataset_on_device"
67
68
  refine_ratio = "refine_ratio"
69
+ refine = "refine"
70
+ refine_type = "refine_type"
71
+ refine_k = "refine_k"
72
+ rbq_bits_query = "rbq_bits_query"
73
+ sq_type = "sq_type"
68
74
  level = "level"
69
75
  maintenance_work_mem = "maintenance_work_mem"
70
76
  max_parallel_workers = "max_parallel_workers"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: vectordb-bench
3
- Version: 0.0.25
3
+ Version: 0.0.26
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
@@ -4,7 +4,7 @@ vectordb_bench/base.py,sha256=AgavIF0P9ku_RmCRk1KKziba-wI4ZpA2aJvjJzNhRSs,129
4
4
  vectordb_bench/interface.py,sha256=XaCjTgUeI17uVjsgOauPeVlkvnkuCyQOWyOaWhrgCt8,9811
5
5
  vectordb_bench/log_util.py,sha256=wDNaU_JBBOfKi_Z4vq7LDa0kOlLjoNNzDX3VZQn_Dxo,3239
6
6
  vectordb_bench/metric.py,sha256=pj-AxQHyIRHTaJY-wTIkTbC6TqEqMzt3kcEmMWEv71w,2063
7
- vectordb_bench/models.py,sha256=yj7WXKPpKgtyRXuLor7VbYdNQpQ5uIDT1EgWnLb9DIc,11339
7
+ vectordb_bench/models.py,sha256=VCnmfvAr7Grtbe6EsixCq9aVdc2F14RBHXO7uJppuB4,11497
8
8
  vectordb_bench/backend/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
9
  vectordb_bench/backend/assembler.py,sha256=6GInRT7yBgfTaIPmo-XMkYX4pA8PJQmjMQInynwaunE,2047
10
10
  vectordb_bench/backend/cases.py,sha256=obDdY6g3p9Z2fog7qDwLLDuRMwo3LGQKMHsP66QZd2M,16296
@@ -14,7 +14,7 @@ vectordb_bench/backend/result_collector.py,sha256=mpROVdZ-HChKBVyMV5TZ5v7YGRb69b
14
14
  vectordb_bench/backend/task_runner.py,sha256=vlaXB0_25-G9w1Lj-F0SrvJzhXT7ceDWGIb2aKRXukU,11488
15
15
  vectordb_bench/backend/utils.py,sha256=R6THuJdZhiQYSSJTqv0Uegl2B20taV_QjwvFrun2yxE,1949
16
16
  vectordb_bench/backend/clients/__init__.py,sha256=M7qjlpe_65OJKttYXItC8szczqzCm_vptM-7XGtL_HA,10128
17
- vectordb_bench/backend/clients/api.py,sha256=6uPex7vc88tpCzFbFgd29zNHx9mOKJBQliGwfzjfll0,6278
17
+ vectordb_bench/backend/clients/api.py,sha256=m-vEypHJZrSMr5Di5zs3ImOSzVV2O5imMM3jfUAQmSs,6516
18
18
  vectordb_bench/backend/clients/aliyun_elasticsearch/aliyun_elasticsearch.py,sha256=7yPYaWoHeHNxDMtpReGXsdEPFD1e4vQblFor7TmLq5o,770
19
19
  vectordb_bench/backend/clients/aliyun_elasticsearch/config.py,sha256=d9RCgfCgauKvy6z9ig_wBormgwiGtkh8POyoHloHnJA,505
20
20
  vectordb_bench/backend/clients/aliyun_opensearch/aliyun_opensearch.py,sha256=rwa4rtbbP2Kaczh7Bf0bc_lE_sGG5w9PhtfdFu7rQNs,13237
@@ -29,8 +29,8 @@ vectordb_bench/backend/clients/aws_opensearch/run.py,sha256=Ry5aAlielWjq0hx7Lnbd
29
29
  vectordb_bench/backend/clients/chroma/chroma.py,sha256=Aqo6AlSWd0TG0SR4cr9AEoLzXtOJ5VNhbIucHnm8NxY,3619
30
30
  vectordb_bench/backend/clients/chroma/config.py,sha256=8nXpPdecQ5HrNqcsQwAVgacSz6uLgI-BI7v4tB8CeDk,347
31
31
  vectordb_bench/backend/clients/clickhouse/cli.py,sha256=9tnDE9e1I-Mul40FAzFG8lViYyeXXgjV3dNDpikhEwg,2017
32
- vectordb_bench/backend/clients/clickhouse/clickhouse.py,sha256=_rnLPrbT3TzZicabz6zniDG0FdXlOQNDziW9EQVi-VE,4863
33
- vectordb_bench/backend/clients/clickhouse/config.py,sha256=okIS494l2cADvlTljVCJvOuQRfDHHkf8F1sHrwgPdQw,1650
32
+ vectordb_bench/backend/clients/clickhouse/clickhouse.py,sha256=nRTFE5KQn-_juKrtI546rbbqn1INqPNDNKrpeuHpdlI,8904
33
+ vectordb_bench/backend/clients/clickhouse/config.py,sha256=Bd2fqpaJU5YcPKTNOL0mzEFWpaoVyxVt_21-Jb_tHKk,2659
34
34
  vectordb_bench/backend/clients/elastic_cloud/config.py,sha256=_5Cz3__CbMU7zCizkhK1pGhH3TLJacn8efVueUZ0lnQ,1573
35
35
  vectordb_bench/backend/clients/elastic_cloud/elastic_cloud.py,sha256=FSslLDH2Yi9ZdUwaCbKC_IXxFbMvW-L1xB3YMU08MVI,5448
36
36
  vectordb_bench/backend/clients/mariadb/cli.py,sha256=nqV9V-gOSKGQ1y6VmxOMxGz0a3jz860Va55x7JBcuPk,2727
@@ -40,8 +40,8 @@ vectordb_bench/backend/clients/memorydb/cli.py,sha256=mUpBN0VoE6M55AAEwyd20uEtPk
40
40
  vectordb_bench/backend/clients/memorydb/config.py,sha256=D2Q-HkDwnmz98ek1e_iNu4o9CIRB14pOQWSZgRvd6oY,1500
41
41
  vectordb_bench/backend/clients/memorydb/memorydb.py,sha256=WrZhDYJqpwN173sk2lmPnOibHcQCPrq_PEAMFcL62U4,10219
42
42
  vectordb_bench/backend/clients/milvus/cli.py,sha256=junIvlQtDbOGscKqacferBETDR9SQ9FK3G7oVVO1_2s,9931
43
- vectordb_bench/backend/clients/milvus/config.py,sha256=hBqDfsFfQdCIKKMpDsD0FqcbHp61v9ISLqooa-LwKuc,8838
44
- vectordb_bench/backend/clients/milvus/milvus.py,sha256=VKINREpGJ6DBpykHzSQN0v2xF9B7vskEN3D9WYJ5gXQ,6867
43
+ vectordb_bench/backend/clients/milvus/config.py,sha256=h4OKAVE5FoSmaoppdFRcgeEMS96YcPWZat04496MrrA,12730
44
+ vectordb_bench/backend/clients/milvus/milvus.py,sha256=DmyhqoMgGawwge3CnftaR1x0nmKDvs0rx_nSFbQk0ys,7053
45
45
  vectordb_bench/backend/clients/mongodb/config.py,sha256=7DZCh0bjPiqJW2luPypfpNeGfvKxVC4mdHLqgcjF1hA,1745
46
46
  vectordb_bench/backend/clients/mongodb/mongodb.py,sha256=ts2gpAzUTarpkfMFnM5ANi6T-xvcjS8kc4-apPt9jug,7225
47
47
  vectordb_bench/backend/clients/pgdiskann/cli.py,sha256=o5ddAp1Be2TOnm8Wh9IyIWUxdnw5N6v92Ms1s6CEwBo,3135
@@ -116,7 +116,7 @@ vectordb_bench/frontend/components/run_test/hideSidebar.py,sha256=vb5kzIMmbMqWX6
116
116
  vectordb_bench/frontend/components/run_test/initStyle.py,sha256=osPUgfFfH7rRlVNHSMumvmZxvKWlLxmZiNqgnMiUJEU,723
117
117
  vectordb_bench/frontend/components/run_test/submitTask.py,sha256=VZjkopkCBNhqLwGqsoM0hbPEeF6Q5UOQcdFUaegerxc,4094
118
118
  vectordb_bench/frontend/components/tables/data.py,sha256=5DdnC64BB7Aj2z9acht2atsPB4NabzQCZKALfIUnqtQ,1233
119
- vectordb_bench/frontend/config/dbCaseConfigs.py,sha256=-ro_zxkpBYhJgF5eyt4em4L5kNGnFJVhpmQhFxnsbQA,42954
119
+ vectordb_bench/frontend/config/dbCaseConfigs.py,sha256=1HjKl9s-ilJgPedaJEK8-hu3bCgOGZa7_53EuvfHHhQ,46715
120
120
  vectordb_bench/frontend/config/dbPrices.py,sha256=10aBKjVcEg8y7TPSda28opmBM1KmXNrvbU9WM_BsZcE,176
121
121
  vectordb_bench/frontend/config/styles.py,sha256=Iic14kvGrm0oW-uXNZegceLvEJErWuYpG7WZF_G1zvE,2544
122
122
  vectordb_bench/frontend/pages/concurrent.py,sha256=bvoSafRSIsRzBQkI3uBwwrdg8jnhRUQG-epZbrJhGiE,2082
@@ -142,9 +142,9 @@ vectordb_bench/results/WeaviateCloud/result_20230808_standard_weaviatecloud.json
142
142
  vectordb_bench/results/ZillizCloud/result_20230727_standard_zillizcloud.json,sha256=-Mdm4By65XDRCrmVOCF8yQXjcZtH4Xo4shcjoDoBUKU,18293
143
143
  vectordb_bench/results/ZillizCloud/result_20230808_standard_zillizcloud.json,sha256=77XlHT5zM_K7mG5HfDQKwXZnSCuR37VUbt6-P3J_amI,15737
144
144
  vectordb_bench/results/ZillizCloud/result_20240105_standard_202401_zillizcloud.json,sha256=TualfJ0664Hs-vdIW68bdkqAEYyzotXmu2P0yIN-GHk,42526
145
- vectordb_bench-0.0.25.dist-info/licenses/LICENSE,sha256=HXbxhrb5u5SegVzeLNF_voVgRsJMavcLaOmD1N0lZkM,1067
146
- vectordb_bench-0.0.25.dist-info/METADATA,sha256=yjnCGSTms5Oh9I0fcBc5q1CKONZk4_lsWUPypoAejLI,38061
147
- vectordb_bench-0.0.25.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
148
- vectordb_bench-0.0.25.dist-info/entry_points.txt,sha256=Qzw6gVx96ui8esG21H6yHsI6nboEohRmV424TYhQNrA,113
149
- vectordb_bench-0.0.25.dist-info/top_level.txt,sha256=jnhZFZAuKX1J60yt-XOeBZ__ctiZMvoC_s0RFq29lpM,15
150
- vectordb_bench-0.0.25.dist-info/RECORD,,
145
+ vectordb_bench-0.0.26.dist-info/licenses/LICENSE,sha256=HXbxhrb5u5SegVzeLNF_voVgRsJMavcLaOmD1N0lZkM,1067
146
+ vectordb_bench-0.0.26.dist-info/METADATA,sha256=lsc4Y28tVwbXr3fUrVHbppegppAtYWoH0rEV3pn820g,38061
147
+ vectordb_bench-0.0.26.dist-info/WHEEL,sha256=ck4Vq1_RXyvS4Jt6SI0Vz6fyVs4GWg7AINwpsaGEgPE,91
148
+ vectordb_bench-0.0.26.dist-info/entry_points.txt,sha256=Qzw6gVx96ui8esG21H6yHsI6nboEohRmV424TYhQNrA,113
149
+ vectordb_bench-0.0.26.dist-info/top_level.txt,sha256=jnhZFZAuKX1J60yt-XOeBZ__ctiZMvoC_s0RFq29lpM,15
150
+ vectordb_bench-0.0.26.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (78.1.0)
2
+ Generator: setuptools (80.0.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5