Skip to content

4.0.0-beta.5 and 4.0.0-beta.6

Choose a tag to compare

@MarkWolters MarkWolters released this 09 Jun 17:09

JVector 4.0.0-beta.5 and 4.0.0-beta.6: Release Notes

Overview

This document covers the features, improvements, and changes introduced in JVector versions 4.0.0-beta.5 (May 23, 2025) and 4.0.0-beta.6 (June 13, 2025).

Major Features

Sequential Disk Writer (beta.6)

File Format Version 5 - A major upgrade to the on-disk graph format that introduces sequential writing capabilities, improving write performance and reliability.

  • Sequential Writing - New OnDiskSequentialGraphIndexWriter provides sequential write operations for better I/O performance
  • Format Upgrade - On-disk format upgraded from version 4 to version 5
  • Improved Reliability - Sequential writes reduce the risk of corruption and improve write throughput

Add Graph Node Using Search Score (beta.6)

Enhanced Node Addition - New capability to add nodes to the graph using pre-computed search scores, enabling more flexible graph construction workflows.

  • Score-Based Insertion - Add nodes with pre-computed similarity scores
  • Flexible Construction - Supports incremental graph building with custom scoring strategies
  • Performance Optimization - Avoids redundant similarity computations during insertion

YAML Configuration System (beta.5)

Comprehensive YAML Support - Major improvements to the YAML-based configuration system for benchmarks and datasets.

  • Dataset Configuration - Support for empty sections in datasets.yml for better organization
  • Flexible Benchmark Control - Enhanced control over benchmark metrics and output formatting
  • String Format Control - Better control over metric string formatting in benchmark output

Performance Improvements

ConcurrentNeighborMap Optimization (beta.5)

Insertion Performance - Optimized the insertion algorithm in ConcurrentNeighborMap to find the insertion point before performing the copy operation, reducing unnecessary data movement.

Diverse Edge Computation (beta.5)

Factorized Diversity Calculation - Refactored the computation of diverse edges to eliminate code duplication and improve maintainability while maintaining performance.

OnDiskGraphIndex.View Simplification (beta.5)

Code Simplification - Simplified the OnDiskGraphIndex.View implementation to avoid code duplication, making the codebase more maintainable.

Testing and Benchmarking

JMH Benchmarks (beta.5)

Random Vector Index Build - Added JMH benchmarks for random vector index construction with setup scripts for consistent testing environments.

AVX-512 Support (beta.5)

Advanced SIMD Testing - Added AVX-512 test runners, jobs, and assertions for testing on advanced CPU architectures.

  • Test Infrastructure - New test runners specifically for AVX-512 capable systems
  • Assertions - Specific assertions to validate AVX-512 optimizations
  • CI Integration - GitHub Actions jobs for AVX-512 testing

Performance Metrics (beta.5)

Enhanced Metrics - Improved performance metrics measurement and summarization:

  • Better Diagnostics - Enhanced diagnostic titles for clearer output
  • Metric Control - Better control over metric string formats
  • Measurement Accuracy - Improved accuracy in performance metric collection

Bug Fixes and Improvements

Product Quantization Validation (beta.5)

Cluster Count Validation - Added validation for clusterCount parameter in Product Quantization to prevent invalid configurations.

Dataset Support (beta.6)

ColBERT Dataset - Added support for the ColBERT-1M dataset in the benchmark suite.

Configuration and Usage Guide

Using Sequential Disk Writer (beta.6)

The sequential disk writer is used automatically when writing on-disk graph indexes:

// Create a sequential writer (automatically used in beta.6+)
Path graphPath = Paths.get("graph.jvector");
try (var writer = new OnDiskSequentialGraphIndexWriter.Builder(
        graphIndex,
        graphPath
    ).build()) {
    
    // Write the graph sequentially
    writer.write();
}

// The file format is automatically version 5

For incremental writes with features:

// Write with inline features (e.g., compressed vectors)
try (var writer = new OnDiskSequentialGraphIndexWriter.Builder(
        graphIndex,
        graphPath
    )
    .with(InlineVectors.inlineVectors(compressedVectors))
    .build()) {
    
    writer.write();
}

Adding Graph Nodes with Search Scores (beta.6)

// Add a node using pre-computed search scores
GraphIndexBuilder builder = new GraphIndexBuilder(
    scoreProvider,
    dimension,
    M,
    beamWidth,
    neighborOverflow,
    alpha,
    addHierarchy,
    refineFinalGraph
);

// Add node with search-based scoring
SearchResult searchResult = performSearch(queryVector);
int newNodeId = builder.addGraphNode(newVector, searchResult);

This is particularly useful when:

  • You have pre-computed similarities from a previous search
  • Building the graph incrementally with custom insertion strategies
  • Optimizing construction by reusing search results

Configuring YAML Benchmarks (beta.5)

