11 Punkte von GN⁺ 2024-10-30 | 1 Kommentare | Auf WhatsApp teilen
  • Eine Botschaft, die Engineering-Teams plagt, die AI-Anwendungen bauen wollen: "Die Embeddings sind wieder nicht synchronisiert"
  • Eine einfache Implementierung der Vektorsuche entwickelt sich zu einer komplexen Orchestrierung aus Monitoring, Synchronisierung und Fehlerbehebung
  • Gespräche mit Engineering-Teams, die AI-Systeme mit Vektor-Datenbanken bauen, zeigen die fehlerhafte Abstraktion von Vektor-Datenbanken und die Mängel ihrer heutigen Nutzung

„Ein häufiger Fall beim Aufbau von RAG-Systemen“

  • Pinecone wird als Vektor-Datenbank verwendet, um Embeddings zu speichern und abzurufen
  • Weil Textdaten nicht gut in die Metadaten von Pinecone passen, werden Blobs und Anwendungsdaten in DynamoDB verarbeitet
  • Für lexikalische Suche wird OpenSearch benötigt
  • Jetzt ist das Verbinden und Synchronisieren von drei Systemen ein Albtraum

Beim Löschen eines Quelldokuments muss Folgendes passieren:

  1. boto3 ausführen, um den Datensatz aus DynamoDB zu entfernen
  2. Pinecone aktualisieren, um sicherzustellen, dass die Embeddings gelöscht wurden
  3. Eine POST-Anfrage senden, um den Index für die lexikalische Suche zu aktualisieren
  • Das muss bei jeder Aktualisierung, Ergänzung oder Löschung eines Quelldokuments geschehen
  • Konfigurationsmanagement ist nicht nur unübersichtlich, sondern riskant
  • Es gibt Teams, die monatlich 2.000 US-Dollar für Indizes zahlen, die schon vor vier Monaten hätten gelöscht werden sollen
  • Es besteht das Risiko, Nutzern falsche oder veraltete Daten zurückzugeben

Vektor-Datenbanken basieren auf einer fehlerhaften Abstraktion

  • Vektor-Datenbanken behandeln Embeddings als eigenständige Daten statt als abgeleitete Daten
  • Dadurch entsteht unnötige Komplexität

Ein besserer Weg: die „Vectorizer“-Abstraktion

  • Vorgeschlagen wird eine „Vectorizer“-Abstraktion, die Embeddings wie Datenbankindizes behandelt
  • Dieser Ansatz hält Embeddings automatisch mit den Quelldaten synchron und beseitigt so den Wartungsaufwand
  • Ein Vectorizer als Gegenstück zum Befehl CREATE INDEX sieht so aus:
SELECT ai.create_vectorizer(
    'public.blogs'::regclass,
    embedding => ai.embedding_openai('text-embedding-3-small', 1536),
    chunking => ai.chunking_recursive_character_text_splitter('content')
);
  • Dieser Befehl erzeugt Embeddings für alle Einträge der Blog-Tabelle und aktualisiert sie fortlaufend, wenn sich die Daten der Tabelle ändern

Die Probleme von Vektor-Datenbanken (und Vektor-Datentypen)

  • Vektor-Datenbanken wurden entwickelt, um große Mengen an Vektor-Embeddings für Text-, Bild- und multimodale Daten zu verarbeiten
  • Auch General-Purpose-Datenbanken wie PostgreSQL, MySQL, MongoDB und Oracle haben Unterstützung für Vektorsuche hinzugefügt
  • Doch die Abstraktion von Vektorsuche als eigenständiges System oder als Zusatz in bestehenden Datenbanken hat einen fatalen Fehler
  • Sobald Embeddings in die Datenbank eingefügt werden, wird die Verbindung zwischen den eingebetteten unstrukturierten Daten und dem Vektor-Embedding selbst getrennt
  • Ohne diese Verbindung werden Embeddings fälschlich als unabhängige Datenatome behandelt, die von Entwicklern verwaltet werden müssen, statt als abgeleitete Daten
  • Wenn man Embeddings als abgeleitete Daten neu denkt, wird die Absurdität der heutigen Vektor-Datenbank-Abstraktion deutlich, bei der Embeddings nicht mit den Quelldaten verbunden sind

