Add PyLucene backend for cuVS-Lucene vector search in cuvs-bench - #2385
Draft
nvzm123 wants to merge 22 commits into
Draft
Add PyLucene backend for cuVS-Lucene vector search in cuvs-bench#2385nvzm123 wants to merge 22 commits into
nvzm123 wants to merge 22 commits into
Conversation
Dataset preparation imports h5py at runtime. Declare it in both the dependency manifest and project metadata so supported environments install it consistently.
Add opt-in atomic JSON persistence for Python-native backends, preserve canonical result fields, and keep derived CSV artifacts synchronized. Propagate sweep failures through the CLI and cover result identity, export, and cleanup behavior.
Register a local PyLucene backend for cuVS-Lucene HNSW and CAGRA codecs. Add deterministic config selection, lazy JVM and codec resolution, GPU writer validation, safe index lifecycle handling, commit-bound provenance, CAGRA integrity checks, and focused unit coverage.
Exercise real JVM and cuVS-Lucene HNSW and CAGRA build/search paths behind an opt-in pytest marker. Cover persisted GPU formats, index reuse, CLI execution, fallback rejection, and integrity failures.
Document the verified dependency build, runtime configuration, supported codecs and limits, manual smoke workflow, index reuse behavior, and benchmark result semantics.
…ark-backend Signed-off-by: nvzm123 <zmeeks@nvidia.com> # Conflicts: # python/cuvs_bench/cuvs_bench/orchestrator/orchestrator.py # python/cuvs_bench/cuvs_bench/run/__main__.py # python/cuvs_bench/cuvs_bench/run/data_export.py # python/cuvs_bench/cuvs_bench/tests/test_data_export.py
Use the shared direct CSV exporter for in-process backends and remove the redundant JSON persistence layer. Preserve scoped result identities, latency percentiles, safe artifact paths, stale-result cleanup, and accurate CLI exit behavior. Signed-off-by: nvzm123 <zmeeks@nvidia.com>
Target the production HNSW and CAGRA codecs exposed by the current cuVS-Lucene PR. Preserve the intentional HNSW CPU fallback, keep fail-closed CAGRA integrity checks, and verify actual HNSW writer selection through a downstream test-only codec adapter. Signed-off-by: nvzm123 <zmeeks@nvidia.com>
Document the current JDK, PyLucene, cuVS Java, and cuVS-Lucene requirements. Describe the two supported production codecs, HNSW fallback behavior, CAGRA validation contract, and the current manual validation workflow. Signed-off-by: nvzm123 <zmeeks@nvidia.com>
Signed-off-by: nvzm123 <zmeeks@nvidia.com>
Signed-off-by: nvzm123 <zmeeks@nvidia.com>
Validate the generated PyLucene ABI before JVM startup and follow the current cuVS-Lucene codec and writer-selection contracts. Preserve Lucene defaults for HNSW while keeping CAGRA segment files directly verifiable across flushes and merges. Extend provenance and live coverage for GPU selection, CPU fallback, and merged CAGRA indexes. Signed-off-by: nvzm123 <zmeeks@nvidia.com>
Document the custom Lucene 10.2 wrapper requirement, temporary PR 174 artifact workflow, codec-specific compound-file policies, fallback behavior, and latency units. Signed-off-by: nvzm123 <zmeeks@nvidia.com>
Pass m and ef_construction through a PyLucene-compatible codec adapter, expose num_candidates sweeps, and support verified direct single-segment builds. Persist the complete build identity and extend unit and live coverage for writer selection, fallback, topology, tuning, and reuse. Signed-off-by: nvzm123 <zmeeks@nvidia.com>
Describe the validated cuVS-Lucene source combination and adapter requirements. Document supported HNSW parameters, tuning ranges, single-segment constraints, and a manual sweep workflow. Signed-off-by: nvzm123 <zmeeks@nvidia.com>
Use cuVS PR NVIDIA#2475 as the pinned source for matching native, cuvs-java, and cuvs-lucene artifacts. Refresh monorepo paths, validation commands, and adapter compatibility guidance. Signed-off-by: nvzm123 <zmeeks@nvidia.com>
Signed-off-by: nvzm123 <zmeeks@nvidia.com>
Group PyLucene unit, runtime, provenance, and integration coverage under a dedicated test subtree. Preserve recursive discovery and update shared helper and project fixture paths. Signed-off-by: nvzm123 <zmeeks@nvidia.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR adds a built-in
pylucenebackend to cuVS Bench for building and searching local Lucene vector indexes through PyLucene and cuVS-Lucene.It supports:
Lucene101AcceleratedHNSWCodecfor cuVS-assisted HNSW construction with Lucene HNSW search;CuVS2510GPUSearchCodecfor GPU CAGRA construction and search;h5pyas an explicit dependency for the existing dataset-preparation path.This PR also owns the PyLucene end-to-end suite. Pytest owns its scenarios, assertions, parameterization, and reporting under
cuvs_bench/tests/pylucene; reusable Python helpers remain non-test modules, and test-only Java adapters live underpython/cuvs_bench/tests/java. Those adapters are compiled into a temporary directory before the process-wide JVM starts and are excluded from published packages.HNSW parameters and topology
The HNSW backend exposes these benchmark parameters:
mmaps toAcceleratedHNSWParams.maxConn;ef_constructionmaps toAcceleratedHNSWParams.beamWidth;SAME_GRAPH_FOOTPRINTheuristic to derive the underlying CAGRA build parameters;num_candidatescontrols Lucene'sKnnFloatVectorQuerycandidate budget and may be swept independently for each built index; anddirect_single_segmentrequests one direct Lucene segment without a force merge and verifies the committed topology.Stock PyLucene instantiates codecs through no-argument constructors. The backend therefore compiles a small Java adapter before JVM startup that delegates to the production accelerated codec with the requested heuristic parameters. It does not reimplement the production codec.
Automatic tuning covers
m,ef_construction, andnum_candidates, with the candidate lower bound resolved fromtop_k. Build parameters and segment count are recorded in schema-v4 provenance so incompatible indexes cannot be silently reused.Runtime and integrity behavior
The backend validates the PyLucene 10.2 ABI, JAR layout, native-library paths, Lucene SPI codecs, dataset shape, and index location before execution. PyLucene and the JVM are initialized lazily.
HNSW preserves cuVS-Lucene's production behavior: it uses the accelerated writer when available and intentionally falls back to Lucene's CPU writer otherwise. CAGRA requires GPU support and is validated fail-closed. CAGRA segment metadata, vector dimensions and counts, file coverage, headers, footers, and checksums are verified before results are accepted.
Atomic, commit-bound provenance protects index reuse. Failed new builds remove only their partial output, and preflight failures preserve an existing index. In-process backend results use the shared direct CSV exporter and preserve build/search identity, latency percentiles, and failure handling.
Requirements and limits
--batch-sizenum_candidates >= top_kfor HNSW; this is Lucene's candidate budget, not a direct cuVSef_searchsettingk <= 1024direct_single_segmentremains subject to Lucene's per-indexing-thread hard RAM limit and fails if Lucene commits more than one segmentPyLucene 10.2 remains a source-built external dependency. This PR depends on the production codec and compatibility changes in NVIDIA/cuvs#2475 until that PR is merged. The Bench guide pins the exact tested producer revision rather than a moving PR head.
Test coverage
Non-live pytest coverage includes backend registration, configuration expansion and tuning, parameter validation, adapter compilation and classpath failures, JVM and SPI validation, index build/reuse/cleanup, single- and multi-segment topology, search candidate propagation, result export, provenance mismatches, CAGRA corruption detection, package-resource ownership, and CLI failure handling.
The opt-in live matrix explicitly distinguishes:
GPU-required cases assert the accelerated writer, reader, and query implementations and fail on unavailable cuVS or CPU fallback. CPU cases explicitly verify and report stock Lucene HNSW execution.
Coverage includes a single live document, one and ten segments, 10-to-1 and 100-to-10 force merges, CAGRA
searchWidthvalues 1, 16, and 32, deletion, selective filtering, persisted HNSW graph degree/layers, an exact Lucene filtered-search boundary, deterministic brute-force recall, duplicate-hit exclusion, inactive/filter-rejected document exclusion, and rank-one self matches. The Java-side query bridge verifies the retained productionsearchWidthvalue rather than echoing Python configuration.CAGRA configurations use
graphDegree=32,intermediateGraphDegree=64, and enough documents to avoid cuVS clamping warnings, including 24,832 vectors for the three-layer case.Artifact gates require the production Java adapter and PyLucene YAML resources in built distributions while rejecting test Java,
PyLuceneTestSupport, and.classpayloads. A Bench-owned formatting POM, the pre-commit matcher, and the Spotless wrapper cover both production and test Java roots without adding a Maven artifact to the package tree.Validation
Final revisions:
7816d6f5ce01111e8b4e9cd381f4b8f021cd5c00d6fcab0946837d7d3997cec4ed18189d3faa12e6The GitHub
pull/2475/headref was fetched into a separate checkout and detached at the exact producer revision. The producer JAR was built from that checkout. GPU tests used a compatible native cuVS runtime reporting 26.10 and a 26.10cuvs-javaJAR; a clean rebuild of all 5,420 current-main native targets was stopped as impractical for this Java/Python-only validation.Producer validation
./build.sh lucene: passedmvn clean verify: 332 tests, 0 failures, 0 errors, 30 skippedThinJarContentsIT: 1 test, 0 failures, 0 errors, 0 skippedTestBackCompat,TestLucene102FormatConstruction: 20 passedcuVS Bench validation
searchWidth16/32 cases: 2 passed, 18 deselected; recall 1.0python/cuvs_benchpytest suite: 487 passed, 71 skipped in 72.68 secondsgit diff --check: passedThe full producer suite retains existing randomized small-dataset graph-clamping, intentional fallback/invalid-configuration, JVM vector/native-access, and Javadoc-plugin warnings. The live PyLucene matrix emitted no cuVS graph-clamping or CPU-fallback warnings; it emitted the expected JVM notice for the incubating vector module. The isolated wheel install emitted pip's expected root-user warning because it used a temporary
--targetdirectory.Related work