In diesem Blogbeitrag werde ich Sie durch die Grundlagen von Vektordatenbanken, der Vektorsuche und dem Langchain-Paket in Python führen, das das Speichern und Abrufen vergleichbarer Vektoren erleichtert.
Um unsere Reise zu beginnen, beginnen wir mit einem zentralen Konzept namens „Einbettungen“.
In diesem Artikel untersuchen wir das Konzept der Einbettungen – ein grundlegender Aspekt des maschinellen Lernens, der es uns ermöglicht, Textdaten in einem Format darzustellen, das Maschinen leicht verstehen können.
Einbettungen dienen im Wesentlichen als Vektordarstellungen von Text und wandeln das komplexe Netz aus Wörtern, Sätzen und Passagen in ein numerisches Format um, das Maschinen verarbeiten können.
Es stellt sich eine drängende Frage: Können Menschen diese Einbettungen entschlüsseln? Die Antwort ist nein. Einbettungen sind im Wesentlichen Zahlenfolgen, die Textinformationen verkapseln.
Folglich kann das Verstehen und Arbeiten mit einem Einbettungsvektor für Menschen eine entmutigende Aufgabe sein, während Maschinen damit problemlos umgehen können.
Es gibt unzählige Techniken zum Generieren von Einbettungen aus Text. Zu den bemerkenswerten Methoden gehören unter anderem TF-IDF, Word2Vec, Glove und BERT. Im heutigen Bereich des maschinellen Lernens haben Satzeinbettungen gegenüber Worteinbettungen an Popularität gewonnen.
Diese Satzeinbettungen, die die Essenz eines Textes darstellen, können aus vorab trainierten Satztransformatormodellen wie „all-MiniLM-L6-V2“ und „all-mpnet-base-v2“ erhalten werden.
Diese Modelle erzeugen Einbettungen mit festen Abmessungen, typischerweise 384 oder 768 Abmessungen, für einen bestimmten Text.
Nachdem wir nun die Grundlagen von Einbettungen und verschiedene Techniken zu ihrer Erzeugung untersucht haben, konzentrieren wir uns nun auf die Herausforderung, diese hochdimensionalen Einbettungsvektoren in einem Vektorspeicher zu speichern.
Ein Vektordatenspeicher ist eine spezielle Datenbank zum Speichern hochdimensionaler Einbettungsdarstellungen verschiedener Datentypen, einschließlich Audio, Video, Bilder, Text und mehr.
Eine seiner Kernfunktionen ist die Möglichkeit, im Store effizient nach Vektoren zu suchen, die einem bestimmten Abfragevektor sehr ähnlich sind.
Vektorspeicher optimieren den Prozess der Speicherung von Einbettungen und der Durchführung von Ähnlichkeitssuchen zwischen diesen Vektoren und vereinfachen so die Verwaltung und den Abruf hochdimensionaler Datendarstellungen.
Im Bereich der Vektoreinbettungen umfasst die Ähnlichkeitssuche die Quantifizierung der Nähe oder Verwandtschaft zwischen zwei oder mehr Einbettungen. Typischerweise wird dies durch die Berechnung der Ähnlichkeit mithilfe verschiedener Distanzmetriken erreicht. Zu den häufig verwendeten und weithin anerkannten Distanzmaßen gehören unter anderem die Euklidische Distanz, die Manhattan-Distanz und die Kosinus-Distanz. Mithilfe dieser Metriken können wir den Grad der Ähnlichkeit oder Unähnlichkeit zwischen Vektoren beurteilen und so eine effektive Ähnlichkeitssuche innerhalb der Daten ermöglichen.
Wenn beispielsweise die Ähnlichkeit oder Nähe zwischen zwei Punkten in einem Diagramm bestimmt wird, wird üblicherweise der euklidische Abstand verwendet. Dieser Abstand kann mit der folgenden Formel berechnet werden:
Euklidischer Abstand = [(x2 - x1)^2 + (y2 - y1)^2]^0,5
Hier repräsentiert (x1, y1) die Koordinaten des ersten Punkts und (x2, y2) die Koordinaten des zweiten Punkts im Diagramm. Das Ergebnis dieser Berechnung liefert ein Maß für den räumlichen Abstand zwischen den beiden Punkten und gibt Aufschluss über ihre Ähnlichkeit oder Unähnlichkeit hinsichtlich ihrer Positionen innerhalb des Diagramms.
In ähnlicher Weise werden bei der Ähnlichkeitssuche Einbettungen in einem hochdimensionalen Raum dargestellt, wobei jeder Datensatz als Datenpunkt dient.
Die folgende Codezeile zeigt, wie die fünf häufigsten ähnlichen Einbettungen für bestimmte Eingabedaten abgerufen werden:
distance, n = vector_store.search(input_embedding, k=5)
Dieser Code würde eine Liste der fünf wichtigsten Einbettungen zurückgeben, die den Eingabedaten sehr ähneln, was ihn zu einem wertvollen Werkzeug für verschiedene Anwendungen wie Empfehlungssysteme, Inhaltsabruf und mehr macht.
Die Ausgabe der Funktion „vector_store.search()“ umfasst die Top-k-ähnlichen Einbettungen zusammen mit ihren jeweiligen Abständen von der Eingabeeinbettung. Der Parameter „k“ ist ein konfigurierbarer Wert, der die Anzahl der nächstgelegenen Einbettungen bestimmt, die bei der Ähnlichkeitssuche abgerufen werden sollen. Sie können „k“ festlegen, um die gewünschte Anzahl der von der Suchoperation zurückgegebenen Ergebnisse zu steuern.
Nachdem wir nun ein grundlegendes Verständnis von Vektorspeichern aufgebaut haben, beschäftigen wir uns nun mit dem LangChain-Paket und FAISS. Diese Tools werden unsere Fähigkeit, mit hochdimensionalen Einbettungen zu arbeiten und effiziente Ähnlichkeitssuchen durchzuführen, weiter verbessern.
Vereinfacht ausgedrückt handelt es sich bei LangChain um ein Framework zum Erstellen von Anwendungen, die die Funktionen von Large Language Models (LLMs) nutzen. Ausführlichere Informationen und Ressourcen finden Sie in der offiziellen LangChain-Dokumentation.
Umgekehrt ist FAISS, was für „Facebook AI Similarity Search“ steht, eine Python-Bibliothek, die Entwicklern eine schnelle und effiziente Möglichkeit bietet, nach ähnlichen Einbettungen zu suchen, die von den herkömmlichen Hash-basierten Ansätzen abweicht.
Diese Bibliothek wurde vom Facebook-KI-Team entwickelt und bietet leistungsstarke Funktionen für Ähnlichkeitssuchaufgaben in hochdimensionalen Räumen.
FAISS ist eine Open-Source-Bibliothek, die auf Ihrem eigenen Server gehostet werden kann.
Bei unserer Erkundung von LangChain und FAISS wollen wir nun darauf abzielen, FAISS innerhalb des LangChain-Frameworks zu implementieren. Nachfolgend finden Sie einige wichtige APIs der FAISS-Integration von LangChain, auf die wir uns in diesem Artikel konzentrieren werden:
add_documents() : Mit dieser Funktion können wir zusätzliche Dokumente in den Vektorspeicher einbinden.
add_embeddings() : Ermöglicht das Hinzufügen weiterer Einbettungen zum Vektorspeicher.
from_documents() : Diese API gibt einen VectorStore basierend auf den bereitgestellten Dokumenten zurück.
from_embeddings() : Diese Funktion stellt einen FAISS-Index bereit, der aus den angegebenen Einbettungen generiert wird.
load_local() : Verwenden Sie dies, um den FAISS-Index von der Festplatte zu laden.
save_local() : Damit können Sie einen FAISS-Index auf der Festplatte speichern.
Similarity_search() : Diese Funktion ruft Dokumente ab, die einer bestimmten Abfrage am ähnlichsten sind.
Similarity_search_by_vector() : Es ruft Dokumente ab, die einer bestimmten Einbettung am ähnlichsten sind.
Diese APIs bilden die Grundlage für die Kombination der Funktionen von LangChain mit FAISS und ermöglichen Ihnen die Arbeit mit Einbettungen und die Durchführung effizienter Ähnlichkeitssuchen innerhalb Ihrer Anwendungen.
Metafilterung ist eine wertvolle Technik zur Verfeinerung der Ergebnisse einer Suchanfrage in LangChain FAISS. Typischerweise gibt es zwei Arten der Metafilterung: Vorfilterung und Nachfilterung. In unserem Framework unterstützen wir gezielt die Nachfilterung von Suchanfragen.
Es ist wichtig zu beachten, dass das Konzept der Metafilterung für Suchergebnisse eine Funktion ist, die in der LangChain-Version von FAISS verfügbar ist und in der ursprünglichen Implementierung von FAISS nicht vorhanden ist. Diese Nachfilterfunktion erhöht die Präzision und Relevanz der Suchergebnisse und bietet den Benutzern maßgeschneiderte Ergebnisse.
Ausgestattet mit dem Wissen über die LangChain FAISS-APIs tauchen wir nun in die Python-Implementierung von LangChain FAISS ein. Mit dieser Implementierung können Sie mit Einbettungen arbeiten, Ähnlichkeitssuchen durchführen und Nachfiltertechniken anwenden, um Ihre Suchergebnisse innerhalb des LangChain-Frameworks zu verfeinern.
Entdecken Sie diese Funktionen und nutzen Sie sie, um Anwendungen zu erstellen, die die Leistungsfähigkeit großer Sprachmodelle und der erweiterten Ähnlichkeitssuche mit FAISS nutzen.
In dieser Anleitung haben wir den Stanford-Datensatz als Basisdatensatz ausgewählt und einige Spalten hinzugefügt, um die Arbeit der Metafilterung in LangChain FAISS zu zeigen.
Wir beginnen mit der Installation und dem Import der erforderlichen Pakete
!pip install langchain[all] !pip3 install Langchain[FAISS] !pip install faiss-cpu # WARNING: langchain 0.0.74 does not provide the extra 'faiss'
from langchain import FAISS import pandas as pd import numpy as np import os import time import pickle
Jetzt importieren wir den Datensatz:
passage_data = pd.read_csv("/Users/shyam/Python_Programs/Text Similarity Codes/Standford_Edited.csv") passage_data.drop(columns=["Unnamed: 0"],axis=1, inplace=True) passage_data
Nachdem wir den Datensatz haben, müssen wir eine Einbettungsfunktion initialisieren, um die Textdaten in Vektoren umzuwandeln. Wir haben „sentence-transformers/all-MiniLM-L6-V2“ verwendet, das Einbettungen in 384 Dimensionen generiert,
from langchain.embeddings import SentenceTransformerEmbeddings embedding_function = SentenceTransformerEmbeddings(model_name="all-MiniLM-L6-v2")
Wir werden die Metadateninformationen festlegen. In den Metadaten haben wir für jede Einbettung (Inhalt) die Dokument-ID und die Dokumentsprache hinzugefügt.
start=time.time() metadatas = [] for index, row in passage_data.iterrows(): doc_meta = { "id": row['Id'], "language": row['Language'] } metadatas.append(doc_meta)
Das ist es… Wir werden jetzt unseren FAISS-Index erstellen,
faiss = FAISS.from_texts(passage_data['Content'].tolist(), embedding_function, metadatas) print("Time Taken --> ", time.time()-start)
Jetzt versuchen wir, den FAISS-Index auf der Festplatte zu speichern und wieder zu laden:
faiss.save_local("/Users/shyam/Python_Programs/LangChain_FAISS", "Standford") loaded_faiss = faiss.load_local("/Users/shyam/Python_Programs/LangChain_FAISS",embedding_function, "Standford")
Wir sind mit dem Erstellen, Speichern und Laden des FAISS-Index fertig. Es ist Inferenzzeit. Wir werden versuchen, einige Suchanfragen zu durchsuchen und den FAISS-Index zu testen.
Zuerst erhalten wir die fünf wichtigsten ähnlichen Dokumente, die sich auf „Atheismus“ beziehen.
start=time.time() loaded_faiss.similarity_search_with_score("What is atheism?",5)
Nun, die Ergebnisse sind überzeugend. Aber wir werden trotzdem noch mehr erforschen …
Dieses Mal werden wir eine andere Sprachabfrage mit etwas Metafilterung versuchen. Wir werden eine russische Abfrage stellen, die angibt, dass die Filterkriterien {lang: 'ru_RU'} sein sollten.
#Что такое атеизм? - Russian loaded_faiss.similarity_search_with_score("Что такое атеизм?",5, {"language":"ru_RU"}, 10)
Hier haben wir erwähnt, dass wir die zehn ähnlichsten Dokumente aus dem Vektorspeicher genommen und dann unsere Filterbedingung angewendet haben, um die fünf Dokumente mit der höchsten Ähnlichkeit für unsere Abfrage zu erhalten.
Ich gehe davon aus, dass Sie nach Abschluss dieses Artikels ein solides Verständnis für Vektorspeicher und die Vektorsuche erworben haben. Wir haben auch eine Demonstration von LangChain FAISS bereitgestellt, um seine Funktionalität zu veranschaulichen.
Ich empfehle Ihnen dringend, andere Vektor-Stores wie ChromaDb, Qdrant, Milvus und mehr zu erkunden.
Jeder Vector Store hat seine eigenen Vor- und Nachteile. Treffen Sie Ihre Auswahl daher auf der Grundlage der spezifischen Anforderungen Ihres Anwendungsfalls.
Ich wünsche Ihnen eine angenehme und fruchtbare Lernreise!