This is a project for using cuVS, NVIDIA's GPU accelerated vector search library, with Apache Lucene.
cuvs-lucene provides a pluggable KnnVectorsFormat that uses cuVS to offload vector index build — and optionally search — to NVIDIA GPUs. Because it plugs in through a standard Lucene codec, existing Lucene applications can take advantage of GPU acceleration with minimal code changes and gracefully fall back to the default CPU codec when no GPU is present.
Four codecs are currently provided:
Lucene101AcceleratedHNSWCodec— GPU-accelerated HNSW build with CPU HNSW search. The on-disk format is standard Lucene HNSW, so indexes built on the GPU can be read by any stock Lucene 10.x reader.LuceneAcceleratedHNSWScalarQuantizedCodec— scalar-quantized vectors for a smaller index footprint.LuceneAcceleratedHNSWBinaryQuantizedCodec— binary-quantized vectors for an even smaller index footprint.
CuVS2510GPUSearchCodec— GPU-accelerated HNSW build and GPU search
- A machine with an NVIDIA GPU
- CUDA 12.0+
- JDK 22
- Maven 3.9.6+
- A matching version of the cuVS libraries. For Maven usage, install the cuVS tarball and add it to your system library load path. See the cuVS tarball install instructions.
To pull cuvs-lucene into a Maven project, add the following dependency to your pom.xml:
<dependency>
<groupId>com.nvidia.cuvs.lucene</groupId>
<artifactId>cuvs-lucene</artifactId>
<version>26.10.0</version>
</dependency>cuvs-lucene lives in the cuVS repository and builds against the cuVS
Java bindings. If the libcuvs libraries and the Java bindings have not been built and installed, use
./build.sh libcuvs java lucene in the top level directory.
Alternatively, if libcuvs is already built and the cuvs-java artifact is already installed in your local
Maven repository, do ./build.sh lucene in the top level directory or just do ./build.sh in this directory.
The resulting artifacts are written to target/.
To run the tests, add --run-java-tests to any of the commands above. Be sure to set (manually, if needed)
your LD_LIBRARY_PATH to include the directory with the appropriate (matching) version of libcuvs.so, as
described in the cuVS tarball install instructions.
The example below plugs the GPU-accelerated HNSW codec into a standard Lucene IndexWriter. Once the codec is set on the IndexWriterConfig, indexing proceeds exactly as it would with the default Lucene codec, and search uses the stock KnnFloatVectorQuery.
Before running it, make sure cuVS is installed and available on your system library load path. The cuVS tarball install instructions show how to set this up.
Applications using CuVS2510GPUSearchCodec can opt into RMM's stream-ordered asynchronous device
allocator during startup:
CuVSProvider.provider().enableRMMAsyncMemory();Call this before creating any cuVS resources, codecs, writers, or readers. The setting affects the entire process on the current CUDA device, so allocator policy belongs to the application rather than an individual Lucene codec. Async allocation is optional for correctness and recommended for GPU workloads with repeated device allocations, especially concurrent or multi-stream searches. Applications that do not opt in use the default RMM device-memory resource.
In a Maven project that includes the cuvs-lucene dependency shown above, create src/main/java/com/nvidia/cuvs/lucene/examples/HelloCuvsLucene.java:
package com.nvidia.cuvs.lucene.examples;
import static org.apache.lucene.index.VectorSimilarityFunction.EUCLIDEAN;
import com.nvidia.cuvs.lucene.AcceleratedHNSWParams;
import com.nvidia.cuvs.lucene.Lucene101AcceleratedHNSWCodec;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.apache.lucene.codecs.Codec;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.KnnFloatVectorField;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
public class HelloCuvsLucene {
public static void main(String[] args) throws Exception {
AcceleratedHNSWParams params = new AcceleratedHNSWParams.Builder().build();
Codec codec = new Lucene101AcceleratedHNSWCodec(params);
IndexWriterConfig config = new IndexWriterConfig().setCodec(codec);
Path indexPath = Paths.get("index");
float[] embedding = new float[] {0.1f, 0.2f, 0.3f, 0.4f};
try (Directory dir = FSDirectory.open(indexPath);
IndexWriter writer = new IndexWriter(dir, config)) {
Document doc = new Document();
doc.add(new KnnFloatVectorField("vector_field", embedding, EUCLIDEAN));
writer.addDocument(doc);
}
System.out.println("Hello cuVS Lucene ran successfully.");
}
}The artifacts would be built and available in the target / folder.
mvn -q compile org.codehaus.mojo:exec-maven-plugin:3.5.1:java \
-Dexec.mainClass=com.nvidia.cuvs.lucene.examples.HelloCuvsLuceneFor more examples, including one that indexes and searches entirely on the GPU using CuVS2510GPUSearchCodec, please refer to the examples/ directory.
If you are interested in contributing to cuvs-lucene, please read the cuVS Contributing guide.
Note
The code style format is enforced using the Spotless maven plugin, which runs as a pre-commit hook. Run pre-commit run --all-files, or mvn spotless:apply in this directory, to format the sources.
- Bring Massive-Scale Vector Search to the GPU with Apache Lucene — NVIDIA GTC 2025 session video
- cuVS and Lucene: GPU-based Vector Search — Berlin Buzzwords 2024 session video
- Exploring GPU-accelerated vector search in Elasticsearch with NVIDIA — Elasticsearch Blog
- Apache Lucene Accelerated with the NVIDIA cuVS 25.06 Release — SearchScale Blog