Dataset Configuration with Empty Sections

Create or modify datasets.yml:

# Group datasets logically with empty sections for clarity
neighborhood-watch-100k:
  - cohere-english-v3-100k
  - ada002-100k
  - openai-v3-small-100k
  - gecko-100k

neighborhood-watch-1M:
  - ada002-1M
  - colbert-1M  # New in beta.6

ann-benchmarks:
  - glove-25-angular.hdf5
  - glove-50-angular.hdf5
  - sift-128-euclidean.hdf5

# Empty sections are now supported for organization
custom-datasets:
  # Add your datasets here

Controlling Benchmark Metric Formats

In your benchmark configuration:

// Control string format for metrics
BenchmarkTablePrinter printer = new BenchmarkTablePrinter();
printer.setMetricFormat("recall", "%.4f");  // 4 decimal places
printer.setMetricFormat("latency", "%.2f ms");  // 2 decimals with unit
printer.setMetricFormat("throughput", "%.0f qps");  // No decimals

Or in YAML configuration:

benchmarks:
  accuracy:
    - recall
  latency:
    - AVG
  throughput:
    - AVG

# Control output formatting
console:
  formats:
    recall: "%.4f"
    latency: "%.2f ms"
    throughput: "%.0f qps"

Validating Product Quantization Parameters (beta.5)

// Cluster count is now validated
try {
    ProductQuantization pq = ProductQuantization.compute(
        vectors,
        M,
        256,  // clusterCount - must be valid (typically 256 for 8-bit)
        centerData
    );
} catch (IllegalArgumentException e) {
    // Invalid clusterCount will throw an exception
    System.err.println("Invalid cluster count: " + e.getMessage());
}

// Valid cluster counts:
// - 256 for standard 8-bit quantization
// - 16 for 4-bit quantization
// - Must be a power of 2 and appropriate for the bit depth

Using Custom ForkJoinPools (beta.5)

// Configure custom executor pools for better control
ForkJoinPool simdExecutor = new ForkJoinPool(
    Runtime.getRuntime().availableProcessors(),
    ForkJoinPool.defaultForkJoinWorkerThreadFactory,
    null,
    false
);

ForkJoinPool parallelExecutor = ForkJoinPool.commonPool();

// Use custom pools in graph builder
GraphIndexBuilder builder = new GraphIndexBuilder(
    scoreProvider,
    dimension,
    M,
    beamWidth,
    neighborOverflow,
    alpha,
    addHierarchy,
    refineFinalGraph,
    simdExecutor,      // Custom SIMD pool
    parallelExecutor   // Custom parallel pool
);

Running JMH Benchmarks (beta.5)

# Navigate to benchmarks-jmh directory
cd benchmarks-jmh

# Run index construction benchmarks
mvn clean install
java -jar target/benchmarks.jar IndexConstructionWithRandomSetBenchmark

# Run with specific parameters
java -jar target/benchmarks.jar \
  -p vectorCount=10000,50000,100000 \
  -p dimension=128,384,768 \
  IndexConstructionWithRandomSetBenchmark

# Use setup scripts for consistent environment
./scripts/test_node_setup.sh

Testing on AVX-512 Systems (beta.5)

# Check if AVX-512 is available
java -XX:+UnlockDiagnosticVMOptions \
     -XX:+PrintIntrinsics \
     -cp target/jvector-tests.jar \
     io.github.jbellis.jvector.vector.VectorizationProviderTest

# Run tests with AVX-512 enabled
mvn test -Dtest=*AVX512*

# In CI/CD (GitHub Actions)
# AVX-512 tests run automatically on compatible runners

Breaking Changes

File Format Version 5 (beta.6)

On-Disk Format Upgrade - The on-disk graph format has been upgraded from version 4 to version 5.

Migration Required:

  • Indexes created with version 4 or earlier must be rebuilt
  • The new format is not backward compatible
  • Sequential writing provides better performance and reliability

Migration Path:

// Load old format index
OnDiskGraphIndex oldIndex = OnDiskGraphIndex.load(oldPath, 0);

// Rebuild with new format
GraphIndexBuilder builder = new GraphIndexBuilder(/* parameters */);
// ... add all vectors ...
OnHeapGraphIndex newGraph = builder.complete();

// Write with new format (version 5)
OnDiskGraphIndex.write(newGraph, newPath, compressor);

API Changes

Sequential Writer - The introduction of OnDiskSequentialGraphIndexWriter changes the recommended approach for writing graphs to disk. While the old API still works, the sequential writer is now preferred for new code.

Version Timeline

  • 4.0.0-beta.5 - May 23, 2025
  • 4.0.0-beta.6 - June 13, 2025

Additional Resources


For detailed commit-by-commit changes, please refer to the CHANGELOG.md file or the GitHub release pages for each version.