Prompt Engineering
Optimieren Sie LLM mit DSPy: Ein Schritt-für-Schritt-Leitfaden zum Erstellen, Optimieren und Auswerten von KI-Systemen
Da die Fähigkeiten großer Sprachmodelle (LLMs) weiter expandieren, ist die Entwicklung robuster KI-Systeme, die ihr Potenzial nutzen, zunehmend komplexer geworden. Herkömmliche Ansätze umfassen oft komplizierte Prompting-Techniken, Datengenerierung für Feinabstimmung und manuelle Anleitung, um die Einhaltung domänen-spezifischer Einschränkungen sicherzustellen. Dieser Prozess kann jedoch mühsam, fehleranfällig und stark von menschlicher Intervention abhängig sein.
Treten Sie in DSPy ein, ein revolutionäres Framework, das die Entwicklung von KI-Systemen, die von LLMs angetrieben werden, vereinfacht. DSPy führt einen systematischen Ansatz zur Optimierung von LM-Prompts und -Gewichten ein, sodass Entwickler mit minimalem manuellem Aufwand anspruchsvolle Anwendungen erstellen können.
In diesem umfassenden Leitfaden werden wir die Kernprinzipien von DSPy, seine modulare Architektur und die Vielzahl leistungsstarker Funktionen, die es bietet, erkunden. Wir werden auch in praktische Beispiele eintauchen, um zu demonstrieren, wie DSPy die Art und Weise, wie Sie KI-Systeme mit LLMs entwickeln, verändern kann.
Was ist DSPy und warum benötigen Sie es?
DSPy ist ein Framework, das den Programmfluss (Module) von den Parametern (LM-Prompts und -Gewichten) jedes Schritts trennt. Diese Trennung ermöglicht die systematische Optimierung von LM-Prompts und -Gewichten, sodass Sie komplexe KI-Systeme mit größerer Zuverlässigkeit, Vorhersehbarkeit und Einhaltung domänen-spezifischer Einschränkungen erstellen können.
Traditionell umfasste die Entwicklung von KI-Systemen mit LLMs einen mühsamen Prozess, bei dem das Problem in Schritte unterteilt, intricate Prompts für jeden Schritt erstellt, synthetische Beispiele für Feinabstimmung generiert und die LMs manuell angeleitet wurden, um bestimmte Einschränkungen einzuhalten. Dieser Ansatz war nicht nur zeitaufwändig, sondern auch fehleranfällig, da sogar kleine Änderungen an der Pipeline, dem LM oder den Daten umfangreiche Überarbeitungen von Prompts und Feinabstimmungsschritten erfordern konnten.
DSPy geht auf diese Herausforderungen ein, indem es ein neues Paradigma einführt: Optimierer. Diese LM-gesteuerten Algorithmen können die Prompts und Gewichte der LM-Aufrufe anhand einer Metrik, die maximiert werden soll, anpassen. Durch die Automatisierung des Optimierungsprozesses ermöglicht DSPy Entwicklern, robuste KI-Systeme mit minimalem manuellem Eingreifen zu erstellen, wodurch die Zuverlässigkeit und Vorhersehbarkeit der LM-Ausgaben verbessert werden.
DSPys modulare Architektur
Im Herzen von DSPy liegt eine modulare Architektur, die die Zusammensetzung komplexer KI-Systeme erleichtert. Das Framework bietet eine Reihe von integrierten Modulen, die verschiedene Prompting-Techniken wie dspy.ChainOfThought und dspy.ReAct abstrahieren. Diese Module können kombiniert und zu größeren Programmen zusammengesetzt werden, sodass Entwickler komplexe Pipelines nach ihren spezifischen Anforderungen erstellen können.
Jedes Modul kapselt lernbare Parameter, einschließlich Anweisungen, Few-Shot-Beispielen und LM-Gewichten. Wenn ein Modul aufgerufen wird, können DSPys Optimierer diese Parameter anpassen, um die gewünschte Metrik zu maximieren, sodass die LM-Ausgaben den angegebenen Einschränkungen und Anforderungen entsprechen.
Optimieren mit DSPy
DSPy bietet eine Reihe leistungsstarker Optimierer, die die Leistung und Zuverlässigkeit Ihrer KI-Systeme verbessern. Diese Optimierer nutzen LM-gesteuerte Algorithmen, um die Prompts und Gewichte der LM-Aufrufe anzupassen, um die angegebene Metrik zu maximieren, während sie domänen-spezifischen Einschränkungen entsprechen.
Einige der wichtigsten Optimierer, die in DSPy verfügbar sind:
- BootstrapFewShot: Dieser Optimierer erweitert die Signatur, indem er automatisch optimierte Beispiele innerhalb des an das Modell gesendeten Prompts generiert und implementiert, wodurch Few-Shot-Lernen ermöglicht wird.
- BootstrapFewShotWithRandomSearch: Wendet
BootstrapFewShotmehrmals mit zufälliger Suche über generierte Demonstrationen an und wählt das beste Programm über die Optimierung aus. - MIPRO: Generiert Anweisungen und Few-Shot-Beispiele in jedem Schritt, wobei die Anweisungsgenerierung daten- und demonstrationsbewusst ist. Es verwendet Bayesian-Optimierung, um effektiv im Raum der Generierungsanweisungen und Demonstrationen über Ihre Module zu suchen.
- BootstrapFinetune: Destilliert ein promptbasiertes DSPy-Programm in Gewichtsaktualisierungen für kleinere LMs, sodass Sie die zugrunde liegenden LLM(s) für eine verbesserte Effizienz feinabstimmen können.
Indem Sie diese Optimierer nutzen, können Entwickler ihre KI-Systeme systematisch optimieren, um hochwertige Ausgaben zu gewährleisten, während sie domänen-spezifischen Einschränkungen und Anforderungen entsprechen.
Erste Schritte mit DSPy
Um die Leistungsfähigkeit von DSPy zu veranschaulichen, gehen wir durch ein praktisches Beispiel, um ein Retrieval-augmentiertes Generierungssystem (RAG) für Fragebeantwortung zu erstellen.
Schritt 1: Einrichten des Sprachmodells und des Retrieval-Modells
Der erste Schritt umfasst die Konfiguration des Sprachmodells (LM) und des Retrieval-Modells (RM) innerhalb von DSPy.
Um DSPy zu installieren, führen Sie aus:
pip install dspy-ai
DSPy unterstützt mehrere LM- und RM-APIs sowie lokale Modellhosting, was es einfach macht, Ihre bevorzugten Modelle zu integrieren.
import dspy # Konfigurieren Sie das LM und RM turbo = dspy.OpenAI(model='gpt-3.5-turbo') colbertv2_wiki17_abstracts = dspy.ColBERTv2(url='http://20.102.90.50:2017/wiki17_abstracts') dspy.settings.configure(lm=turbo, rm=colbertv2_wiki17_abstracts)
Schritt 2: Laden des Datensatzes
Als Nächstes laden wir den HotPotQA-Datensatz, der eine Sammlung von komplexen Frage-Antwort-Paaren enthält, die normalerweise in einer mehrstufigen Art und Weise beantwortet werden.
from dspy.datasets import HotPotQA
# Laden des Datensatzes
dataset = HotPotQA(train_seed=1, train_size=20, eval_seed=2023, dev_size=50, test_size=0)
# Spezifizieren des 'question'-Felds als Eingabe
trainset = [x.with_inputs('question') for x in dataset.train]
devset = [x.with_inputs('question') for x in dataset.dev]
Schritt 3: Erstellen von Signaturen
DSPy verwendet Signaturen, um das Verhalten von Modulen zu definieren. In diesem Beispiel definieren wir eine Signatur für die Aufgabe der Antwortgenerierung, wobei wir die Eingabefelder (Kontext und Frage) und das Ausgabefeld (Antwort) angeben.
class GenerateAnswer(dspy.Signature): """Beantworten Sie Fragen mit kurzen faktoiden Antworten.""" context = dspy.InputField(desc="enthält möglicherweise relevante Fakten") question = dspy.InputField() answer = dspy.OutputField(desc="meist zwischen 1 und 5 Wörtern")
Schritt 4: Erstellen der Pipeline
Wir erstellen unsere RAG-Pipeline als DSPy-Modul, das aus einer Initialisierungsmethode (__init__) besteht, um die Submodule (dspy.Retrieve und dspy.ChainOfThought) zu deklarieren, und einer Forward-Methode (forward), um den Kontrollfluss der Beantwortung der Frage mithilfe dieser Module zu beschreiben.
class RAG(dspy.Module): def __init__(self, num_passages=3): super().__init__() self.retrieve = dspy.Retrieve(k=num_passages) self.generate_answer = dspy.ChainOfThought(GenerateAnswer) def forward(self, question): context = self.retrieve(question).passages prediction = self.generate_answer(context=context, question=question) return dspy.Prediction(context=context, answer=prediction.answer)
Schritt 5: Optimieren der Pipeline
Mit der definierten Pipeline können wir sie jetzt mithilfe von DSPys Optimierern optimieren. In diesem Beispiel verwenden wir den BootstrapFewShot-Optimierer, der effektive Prompts für unsere Module basierend auf einem Trainingsset und einer Metrik für die Validierung generiert und auswählt.
from dspy.teleprompt import BootstrapFewShot # Validierungsmetrik def validate_context_and_answer(example, pred, trace=None): answer_EM = dspy.evaluate.answer_exact_match(example, pred) answer_PM = dspy.evaluate.answer_passage_match(example, pred) return answer_EM and answer_PM # Einrichten des Optimierers teleprompter = BootstrapFewShot(metric=validate_context_and_answer) # Kompilieren des Programms compiled_rag = teleprompter.compile(RAG(), trainset=trainset)
Schritt 6: Auswerten der Pipeline
Nach der Kompilierung des Programms ist es wichtig, seine Leistung auf einem Entwicklungsset zu bewerten, um sicherzustellen, dass es die gewünschte Genauigkeit und Zuverlässigkeit erreicht.
from dspy.evaluate import Evaluate
# Einrichten des Evaluators
evaluate = Evaluate(devset=devset, metric=validate_context_and_answer, num_threads=4, display_progress=True, display_table=0)
# Auswerten des kompilierten RAG-Programms
evaluation_result = evaluate(compiled_rag)
print(f"Evaluierungsergebnis: {evaluation_result}")
Schritt 7: Überprüfen der Modellhistorie
Um ein tieferes Verständnis der Modellinteraktionen zu erhalten, können Sie die jüngsten Generierungen überprüfen, indem Sie die Modellhistorie überprüfen.
# Überprüfen der Modellhistorie turbo.inspect_history(n=1)
Schritt 8: Erstellen von Vorhersagen
Mit der optimierten und ausgewerteten Pipeline können Sie sie jetzt verwenden, um Vorhersagen für neue Fragen zu erstellen.
# Beispiel-Frage
question = "Welchen Preis hat das erste Buch von Gary Zukav erhalten?"
# Erstellen einer Vorhersage mithilfe des kompilierten RAG-Programms
prediction = compiled_rag(question)
print(f"Frage: {question}")
print(f"Antwort: {prediction.answer}")
print(f"Abgerufener Kontext: {prediction.context}")
Minimales Arbeitsbeispiel mit DSPy
Lassen Sie uns nun ein weiteres minimales Arbeitsbeispiel mit dem GSM8K-Datensatz und dem OpenAI-GPT-3.5-Turbo-Modell durchgehen, um Prompting-Aufgaben innerhalb von DSPy zu simulieren.
Einrichtung
Stellen Sie zunächst sicher, dass Ihre Umgebung ordnungsgemäß konfiguriert ist:
import dspy from dspy.datasets.gsm8k import GSM8K, gsm8k_metric # Einrichten des LMs turbo = dspy.OpenAI(model='gpt-3.5-turbo-instruct', max_tokens=250) dspy.settings.configure(lm=turbo) # Laden von Mathematikfragen aus dem GSM8K-Datensatz gsm8k = GSM8K() gsm8k_trainset, gsm8k_devset = gsm8k.train[:10], gsm8k.dev[:10] print(gsm8k_trainset)
Der gsm8k_trainset und gsm8k_devset enthalten eine Liste von Beispielen, wobei jeder Beispiel eine Frage und eine Antwort enthält.
Definieren des Moduls
Definieren Sie als Nächstes ein benutzerdefiniertes Programm, das das ChainOfThought-Modul für schrittweises Reasoning nutzt:
class CoT(dspy.Module):
def __init__(self):
super().__init__()
self.prog = dspy.ChainOfThought("Frage -> Antwort")
def forward(self, question):
return self.prog(question=question)
Kompilieren und Auswerten des Modells
Kompilieren Sie es jetzt mit dem BootstrapFewShot-Teleprompter:
from dspy.teleprompt import BootstrapFewShot # Einrichten des Optimierers config = dict(max_bootstrapped_demos=4, max_labeled_demos=4) # Optimieren mithilfe der gsm8k_metric teleprompter = BootstrapFewShot(metric=gsm8k_metric, **config) optimized_cot = teleprompter.compile(CoT(), trainset=gsm8k_trainset) # Einrichten des Evaluators from dspy.evaluate import Evaluate evaluate = Evaluate(devset=gsm8k_devset, metric=gsm8k_metric, num_threads=4, display_progress=True, display_table=0) evaluate(optimized_cot) # Überprüfen der Modellhistorie turbo.inspect_history(n=1)
Dieses Beispiel zeigt, wie Sie Ihre Umgebung einrichten, ein benutzerdefiniertes Modul definieren, ein Modell kompilieren und seine Leistung mithilfe des bereitgestellten Datensatzes und der Teleprompter-Konfigurationen rigoros auswerten können.
Datemanagement in DSPy
DSPy arbeitet mit Trainings-, Entwicklungs- und Testsets. Für jedes Beispiel in Ihren Daten haben Sie normalerweise drei Arten von Werten: Eingaben, Zwischenlabels und Endlabels. Während Zwischen- oder Endlabels optional sind, ist es wichtig, einige Beispiel-Eingaben zu haben.
Erstellen von Beispiel-Objekten
Beispiel-Objekte in DSPy sind ähnlich wie Python-Wörterbücher, aber sie kommen mit nützlichen Hilfsmitteln:
qa_pair = dspy.Example(question="Dies ist eine Frage?", answer="Dies ist eine Antwort.") print(qa_pair) print(qa_pair.question) print(qa_pair.answer)












