29. Februar 2024 von Sascha Windisch und Immo Weber
Retrieval Augmented Generation: LLM auf Steroiden
Schwachstellen im KI-Hype: Wenn ChatGPT an seine Grenzen stößt
Large Language Models (LLMs), allen voran ChatGPT, haben im letzten Jahr alle Bereiche der Informatik im Sturm erobert. Da sie auf einer breiten Datenbasis trainiert werden, sind LLMs grundsätzlich anwendungsagnostisch einsetzbar. Trotz ihres umfangreichen Wissens weisen sie jedoch gerade in hochspezialisierten Anwendungsfällen Lücken auf, die im schlimmsten Fall nur scheinbar durch Halluzinationen kompensiert werden. Dies zeigt sich vor allem dann, wenn hochspezialisiertes Domänenwissen abgefragt werden soll, das aber in den meisten Fällen nicht Bestandteil der Trainingsdaten ist.
Mitte 2023 sorgte ein Fall in den USA für Aufsehen, der die Grenzen von ChatGPT und Co. deutlich machte. Ein Passagier hatte die Fluggesellschaft Avianca verklagt, nachdem er von einem Servierwagen im Flugzeug am Knie verletzt worden war. Der Anwalt des Klägers berief sich auf mehrere frühere Entscheidungen, von denen allerdings sechs frei erfunden schienen. Es stellte sich heraus, dass der Anwalt ChatGPT nach entsprechenden früheren Urteilen befragt hatte, es aber versäumt hatte, diese zu validieren. Es stellte sich heraus, dass ChatGPT diese Urteile nur erfunden hatte. Tatsächlich war das abgefragte Wissen in diesem Fall so speziell, dass es nicht Teil des Datensatzes war, mit dem ChatGPT trainiert wurde.
Um dennoch hochspezialisiertes Domänenwissen durch ein großes Sprachmodell abzufragen und die Gefahr von Halluzinationen zu reduzieren, hat sich in jüngster Zeit das KI-Framework der sogenannten „Retrieval Augmented Generation“ (RAG) etabliert.
Woher kommt RAG?
Der Begriff RAG geht zurück auf das 2020 erschienene Paper „Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks“ von Lewis et al. Die Ursprünge der Methode reichen sogar bis in die 70er Jahre zurück. In dieser Zeit entwickelten Wissenschaftlerinnen und Wissenschaftler die ersten Frage-Antwort-Systeme, insbesondere unter Verwendung der Verarbeitung natürlicher Sprache, allerdings zunächst noch für sehr eng umrissene Themengebiete. Im Jahr 2011 erlangte das Frage-Antwort-System Watson der Firma IBM weltweite Aufmerksamkeit, nachdem es sich in der Quizsendung Jeopardy gegen zwei menschliche Mitspieler durchsetzen konnte.
Klassischerweise erfolgte die Suche nach Dokumenteninhalten bisher über Stichwortsuchen, Volltextsuchen oder Index- und Kategoriensuchen. Der Nachteil dieser klassischen Ansätze liegt vor allem darin, dass zum einen der Suchbegriff explizit im Dokument vorhanden sein muss und zum anderen nur explizite Textsegmente aus der Dokumentbasis wiedergegeben werden können. Im Gegensatz dazu kann RAG auch semantisch ähnliche Informationen finden und in natürlicher Sprache wiedergeben.
Retrieval Augmentend Generation: Wie werden LLMs zu Fachexperten?
Wie die englische Bezeichnung „General Purpose AI“ (KI-Systeme mit allgemeinem Verwendungszweck) bereits andeutet, sollen LLM anwendungsagnostisch einsetzbar sein. Dazu werden sie in der Regel auf einem extrem großen Datensatz trainiert (GPT-4 verwendet 1 Petabyte Trainingsdaten). Trotz dieser enormen Größe enthält dieser Datensatz jedoch in den meisten Fällen kein hochspezialisiertes Domänenwissen.
Um dennoch solches Domänenwissen mittels eines LLM nutzbar zu machen, stehen im Wesentlichen drei Ansätze zur Auswahl:
- 1. Training eines eigenen Modells,
- 2. die Verfeinerung eines bestehenden Modells und
- 3. die sogenannte „Retrieval Augmented Generation“ (RAG).
Im ersten Ansatz besteht natürlich prinzipiell die Möglichkeit, ein LLM von Grund auf neu zu entwickeln und mit dem benötigten Wissen auszustatten beziehungsweise zu trainieren. Eine weitere Möglichkeit besteht im zweiten Ansatz darin, auf dem vorhandenen Wissen eines für den Anwendungsfall geeigneten Modells aufzubauen und das domänenspezifische Wissen nachzutrainieren. Während die beiden Ansätze zum Teil mit erheblichem zeitlichen und finanziellen Aufwand verbunden sind, ist die RAG deutlich einfacher umzusetzen und in den meisten Anwendungsfällen auch mehr als ausreichend.
Wie funktioniert RAG?
Der RAG-Prozess kann grob in eine Datenaufbereitung und die eigentliche Nutzerabfrage unterteilt werden.
Die Datenaufbereitung beginnt mit der Sammlung beliebiger Rohdaten. Dies können beispielsweise Textdokumente wie PDFs oder auch Webseiten sein. In einem ersten Schritt werden I) die relevanten Informationen aus den Rohdaten extrahiert und II) in Textblöcke definierter Größe zerlegt. Die Textblöcke werden dann durch ein sogenanntes Embedding in eine für LLMs verständliche numerische Form übersetzt und IV) persistent in einer Vektordatenbank gespeichert. Damit ist die Datenaufbereitung abgeschlossen.
Wenn ein User eine Anfrage an das RAG-System stellt, wird diese 1) zunächst ebenfalls eingebettet. Anschließend wird 2) eine Ähnlichkeitssuche ( in der Regel mit dem Maß der Kosinusähnlichkeit) zwischen der Anfrage und den in der Vektordatenbank gespeicherten Dokumenten durchgeführt. Die Top n ähnlichsten Textelemente werden 3) extrahiert und 4) zusammen mit der Benutzeranfrage an einen beliebigen LLM übergeben. Dieser generiert schließlich die Antwort auf die Benutzeranfrage auf der Grundlage der extrahierten Informationen.
Welche Software-Tools können wir nutzen?
Die wesentlichen Softwarekomponenten einer RAG-Architektur sind das Einbettungsmodell, die Vektordatenbank und das eigentliche LLM. Für jede der drei Komponenten stehen sowohl kommerzielle als auch Open-Source-Lösungen zur Verfügung.
Für das Embedding größerer Textblöcke wird häufig das kommerzielle Modell text-embedding-ada-002 von OpenAI oder auch das Framework von Cohere verwendet. Für das Embedding einzelner Sätze eignet sich beispielsweise das Open-Source Framework Sentence Transformer (www.SBERT.net). Für eine Übersicht der aktuell besten Embedding-Modelle empfiehlt sich das MTEB Leaderboard auf Hugging Face (MTEB Leaderboard - a Hugging Face Space by mteb).
Mit der zunehmenden Popularität von RAG wächst auch die Auswahl an Anbietern dedizierter Vektordatenbanken (folgende Tabelle). Auf kommerzieller Seite sind hier unter anderem die Anbieter Weaviate und Pinecone zu nennen. Unter den Open-Source-Lösungen wird ChromaDB häufig eingesetzt. Weitere Open-Source-Alternativen sind LanceDB, Milvus, Vespa und Qdrant.
Aber auch klassische Datenbankanbieter haben das Potential von RAG erkannt und unterstützen mittlerweile die Vektorsuche. Auch hier finden sich sowohl Open Source (ClickHouse, Cassandra, PostgreSQL) als auch kommerzielle Lösungen (Elasticsearch, Redis, SingleStore, Rockset, MongoDB).
Auch für die Wahl eines LLM stehen verschiedene kommerzielle und Open Source Lösungen zur Verfügung. Unter den kommerziellen Lösungen sind GPT-4 von OpenAI und die Luminous-Modelle von Aleph Alpha weit verbreitet. Letztere haben ebenso wie die verschiedenen Open-Source-Modelle den Vorteil, dass sie auch vollständig lokal betrieben werden können. Einen Überblick über die derzeit leistungsfähigsten LLMs findet ihr auf dieser Webseite: Open LLM Leaderboard - a Hugging Face Space by HuggingFaceH4.
Verschiedene Software-Frameworks wie Haystack, LangChain und LlamaIndex vereinfachen die Implementierung einer RAG-Architektur indem sie die Syntax der verschiedenen Elemente wie Embedding-Modelle, Vektordatenbanken und LLM abstrahieren und vereinheitlichen.
Welche Vorteile bieten uns RAG-basierte Systeme?
Die Vorteile von RAG aus Sicht des Anwenders liegen auf der Hand.
- 1. Wie das eingangs erwähnte Beispiel zeigt, werden LLM in der Regel auf einer breiten Wissensbasis ausgebildet, haben aber Probleme mit domänenspezifischem Wissen. Dieses kann durch RAG ohne aufwendiges Feintuning zur Verfügung gestellt werden.
- 2. Ein weiteres Problem großer Sprachmodelle ist, dass ihr verfügbares Wissen mehr oder weniger statisch ist. Benutzer von ChatGPT kannten dieses Problem bis vor kurzem nur zu gut. Denn fragte man das Modell bis vor kurzem nach aktuellen Nachrichten, antwortete es in der Regel, das Wissen reiche nur bis September 2021. Mit RAG ist es jedoch möglich, das Modell ohne Nachtrainieren mit Wissen aus externen Dokumenten zu versorgen und damit aktuell zu halten. Dadurch kann beispielsweise die Wissensbasis eines LLM täglich mit Unternehmensdaten aktualisiert werden.
- 3. Daraus ergibt sich ein weiterer Vorteil: RAG ist kosteneffizient, da eine deutlich teurere Neuentwicklung inklusive Schulung oder Feintuning bestehender Modelle nicht notwendig ist. Schließlich erfüllt RAG auch eine Kernanforderung an KI-Systeme in anwendungskritischen Kontexten: Transparenz und wie es im Englischen heißt: Trustworthy AI.
- 4. Ein RAG-Framework, wie es zum Beispiel mit LlamaIndex implementiert werden kann, erlaubt es, die Quellen der vom LLM ausgegebenen Informationen zu referenzieren und damit überprüfbar zu machen. Wie das eingangs gezeigte Beispiel des Anwalts, der ChatGPTs verwendet, gezeigt hat, sind vor allem Halluzinationen von LLMs ein großes Problem.
- 5. Durch Konfiguration des RAG-Systems, optimiertes Prompting und Referenzierung auf Quellen können Halluzinationen weitgehend vermieden werden. Damit wäre schnell klar gewesen, dass die sechs vorherigen Gerichtsurteile nur Phantasieprodukte der KI waren.
Was sind typische Anwendungsfälle?
Ein typischer Anwendungsfall ist das „Chatten“ über komplexe unternehmensinterne Handbücher oder Richtlinien, wie zum Beispiel Reiserichtlinien. Da diese in der Regel relativ komplex sind und in der Regel zu einem hohen Anfragevolumen im Support führen, kann RAG eingesetzt werden, um konkrete Fragen der Mitarbeitenden zu beantworten. Statt umständlich selbst im Dokument nach bestimmten Informationen zu suchen, haben die Mitarbeitenden die Möglichkeit, ihre Fragen in Alltagssprache direkt an das Dokument zu richten.
Die Vorteile von RAG zeigen sich auch in Anwendungsbereichen, die auf eine kontinuierliche Aktualisierung ausgerichtet sind. So könnte ein RAG-Agent im Sportbereich die User über aktuelle Spielergebnisse oder Spielverläufe informieren. Während ein einzelnes LLM aufwendig verfeinert werden müsste, ist in einer RAG-Architektur nur das Einbetten der neuen Information notwendig.
Packen wir es an – Erste Schritte in die RAG-Welt!
In diesem Kapitel soll anhand einiger Beispiele der praktische Einsatz von RAG demonstriert werden. Um die Beispiele überschaubar zu halten, verzichten wir auf typische Komponenten eines Produktivsystems, wie beispielsweise Benutzerberechtigungen oder die Behandlung von Ausnahme- und Fehlersituationen.
Für den oben beschriebenen Prozess der Nutzung verschiedener Werkzeuge und Sprachmodelle im Kontext von RAG entstehen seit einigen Monaten Bibliotheken, die die Prozesskette abstrahieren und damit einen relativ einfachen und standardisierten Zugriff auf die verschiedenen Werkzeuge bieten. Dadurch ist es möglich, zum Beispiel die Sprachmodelle von Lizenzmodellen über Open Source bis hin zu On-Premises über Konfigurationen zu wechseln, ohne den Quellcode anpassen zu müssen.
Zum Zeitpunkt der Erstellung dieses Blogeintrags sind die bekanntesten Bibliotheken LlamaIndex, LangChain und Haystack. Alle drei sind als Open Source verfügbar. Für diese Blog-Reihe beginnen wir die Beispiele mit LlamaIndex.
LlamaIndex ist ein Open Source Framework, das es Entwicklerinnen und Entwicklern ermöglicht, große Sprachmodelle (LLMs) mit externen Werkzeugen und Daten zu verbinden. Es bietet eine Reihe von Funktionen, die die Entwicklung von LLM-Anwendungen vereinfachen, darunter Standardschnittstellen
- für die Datenerfassung und -aufbereitung,
- die Indizierung (Einbettung) von Daten in verschiedene Vektordatenbankenund
- für die verschiedenen Abfrageschnittstellen, beispielsweise Question/Answer-Endpoints oder ChatBots.
Für die praktische Nachvollziehbarkeit der Beispiele wird eine Python-Umgebung, wie beispielsweise Anaconda, vorausgesetzt.
Installiert wird LlamaIndex über den Befehl:
pip install llama-index
Für eine bessere Nachvollziehbarkeit der Internas empfehlen wir das Logging zu aktivieren.
Dazu werden folgende Importe und Konfigurationen genutzt:
import logging
import sys
# Logging Level hochsetzen, damit wir alle Meldungen sehen.
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stdout))
Die einzigen beiden weiteren Importe, die wir für ein erstes Beispiel benötigen sind:
from llama_index import SimpleDirectoryReader, VectorStoreIndex
Mit dem SimpleDirectoryReader verwenden wir eine Komponente, die Daten aus Verzeichnissen liest und als Dokumentobjekte zurückgibt. Mit dem VectorStoreIndex erhalten wir eine mächtige Komponente, die einerseits das Embedding der Dokumente vornimmt und uns andererseits einen Index erzeugt, auf den wir dann unsere Frage formulieren können. In unserem Beispiel befinden sich im Unterverzeichnis “data” beliebige Textdateien, die wir für die Vektordatenbank einlesen.
# Erstelle den Index aus den Dokumenten.
documents = SimpleDirectoryReader("data").load_data()
index = VectorStoreIndex.from_documents(documents)
Das Index-Objekt mit den gespeicherten Embedding-Daten existiert hier nur im Hauptspeicher des Computers. Aus dem Index-Objekt können wir nun eine Abfrage erstellen und das Ergebnis ausgeben:
# Der Index wurde geladen, nun kann er verwendet werden.
query_engine = index.as_query_engine()
response = query_engine.query("Was ist generative KI?")
print(response)
Zusammenfassend können wir festhalten, dass bereits mit fünf Zeilen Code ein RAG-Prozess mit LlamaIndex entwickelt und ausgeführt werden kann.
Ein zweites Beispiel zeigt, wie wir einen bereits vorher erstellten Index von der Festplatte einlesen oder aber einen neu erstellten Index persistent Speichern können.
StorageDir = "./storage"
if os.path.exists(StorageDir):
# Lade den vorhandenen Index.
storage_context = StorageContext.from_defaults(persist_dir=StorageDir)
index = load_index_from_storage(storage_context)
else:
# Erstelle den Index.
documents = SimpleDirectoryReader("data").load_data()
index = VectorStoreIndex.from_documents(documents)
# Speichere den Index.
index.storage_context.persist(persist_dir=StorageDir)
Ab hier kann das Index-Objekt wieder benutzt werden.
Wie geht es weiter?
Dieser Blog-Beitrag gibt nur einen ersten Überblick über das Thema LLM. In weiteren Blog-Beiträgen werden wir das Thema vertiefen und u.a. auf die Nutzung von lokalen RAGs für unterschiedliche fachliche Schwerpunkte oder auch speziellere Anwendungsgebiete eingehen. So kann RAG beispielsweise auch über Text2SQL-Abfragen genutzt werden, um Anfragen in natürlicher Sprache an Data Warehouses zu stellen. Darüber hinaus gibt es zahlreiche Möglichkeiten, die konventionelle RAG-Architektur durch spezielle Techniken – etwa RAG Fusion, HYDE, Context Expansion oder Query Transformation – verbessern.
Ihr möchtet mehr über spannende Themen aus der adesso-Welt erfahren? Dann werft auch einen Blick in unsere bisher erschienenen Blog-Beiträge.