Vektordatenbank-Release 0.7.0: IVF-RaBitQ, DiskANN mit io_uring und 40 % kleinere Bibliothek
Ein Rundgang durch Release 0.7.0 einer einbettbaren Vektordatenbank: lokale Workspace-Suche, ReMe-Integration, quantisierte und Disk-Indizes, musllinux-Wheels und DocIterator.
Version 0.7.0 ist ein umfangreiches Release dieser einbettbaren Vektordatenbank. Vier Bereiche haben sich geändert: das Ökosystem drumherum, die Indexalgorithmen, die Art, wie die Bibliothek ausgeliefert wird, und die Bedienbarkeit im Alltag. Die wichtigsten Punkte sind ein CLI für die Workspace-Suche namens zvec-grep, eine Integration mit ReMe, IVF-RaBitQ, ein produktionsreifes DiskANN mit io_uring und ARM64-Unterstützung, AVX2- und AVX512-Dispatch zur Laufzeit für RaBitQ, eine rund 40 % kleinere dynamische Bibliothek, musllinux-Wheels, vorgefertigte SDK-Binaries aus der CI, DocIterator und ein N-Gramm-Tokenizer für die Volltextsuche. Die vollständigen Release Notes stehen auf der GitHub-Release-Seite des Projekts zum Tag v0.7.0.
Ökosystem
zg: lokale Workspace-Suche
Das neue Kommandozeilenwerkzeug zvec-grep durchsucht einen Workspace komplett auf dem eigenen Rechner. Hinter einer Oberfläche stecken drei Schichten:
- ripgrep für schnelle Literal- und Regex-Treffer
- BM25 mit jieba für lexikalisches Ranking
- HNSW-Vektorsuche für semantische Abfragen
Gedacht ist es für Menschen wie für KI-Agenten, und per MCP lässt es sich in Agenten-Workflows einhängen. Wer RAG über eine Codebasis, ein Agentengedächtnis oder eine Dokumentation baut, bekommt mit zg einen einzigen Befehl statt mehrerer zusammengeflickter Tools.
ReMe-Integration
Die Datenbank dient jetzt als Dateispeicher-Backend für ReMe, ein Toolkit zur Gedächtnisverwaltung von Agenten. ReMe nutzt sie für eine HNSW-basierte approximative Nächste-Nachbarn-Suche im selben Prozess über die Gedächtnisdateien der Agenten. Anwendungen bekommen so Vektorabfragen mit niedriger Latenz, ohne einen eigenen Datenbankprozess zu starten.
Indexalgorithmen
IVF-RaBitQ
RaBitQ kam in früheren Versionen zuerst für HNSW- und Flat-Indizes. Mit 0.7.0 erreicht es auch IVF-Indizes und bietet damit einen weiteren Weg, ein wenig Recall gegen deutlich weniger Speicher bei Daten im Milliardenbereich zu tauschen.
Ein IVF-RaBitQ-Index gruppiert Vektoren in invertierte Listen, und jede Liste wird mit RaBitQ auf etwa ein Bit pro Dimension quantisiert. Der Index bleibt kompakt, unterstützt aber weiterhin Reranking über einen Refiner sowie skalare Filter und nutzt dieselbe Query-API wie bisher. Für Workloads, die zum IVF-Profil passen, also große Batch-Jobs oder speicherknappe Suche, ist das oft die günstigste Option.
SIMD-Dispatch für RaBitQ
RaBitQ wählt seinen schnellsten Codepfad jetzt zur Laufzeit. Auf einer CPU mit AVX512 laufen die AVX512-Kernel, sonst AVX2, und skalarer Code ist die letzte Rückfallebene. Ein einziges Binary profitiert so von neuer Hardware, ohne separate Builds oder Compiler-Flags.
DiskANN, bereit für die Produktion
DiskANN war das Aushängeschild von v0.5.0. Dieses Release macht es schneller, robuster und auf mehr Plattformen verfügbar.
io_uring-Backend. Unter Linux 5.3 und neuer bevorzugt DiskANN io_uring gegenüber libaio. Es spricht den Kernel direkt an, deshalb braucht der Build kein liburing. Die Rückfallreihenfolge lautet io_uring, dann libaio, dann pread, und fehlt ein Backend, verschlechtert sich das Verhalten geordnet statt abzubrechen.
Überlappende asynchrone I/O und dynamischer Beam. Die Beam-Suche überlappt CPU-Arbeit jetzt mit Lesezugriffen auf die Platte und passt die Beam-Breite laufend an, damit die I/O ausgelastet bleibt, ohne die Platte mit Anfragen zu fluten. Plattenlastige Workloads haben dadurch niedrigere Latenzen. Ein zugehöriger Fix bei der Deduplizierung im Visit-Filter entfernt überflüssige Kandidaten-Einfügungen.
ARM64. DiskANN lässt sich unter Linux ARM64 und auf Macs mit Apple Silicon bauen und ausführen. Unter macOS kommt synchrones pread mit F_NOCACHE und abgeschaltetem Read-ahead zum Einsatz, während die CI unter Linux jedes Backend durchtestet. Randfälle wie partielle oder kurze Lesevorgänge, EINTR und der Wechsel zwischen Backends werden sicher behandelt.
Introspektion. Das aktive I/O-Backend wird gecacht und ist über die C-, C++- und Python-APIs sichtbar. So lässt sich zur Laufzeit prüfen, ob Abfragen über io_uring, libaio oder pread laufen.
Bessere Graphqualität
Vamana erhält einen optionalen Build in zwei Durchläufen. Ein schneller erster Durchlauf erzeugt einen groben Graphen, ein zweiter verfeinert ihn – ein guter Tausch, wenn Recall wichtiger ist als die Build-Zeit.
HNSW kann seinen Graphen außerdem aus den ursprünglichen Rohvektoren eines Index-Providers aufbauen, auch wenn der Index für die Suche eine quantisierte oder transformierte Kopie speichert. Der Graphaufbau arbeitet mit voller Präzision, die Qualität steigt, und der Speicherbedarf bei Abfragen bleibt klein.
Auslieferung
Eine schlankere dynamische Bibliothek
Die vorgefertigten Shared Libraries für C und C++ sind unter macOS ARM64 rund 40 % kleiner. So schrumpft etwa libzvec_c_api.dylib von ungefähr 37 MB auf 22 MB. Die öffentlichen APIs bleiben gleich, die Abfragegeschwindigkeit leidet nicht, und der zentrale Suchcode wird weiterhin mit -O3 kompiliert.
Die Einsparung geht auf drei Änderungen zurück:
- Kompilieren mit
-ffunction-sections -fdata-sections, sodass der Linker ungenutzten Code verwirft - Export ausschließlich der eigenen öffentlichen Symbole der Bibliothek über
-exported_symbols_listoder--version-script - protobuf fliegt komplett aus dem Abhängigkeitsbaum
Collection-Manifeste bleiben Byte für Byte kompatibel mit dem bisherigen protobuf-Format. Die Serialisierung übernehmen jetzt ein kleiner interner Encoder und Decoder.
musllinux-Wheels
Es gibt offizielle musllinux-Wheels für x86_64 und ARM64, die Bibliothek lässt sich also problemlos auf Alpine Linux und anderen musl-basierten Systemen installieren. Dafür waren einige musl-spezifische Korrekturen nötig. Große SIMD-Puffer wurden vom standardmäßigen 128-KB-Thread-Stack verlegt, und der Logger wurde zum Meyers-Singleton, damit es keine doppelten __cxa_atexit-Registrierungen über mehrere Shared Libraries hinweg gibt.
Pipeline für vorgefertigte SDKs
Ein GitHub-Release-Workflow erzeugt jetzt einsatzbereite SDK-Pakete für C und C++. Alpha-, Beta- und RC-Tags werden automatisch als Prerelease markiert. Bevor etwas hochgeladen wird, durchläuft jedes Paket einen Smoke-Test. Desktop- und musl-Runner kompilieren kleine Testprogramme in C und C++ und führen sie gegen das bereitgestellte SDK aus. Für Android besteht die Prüfung aus einem Cross-Build, der linken muss, für iOS aus einer Kontrolle beider XCFramework-Slices und des Header-Layouts.
Bedienbarkeit
DocIterator
Wer mit Agentengedächtnis oder ETL arbeitet, will oft jedes Dokument einer Collection ohne Abfragevektor durchgehen. Genau dafür gibt es DocIterator. Beim Erzeugen macht er einen Snapshot der aktuellen Segmente und der Lösch-Bitmap, sodass spätere Schreib- und Löschvorgänge den Durchlauf nicht stören. Er funktioniert aus C++, C und Python, und eine Zulassungskontrolle verhindert, dass sich Durchlauf und Wartungsoperationen überschneiden.
In Python:
with collection.iter_docs(
output_fields=["title"], # only fetch needed scalar fields; primary key is always returned
include_vector=False,
) as docs:
for doc in docs:
print(doc.id, doc.fields["title"])
N-Gramm-Tokenizer für FTS
Die Volltextsuche hat einen neuen N-Gramm-Tokenizer. Er indexiert überlappende Zeichenfolgen der Länge n und ignoriert Wortgrenzen. Das passt zur Phrasen- und Teilstringsuche in kurzen Texten, Code-Bezeichnern und Logzeilen sowie zu Sprachen, in denen Wortgrenzen schwer zu bestimmen sind. n wird beim Anlegen des FTS-Index über extra_params gesetzt.
Performance
- DiskANN überlappt in der Beam-Suche CPU- und Plattenarbeit, die dynamische Beam-Breite hält die Parallelität auf einem vernünftigen Niveau.
- RaBitQ wählt AVX512- oder AVX2-Kernel zur Laufzeit, ein fest vorgegebenes Build-Ziel ist nicht nötig.
- Dead-Code-Elimination in der dynamischen Bibliothek sorgt für kleinere Binaries, die schneller laden und weniger residenten Speicher belegen, während die Such-Kernel bei
-O3bleiben.
Weitere Änderungen und Fixes
- Python-API: neues
collection.close(), Validierung leerer FTS-Abfragen, vontopkund unbekannten Feldnamen sowie sauberere Behandlung von NumPy-Vektoren. - C++-API: öffentliche Namen folgen jetzt
snake_case. - C-API: kein falscher Versionsstring
0.2.1mehr, wenn Git-Tags fehlen. - Korrektheit der Suche: Filter werden validiert, veralteter Filterzustand wird zurückgesetzt, und Heap-Invarianten lassen sich nicht mehr umgehen.
- K-Means: Die Sampling-Gewichte im sphärischen K-MC2 und die Normalisierung der Zentroide wurden korrigiert.
- Speicher: Nicht übereinstimmende Grenzen skalarer Batches werden behandelt, der letzte IPC-Chunk im mmap-Store wird korrekt verarbeitet, schreibende Segmente mit reinen Löschungen werden persistiert, und verwaiste oder ausgemusterte Segmentverzeichnisse werden bei der Wiederherstellung nach Abstürzen und unter Windows aufgeräumt.
- Collections: Lese- und Schreibzugriffe laufen weiter, während
Optimizearbeitet. - Vamana: asymmetrische Abfragemetriken werden berücksichtigt.
- Build und CI: weniger DLL-Exporte unter Windows, veraltete Patch-Marker in Submodulen entfernt, Abhängigkeiten der GitHub Actions aktualisiert, und Checks laufen, sobald Draft-PRs auf „ready“ gesetzt werden.
Die kommenden Arbeiten an der Skalierbarkeit des Speichers, weiteren Algorithmen und zusätzlichen Sprach-SDKs werden im öffentlichen Roadmap-Issue Nummer 309 im GitHub-Repository des Projekts verfolgt.