Große Sprachmodelle (LLMs), agentische Workflows und Vektorspeicher sind stetig leistungsfähiger geworden, und Frameworks zur Rationalisierung der Entwicklung von KI-Anwendungen erfreuen sich zunehmender Beliebtheit. DSPy ist ein Toolkit, das Allzweckmodule bereitstellt, die das Prompt Engineering und die direkte Eingabe natürlicher Sprache mit der Konfiguration mit Python ersetzen.
Im Allgemeinen erfordert die Arbeit mit LLMs oder Foundation Models ein sorgfältiges Prompt Engineering, bei dem der Benutzer die Textaufforderungen optimiert, um die richtige Ausgabe zu erhalten. Dieser Ansatz kann zwar effektiv sein, ist aber zeitaufwändig und fehleranfällig und führt zu anfälligen Toolchains, die aktualisiert werden müssen, wenn neue Versionen eines Modells veröffentlicht werden. Beliebte Frameworks wie LangChain Chain Language Models für die Anwendungserstellung und LlamaIndex konzentrieren sich auf die Verbesserung der Suchfunktionen in Texten. Bei diesen Entwicklern benötigen sie immer noch Fachwissen in der Feinabstimmung von Prompts und Zeit, um jeden Prompt zu testen, um die gewünschte Ausgabe zu erhalten. DSPy vereinfacht diesen Prompt-Tuning-Prozess mit einem programmatischen Ansatz zur Steuerung und Begrenzung des Verhaltens des Sprachmodells.
DSPy konzentriert sich auf die Automatisierung der Optimierung der Prompt-Erstellung. Um Prompt-Hacking und einmalige Generatoren synthetischer Daten zu ersetzen, bietet DSPy allgemeine Optimierer, d. h. Algorithmen, die Parameter in Ihrem Programm aktualisieren. Jedes Mal, wenn Sie Ihren Code, Ihre Daten, Ihre Behauptungen oder Ihre Metriken ändern, können Sie Ihr Programm erneut kompilieren. DSPy führt dann die Prompt-Optimierung durch, um neue effektive Prompts zu erstellen, die zu Ihren Änderungen passen.
Manchmal stellt man sich vor, dass automatische Prompt-Optimierung die Schaffung eines Systems bedeutet, in dem LLMs benutzergenerierte Prompts kritisieren und verbessern. Dies ist nicht die effektivste Art und Weise, LLMs zu verwenden. DSPy nutzt die Ideenfindungskraft von LLMs, um eigene Prompts zu generieren. Anschließend werden diese Varianten mithilfe eines Satzes von Metriken getestet, um zu sehen, ob sie das Problem besser lösen. Wenn sie bei einer vom Benutzer zugewiesenen Metrik numerisch nicht besser abschneiden, werden die neuen Prompts verworfen. Es ähnelt einem evolutionären Algorithmus, bei dem die Prompt auf ihre Eignung hin bewertet und iterativ verbessert wird.
DSPy kann bei verschiedenen Arten von Workflows und Szenarien hilfreich sein. Einige der am häufigsten verwendeten sind die Generierung mit erweitertem Abruf, die Beantwortung von Multihop-Fragen und die Zusammenfassung von Dokumenten.
Das Chain of Thought (CoT)-Prompting simuliert menschenähnliche Denkprozesse, indem das Modell aufgefordert wird, komplexe Aufgaben in eine Abfolge logischer Schritte zu einer endgültigen Lösung zu zerlegen. Diese Argumentationsschritte werden in das Kontextfenster des Modells eingespeist und geben ihm einen besseren Einblick in die jeweilige Aufgabe. Oft führen sie selbst in komplexen Szenarien zu besseren Antworten. DSPy hilft dabei, indem es das Sprachmodell eine Kette von Denkaufforderungen und Strategien generieren lässt und diese mit dem Sprachmodell testet, um die effektivsten CoT-Prompts für das gegebene Modell zu generieren.
Retrieval-Augmented Generation
Retrieval-Augmented Generation (RAG) ist ein Ansatz, der es LLMs ermöglicht, auf einen großen Wissenskorpus aus Quellen zuzugreifen und seinen Wissensspeicher abzufragen, um relevante Passagen oder Inhalte zu finden und eine gut verfeinerte Antwort zu geben. Die RAG stellt sicher, dass LLMs Echtzeitwissen auch dann dynamisch nutzen können, wenn sie ursprünglich nicht auf dem Gebiet geschult wurden, und korrekte Antworten geben können. Diese zusätzliche Leistung führt zu einer größeren Komplexität bei der Einrichtung von RAG-Pipelines. DSPy bietet einen nahtlosen Ansatz für die Einrichtung von Prompting-Pipelines und entweder zur Generierung effektiver Prompts (Prompt-Tuning) oder bei kleineren Modellen zur Feinabstimmung der Modellgewichtungen selbst.
RAG-Pipelines können mit DSPy auf zwei Arten optimiert werden: mithilfe von gekennzeichneten Beispielen oder mithilfe von Bootstrap-Beispielen. Beschriftete Beispiele sind einfach bereits vorhanden, manuell beschriftete Beispiele werden für das direkte Training des Schülermodells verwendet. Bootstrapping im DSPy-Kontext bedeutet die Verwendung eines Sprachmodus in einem Lehrer- und Schülerparadigma. Der Lehrer generiert neue Trainingsbeispiele auf der Grundlage einiger weniger Prompts. Diese Bootstrapping-Beispiele werden dann zusammen oder anstelle der manuell beschrifteten Beispiele verwendet, um das Schülermodul so lange zu schulen, bis es die richtigen Antworten liefert. Die Prompts, die richtigen Antworten generieren, werden dann in der gesamten DSPy-Pipeline iterativ aktualisiert.
Für eine komplexe Frage-und-Antwort-Aufgabe reicht eine einzelne Suchanfrage oft nicht aus. Der beliebte HotPot Question Answering-Datensatz besteht aus Fragen, die mehrere Analyse- und Abfrageoperationen erfordern, bevor sie beantwortet werden können. Zum Beispiel: „In welchem Jahr flog Bill Nelson als Nutzlastspezialist mit einem Space Shuttle, das zum ersten Mal gestartet wurde?“ Um diese Antwort zu erhalten, muss man wissen, dass Bill Nelson mit dem Space Shuttle Columbia geflogen ist, und dann feststellen können, dass die Columbia 1981 zum ersten Mal geflogen ist.
Der Standardansatz für diese Herausforderung in der Retrieval-Augmented-Literatur ist der Aufbau eines Multihop-Suchsystems. Diese Systeme lesen die abgerufenen Ergebnisse und generieren dann zusätzliche Abfragen, um bei Bedarf zusätzliche Informationen zu sammeln, bevor sie zu einer endgültigen Antwort gelangen. Mit DSPy können Sie dasselbe System in wenigen Codezeilen auf robuste Weise erstellen, sodass Sie Modelle aktualisieren und Ihre Pipeline einfach erneut ausführen können.
Bei der Zusammenfassung wird ein längerer Textabschnitt zu einer kürzeren Version verdichtet, wobei die wichtigsten Informationen und Hauptgedanken erhalten bleiben. Für ein LLM ist es eine wichtige Fähigkeit, die sich in vielen Bereichen einsetzen lässt, beispielsweise beim Verfassen von Artikelzusammenfassungen oder beim Erstellen prägnanter Berichte aus umfangreichen Dokumenten.
Die Bewertung der Qualität von Zusammenfassungen, die von Sprachmodellen erstellt wurden, wirft eine große Herausforderung auf. Im Gegensatz zu Aufgaben mit eindeutigen richtigen oder falschen Antworten ist die Qualität der Zusammenfassung oft subjektiv und kontextabhängig. Das Modell muss ein Gleichgewicht zwischen Informationsspeicherung und Präzision herstellen und dabei den Ton und die Absicht des Originaltexts beibehalten und die sachliche Genauigkeit ohne Fehler gewährleisten. Die Anpassung an verschiedene Arten von Quellenmaterial und Zusammenfassungszwecke stellt eine zusätzliche Herausforderung dar. DSPy ermöglicht es Ihnen, gelabelte Daten zu verwenden, um Ihre Zusammenfassungs-Prompts abzustimmen, damit Sie die bestmöglichen Antworten erhalten.
DSPy hat sein eigenes Vokabular und seine eigene Terminologie. Das Lernen einiger dieser Schlüsselbegriffe wird dazu beitragen, etwas Licht in die allgemeine Architektur zu bringen.
Kompilieren: Mit diesem Prozess übersetzt DSPy ein Python-basiertes Programm in Anweisungen, die ein Sprachmodell verstehen und effizient ausführen kann.
Signatur: Dies ist eine Klasse, die die Eingabe- und Ausgabetypen eines Moduls definiert und so die Kompatibilität zwischen verschiedenen Modulen in einem DSPy-Programm sicherstellt. Einige Beispiele für Signaturen sind Aufgaben wie die Eingabe einer Frage und die Ausgabe der Begründung und der Antwort oder die Annahme eines Dokuments als Eingabe und die Ausgabe einer Zusammenfassung.
Optimierer: Diese Komponente von DSPy optimiert das kompilierte Programm für das von Ihnen verwendete Sprachmodell, z. B. GPT3.5-Turbo oder GPT-4.0 oder Llama 3.1. Optimierer stellen sicher, dass Sie die Leistung und Genauigkeit Ihres Programms maximieren. In älteren Versionen von DSPy wurden diese als Teleprompter bezeichnet. DSPy-Programme bestehen aus mehreren Aufrufen von Sprachmodellen, die als DSPy-Module gestapelt sind. Jedes DSPy-Modul verfügt über drei Arten von internen Parametern: die LM-Gewichte, die Anweisungen, denen es folgen soll, und gespeicherte Demonstrationen des Eingabe-/Ausgabeverhaltens.
Wenn eine Metrik vorgegeben wird, erstellt DSPy optimierte Prompts unter Verwendung aller Gewichtungen, Anweisungen und des Modellverhaltens mit mehrstufigen Optimierungsalgorithmen. Diese können Gradientenabstieg (für Sprachmodellgewichtungen) und diskrete sprachmodellgesteuerte Optimierung kombinieren, d. h. zum Erstellen oder Aktualisieren von Anweisungen und zum Erstellen oder Validieren von Demonstrationen. DSPy-Demonstrationen ähneln Few-Shot-Beispielen, sind aber weitaus leistungsfähiger. Sie können von Grund auf neu erstellt werden, da Ihr Programm und ihre Erstellung und Auswahl auf viele effektive Arten optimiert werden können.
In vielen Fällen führt das Kompilieren zu besseren Prompts als das menschliche Schreiben, weil Optimierer mehr Dinge ausprobieren können, viel systematischer und die Metriken direkt abstimmen können als ein Mensch.
Pipeline: Unter „Pipeline“ versteht DSPy eine Abfolge von verbundenen Modulen, die zusammenarbeiten, um eine komplexe Aufgabe zu erfüllen. Eine Pipeline könnte zum Beispiel einen Artikel zusammenfassen, ihn aus einer Quellsprache in eine Zielsprache übersetzen und dann Fragen dazu in einer Zielsprache generieren.
Metriken: DSPy definiert mehrere verschiedene Metriken, um die Leistung der Ausgabe zu messen. Beispielsweise möchten Sie möglicherweise, dass die Ausgabe genau mit Ihrem Label übereinstimmt. In anderen Fällen kann eine teilweise Übereinstimmung für Ihre Anforderungen gut geeignet sein. Eine häufig verwendete Metrik von DSPy ist Semantic F1. Diese Metrik misst, wie viele der Informationen des Labels in der Antwort enthalten sind und wie wenig überflüssige Daten, die nicht in der gelabelten Zielantwort enthalten sind, in der Antwort enthalten sind. Wenn Sie eine andere Methode zur Leistung benötigen, können Sie auch Ihre eigenen benutzerdefinierten Metriken bereitstellen.
Die ersten Schritte mit DSPy sind so einfach wie der Aufruf von pip install dspy-KI. Es ist keine spezielle Hardware erforderlich, da die meisten Modelle über eine API in der Cloud verwendet oder lokal ausgeführt werden können. Sie kann lokal oder in gehosteten Notebook-Umgebungen wie Google Colab oder Watson Studio ausgeführt werden.
Eine typische DSPy-Pipeline für Retrieval Augmented Generation besteht aus einem Sprachmodell und einem Retrieval-Modell. Um beispielsweise mit OpenAI GPT-3.5 Turbo als Sprachmodell und ColBERTV2 Retriever als Abrufmodell zu arbeiten, würden wir DSPy wie folgt konfigurieren:
Signaturen sind Vorlagen, mit denen Sie konfigurieren können, wie die Eingabe- und Ausgabefelder für das Sprachmodell und das Retrieval-Modell strukturiert werden können. Dieser Codeschnipsel zeigt beispielsweise die Syntax, um das Sprachmodell mit Kontext und das Abrufmodell mit Struktur zu prompten:
Wir fügen kurze Beschreibungen für den Kontext und die Antwortfelder hinzu, um bessere Richtlinien dafür zu definieren, was das Modell empfangen und erzeugen soll.
Sobald Sie Ihre Signaturen definiert haben, können Sie Ihr Programm ausführen und optimale Prompts für Ihre Aufgabe erstellen, indem Sie ein geeignetes Optimierungsprogramm für Ihre Aufgabe verwenden. In DSPy wird dieser Vorgang als Kompilieren bezeichnet. Beim Kompilieren eines Programms werden die in jedem Modul gespeicherten Parameter aktualisiert. In den meisten Szenarien geschieht dies in erster Linie durch das Sammeln und Auswählen guter Demonstrationen, die in den Prompt aufgenommen werden.
Das Kompilieren erfordert:
• Einen Trainingssatz oder Bootstrapping-Beispiele.
• Eine Metrik zur Validierung. In einem RAG-Szenario wäre dies eine Möglichkeit, zu messen, wie genau die vorhergesagte Antwort ist und ob der abgerufene Kontext die Antwort enthält.
• Einen spezifischen Optimierer zum Erstellen von Prompts zum Testen. Beispielsweise könnte der BootstrapFewShot-Optimierer verwendet werden, um Prompts zu generieren und diese generierten Prompts dann zu testen.
Um ein DSPy-Programm zu kompilieren, konfigurieren Sie die Modelle, die Sie verwenden möchten, und übergeben diese an die Kompilierungsmethode des ausgewählten Optimierers. Ein Programm für eine RAG-Anwendung würde zum Beispiel ein Sprachmodell und ein Abfragemodell enthalten. Diese werden dann an die compile-Methode übergeben, und der Optimierer verwendet die abgerufenen Daten, um den Kontext für die Sprachgenerierung festzulegen.
Anschließend definieren Sie eine Metrik, um sowohl die Abfrage als auch das Sprachmodell zu bewerten. Diese Metrikendefinition würde dann an einen Optimierer wie den BootstrapFewShot- oder LabeledFewShot-Optimierer übergeben, um sie bei der Auswertung der vom Sprachmodell generierten Prompts zu verwenden. Schließlich kompiliert der Optimierer ein benutzerdefiniertes Modul, das die von Ihnen definierte Forward-Methode zusammen mit einem Trainingsdatensatz enthält.
Die Auswahl des zu verwendenden Optimierers erfordert in der Regel Experimente, aber es gibt Richtlinien:
• Bei sehr wenigen Beispielen (ca. 10) können Sie mit BootstrapFewShot beginnen, um neue Trainingsdaten zu generieren.
• Wenn Sie über mehr Daten verfügen, beispielsweise 50 Beispiele oder mehr, versuchen Sie BootstrapFewShotWithRandomSearch, um neue Trainingsdaten aus zufälligen Teilen Ihrer Trainingsdaten zu generieren.
• Wenn Sie ein sehr effizientes Programm benötigen, können Sie ein kleines LLM für Ihre Aufgabe mit Feinabstimmung anpassen.
Nachdem Sie Ihr Programm kompiliert und Ihre Metriken verglichen haben, könnten Sie mit den Ergebnissen zufrieden sein. Es kann auch sein, dass Ihnen etwas am endgültigen Programm oder an den Ergebnissen gemäß der von Ihnen gewählten Metrik oder Metriken nicht gefällt. Iterative Entwicklung ist entscheidend. DSPy bietet Tools, mit denen Sie dies schrittweise tun können, indem Sie Ihre Daten iterieren, Ihre Programmstruktur, die gewählten Metriken und den gewählten Optimierer aktualisieren.
DSPy ist Open Source, sodass Sie den Code überprüfen und den Fortschritt der Entwicklung verfolgen können. Die Dokumente auf der StanfordNLP-Website auf Github enthalten die Dokumentation sowie mehrere Schritt-für-Schritt-Tutorials und Demos für die ersten Schritte mit DSPy.