Was ist Pymilvus?
Einführung
Pymilvus ist das Python-SDK, das für Milvus und Zilliz Cloud entwickelt wurde. Es ist ein gRPC-basierter Client, der ein gemeinsames Milvus-Protobuf verwendet, das von allen SDKs geteilt wird. Sowohl neuen als auch fortgeschrittenen Benutzern bietet es Zugriff auf alle von Milvus angebotenen Funktionen und ist eines unserer beliebtesten SDKs.
Probleme, die wir festgestellt haben
Die zentrale Idee hinter der Milvus-Vektordatenbank besteht darin, Benutzern so viele Stellschrauben wie möglich zu geben, um das System auf ihren spezifischen Anwendungsfall feinabzustimmen. Allerdings ist approximative Suche im Kern approximativ; es gibt keinen universellen Algorithmus. Jeder der Algorithmen glänzt in Bezug auf Rechenaufwand vs. Geschwindigkeit vs. Recall/Genauigkeit. Darüber hinaus kann jeder der Algorithmen so konfiguriert werden, dass ein anderes Gleichgewicht zwischen den vorherigen Kategorien erreicht wird. Zum Beispiel HNSW vs. IVF-PQ. IVF-PQ ist auf Rechenaufwand und Geschwindigkeit optimiert und reduziert den Speicherbedarf und die Suchzeiten erheblich, allerdings auf Kosten eines deutlich reduzierten Recalls. HNSW ist das Gegenteil; HNSW opfert Rechenleistung zugunsten von Geschwindigkeit und Recall. Das Spannende ist, dass ihre Stärken durch Konfiguration ausgetauscht werden können. Diese gesamte Konfiguration befindet sich nur auf Indexebene. Auf Clusterebene müssen Abwägungen in Bezug auf Kosten vs. Geschwindigkeit vorgenommen werden, was für jeden Benutzer einzigartig ist. Einige Benutzer legen möglicherweise keinen Wert auf hohe Verfügbarkeit und möchten keine Replikation. Einige Benutzer legen möglicherweise keinen Wert auf Konsistenz und wären lieber weniger konsistent zugunsten der Geschwindigkeit. Einige Benutzer möchten ihren Daten möglicherweise eine TTL zuweisen, um Speicherkosten zu reduzieren, während andere jede Operation gesichert haben möchten. Obwohl diese Anpassbarkeit für große Benutzer hervorragend ist, bei denen das Austarieren bei Datensätzen in Milliardenhöhe vorteilhaft ist, sorgen all diese Stellschrauben bei kleineren Benutzern einfach für zu viel Verwirrung.
Zusätzlich dazu, dass diese Stellschrauben ein Problem darstellen, sind Zilliz Cloud und Milvus derzeit aufgrund von Indizes und Verbindungsparametern nicht austauschbar.
Was ist MilvusClient
MilvusClient ist ein Versuch, die API für die meisten Benutzer zu vereinfachen. Viele Benutzer möchten sich nicht mit Verbindungen, Schemas, Indexierung, Laden, Parametern usw. befassen. MilvusClient verbirgt all diese Aspekte, indem es das Pymilvus-SDK mit einer einfachen API umhüllt, die sowohl für Milvus als auch für Zilliz identisch ist. Derzeit bietet es:
- insert_data()
- upsert_data()
- search_data()
- query_data()
- get_vectors_by_pk()
- delete_by_pk()
- add_partition()
- remove_partition()
Diese Funktionen wurden als die Schlüsselfunktionen festgelegt, die jeder grundlegende Benutzer benötigen würde. Derzeit werden die Operationen von Pymilvus angeboten, aber es gibt viele zusätzliche Dinge, die getan werden müssen, um sicherzustellen, dass sie korrekt funktionieren.
insert_data:
Mit MilvusClient ist es nicht erforderlich, ein Schema für eine Collection zu erstellen. Stattdessen wird das Schema automatisch aus den eingefügten Daten generiert. Dies beinhaltet die Bestimmung des erforderlichen FieldSchema und dessen Organisation. Viele Benutzer empfanden das Erstellen dieses Schemas als Problemstelle, weshalb wir dies im Hintergrund erledigen. Sobald dynamisches Schema unterstützt wird, können wir die Implementierung ändern, ohne Änderungen für den Benutzer vorzunehmen.
def _infer_fields(self, data):
"""Infer all the fields based on the input data."""
# TODO: Assuming ordered dict for 3.7
fields = {}
# Figure out each datatype of the input.
for key, value in data.items():
# Infer the corresponding datatype of the metadata
dtype = infer_dtype_bydata(value)
# Datatype isnt compatible
if dtype in (DataType.UNKNOWN, DataType.NONE):
logger.error(
"Failed to parse schema for collection %s, unrecognized dtype for key: %s",
self.collection_name,
key,
)
raise ValueError(f"Unrecognized datatype for {key}.")
# Create an entry under the field name
fields[key] = {}
fields[key]["name"] = key
fields[key]["dtype"] = dtype
# Area for attaching kwargs for certain datatypes
if dtype == DataType.VARCHAR:
fields[key]["max_length"] = 65_535
return fields
Für MilvusClient wollten wir bei einem Datenformat bleiben, das anderen Projekten in diesem Bereich ähnelt – einer Liste von Dictionaries. Dieses Format ist leicht zu verstehen und zu handhaben und entspricht den Documents, die man in LlamaIndex und LangChain findet. Dieses Format ist jedoch nicht mit pymilvus kompatibel, da insert von pymilvus spaltenorientierte Daten als Liste von Listen entgegennimmt. Dieses spaltenorientierte Datenformat ist nicht einfach zu handhaben, da es erfordert, die Listen exakt in der Reihenfolge anzuordnen, in der das Schema erstellt wurde, und keine Flexibilität bot. Darüber hinaus könnten die Fehlermeldungen, die bei falsch formatierten Daten ausgegeben werden, besser sein.
for k in data:
for key, value in k.items():
if key in self.fields:
insert_dict.setdefault(key, []).append(value)
for i in self.tqdm(range(0, len(data), batch_size), disable=not progress_bar):
# Convert dict to list of lists batch for insertion
try:
insert_batch = [
insert_dict[key][i : i + batch_size]
for key in self.fields
if key != ignore_pk
]
Angesichts all der künftigen Änderungen für Schema, JSONs usw. ermöglicht uns ein Wrapper um ein einfaches insert, die Schwerarbeit zu übernehmen und dem Benutzer eine einfache API zu belassen.
upsert_data:
In Version 2.2 existiert upsert in Milvus nicht. Um ein upsert durchzuführen, ist es notwendig, ein delete -> insert auszuführen. Da viele Benutzer nach dieser Funktion suchen, haben wir beschlossen, sie in den Client aufzunehmen. Sobald die Funktion zu pymilvus hinzugefügt wurde, können wir sie leicht ändern, ohne Änderungen am Code des Benutzers zu erfordern.
pks = [x[self.pk_field] for x in data]
self.delete_by_pk(pks, timeout)
ret = self.insert_data(
data=data,
timeout=timeout,
batch_size=batch_size,
partition=partition,
progress_bar=progress_bar,
)
search_data:
Die wichtigsten Änderungen am search-Befehl waren Standard-Suchparameter und die Umwandlung der Ausgaben in eine Ausgabe als Liste von Dictionaries.
ret = []
for hits in res:
query_result = []
for hit in hits:
ret_dict = {x: hit.entity.get(x) for x in return_fields}
query_result.append({"score": hit.score, "data": ret_dict})
ret.append(query_result)
query_data:
Die wichtigsten Änderungen am query-Befehl waren die Umwandlung der Ausgaben in eine Liste von Dictionaries.
get_vectors_by_pk:
Das Extrahieren von Vektoren in pymilvus erfolgt über querying. Was viele Benutzer nicht wissen, ist, dass die query auf Basis eines Primärschlüssel-Filters erfolgen muss. Darüber hinaus müsste bei Verwendung eines varchar-Primärschlüssels der Ausdruck in der query maskierte Anführungszeichen enthalten, was für Benutzer mühsam und unbekannt ist.
# Varchar pks need double quotes around the values
if self.fields[self.pk_field] == DataType.VARCHAR:
ids = ['"' + str(entry) + '"' for entry in pks]
expr = f"""{self.pk_field} in [{','.join(ids)}]"""
else:
ids = [str(entry) for entry in pks]
expr = f"{self.pk_field} in [{','.join(ids)}]"
delete_by_pk:
Ähnlich wie get_vectors_by_pk.
add_partition und delete_partition:
Für die Partitionslogik müssen Benutzer wissen, dass das Ändern von Partitionen das Entladen und Laden einer Collection erfordert. Dies wird nun im Hintergrund gehandhabt.
Fazit:
Insgesamt besteht das Hauptziel dieses Clients darin, benutzerfreundliche Operationen hinzuzufügen, die auf der pymilvus-Seite nicht existieren oder nicht optimiert sind. Wenn pymilvus verbessert wird, werden wir diese Operationen im Hintergrund optimieren und eine einfach zu verwendende API beibehalten können.
Weiterlesen

VDBBench Adds Cost-Aware Benchmarking for Vector Databases
Compare Zilliz Cloud, Pinecone, and turbopuffer with VDBBench cost-aware vector database benchmarks across latency, freshness, multitenancy, and cold starts.

The AWS Outage Was a Wake-Up Call for Vector Database Cross-Region Disaster Recovery
Zilliz Cloud Had the Answer Before the Crisis. Zilliz Cloud is the world's first vector database with native cross-region disaster recovery.

What Exactly Are AI Agents? Why OpenAI and LangChain Are Fighting Over Their Definition?
AI agents are software programs powered by AI that can perceive their environment, make decisions, and take actions to achieve a goal—often autonomously.