Entwicklungsteams müssen Folgendes verwalten:

  • Komplexe ETL-Pipelines (Extract, Load, Transform)

  • Eine Vektor-Datenbank für Embeddings, eine weitere Datenbank für Metadaten und App-Daten sowie einen Index für lexikalische Suche

  • Dienste zur Datensynchronisierung

  • Queueing-Systeme für Updates und Synchronisierung

  • Monitoring-Tools, um Data Drift zu erkennen und Dinge wie Rate Limits von Embedding-Diensten zu handhaben

  • Benachrichtigungssysteme, wenn die Suche veraltete Ergebnisse zurückliefert

  • Validierungsprüfungen für alle Systeme

  • Wer auf ein neues Embedding-Modell upgraden oder eine andere Chunking-Methode ausprobieren will, muss Custom Code schreiben und Änderungen über mehrere Datendienste und Datenbanken hinweg koordinieren

  • Das belastet Entwicklungsteams mit der Verantwortung sicherzustellen, dass Embeddings rechtzeitig erzeugt werden, wenn sich Quelldaten ändern

  • Andernfalls drohen Embeddings häufig zu veralten, was Nutzern eine schlechtere Anwendungserfahrung liefert

Ein besserer Weg: die Datenbank die Komplexität übernehmen lassen

  • Wenn Embeddings als abgeleitete Daten verstanden werden, kann die Verantwortung für ihre Erzeugung und Aktualisierung bei Änderungen der Basisdaten an das Datenbankmanagementsystem delegiert werden
  • Diese Änderung entlastet Entwickler davon, Embeddings manuell mit den Quelldaten synchron zu halten
  • Für einfache Anwendungen, die einmalig Daten für RAG importieren, ist diese Unterscheidung vielleicht nicht wichtig
  • In den meisten realen Anwendungen ändern sich Daten jedoch laufend
  • Man denke an E-Commerce-Plattformen mit embedding-basierter semantischer Suche oder an RAG-Apps für Produktassistenten, die mit aktuellen Produktinformationen auf dem neuesten Stand bleiben müssen
  • Diese Änderungen manuell nachzuverfolgen und Embeddings neu zu erzeugen, ist nicht nur arbeitsintensiv und fehleranfällig, sondern hält Entwickler auch davon ab, sich auf zentrale Geschäftsziele zu konzentrieren
  • Warum Entwicklungszeit verschwenden, wenn ein Datenbanksystem das automatisch erledigen kann?

Vectorizer: Vektor-Embeddings als Index

  • Eine effektivere Abstraktion ist es, Vektor-Embeddings nicht als eigenständige Tabellen oder Datentypen zu verstehen, sondern als speziellen Index für die eingebetteten Daten
  • Vektor-Embeddings sind im traditionellen Sinn keine Indizes
  • Stattdessen fungieren sie als Indexierungsmechanismus, der auf Basis der Embeddings die relevantesten Teile der Daten abruft
  • Diese neue indexähnliche Abstraktion könnte man „Vectorizer“ nennen

Zentrale Vorteile der Vectorizer-Abstraktion:

Automatische Synchronisierung

  • Einer der wichtigsten Vorteile von Indizierung in Datenbanken ist, dass Basisdaten und Index automatisch synchron gehalten werden
  • Wenn sich Daten in einer Spalte ändern, wird der Index entsprechend aktualisiert
  • Wenn Vektor-Embeddings als eine Form der Indizierung behandelt werden, kann dieselbe automatische Synchronisierung genutzt werden
  • Das System stellt sicher, dass Vektor-Embeddings immer mit den neuesten Daten aktuell bleiben, wodurch manuelle Updates entfallen und das Fehlerrisiko sinkt

Verstärkte Beziehung zwischen Daten und Embeddings

  • Wenn Vektoren unabhängig gespeichert werden, geht ihre Beziehung zu den ursprünglichen Daten leicht verloren
  • Wurde dieser Vektor aus den neuesten Datenupdates erzeugt? Oder ist es ein alter Vektor aus einem früheren Embedding-Modell?
  • Diese Fragen sind wichtig, und Verwirrung an dieser Stelle kann zu schweren Fehlern führen
  • Wenn Vektor-Embeddings als Index direkt an die Daten gekoppelt werden, wird diese Beziehung klar und automatisch erhalten

