Von CLIP zu JinaCLIP: Allgemeines Text-Bild-Repräsentationslernen für Suche und multimodales RAG
In letzter Zeit hat der rasante Aufstieg von multimodalen Embedding-Modellen in verschiedenen Branchen Aufmerksamkeit erregt und verändert, wie Maschinen Text und Bilder interpretieren. Trotz erheblicher Fortschritte stehen diese Modelle jedoch vor grundlegenden Herausforderungen, von denen eine die Modalitätslücke ist. Diese Lücke zeigt sich darin, dass Bild- und Text-Embeddings im latenten Raum räumlich weit voneinander entfernt sind, selbst wenn sie dasselbe Objekt beschreiben.
Bei einem kürzlich von Zilliz veranstalteten Unstructured Data Meetup führte uns Bo Wang, Engineering Manager bei Jina AI, durch die Komplexität der Modalitätslücke und den Übergang von OpenAIs CLIP-Modell zu JinaCLIP.
In diesem Blog fassen wir seine wichtigsten Punkte zusammen und implementieren außerdem ein multimodales Ähnlichkeitssuchsystem. Dieses System wird JinaCLIP verwenden, um multimodale Embeddings zu erzeugen, und die Milvus-Vektordatenbank, um ähnliche Embeddings bei einer bestimmten Abfrage zu speichern und abzurufen. Für weitere Details empfehlen wir Ihnen, sich Bos vollständige Ausführungen auf YouTube anzusehen.
Was macht ein gutes Embedding-Modell aus?
Die Hauptfunktion eines Embedding-Modells besteht darin, Dinge wie Texte und Bilder in Vektoren abzubilden, numerische Repräsentationen, die semantische Beziehungen innerhalb der Daten erfassen. Zum Beispiel sollte der Abstand zwischen zwei Vektoren die Ähnlichkeit der beiden Elemente widerspiegeln, die sie repräsentieren, seien es zwei Bilder, zwei Texte oder jeweils eines davon.
Embedding-Modelle stehen im Zentrum moderner KI-Aufgaben wie semantischer Suche, Bildabruf und mehr. Aber was macht ein Embedding-Modell gut?
Vielseitigkeit über Domänen hinweg
Ein gutes Embedding-Modell sollte in einer breiten Palette von Domänen gut funktionieren, ohne Fine-Tuning zu erfordern. Diese Anpassungsfähigkeit stellt sicher, dass die Embeddings universell nützlich sind, unabhängig davon, ob die Eingabe Text, Bilder oder andere Datentypen sind. Wenn beispielsweise ein Bild in einen Vektorraum eingebettet wird und ein zugehöriger Text in denselben Raum eingebettet wird, sollten die beiden Embeddings nahe beieinander liegen und damit ihre semantische Ähnlichkeit signalisieren. Diese breite Anwendbarkeit ist für KI-Aufgaben wie Ähnlichkeitssuche, Bildabruf und domänenübergreifende Anwendungen unerlässlich.
Präzise semantische Ähnlichkeit
Ein zentrales Merkmal eines guten Embedding-Modells ist seine Fähigkeit, links und rechts zu verbinden, indem es Embeddings mit hohen Ähnlichkeitswerten für semantisch verwandte Elemente erzeugt. Dies geht über reine Textdaten hinaus, es gilt für beliebige multimodale Eingaben. Ob Text mit Text, Bild mit Bild oder Text mit Bild verglichen wird, das Modell sollte die korrekten Beziehungen durch die Nähe der Embeddings im Vektorraum widerspiegeln.
Ältere Modelle, die Text- und Bildmodalitäten verbanden, hatten es jedoch schwerer, dieses Ziel zu erreichen. Sie stützten sich auf manuelle Prozesse, wie das Taggen von Bildern oder die Verwendung umgebender Texte, um Verbindungen herzustellen. Diese Methoden führten zu schlechter Generalisierung, insbesondere in Out-of-Distribution-Szenarien.
Die Herausforderung multimodaler Aufgaben
Vor der Einführung von Modellen wie CLIP war das Verknüpfen von Modalitäten (Text und Bilder) eine stark manuelle und hypothesengetriebene Aufgabe. Ob es sich um Flickr-Tags oder von Nutzern hinzugefügte textuelle Beschreibungen handelte, der Prozess war alles andere als nahtlos. Überwachte Ansätze, die häufig Klassifikator-Labels verwendeten, waren anfällig für Instabilität, und ihre Leistung außerhalb der Domäne war unbefriedigend. Das bedeutete, dass man zwar Bilder und Texte verknüpfen konnte, die Ergebnisse jedoch nicht immer konsistent waren, insbesondere wenn die Eingabe komplex war.
Um dieses Problem zu lösen, wurde CLIP, ein kontrastives Sprach-Bild-Vortrainingsmodell, entwickelt, um die Leistung multimodaler Modelle zu verbessern, indem sie mit Bild-Text-Paaren trainiert werden. CLIPs Fähigkeit, die beiden Modalitäten in einem gemeinsamen Einbettungsraum auszurichten, war innovativ. Dieses Modell hat jedoch auch seine Grenzen.
CLIP-Modell: Ein Durchbruch mit Einschränkungen
CLIP setzte einen neuen Standard, indem es zwei separate Encoder trainierte, einen für Text und einen für Bilder. Die Kernidee bestand darin, einen gemeinsamen Einbettungsraum zu lernen, in dem Text- und Bildvektoren koexistieren konnten, wobei semantisch ähnliche Texte und Bilder näher beieinander lagen. Die Ergebnisse waren beeindruckend: CLIP ermöglichte multimodale Aufgaben mithilfe einer einfachen Kosinusähnlichkeitsfunktion.
Abbildung: Wie das CLIP-Modell funktioniert
CLIP hat jedoch seine Schwächen. Ein bedeutendes Problem ist seine Unfähigkeit, reine Textaufgaben effektiv zu bewältigen. Da CLIP hauptsächlich für kurze Bildunterschriften optimiert wurde (oft weniger als 77 Zeichen), stellen längere Texte eine Herausforderung dar. Darüber hinaus fehlten CLIP in seinem Trainingsprozess Hard-Negative-Beispiele. Hard Negatives sind Beispiele, die nah beieinander liegen, aber falsch sind, und sie sind entscheidend für die Verfeinerung von Modellen, insbesondere bei Aufgaben wie der Textsuche. Ohne sie stagnierte CLIPs Leistung bei Aufgaben, die ein detailliertes Textverständnis erfordern.
Übergang zu JinaCLIP: Behebung der Schwächen von CLIP
JinaCLIP baut auf der ursprünglichen CLIP-Architektur auf, um deren Einschränkungen zu beheben. Es erweitert die Texteingabe und verwendet eine angepasste BERT-v2-Architektur für die Textkodierung. Für die Bildverarbeitung integriert JinaCLIP das EVA-02-Modell. Der Trainingsprozess von JinaCLIP konzentriert sich darauf, die Herausforderungen zu überwinden, die durch kurze Texteingaben in Bildunterschriften entstehen, und Hard Negatives einzuführen. Dieser Prozess erfolgt in drei Phasen, wie unten gezeigt:
Abbildung: Trainingsprozess von JinaCLIP
Die Phasen sind Alignment Learning, Integration langer Texte und Fine-Tuning:
Alignment Learning mit kurzen Texten und Bildunterschriften: In dieser Phase wird das Modell sowohl mit beschrifteten Bilddaten als auch mit Textpaaren mit ähnlicher Bedeutung trainiert. Das Ziel besteht darin, Bild- und Texteinbettungen auszurichten, indem gemeinsam auf Text-Bild- und Text-Text-Ähnlichkeit optimiert wird. Dieser Co-Training-Prozess stellt sicher, dass das Modell zwar lernt, Text mit Bildern zu verknüpfen, aber auch seine reinen Textfähigkeiten beibehält. Obwohl die reine Textleistung im Vergleich zum Training ausschließlich mit Textpaaren leicht abnimmt, bewahrt diese Phase einen ausgewogenen Ansatz.
Integration langer Textbeschreibungen: In der zweiten Phase werden synthetische Daten eingeführt, um das Modell zu trainieren. Diese Daten richten Bilder an längeren Texten aus, die von KI-Modellen generiert wurden und den Inhalt detaillierter beschreiben. Gleichzeitig werden weiterhin reine Textpaare für das Training verwendet. Das Modell lernt, umfangreichere Textbeschreibungen zu verarbeiten und gleichzeitig die Ausrichtung mit den Bildern beizubehalten, wodurch seine Fähigkeit verbessert wird, sowohl kurze als auch lange Text-Bild-Beziehungen zu verstehen.
Feinabstimmung mit Text-Triplets und Hard Negatives: Die letzte Phase konzentriert sich auf die Verwendung von Text-Triplets, die Hard Negatives enthalten, also Textpaare, bei denen zwei semantisch ähnlich sind, eines jedoch absichtlich anders ist. Dies hilft dem Modell, feinere semantische Unterscheidungen zu treffen, insbesondere in reinen Textszenarien. Gleichzeitig trainiert das Modell weiterhin mit synthetischen Bild-Langtext-Paaren. Diese Phase verbessert die reine Textleistung des Modells erheblich und stellt zugleich sicher, dass die in früheren Phasen gelernte Bild-Text-Ausrichtung robust bleibt.
Dieser Ansatz sorgt für eine starke Leistung bei multimodalen Aufgaben und verbessert gleichzeitig die Fähigkeiten in reinen Textszenarien. Sehen wir uns an, wie dieser neue Ansatz im Vergleich zum ursprünglichen Clip abschneidet.
Leistungsmetriken zeigen Veränderungen in der Retrieval-Leistung im Vergleich zum ursprünglichen CLIP-Modell: eine Veränderung von 165 % bei Text-zu-Text, 12 % bei Bild-zu-Bild, 6 % bei Bild-zu-Text und 2 % bei Text-zu-Bild-Retrieval, wie in der folgenden Abbildung gezeigt.
Abbildung: Vergleich der Modellleistung zwischen jina-clip, openai-clip-vit-b-16 und jina-embeddings-v2-base-en
Der neue Trainingsprozess verbessert die Generalisierung über Aufgaben hinweg und hilft, die Modalitätslücke zu verringern. Lassen Sie uns die Modalitätslücke besprechen, ein großes Hindernis in multimodalen KI-Modellen, und warum dieses Problem entsteht.
Die Modalitätslücke: Warum sie entsteht
Die Modalitätslücke ist die räumliche Trennung zwischen Einbettungen aus unterschiedlichen Eingabetypen, wie etwa Texten und Bildern, die semantisch ähnlich sind, aber im Vektorraum weit voneinander entfernt liegen. Diese Lücke schwächt die Effektivität multimodaler Retrieval-Systeme, da die Einbettungen die tatsächliche Beziehung zwischen verwandten Eingaben nicht vollständig widerspiegeln. Wie Sie in der folgenden Abbildung sehen können, sieht die Darstellung wie ein abgeschnittener Kegel aus, mit Bildeinbettungen an einem Ende und Texteinbettungen am anderen, was die Modalitätslücke deutlich zeigt.
Abbildung: Die anfänglichen Positionen von Bild- und Texteinbettungen in Jina CLIP, mit vollständig randomisierten Gewichten und ohne vorheriges Training, in zwei Dimensionen projiziert
Es gibt einige zentrale Gründe, warum diese Lücke selbst in modernen Modellen entsteht:
Der Kegel-Effekt während der Initialisierung
Multimodale Modelle, insbesondere solche, die Text- und Bildeingaben verarbeiten, verwenden häufig separate Encoder für jede Modalität. Diese Encoder werden typischerweise mit zufälligen oder vortrainierten Gewichten initialisiert, was dazu führt, dass sich Texteinbettungen in einem Bereich des Vektorraums und Bildeinbettungen in einem anderen gruppieren, wie in der obigen Abbildung zu sehen ist. Diese anfängliche Trennung, der sogenannte Kegel-Effekt, erschwert es Einbettungen aus unterschiedlichen Modalitäten (z. B. Bildern und zugehörigen Texten), sich korrekt auszurichten. Beispielsweise können die Texteinbettung für a fluffy cat und die Bildeinbettung einer Katze aufgrund dieser Initialisierungsverzerrung zunächst weit voneinander entfernt liegen, obwohl sie semantisch verwandt sind.
Temperatur-Skalierung
Während des Trainings verwenden KI-Modelle eine Technik namens Temperatur-Skalierung in ihrer kontrastiven Verlustfunktion, um anzupassen, wie eng Einbettungen ausgerichtet werden. Während sie hilft, die Abstände zwischen Einbettungen fein abzustimmen, kann die Temperatur-Skalierung auch unbeabsichtigt die anfängliche Trennung zwischen Modalitäten bewahren und so die Modalitätslücke verstärken. Wenn die Temperatur-Skalierung beispielsweise nicht sorgfältig abgestimmt wird, könnten die Einbettungen für a playful puppy und das Bild eines Hundes im Vektorraum zu weit voneinander entfernt bleiben, obwohl sie dasselbe Konzept beschreiben.
In-Batch False Negatives
Beim Training mit großen Datensätzen werden nicht übereinstimmende Paare von Datenpunkten (z. B. ein Bild eines Hundes, das mit dem Text „a red apple” gepaart ist) als negative Beispiele behandelt. Diese falschen Negative können jedoch dennoch eine gewisse semantische Überschneidung aufweisen. Wenn sich beispielsweise beide Elemente auf eine breite Kategorie von Tieren beziehen (z. B. ein Bild eines Hundes und der Text „a playful wolf”), könnte das Modell diese Einbettungen weiter auseinanderdrücken als nötig, wodurch die Modalitätslücke weiter verschärft wird, indem sie fälschlicherweise als vollständig unzusammenhängend behandelt werden.
Zu verstehen, warum die Modalitätslücke entsteht, ist nur der erste Schritt. Um diese Lücke zu schließen, wurden verschiedene Trainingsstrategien entwickelt, um Einbettungen aus unterschiedlichen Modalitäten näher zusammenzubringen und so eine genauere Suche in multimodalen Aufgaben sicherzustellen.
Die Modalitätslücke angehen: Trainingstechniken und mehr
Die Modalitätslücke ist ein strukturelles Problem, für das es keine einfache Lösung gibt, aber es gibt Strategien, um ihre Auswirkungen zu mindern. Entscheidend ist, die Trennung zwischen Einbettungen aus verschiedenen Modalitäten während des Trainings zu verringern und sicherzustellen, dass Bilder und Texte, die zusammengehören, im Vektorraum näher beieinander abgebildet werden.
Höhere Temperaturskalierung
In der Praxis kann eine Erhöhung der Temperatur während des Trainings Einbettungen aus verschiedenen Modalitäten dazu anregen, näher zusammenzurücken, indem dem Lernprozess des Modells mehr Zufälligkeit hinzugefügt wird. Beispielsweise kann eine höhere Temperatur helfen, die Einbettungen eines Bildes einer Katze und des Textes „a fluffy cat” enger aufeinander abzustimmen. Dies geht jedoch zulasten einer langsameren Konvergenz und erfordert mehr Rechenressourcen. Während Modelle, die mit hoher Temperaturskalierung trainiert wurden, tendenziell die Ausrichtung von Text- und Bildeinbettungen verbessern, besteht der Kompromiss häufig in längeren Trainingszeiten und höheren Rechenanforderungen.
Hard-Negative Sampling
Die Einführung von Hard-Negative-Beispielen, also nicht übereinstimmenden Paaren, die semantisch nahe beieinander liegen, ist eine weitere Technik zur Verringerung der Modalitätslücke. Diese Hard-Negative-Paare bringen das Modell dazu, feinere Unterschiede zwischen verwandten Konzepten zu lernen, wodurch die Genauigkeit der Suche verbessert wird. Beispielsweise mag die Paarung eines Bildes einer Katze mit dem Text „a small tiger” wie eine Fehlübereinstimmung erscheinen, aber das Modell lernt, dass diese beiden Eingaben überlappende Semantik haben (beide sind Katzenartige) und im Einbettungsraum dennoch in gewissem Maße ausgerichtet sein sollten. Dieser Prozess lehrt das Modell, sowohl die Ähnlichkeiten als auch die Unterschiede zwischen verwandten Konzepten zu erkennen, und verfeinert seine Fähigkeit, zwischen nahezu passenden Treffern zu unterscheiden.
Multimodale Suche mit Milvus und JinaCLIP: Ein praktisches Beispiel
Nachdem wir nun die technischen Gründe hinter der Modalitätslücke untersucht haben, tauchen wir in ein praktisches Beispiel ein, wie man ein multimodales Suchsystem mit Milvus, einer Open-Source-Vektordatenbank, und JinaCLIP aufbaut.
Milvus verwaltet, durchsucht und fragt hochdimensionale Vektoren ab und ist damit eine ideale Lösung für multimodale Suchaufgaben und Aufgaben der Retrieval Augmented Generation (RAG). Ob Sie mit Text, Bildern oder anderen Datentypen arbeiten, Milvus ermöglicht es Ihnen, Einbettungen effizient zu speichern und relevante Ergebnisse mithilfe fortschrittlicher Ähnlichkeitssuchtechniken abzurufen.
In diesem Abschnitt gehen wir den Prozess durch, Milvus zu verwenden, um ein multimodales Suchsystem zu erstellen, das Text- und Bildeinbettungen verarbeitet. Das System ermöglicht es Benutzern, entweder Text oder Bilder einzugeben und die semantisch relevantesten Ergebnisse aus einem gemischten Datensatz abzurufen.
Schritt 1: Einrichten der Umgebung
Zunächst müssen wir die Bibliotheken installieren, die wir für unser System in unserer Umgebung benötigen:
!pip install pymilvus transformers torch timm
Dann müssen wir die notwendigen Bibliotheken importieren und unsere Encoder-Klasse einrichten.
# Import necessary libraries
from transformers import AutoModel
from pymilvus import MilvusClient
import torch
# Define Encoder class to handle text and image embedding generation
class Encoder:
def __init__(self, model_name: str):
# Initialize the model (AutoModel from transformers instead of SentenceTransformer)
self.model = AutoModel.from_pretrained(model_name, trust_remote_code=True)
def encode_text(self, text: list[str]) -> list[float]:
# Generate embeddings for text only
with torch.no_grad():
text_emb = self.model.encode_text(text)
return text_emb
def encode_image(self, image_urls: list[str]) -> list[list[float]]:
# Generate embeddings for images only
with torch.no_grad():
image_emb = self.model.encode_image(image_urls)
return image_emb
# Initialize the encoder with the model jinaai/jina-clip-v1
model_name = "jinaai/jina-clip-v1"
encoder = Encoder(model_name)
Im obigen Code importieren wir zunächst die erforderlichen Bibliotheken: AutoModel aus transformers für unser Encoding-Modell, MilvusClient für die Interaktion mit Milvus und torch für Tensor-Operationen.
Anschließend definieren wir eine Encoder-Klasse, die das AutoModel aus transformers kapselt. Die Methoden encode_text und encode_image verwenden das Modell, um Einbettungen für Text bzw. Bilder zu generieren. Der Kontextmanager torch.no_grad() wird verwendet, um die Gradientenberechnung zu deaktivieren, die für die Inferenz nicht benötigt wird und Speicher spart.
Schließlich initialisieren wir den Encoder mit dem Modell jinaai/jina-clip-v1, das sowohl Text als auch Bilder in einen gemeinsamen Einbettungsraum codieren kann.
Schritt 2: Vorbereiten der Daten
Als Nächstes bereiten wir unsere Beispieldaten für die Einbettung und das Einfügen in Milvus vor.
# Load data: images and text for embeddings
sentences = ['A blue cat', 'A red cat', 'A red cat generated by AI', 'A dog biting on a stick']
image_urls = [
'https://i.pinimg.com/600x315/21/48/7e/21487e8e0970dd366dafaed6ab25d8d8.jpg',
'https://i.pinimg.com/736x/c9/f2/3e/c9f23e212529f13f19bad5602d84b78b.jpg',
'https://images.fineartamerica.com/images/artworkimages/mediumlarge/1/red-cat-art-3771-bb-james-ahn.jpg',
'https://images.squarespace-cdn.com/content/v1/54822a56e4b0b30bd821480c/29708160-9b39-42d0-a5ed-4f8b9c85a267/labrador+retriever+dans+pet+care.jpeg?format=1500w'
]
# Generate embeddings for text and images
text_embeddings = encoder.encode_text(sentences)
image_embeddings = encoder.encode_image(image_urls)
# Ensure consistent dimensions
dim = len(image_embeddings[0])
Hier definieren wir Listen mit Beispielsätzen und Bild-URLs. Die URLs enthalten Bilder von roten Katzen, blauen Katzen und einem Hund. Anschließend verwenden wir unseren Encoder, um Einbettungen sowohl für den Text als auch für die Bilder zu generieren. Die Variable dim speichert die Dimension der Einbettungen, die wir beim Erstellen unserer Milvus-Collection benötigen.
Schritt 3: Einrichten von Milvus
Jetzt richten wir unseren Milvus-Client ein und erstellen eine Collection für unsere multimodalen Daten.
# Insert embeddings into Milvus
collection_name = "multimodal_rag_demo"
milvus_client = MilvusClient(uri="./milvus_demo.db")
# Check if collection exists and drop it if so
if milvus_client.has_collection(collection_name):
print(f"Collection {collection_name} already exists. Deleting it...")
milvus_client.drop_collection(collection_name)
# Create Milvus collection
milvus_client.create_collection(
collection_name=collection_name,
auto_id=True,
dimension=dim,
enable_dynamic_field=True,
)
Wir initialisieren einen Milvus-Client und stellen eine Verbindung zu einer lokalen Datenbankdatei her. Wir prüfen, ob bereits eine Collection mit unserem gewünschten Namen existiert, und löschen sie in diesem Fall, um einen sauberen Ausgangszustand sicherzustellen.
Anschließend erstellen wir eine neue Collection mit dem angegebenen Namen. Der Parameter auto_id=True weist Milvus an, automatisch IDs für unsere Einträge zu generieren. Wir setzen dimension so, dass sie unseren Einbettungen entspricht, und aktivieren dynamische Felder, wodurch wir unseren Einträgen zusätzliche Metadaten hinzufügen können.
Schritt 4: Erstellen eines Index
Vor dem Einfügen von Daten erstellen wir einen Index, um die Suchleistung zu optimieren:
index_params = MilvusClient.prepare_index_params()
index_params.add_index(
field_name="vector", # The field to be indexed (your embedding field)
metric_type="COSINE", # Can be L2, COSINE, etc.
index_type="FLAT", # FLAT ensures exact search, ideal for small datasets
)
# Create the index for the collection
milvus_client.create_index(collection_name, index_params)
print(f"Index created successfully for collection: {collection_name}")
Der obige Code erstellt einen FLAT-Index unter Verwendung von Kosinus-Ähnlichkeit als Distanzmetrik.
Schritt 5: Einfügen von Daten in Milvus
Nachdem unsere Collection und unser Index eingerichtet sind, können wir nun unsere Daten in Milvus einfügen.
data_to_insert = []
# Insert text embeddings
for idx, txt_emb in enumerate(text_embeddings):
data_to_insert.append({"text": sentences[idx], "vector": txt_emb})
# Insert image embeddings
for idx, img_emb in enumerate(image_embeddings):
data_to_insert.append({"image_url": image_urls[idx], "vector": img_emb})
# Insert data into Milvus
insert_result = milvus_client.insert(
collection_name=collection_name,
data=data_to_insert,
)
print(f"Insert result: {insert_result}")
milvus_client.load_collection(collection_name)
Im obigen Code erstellen wir eine Liste von Dictionaries, die jeweils entweder einen Textsatz oder eine Bild-URL zusammen mit dem entsprechenden Embedding-Vektor enthalten. Anschließend verwenden wir die insert-Methode des Milvus-Clients, um diese Daten unserer Collection hinzuzufügen. Nach dem Einfügen laden wir die Collection in den Arbeitsspeicher, um sie für die Suche vorzubereiten.
Schritt 6: Durchführen einer multimodalen Suche
Schließlich führen wir eine multimodale Suche mit Bild- und Textabfragen durch.
# Multimodal search with a combination of image and text query
query_image_url = 'https://imgcdn.stablediffusionweb.com/2024/4/5/5e70d71c-a7f6-44e9-972d-8c5a27d45c3d.jpg'
query_text = "Give me similar red cats"
# Generate query embedding (image + text)
query_embedding_image = encoder.encode_image([query_image_url])[0]
query_embedding_text = encoder.encode_text([query_text])[0]
# Perform search in Milvus using image embedding
search_results_image = milvus_client.search(
collection_name=collection_name,
data=[query_embedding_image],
output_fields=["image_url", "text"], # Ensure both fields are included in the results
limit=5, # Number of results to return
search_params={"metric_type": "COSINE", "params": {"nprobe": 10}}
)
# Perform search in Milvus using text embedding
search_results_text = milvus_client.search(
collection_name=collection_name,
data=[query_embedding_text],
output_fields=["image_url", "text"], # Ensure both fields are included in the results
limit=5, # Number of results to return
search_params={"metric_type": "COSINE", "params": {"nprobe": 10}}
)
# Retrieve and print results from image query
print("Image Query Results:")
for result in search_results_image:
for hit in result:
image_url = hit['entity'].get('image_url')
text = hit['entity'].get('text')
if image_url:
print(f"Retrieved Image URL (from image query): {image_url}")
if text:
print(f"Retrieved Text (from image query): {text}")
# Retrieve and print results from text query
print("Text Query Results:")
for result in search_results_text:
for hit in result:
image_url = hit['entity'].get('image_url')
text = hit['entity'].get('text')
if image_url:
print(f"Retrieved Image URL (from text query): {image_url}")
if text:
print(f"Retrieved Text (from text query): {text}")
Im obigen Code demonstrieren wir den Prozess der Durchführung einer multimodalen Suche. Wir beginnen damit, sowohl eine Abfragebild-URL als auch einen Abfragetext zu definieren. Das Abfragebild sieht so aus:
Abbildung 2: Abfrageeingabebild einer rot-weißen Katze
Anschließend kodieren wir diese Abfragen mithilfe unseres Encoders, um ihre jeweiligen Embeddings zu erzeugen. Danach führen wir zwei separate Suchen in Milvus durch: eine mit dem Bild-Embedding und eine weitere mit dem Text-Embedding. Für jede Suche fordern wir sowohl die Felder image_url als auch text in der Ausgabe an, wodurch wir beide Datentypen abrufen können. Wir beschränken unsere Ergebnisse auf jeweils 5 pro Suche und verwenden die Kosinus-Ähnlichkeit als Distanzmetrik. Der Parameter nprobe in unseren Suchparametern ermöglicht es uns, die Anzahl der zu durchsuchenden Cluster fein abzustimmen und bietet so ein Gleichgewicht zwischen Suchgeschwindigkeit und Genauigkeit. Schließlich zeigen wir die Ergebnisse an und veranschaulichen, welche Bilder oder Texte für jeden Abfragetyp abgerufen wurden, wodurch die Fähigkeit des Systems demonstriert wird, sowohl text- als auch bildbasierte Abfragen zu verarbeiten und miteinander zu korrelieren.
Den vollständigen Code finden Sie hier.
Hier sind Beispielergebnisse:
Wie Sie sehen können, erhalten wir, wenn wir ein Bild verwenden, um eine Vektorsuche durchzuführen, sowohl Bild-URLs als auch Text, der mit dem Bild in Zusammenhang steht, und umgekehrt. Das ist die Stärke der multimodalen Suche. Hier ist eines der Bilder, das in beiden Fällen als ähnliches Bild abgerufen wird.
Abbildung 3: Ausgabebild einer roten Katze nach der Durchführung einer Ähnlichkeitssuche in Milvus
Wie Sie sehen können, ähnelt das Bild dem Bild der roten Katze, das wir dem System als unsere Abfrage gegeben haben.
Sie können diesem System einen Reranker hinzufügen, um die Suchergebnisse nach Relevanz zu ordnen, wobei die relevantesten Ergebnisse ganz oben erscheinen. Allerdings leistet Milvus, wie deutlich zu sehen ist, bereits gute Arbeit darin, die besten Treffer zuerst abzurufen. Sie können dieses System auch weiterentwickeln, um ein multimodales RAG-System zu erstellen.
Fazit
Bo Wang erläuterte die Feinheiten der Überbrückung der Modalitätslücke in multimodalen Modellen und zeigte den Übergang von CLIP zu JinaCLIP. Er schlüsselte die zentralen Herausforderungen der Text-Bild-Ausrichtung auf und demonstrierte, wie JinaCLIP diese Probleme angeht.
In diesem Artikel haben wir seine Erkenntnisse erweitert, indem wir ein multimodales Ähnlichkeitssuchsystem aufgebaut haben, das JinaCLIP zur Erzeugung von Embeddings und Milvus für einen effizienten Abruf verwendet. Mit diesem Wissen können Sie nun Ihre eigenen multimodalen Suchanwendungen implementieren, eine nahtlose Leistung über text- und bildbasierte Abfragen hinweg sicherstellen und das System sogar weiter ausbauen, indem Sie fortgeschrittene Suchtechniken wie Reranking integrieren.
Weitere Ressourcen
Weiterlesen

Zilliz Cloud Now Available in Azure North Europe: Bringing AI-Powered Vector Search Closer to European Customers
The addition of the Azure North Europe (Ireland) region further expands our global footprint to better serve our European customers.

Introducing Zilliz MCP Server: Natural Language Access to Your Vector Database
Developers can easily manage and query vector databases with natural language via Zilliz MCP Server in AI-native environments.

DeepSeek-VL2: Mixture-of-Experts Vision-Language Models for Advanced Multimodal Understanding
Explore DeepSeek-VL2, the open-source MoE vision-language model. Discover its architecture, efficient training pipeline, and top-tier performance.


