day 2 pitstop updated

This commit is contained in:
Kirstin
2025-10-22 22:36:13 +02:00
parent e4759b647a
commit 23b30ff196
@@ -72,10 +72,10 @@ Test different HNSW configurations to find what works best:
```python
# Test configurations
configs = [
{"name": "fast_initial_upload", "m": 0, "ef_construct": 100},
{"name": "memory_optimized", "m": 8, "ef_construct": 100},
{"name": "balanced", "m": 16, "ef_construct": 200},
{"name": "high_quality", "m": 32, "ef_construct": 400},
{"name": "fast_initial_upload", "m": 0, "ef_construct": 100}, # m=0 = ingest-only
{"name": "memory_optimized", "m": 8, "ef_construct": 100}, # m=8 = lower RAM
{"name": "balanced", "m": 16, "ef_construct": 200}, # m=16 = balanced
{"name": "high_quality", "m": 32, "ef_construct": 400}, # m=32 = higher recall, slower build
]
for config in configs:
@@ -90,9 +90,6 @@ for config in configs:
m=config["m"], ef_construct=config["ef_construct"], full_scan_threshold=10
),
optimizers_config=models.OptimizersConfigDiff(indexing_threshold=0),
strict_mode_config=models.StrictModeConfig(
unindexed_filtering_retrieve=True, unindexed_filtering_update=True
),
)
print(f"Created collection: {collection_name}")
```
@@ -103,7 +100,10 @@ Measure upload performance for each configuration:
```python
def upload_with_timing(collection_name, data, config_name):
embeddings = [encoder.encode(dat["description"]).tolist() for dat in data]
embeddings = encoder.encode(
[d["description"] for d in data], show_progress_bar=True
).tolist()
points = []
for i, item in enumerate(data):
embedding = embeddings[i]
@@ -124,6 +124,9 @@ def upload_with_timing(collection_name, data, config_name):
)
)
# Warmup
client.query_points(collection_name=collection_name, query=points[0].vector, limit=1)
start_time = time.time()
client.upload_points(collection_name=collection_name, points=points)
upload_time = time.time() - start_time
@@ -133,7 +136,7 @@ def upload_with_timing(collection_name, data, config_name):
# Load your dataset here
# your_dataset = [{"description": "This is a description of a product"}, ...]
# your_dataset = [{"description": "This is a description of a product"}, ...]
# Upload to each collection
upload_times = {}
@@ -143,11 +146,15 @@ for config in configs:
collection_name, your_dataset, config["name"]
)
# Wait for index to be built
def wait_for_index_built(collection_name, vectors_per_point=1):
info = client.get_collection(collection_name=collection_name)
count = 0
while info.points_count * vectors_per_point - info.indexed_vectors_count != 0 and count < 10:
while (
info.points_count * vectors_per_point - info.indexed_vectors_count != 0
and count < 10
):
time.sleep(1)
info = client.get_collection(collection_name=collection_name)
count += 1
@@ -158,9 +165,9 @@ def wait_for_index_built(collection_name, vectors_per_point=1):
for config in configs:
collection_name = f"my_domain_{config['name']}"
wait_for_index_built(collection_name)
if config["m"] > 0: # m=0 has no HNSW to wait for
collection_name = f"my_domain_{config['name']}"
wait_for_index_built(collection_name)
```
### Step 4: Benchmark Search Performance
@@ -170,13 +177,9 @@ Test search speed with different `hnsw_ef` values:
```python
def benchmark_search(collection_name, query_embedding, ef_values=[64, 128, 256]):
# Warmup
_ = client.query_points(
collection_name=collection_name,
query=query_embedding,
limit=10,
search_params=models.SearchParams(hnsw_ef=ef_values[0]),
)
client.query_points(collection_name=collection_name, query=query_embedding, limit=1)
# hnsw_ef: higher = better recall, but slower. Tune per your latency goal.
results = {}
for hnsw_ef in ef_values:
times = []
@@ -225,8 +228,17 @@ def test_filtering_performance(collection_name):
# Test filter without index
filter_condition = models.Filter(
must=[models.FieldCondition(key="length", range=models.Range(gte=100, lte=500))]
must=[models.FieldCondition(key="length", range=models.Range(gte=10, lte=200))]
)
# Demo only: unindexed_filtering_retrieve=True forces a scan; turn it off right after measuring.
client.update_collection(
collection_name=collection_name,
strict_mode_config=models.StrictModeConfig(unindexed_filtering_retrieve=True),
)
# Warmup
client.query_points(collection_name=collection_name, query=query_embedding, limit=1)
# Timing without payload index
start_time = time.time()
@@ -240,33 +252,36 @@ def test_filtering_performance(collection_name):
# Create payload index
client.create_payload_index(
collection_name=collection_name, field_name="length", field_schema="integer"
collection_name=collection_name,
field_name="length",
field_schema=models.PayloadSchemaType.INTEGER,
)
# Rebuild HNSW to attach filter data structures.
# Note: This is not advised for production. Better create payload index before uploading any data to avoid rebuild.
suffix = collection_name.replace("my_domain_", "")
config = next((c for c in configs if c["name"] == suffix), None)
client.update_collection(
collection_name=collection_name, hnsw_config=models.HnswConfigDiff(m=0)
)
base_ef = client.get_collection(
collection_name=collection_name
).config.hnsw_config.ef_construct
client.update_collection(
collection_name=collection_name,
hnsw_config=models.HnswConfigDiff(
m=16,
ef_construct=config["ef_construct"],
full_scan_threshold=10,
payload_m=None,
max_indexing_threads=1,
# HNSW was already built; adding the payload index doesn’t rebuild it.
# Bump ef_construct (+1) once to trigger a safe rebuild and turn off scanning.
ef_construct=base_ef
+ 1,
),
optimizers_config=models.OptimizersConfigDiff(vacuum_min_vector_number=0),
strict_mode_config=models.StrictModeConfig(
unindexed_filtering_retrieve=False
), # Turn off scanning and use payload index instead.
)
# Wait for index to be built
wait_for_index_built(collection_name)
# Warmup
client.query_points(collection_name=collection_name, query=query_embedding, limit=1)
# Timing with index
start_time = time.time()
_ = client.query_points(