Sind die Anfragen der KI Knowledge Base wieder nicht verlässlich?
Produktionsreife “Chat-With-your-Data”-Applikationen, basierend auf RAG (=Retrieval Augmented Generation) sind eine harte Nuss. Was schnell in einem Proof of Concept sehr gut funktioniert, ist in der Praxis meistens nicht brauchbar. Gerade die Optimierung von Black Box KI-Systemen, wie RAG, ist alles andere als einfach.
In dieser Artikelreihe gehe ich auf die relevantesten Herausforderungen und Optimierungshebel aus technischer Sicht ein, zur Sicherstellung einer verlässlichen und qualitativen “Chat-with-your-Data”-Applikation.
Heute im Programm: Effektives Chunking.
Herausforderungen: LLM (Large Language Model) Kontextgröße & Chunking
Im letzten Artikel wurde das Thema Parsing besprochen. Unter der Annahme, dass wir das nun perfekt beherrschen, stehen wir vor dem nächsten Problem: die Wahl der Chunking Strategie und Chunk Größe.
Stellen Sie sich vor, wir besitzen eine digitale Kopie aller 24 Bände der Brockhaus-Enzyklopädie, die so aufbereitet wurde, dass ein Sprachmodell sowohl den Inhalt als auch das Layout aller Bände verstehen kann.
Können wir alle 24 Bände in ein Sprachmodell laden und dann Fragen zu den Inhalten stellen? Jein. Um zu verstehen, warum dies nur mit Einschränkungen funktioniert, müssen wir uns mit den aktuellen technischen Beschränkungen von Large Language Models (LLMs) auseinandersetzen, insbesondere mit der Begrenzung der Kontextgröße und dem “Lost-in-the-Middle” Problem.
Kontextgröße
Die Kontextgröße eines Sprachmodells bestimmt, wie viele Teilwörter (Tokens) das Modell gleichzeitig berücksichtigen kann. Nehmen wir an ein Modell hätte Platz für genau einen Band der Enzyklopädien. Da die anderen 23 Bänder über die Kontextgröße hinausgehen, würde die Information aus den restlichen Bändern gar nicht beachtet werden, wenn wir dem Sprachmodell eine Frage zum Inhalt stellen.
Die größten öffentlich zugänglichen Sprachmodelle können derzeit etwa 1 Million Tokens verarbeiten (Stand: Mai 2024). Da ein Band der Brockhaus-Enzyklopädie durchschnittlich über eine Million Wörter umfasst, stoßen wir hier an Grenzen. Zudem ist bei dieser Menge an Tokens die Wahrscheinlichkeit, auf das Lost-in-the-Middle-Problem zu stoßen, sehr hoch.
Lost-in-the-Middle Problem
Das Lost-in-the-Middle-Problem entsteht, wenn wichtige Informationen, die sich in der Mitte eines langen Textes befinden, vom Modell übersehen oder vergessen werden. Dies liegt daran, dass das Modell dazu neigt, sich stärker auf den Anfang und das Ende des Kontextes zu konzentrieren. In Bezug auf einen Band der Brockhaus-Enzyklopädie bedeutet dies, dass das Modell möglicherweise nur die ersten 15% und die letzten 15% des Inhalts effektiv verarbeitet. Informationen in den dazwischenliegenden 70% des Buches könnten teilweise verloren gehen. Die Ursache für dieses Phänomen ist Gegenstand aktueller Forschungsdebatten; es wird vermutet, dass sie in der Methodik des Modelltrainings begründet liegt.
Chunking
Um nun eine Überleitung zum Thema Chunking zu schaffen: Bei Chunking geht es darum, aufbereitete Dokumente in kleinere Bestandteile zu zerlegen. Dies bedeutet, dass ein Dokument in Subteile (Textpassagen) heruntergebrochen wird, um den Kern der Information zu bewahren. Sobald man mit kürzeren Textpassagen arbeitet, kann man im nächsten Schritt der RAG-Pipeline die relevantesten Textpassagen finden und an das Sprachmodell übergeben, anstatt den Kontext mit dem gesamten Dokument zu füllen.
Doch was ist die optimale Länge eines Chunks? Das unterscheidet sich je nach Anwendungsfall. Allgemein kann gesagt werden, dass kleinere Chunks genauere Informationen liefern, aber auch die Beziehung zu anderen wichtigen Textpassagen verlieren können. Größere Chunks hingegen können durch “Noise” (nicht relevante Zusatzinformationen) in längeren Textpassagen die Antwort verfälschen und in manchen Fällen das Lost-in-the-Middle-Problem auslösen.
Festlegung der Chunk Länge
Die Entscheidung zur Chunkgröße sollte einem experimentellen Ablauf und mit Abstimmung von Endnnutzern erfolgen. Zunächst sollten Evaluierungs-Indikatoren festgelegt werden. In der Regel nutzt man akademische Evaluierungsmethoden wie beispielsweise RAGAS Metriken. Aber man sollte sich nicht nur auf diese festfahren, denn es gibt auch andere qualitative und funktionale Ziele, die man in der Antwortgenerierung verfolgen kann (z.B. geringere Latenzzeiten).
Die wichtigste Perspektive ist aber die des Endnutzers: Es kann passieren, dass eine akademische Metrik die Performance eher schlecht evaluiert, während der Endnutzer eigentlich vollkommen zufrieden mit der Antwort ist.
Wie man schnell und unkompliziert Chunkgrößen evaluiert, wurde bereits in einem sehr guten Blogartikel von Ravi Theja (LlamaIndex) diskutiert. Möchte man das Rad nicht neu erfinden, gibt es bereits leistungsstarke Tools wie Galileo.io, die zur automatischen Evaluierung von Chunks genutzt werden können.
Das Erzeugen von Chunks nennt man auch Dokument-Splitting. In den nächsten Abschnitten diskutiere ich zwei etablierte Varianten des Splittings: Content-Aware Splits und Fixed-Size. Abschließend möchte ich das Konzept des semantischen Chunkings kurz erläutern.
Dokument-Splitting: Content Aware
Wie bereits im letzten Artikel besprochen, gibt es keinen „One-Size-Fits-All“-Ansatz im Parsing. Das gleiche Prinzip gilt auch für das Chunking in Anwendungen die hohe Antwortgenauigkeit erfordern. Dokumente mit unterschiedlichen Layoutstrukturen sollten nach dem Parsen so zerlegt werden, dass ihre Layoutinformationen erhalten bleiben. Ein Beispiel ist eine Tabelle mit Finanzkennzahlen. Wenn man diese Tabelle Zeile für Zeile als isolierte Chunks behandelt, wird das Sprachmodell nicht in der Lage sein, den Kontext der Zahlen zu verstehen. Das Modell erhält eine Zeile mit unterschiedlichen Zahlen, ohne zu wissen, ob es sich um Umsatz, Gewinn etc. handelt. Das wäre fatal bei einer Applikation die verlässlich Finanzdaten aus einem Dokument extrahieren soll. Bei einer solchen Tabelle müssen die Informationen zur Tabellenkopfzeile im Chunk bleiben.
Die Erhaltung der Information kann durch Content-Aware Splitting gewährleistet werden. Dieser Ansatz teilt ein geparstes Dokument gemäß seiner Layoutstruktur. Zum Beispiel könnten bei einer strukturierten Textdatei (wie .docx oder .md) Abschnitte nach Überschriften (wie Heading 1, Heading 2 usw.) geteilt werden, um diese Informationen in Chunks zu bewahren. Doch was geschieht, wenn diese Chunks unerwartet groß ausfallen oder keine erkennbare Struktur in einer Datei vorhanden ist?
Dokument-Splitting: Fixed Size Overlapping
Solange Sprachmodelle durch Tokenzahlen limitiert sind, ist es sinnvoll, Chunks so zu teilen, dass man die Menge an Tokens im Griff behält und zählen kann. Dazu definiert man Chunks mit festen Größen, die man auch experimentell auswerten kann.
Ein Trick, um den Informationsverlust zwischen Chunks fester Größe zu minimieren, ist das sogenannte Overlapping. Dieser Ansatz, der sich in der Praxis gut bewährt hat, beinhaltet das Überlappen kleiner Teile der vorherigen und nachfolgenden Chunks. Dadurch bleiben zumindest teilweise semantische Verbindungen zwischen verschiedenen Chunks erhalten. Es ist vergleichbar mit einer Netflix-Serie, bei der im Vorspann die vorherige Folge und im Abspann die nächste Folge angeteasert werden.
Extra: Semantische Chunks
In seiner umfassenden Analyse zum Thema Chunking hat Greg Kamradt das Konzept der semantischen Chunks vorgestellt. Diese Analyse ist in dem folgenden Video dargestellt. Die Varianten des Document-Splittings, die ich bisher vorgestellt habe, befassen sich mit der Layoutstruktur, nicht jedoch mit der semantischen Bedeutung des Inhalts. Bei dieser Art der Segmentierung werden die Sätze auf ihre Bedeutung hin analysiert. Sobald sich das Thema innerhalb eines Textabschnitts ändert, wird eine Trennung vorgenommen. Zum Beispiel: In einem Testbericht zu einem neuen Automodell wird zunächst die Motorleistung behandelt. Sobald das Thema zu „Innenausstattung“ wechselt, erfolgt eine Trennung. Als Ergebnis entstehen zwei Chunks: eines, das sich mit der Motorleistung befasst, und ein weiteres, das Informationen zur Innenausstattung enthält. Im Gegensatz zum Content-Aware Segmentieren sind wir nicht von der Layoutstruktur des Dokumentenerstellers abhängig, sondern können eine eigene Struktur aus den semantischen Bedeutungen des Inhalts ableiten.
Zusammenfassung
- Kontextgrößenlimitationen: Sprachmodelle wie LLMs haben eine maximale Tokenanzahl, die sie gleichzeitig verarbeiten können. Diese Beschränkung erfordert Strategien, um mit umfangreichen Dokumenten effektiv umzugehen, da nur ein Teil der Daten in einer Anfrage analysiert werden kann.
- Lost-in-the-Middle-Problem: Bei langen Texteingaben kann es passieren, dass wesentliche Informationen, die in der Mitte der Eingabe stehen, vom Modell übersehen oder vergessen werden, weil sich die Aufmerksamkeit auf Anfang und Ende konzentriert.
- Chunking als Lösung: Um die Informationen in umfangreichen Dokumenten besser zu verarbeiten, wird das Dokument in kleinere Bestandteile zerlegt. Dies ermöglicht eine effizientere Verarbeitung und hilft, den Kern der Information zu bewahren.
- Optimale Chunk-Größe festlegen: Die Bestimmung der idealen Chunk-Größe ist ein experimenteller Prozess und sollte auf den Bedürfnissen der Endnutzer basieren. Verschiedene Techniken wie Content-Aware Splits und Fixed Size Overlapping helfen, Informationsverlust zu minimieren und relevante Textpassagen effektiv zu nutzen.