Vereinfachtes Datenmanagement

  • Entwickler stoßen häufig auf Schwierigkeiten, wenn sie Datensynchronisierung manuell verwalten müssen
  • Wenn zum Beispiel beim Löschen der Basisdaten vergessen wird, Daten aus einem früheren Embedding-Modell zu entfernen, können Inkonsistenzen entstehen
  • Die Vectorizer-Abstraktion macht die Verwaltung dieser Beziehungen zur Aufgabe des Systems, reduziert so die kognitive Last für Entwickler und minimiert die Fehlerwahrscheinlichkeit

Vectorizer sind eine natürliche Weiterentwicklung des zentralen DBMS-Versprechens

  • Das Konzept des Vectorizers ist eine natürliche Weiterentwicklung moderner Funktionen von Datenbankmanagementsystemen (DBMS)
  • Heutige DBMS sind bereits sehr gut darin, Datentransformation und Synchronisierung über deklarative Strukturen wie Indizes, Trigger und materialisierte Views zu verwalten
  • Die Vectorizer-Abstraktion passt gut in dieses Paradigma, indem sie ein neues Werkzeug für die immer wichtigere Aufgabe der Verwaltung von Vektor-Embeddings bereitstellt
  • Durch die direkte Integration dieser Funktion in das DBMS kommt man dem ultimativen Versprechen von Datenbanksystemen näher
  • Daten so zu verwalten, dass Komplexität abstrahiert wird, damit Nutzer sich auf das konzentrieren können, was sie am besten können: Anwendungen bauen, Daten analysieren und Innovation vorantreiben

Vectorizer-Implementierung für PostgreSQL: pgai Vectorizer

  • Angetrieben vom Ziel, Entwickler zu entlasten, hat das AI-Engineering-Team von Timescale einen Vectorizer für PostgreSQL implementiert
  • Er heißt pgai Vectorizer und befindet sich derzeit im Early Access
  • Er ist Teil des PGAI-Projekts, das PostgreSQL besser für AI-Systeme geeignet machen und AI-Entwicklung für Entwickler erleichtern soll, die bereits mit PostgreSQL vertraut sind
  • Wer sehen will, wie pgai Vectorizer automatisch Vektor-Embeddings für Daten in PostgreSQL erzeugt und aktualisiert, sollte sich das Demo-Video ansehen

So funktioniert pgai Vectorizer

  • Der Vectorizer wird in SQL definiert und erzeugt
  • Die folgende Abfrage erstellt einen Vectorizer und legt fest, auf welche Tabelle er wirkt, welche Spalten vektorisiert werden, welches Embedding-Modell verwendet wird und welche zusätzliche Formatierung für die einzubettenden Quelldaten genutzt wird
-- Vectorizer erstellen, der Daten aus der blogs-Tabelle automatisch einbettet
SELECT ai.create_vectorizer(
   'public.blogs'::regclass
   -- OpenAI-Modell text-embedding-3-small verwenden
 , embedding=>ai.embedding_openai('text-embedding-3-small', 1536, api_key_name=>'OPENAI_API_KEY')
   -- StreamingDiskANN-Index automatisch erstellen, wenn die Tabelle 100k Zeilen hat
 , indexing => ai.indexing_diskann(min_rows => 100000, storage_layout => 'memory_optimized'),
   -- rekursives Chunking auf die Spalte content anwenden
 , chunking=>ai.chunking_recursive_character_text_splitter('content')
   -- Metadaten aus anderen Spalten für bessere Suche in die Embeddings einfügen
 , formatting=>ai.formatting_python_template('Blog title: $title url: $url blog chunk: $chunk')
);
-- Der Vectorizer aktualisiert Embeddings, wenn sich die Quelltabelle ändert
-- Keine weitere Nutzeraktion erforderlich
  • Außerdem wird eine Standardfunktion für Chunking definiert, weil lange Texte in mehrere kleinere Abschnitte aufgeteilt werden müssen, damit sie innerhalb der Token-Limits von Embedding-Modellen bleiben

Änderungen in Quelldaten verfolgen

  • pgai Vectorizer prüft intern Änderungen an der Quelltabelle (Insert, Update, Delete) und erzeugt bzw. aktualisiert Vektor-Embeddings asynchron
  • pgai Vectorizer wurde für zwei Bereitstellungsarten gebaut: Self-Hosting und vollständig gemanagt in Timescale Cloud
  • In der Cloud-gehosteten Implementierung von pgai Vectorizer werden Cloud-Funktionen der Timescale-Cloud-Plattform für die Erzeugung von Embeddings verwendet
  • In der Open-Source-Version von pgai Vectorizer wird ein externer Worker zur Erzeugung von Embeddings ausgeführt
  • pgai Vectorizer speichert Konfigurations- und Kataloginformationen zusammen mit den zentralen internen Buchhaltungsdaten innerhalb der Datenbank

