Announcing Zvec v0.6.0
TL;DR: We are releasing Zvec v0.6.0, headlined by the new Turbo quantizer framework, random rotation for INT8/INT4 quantization, group-by search, FTS(language support, matching operators, stemming), and DiskANN I/O decoupling via dlopen. This release pushes quantization accuracy and memory efficiency further, enriches the full-text search pipeline with multi-language and Unicode support, and makes DiskANN deployment simpler than ever β no more plugin
.soorlibaio-devbuild-time dependency.
You can find the complete release notes on GitHub.
Turbo: New Quantizer Framework
Zvec v0.6.0 introduces Turbo β a pluggable quantizer framework that decouples quantization logic from index builders and searchers. Turbo establishes a uniform interface that future quantizers (int8 uniform, int8 record, PQ, RaBitQ, β¦) can implement, making it easier to add new quantization methods without touching index code.
The initial release includes:
- Quantizer abstraction β an abstract base class with a
DistanceImplcallable distance handle, the first concreteFp32Quantizerimplementation, and scalar FP32 distance kernels.IndexMetaandIndexQueryMetahave been extended with quantizer support, andIndexFactorynow wires quantizers into the index pipeline.
This framework lays the groundwork for RaBitQ quantization on IVF indexes β a memory optimization that compresses vectors to 1-bit representations, dramatically reducing memory footprint while maintaining competitive recall. The Turbo abstraction ensures RaBitQ can be integrated cleanly across IVF and other index types. A Turbo preprocessor (rotation, dimensionality reduction) is planned for a follow-up release.
Random Rotation for INT8/INT4 Quantization
Quantization error in INT8 is directly proportional to the data range (max β min). By applying a random rotation before quantization, variance is distributed evenly across all vector dimensions, reducing the overall range and thereby improving quantization accuracy.
This release adds an optional rotation parameter to INT8/INT4 quantization, now supporting HNSW, Flat and Vamana indexes. The benefits are significant β recall improves while maintaining the same QPS:
| Dataset | Index | INT8 Recall (before β after) | INT4 Recall (before β after) |
|---|---|---|---|
| cohere-1m | HNSW | 0.9285 β 0.9397 | 0.2114 β 0.7117 |
| cohere-1m | Flat | 0.9695 β 0.9881 | 0.248 β 0.8146 |
| cohere-1m | Vamana | 0.9576 β 0.9734 | 0.2415 β 0.771 |
The rotation is implemented via an abstract Rotator base class with FhtRotator (Fast Hadamard Transform) and MatrixRotator inheritance, providing flexibility for different rotation strategies.
Group-By Search
Zvec v0.6.0 adds group-by search (a.k.a. group-by deduplication) across the core interface, algorithm, and DB layers. Users can now retrieve top-K results per group instead of globally β essential for de-duplicating near-identical documents, returning diverse results per category, or implementing per-group pagination.
Key capabilities:
- Supports
fetch_vector,is_linear, andbf_pksquery modes - Works with Flat (dense & sparse), HNSW (dense & sparse), and HNSW-RaBitQ indexes
- Group-by is mutually exclusive with refiner search (rejected when
refiner_paramis set) - Unsupported index types (DiskANN, IVF, Vamana) now fail fast with
IndexError_Unsupportedinstead of silently returning empty or incorrect results
Group-by search is also exposed in the Python API:
from zvec import Query, GroupByParam
result = collection.query(
queries=Query(
field_name="embedding",
vector=[0.1] * 128,
group_by_param=GroupByParam(
group_topk=3, # top-K per group
group_count=10, # number of groups
),
),
topk=30,
)FTS: Language Support, Matching Operators & Stemming
Building on the native full-text search introduced in v0.5.0, this release significantly expands the FTS text analysis pipeline with full Unicode support, multi-language stemming, and a production-grade standard tokenizer.
Standard Tokenizer (UAX #29)
Replaced the previous general-category tokenizer with Unicode 17 UAX #29 word-boundary tables generated from official Unicode data. The new tokenizer implements Lucene-style token selection for alphanumeric, numeric, ideographic, hiragana, katakana, hangul, southeast Asian, regional indicator, and common emoji sequences β bringing Zvec's tokenization behavior closer to Elasticsearch's standard tokenizer.
UTF-8 Lowercase & ASCII Folding
Integrated utf8proc 2.11.3 to upgrade the entire FTS text analysis pipeline with full Unicode support:
- LowercaseTokenFilter: Codepoint-aware lowercase conversion replacing byte-level
std::tolower - AsciiFoldingTokenFilter (new): Converts Unicode characters to ASCII equivalents using NFKD decomposition + STRIPMARK, with a supplementary folding table for characters without decomposition mappings (ΓΈβo, Δβd, Γβss, ΓβAE, ΓβTH, etc.)
Stemmer Token Filter
Added a stemmer token filter based on Snowball 3.1.1, reducing words to their root form with support for 34+ languages configurable via stemmer_lang in extra_params (defaults to English). The filter uses a thread-local stemmer cache for lock-free performance.
from zvec import FieldSchema, DataType, FtsIndexParam
FieldSchema(
"content",
DataType.STRING,
index_param=FtsIndexParam(
tokenizer_name="standard",
filters=["lowercase", "ascii_folding", "stemmer"],
extra_params={"stemmer_lang": "english"},
),
)DiskANN I/O Decoupling
Prior to v0.6.0, DiskANN shipped as a separate runtime-loaded plugin .so that required a hard build-time dependency on libaio-dev. This release replaces that design with a simpler, more robust approach:
- Runtime dlopen: A thread-safe singleton
dlopenslibaio.soat runtime and caches the syscall pointers β no morelibaio-devbuild dependency - Graceful fallback: If
libaiois absent, DiskANN automatically falls back to synchronouspread()with a warning - Simplified deployment: No more plugin
.soto ship or preload β DiskANN is now compiled directly into the core library
Performance comparison on Cohere 1M (Aliyun g9i, PL0, 10000 IOPS) shows that AIO-enabled pread delivers ~1.7Γ the QPS of the synchronous fallback, while recall remains identical β so users on systems with libaio still get full performance automatically.
Performance Improvements
- Faster FTS Conjunction Queries: Added block-max skip and score early-exit to
ConjunctionIteratorβ skip entire non-competitive blocks (128 docs) by checking block-max score upper bounds, and short-circuit score accumulation when the remaining upper bound cannot beat the threshold. Benchmark (500k docs, quora dataset): AND queries 22β38% faster, phrase queries 33% faster. - Zero-Copy Python Vector Query: Replaced
serialize_vectormemcpy withVectorViewClausethat points directly at the numpy buffer, eliminating redundant memory copies for Python dense vector queries.
Other Improvements & Fixes
- DiskANN C API: Added complete DiskANN C API interfaces including index params setter/getters, query params with CRUD operations, and query wiring for vector / group-by vector / sub-query.
- Collection Consistency: Preserved the live writing segment across CreateIndex/DropIndex DDL failures so persisted-segment tasks no longer corrupt the active segment.
- Index Stability: Fixed lost-wakeup race in DiskANN and HNSW sparse builder progress loops, IVF nprobe selected list scanning, and miscellaneous IVF index bugs.
- FTS Correctness: Fixed segment stats not written on reopen, zero-match filter semantics, global doc id gaps during compaction, and snapshot read-only indexes without flush.
- Collection: Fixed LOCK file to open read-only when collection is read-only.
- Build: Propagated compiler settings to Arrow ExternalProject, propagated
CMAKE_C_COMPILERto LZ4, accepted Xcode 26.5's renamed libtool version string, and declared 64-bit-only Python support.
Roadmap
For a glimpse into our future plans β including storage scalability, expanded algorithm support, and more language SDKs β please visit our official roadmap.