feat(lancedb): enhance index types and CLI integration#787
Conversation
…upport, batch insert optimization and full CLI integration Core changes: - api.py: Add IVF_HNSW_SQ and IVF_HNSW_PQ to IndexType enum - config.py: Rewrite into 5 independent config classes (IVF_PQ / NONE / AUTOINDEX / IVF_HNSW_SQ / IVF_HNSW_PQ); all IVF variants share refine_factor search param; add storage_options for remote storage - lancedb.py: Implement standard prepare_filter() pattern (NumGE/StrEqual); support scalar labels insert; use PyArrow FixedSizeListArray for batch writes instead of per-row dicts; unify search param passing; optimize() supports compact_files + cleanup_old_versions; custom __deepcopy__ to solve multi-process Rust handle serialization issue; explicit select _distance to suppress lance deprecation warning - cli.py: Add 5 CLI commands (LanceDB/AutoIndex/IVFPQ/IVFHNSWSQ/IVFHNSWPQ); fix IndexType.NONE lookup bug; add COS/GooseFS remote storage_options builder - vectordbbench.py: Register all new LanceDB CLI commands New files: - docs/lancedb-enhancement-plan.md: Development plan and implementation notes - docs/lancedb-integration.md: Integration verification report - tests/test_lancedb_config.py: 10 offline unit tests covering config/registration/CLI structure - scripts/bench_lancedb_500k.sh: One-click 500K three-index comparison benchmark script - scripts/aggregate_lancedb_results.py: Aggregate results into Markdown comparison table
|
/assign @XuanYang-cn |
|
Hi @XuanYang-cn, all checks have passed and there are no conflicts. Could you help review this PR when you get a chance? Thanks! |
XuanYang-cn
left a comment
There was a problem hiding this comment.
IndexType.NONE skips create_index(), but search_embedding() never applies case_config.metric_type to the LanceDB query. For cosine benchmark cases, no-index LanceDB searches therefore use LanceDB's default L2 distance while recall is measured against cosine ground truth. Please apply .metric(self.case_config.parse_metric()) for the no-index path, or otherwise make search use the dataset metric consistently.
Previously search_embedding() relied on the index's metric being applied implicitly. This works for indexed paths (IVF_PQ / IVF_HNSW_SQ / IVF_HNSW_PQ / AutoIndex) but silently falls back to LanceDB's default (L2) on the no-index brute-force path, which corrupts recall on cosine / IP datasets whose ground-truth uses a different metric. Fix: always call .metric(self.case_config.parse_metric()) on the query builder. For indexed paths this is a no-op when the index metric already matches; for the no-index path it aligns the scan with the case-configured metric.
Thanks for the detailed review, @XuanYang-cn! You're absolutely right about the no-index path. I've updated the PR to always pin the query metric to the case metric in Could you take another look when you get a chance? Thanks! |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: XuanYang-cn, XuQianJin-Stars The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
Summary
Rewrites the
lancedbclient for LanceDB, adding support for IVF_HNSW_SQ and IVF_HNSW_PQ index types, standard filter queries, PyArrow batch insert optimization, COS/GooseFS remote storage, and full CLI integration.What's added
vectordb_bench/backend/clients/lancedb/{lancedb.py,config.py,cli.py}vectordbbench LanceDB .../LanceDBAutoIndex/LanceDBIVFPQ/LanceDBIVFHNSWSQ/LanceDBIVFHNSWPQvectordb_bench/backend/clients/api.py— addIVF_HNSW_SQandIVF_HNSW_PQtoIndexTypeenumtests/test_lancedb_config.py— 10 offline tests covering config defaults,to_dictconnection options,index_param/search_paramgeneration, metric parsing, case-config registry, and CLI structurevectordb_bench/cli/vectordbbench.py— register all new LanceDB CLI commandsAlgorithms supported
num_partitions,num_sub_vectors,nbits,sample_rate,max_iterationsnprobes,refine_factornprobes,refine_factornum_partitions,m,ef_constructionef,nprobes,refine_factornum_partitions,num_sub_vectors,m,ef_constructionef,nprobes,refine_factorrefine_factorKey improvements
prepare_filter()pattern (NumGE/StrEqual)FixedSizeListArrayfor batch writes instead of per-row dicts__deepcopy__to solve Rust handle serialization issuestorage_optionsfor COS/GooseFS backendscompact_files+cleanup_old_versionssupportExample
vectordbbench LanceDBIVFHNSWSQ --case-type Performance768D1M --k 10 \ --uri /tmp/lancedb \ --num-partitions 256 --m 16 --ef-construction 128 \ --ef 64 --nprobes 20 --refine-factor 25vectordbbench LanceDBIVFPQ --case-type Performance768D1M --k 10 \ --uri s3://my-bucket/lancedb \ --storage-options '{"aws_access_key_id":"...","aws_secret_access_key":"..."}' \ --num-partitions 256 --num-sub-vectors 48 --nprobes 20