Wo werden die Embeddings tatsächlich erzeugt?

  • Der eigentliche Embedding-Prozess findet in einem externen Prozess außerhalb der Datenbank statt
  • Dadurch wird die Last auf dem Datenbankserver reduziert und sichergestellt, dass der Vectorizer die Fähigkeit der Datenbank zur Verarbeitung von Anwendungsabfragen nicht beeinträchtigt
  • Außerdem lässt sich die Embedding-Arbeit so unabhängig von anderen Datenbankaufgaben leicht skalieren
  • Der Prozess liest zunächst aus der Datenbank, um zu prüfen, ob Arbeit ansteht
  • Falls ja, liest er die Daten aus der Datenbank, führt Chunking und Formatierung aus, ruft einen Anbieter von Embedding-Modellen wie OpenAI auf, um Embeddings zu erzeugen, und schreibt das Ergebnis zurück in die Datenbank

Den Prozess anpassen

  • pgai Vectorizer ist flexibel: Chunking- und Formatierungsregeln für die Erzeugung von Embeddings können festgelegt werden
  • Insbesondere lassen sich die zu vektorisierenden Spalten der Quelltabelle sowie Chunking- und Formatierungsregeln konfigurieren, damit die Quelldaten innerhalb der Token-Limits des Embedding-Modells bleiben und relevante Daten in jedes Embedding aufgenommen werden
  • Im Early-Access-Release von pgai Vectorizer lassen sich die Auswahl des OpenAI-Embedding-Modells, Strategien zur Aufteilung von Text in kleinere Chunks, Formatierungsoptionen zur Einfügung zusätzlichen Kontexts in jeden Chunk sowie benutzerdefinierte Indexing-Konfigurationen für automatische Indexerstellung und Performance-Tuning anpassen
  • Bald soll das noch flexibler werden, indem Nutzer eigenen Python-Code einreichen können, um Chunking, Embedding und Formatierung vollständig anzupassen

Zum Beispiel ist Folgendes ein Vectorizer, der so konfiguriert ist, dass HTML-Quelldateien rekursiv aufgeteilt und OpenAI-Embeddings aus den Quelldaten erzeugt werden. Chunking und Formatierung lassen sich passend zu Anwendungsdaten wie Code, Dokumentation, Markdown usw. konfigurieren

-- Erweiterte Vectorizer-Konfiguration
SELECT ai.create_vectorizer(
   'public.blogs'::regclass,
   destination => 'blogs_embedding_recursive',
   embedding => ai.embedding_openai('text-embedding-3-small', 1536),
   -- rekursives Chunking mit den angegebenen Einstellungen für HTML-Inhalte anwenden
   chunking => ai.chunking_recursive_character_text_splitter(
       'content',
       chunk_size => 800,
       chunk_overlap => 400,
       -- HTML-bewusste Trennzeichen, nach Priorität von hoch nach niedrig sortiert
       separator => array[
           E'

', -- an großen Dokumentabschnitten teilen
           E'

',    -- an div-Grenzen teilen
           E'

',
           E'

',      -- an Absätzen teilen
           E'
',      -- an Zeilenumbrüchen teilen
           E'
',     -- an Listeneinträgen teilen
           E'. ',        -- Ersatz für Satzgrenzen
           ' '          -- letzter Ausweg: an Leerzeichen teilen
       ]
   ),
   formatting => ai.formatting_python_template('title: $title url: $url $chunk')
);

