Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

pyvsag

pyvsag is the official Python binding for VSAG, implemented with pybind11. Sources live under python_bindings/ and python/.

Installation

pip install pyvsag

To build from source:

make pyvsag PY_VERSION=3.10
# Build wheels for multiple Python versions:
make pyvsag-all

Quick Start

pyvsag.Index(name, parameters) accepts the index name and a JSON-encoded parameter string, matching the C++ vsag::Factory::CreateIndex signature:

import json
import numpy as np
import pyvsag

dim = 128
num_elements = 10_000

data = np.random.random((num_elements, dim)).astype(np.float32)
ids = np.arange(num_elements, dtype=np.int64)

index_params = json.dumps({
    "dtype": "float32",
    "metric_type": "l2",
    "dim": dim,
    "index_param": {
        "base_quantization_type": "fp32",
        "max_degree": 32,
        "ef_construction": 300,
    },
})

index = pyvsag.Index("hgraph", index_params)
index.build(vectors=data, ids=ids, num_elements=num_elements, dim=dim)

query = np.random.random(dim).astype(np.float32)
search_params = json.dumps({"hgraph": {"ef_search": 60}})
result_ids, result_dists = index.knn_search(
    vector=query, k=10, parameters=search_params,
)
print(result_ids, result_dists)

Saving & Loading

index.save("index.bin")

new_index = pyvsag.Index("hgraph", index_params)
new_index.load("index.bin")

The current save and load wrappers do not propagate errors returned by the underlying serialization and deserialization operations. Verify that the output file was created and round-trip important indexes before relying on persisted data.

Index Operations

The Python binding exposes the following index-management methods in addition to build, search, save, and load:

MethodResultNotes
get_num_elements()intCurrent number of elements.
get_memory_usage()intIndex memory usage in bytes.
check_id_exist(id)boolWhether an ID currently exists.
get_min_max_id()(min_id, max_id)Returns (-1, -1) if the operation fails.
add(vectors, ids, num_elements, dim)NoneAdds a contiguous dense vector matrix; dtype must match the index.
remove(ids)intRemoves a one-dimensional int64 ID array. Returns 0 both when no ID is removed and when the underlying operation fails.
cal_distance_by_id(query, ids)numpy.ndarrayReturns one float32 distance per ID. Invalid IDs produce -1; an underlying operation failure leaves the entire result at -1.
# Add two dense vectors.
new_vectors = np.random.random((2, dim)).astype(np.float32)
new_ids = np.array([10_001, 10_002], dtype=np.int64)
index.add(new_vectors, new_ids, len(new_ids), dim)

assert index.check_id_exist(10_001)
print(index.get_num_elements(), index.get_memory_usage())
print(index.get_min_max_id())

# Calculate distances from one query to a candidate list.
candidate_ids = np.array([10_001, 10_002], dtype=np.int64)
distances = index.cal_distance_by_id(query, candidate_ids)

# Remove IDs; the return value is the number actually removed.
removed = index.remove(candidate_ids)

add accepts a flat contiguous array or a row-major two-dimensional matrix. For dtype: "float16", pass numpy.float16; for dtype: "bfloat16", pass a numpy.uint16 array containing BF16 bit patterns. Operation support remains index-dependent. Input validation and operations such as add raise Python exceptions, but remove, cal_distance_by_id, save, and load use the sentinel or unchecked behaviors described above instead of consistently propagating underlying operation failures.

Relationship with the C++ Library

pyvsag wraps the same vsag::Index API as C++ and shares the underlying index binaries. You can build an index in Python and load it in C++ (and vice versa) as long as parameters match.

More Examples

See examples/python/ in the repository.