Meinung von GN⁺

  • pgai Vectorizer wirkt wie ein leistungsfähiges und innovatives Werkzeug, das die Verwaltung von Embeddings deutlich vereinfachen kann. Die Vectorizer-Abstraktion nimmt Entwicklern die Last der manuellen Pflege von Embeddings ab und stellt sicher, dass Embeddings mit den Quelldaten synchron bleiben.
  • Besonders nützlich erscheint das bei Änderungen wie Upgrades des Embedding-Modells oder Anpassungen der Chunking-Strategie. In herkömmlichen Vektor-Datenbanken können solche Änderungen einen komplexen Prozess auslösen, bei dem Custom Code über mehrere Systeme hinweg geschrieben und koordiniert werden muss; mit pgai Vectorizer muss dagegen nur die Vectorizer-Konfiguration aktualisiert werden.
  • Auch die Verwaltung von Embeddings in einer General-Purpose-Datenbank wie PostgreSQL kann das Problem vermeiden, mehrere spezialisierte Systeme orchestrieren zu müssen. Das kann die Anwendungsentwicklung erheblich vereinfachen.
  • Ein Punkt, den man beachten sollte: Die eigentlichen Embeddings werden in einem externen Python-Prozess erzeugt. Das ist zwar eine gute Designentscheidung, damit die Datenbank-Performance nicht beeinträchtigt wird, bedeutet aber auch, dass der Embedding-Erzeugungsprozess separat überwacht und verwaltet werden muss.
  • Insgesamt stellt pgai Vectorizer einen bedeutenden Fortschritt bei der Verwaltung von Embeddings für AI-Anwendungen dar. Je mehr Teams ihn einführen und Feedback geben, desto weiter dürfte sich dieses leistungsfähige Werkzeug entwickeln. Die Integration von Embedding-Management in vertraute Werkzeuge wie Postgres könnte mehr Entwicklern den Zugang zu fortschrittlichen AI-Funktionen ermöglichen.

1 Kommentare

 
GN⁺ 2024-10-30
Hacker-News-Kommentare
  • Der Overhead der Datensynchronisation wird überschätzt, und die meisten embedding-basierten Workflows haben nicht viele Updates oder Löschungen. Selbst bei kleinen Datensätzen sind Konsistenzprobleme schwer zu erkennen. Trotzdem ist es weiterhin großartig, sich keine Sorgen um Datensynchronisation machen zu müssen

    • Der größte Nachteil beim Speichern von Embeddings in einer Postgres-Datenbank ist, dass die Workloads sehr unterschiedlich sind. HNSW-Indizes verbrauchen viele Ressourcen und können zu Ressourcen-Konkurrenz führen. Wenn man die Datenbank verschiebt, treten Konsistenzprobleme erneut auf
    • Es gibt eine Frage zur Interaktion mit dem Filtern. Es ist unklar, ob partielle Indizes genutzt werden können und ob die Einschränkungen der HNSW-Implementierung von pgvector weiterhin bestehen
  • Als Elastic-Mitarbeiter wird erwähnt, dass Elasticsearch kürzlich den Datentyp semantic_text hinzugefügt hat. Dieser teilt Text automatisch in Chunks auf und berechnet und speichert Embeddings. Auch Abfragen wurden vereinfacht, wodurch I/O reduziert und der Client-Code einfacher wird

  • Es wird ein PostgreSQL-Tool vorgestellt, das Vektor-Embeddings als Datenbankindex neu denkt. Derzeit wird nur OpenAI unterstützt, aber Unterstützung für lokale und OSS-Modelle ist bald geplant. Man freut sich auf Feedback und Reaktionen

  • Es wird infrage gestellt, FAISS als einzelne Datenbank zu verwenden. Das sei wie sqlite für Vektor-Embeddings und könne Metadaten und Vektoren zusammen speichern, um Beziehungen beizubehalten

  • Die Nutzung von Vektoren in Postgres wird positiv gesehen, und es wird die Frage nach der Reihenfolge beim Filtern aufgeworfen, wenn Vektorsuche und Logik in SQL-Abfragen enthalten sind. Die DX von pg_vector gefällt, aber Filtern nach der Vektorsuche kann die Geschwindigkeit beeinträchtigen

  • Es wird erwähnt, dass das Speichern roher Embeddings in einer Vektordatenbank dem Speichern roher n-Gramme von Text in einer Datenbank ähnelt. Es sei sinnvoller, Dokumente zu speichern

  • Es wird erwähnt, dass sqlite-vec und FTS5 in SQLite verwendet werden und sehr nützlich sind

  • Es wurde ein PostgreSQL-ORM für Node.js gebaut, sodass Code mit Vektorfeldern geschrieben werden kann. Damit lassen sich Daten oder Embedding-Inhalte abfragen, und es kann definiert werden, wie Felder des Modells als Embeddings gespeichert werden

  • Es wird erwähnt, dass Materialized Views gut sind

  • Es wird erwähnt, dass AI-Apps mit zeichenbasierten Chunks nicht über die PoC-Phase hinausgekommen sind