Robustheit und Determinismus in LLM-Anwendungen aufbauen

Bild vom Autor

OpenAI vor kurzem angekündigt Unterstützung für Strukturierte Ausgaben in seiner neuesten gpt-4o-2024–08–06 Modelle. Strukturierte Ausgaben im Zusammenhang mit großen Sprachmodellen (LLMs) sind nichts Neues – Entwickler haben entweder verschiedene Immediate-Engineering-Techniken oder Instruments von Drittanbietern verwendet.

In diesem Artikel erklären wir, was strukturierte Ausgaben sind, wie sie funktionieren und wie Sie sie in Ihren eigenen LLM-basierten Anwendungen anwenden können. Obwohl die Ankündigung von OpenAI die Implementierung mithilfe ihrer APIs recht einfach macht (wie wir hier zeigen werden), möchten Sie sich vielleicht stattdessen für die Open-Supply-Model entscheiden. Umrisse Paket (gepflegt von den netten Leuten bei dottxt), da es sowohl auf die selbstgehosteten Open-Weight-Modelle (z. B. Mistral und LLaMA) als auch auf die proprietären APIs (Haftungsausschluss: wegen dieses Drawback Outlines unterstützt zum Zeitpunkt des Schreibens dieses Artikels noch nicht die strukturierte JSON-Generierung über OpenAI-APIs; das wird sich jedoch bald ändern!).

Wenn RedPajama-Datensatz ist ein Hinweis, dass die überwiegende Mehrheit der vor dem Coaching gewonnenen Daten menschlicher Textual content ist. Daher ist „natürliche Sprache“ die native Domäne von LLMs – sowohl bei der Eingabe als auch bei der Ausgabe. Wenn wir jedoch Anwendungen erstellen, möchten wir maschinenlesbare formale Strukturen oder Schemata verwenden, um unsere Dateneingabe/-ausgabe zu kapseln. Auf diese Weise bauen wir Robustheit und Determinismus in unsere Anwendungen ein.

Strukturierte Ausgaben ist ein Mechanismus, mit dem wir ein vordefiniertes Schema für die LLM-Ausgabe erzwingen. Dies bedeutet normalerweise, dass wir ein JSON-Schema erzwingen, es ist jedoch nicht nur auf JSON beschränkt – wir könnten grundsätzlich XML, Markdown oder ein vollständig benutzerdefiniertes Schema erzwingen. Die Vorteile strukturierter Ausgaben sind zweifach:

  1. Einfacheres Immediate-Design — wir brauchen nicht seien Sie zu ausführlich, wenn Sie angeben, wie die Ausgabe aussehen soll
  2. Deterministische Namen und Typen — wir können Garantie um beispielsweise ein Attribut zu erhalten age mit einem Quantity JSON-Typ in der LLM-Antwort

Für dieses Beispiel verwenden wir den ersten Satz aus Sam Altmans Wikipedia-Eintrag

Samuel Harris Altman (* 22. April 1985) ist ein US-amerikanischer Unternehmer und Investor, der vor allem seit 2019 als CEO von OpenAI bekannt ist (er wurde kurzzeitig entlassen und im November 2023 wieder eingestellt).

…und wir werden den neuesten GPT-4o-Checkpoint als Named-Entity-Recognition-System (NER) verwenden. Wir werden das folgende JSON-Schema erzwingen:

json_schema = {
"identify": "NamedEntities",
"schema": {
"sort": "object",
"properties": {
"entities": {
"sort": "array",
"description": "Record of entity names and their corresponding varieties",
"gadgets": {
"sort": "object",
"properties": {
"identify": {
"sort": "string",
"description": "The precise identify as specified within the textual content, e.g. an individual's identify, or the identify of the nation"
},
"sort": {
"sort": "string",
"description": "The entity sort, resembling 'Particular person' or 'Group'",
"enum": ("Particular person", "Group", "Location", "DateTime")
}
},
"required": ("identify", "sort"),
"additionalProperties": False
}
}
},
"required": ("entities"),
"additionalProperties": False
},
"strict": True
}

Im Wesentlichen sollte unsere LLM-Antwort enthalten: NamedEntities Objekt, das aus einem Array von entitiesjede enthält eine identify Und sort. Hier gibt es einige Dinge zu beachten. Wir können zum Beispiel erzwingen Aufzählung Typ, was in NER sehr nützlich ist, da wir die Ausgabe auf einen festen Satz von Entitätstypen beschränken können. Wir müssen alle Felder im required Array: Wir können jedoch auch „optionale“ Felder emulieren, indem wir den Typ beispielsweise auf ("string", null) .

Wir können nun unser Schema zusammen mit den Daten und Anweisungen an die API übergeben. Wir müssen die response_format Streit mit einem diktieren wo wir sort Zu "json_schema” und geben Sie dann das entsprechende Schema an.

completion = consumer.beta.chat.completions.parse(
mannequin="gpt-4o-2024-08-06",
messages=(
{
"function": "system",
"content material": """You're a Named Entity Recognition (NER) assistant.
Your job is to establish and return all entity names and their
varieties for a given piece of textual content. You might be to strictly conform
solely to the next entity varieties: Particular person, Location, Group
and DateTime. If unsure about entity sort, please ignore it.
Watch out of sure acronyms, resembling function titles "CEO", "CTO",
"VP", and so forth - these are to be ignore.""",
},
{
"function": "consumer",
"content material": s
}
),
response_format={
"sort": "json_schema",
"json_schema": json_schema,
}
)

Die Ausgabe sollte ungefähr so ​​aussehen:

{   'entities': (   {'identify': 'Samuel Harris Altman', 'sort': 'Particular person'},
{'identify': 'April 22, 1985', 'sort': 'DateTime'},
{'identify': 'American', 'sort': 'Location'},
{'identify': 'OpenAI', 'sort': 'Group'},
{'identify': '2019', 'sort': 'DateTime'},
{'identify': 'November 2023', 'sort': 'DateTime'})}

Der vollständige Quellcode, der in diesem Artikel verwendet wird, ist verfügbar Hier.

Die Magie liegt in der Kombination von eingeschränkte StichprobennahmeUnd kontextfreie Grammatik (CFG). Wir haben bereits erwähnt, dass die überwiegende Mehrheit der vor dem Coaching gewonnenen Daten aus „natürlicher Sprache“ besteht. Statistisch gesehen bedeutet dies, dass bei jedem Dekodierungs-/Abtastschritt eine nicht zu vernachlässigende Wahrscheinlichkeit besteht, ein beliebiges Token aus dem erlernten Vokabular abzutasten (und in modernen LLMs umfassen Vokabulare normalerweise über 40.000 Token). Beim Umgang mit formalen Schemata möchten wir jedoch alle unwahrscheinlichen Token schnell eliminieren.

Wenn wir im vorherigen Beispiel bereits Folgendes generiert haben …

{   'entities': (   {'identify': 'Samuel Harris Altman',

…dann würden wir im Idealfall einen sehr hohen Logit-Bias auf die 'typ Token im nächsten Dekodierungsschritt und sehr geringe Wahrscheinlichkeit für alle anderen Token im Vokabular.

Im Wesentlichen passiert Folgendes. Wenn wir das Schema bereitstellen, wird es in eine formale Grammatik (CFG) umgewandelt, die dazu dient, die Logit-Bias-Werte während des Dekodierungsschritts zu steuern. CFG ist einer dieser altmodischen Mechanismen der Informatik und der natürlichen Sprachverarbeitung (NLP), der gerade ein Comeback erlebt. Eine sehr schöne Einführung in CFG wurde tatsächlich in diese StackOverflow-Antwortim Wesentlichen handelt es sich jedoch um eine Möglichkeit, Transformationsregeln für eine Sammlung von Symbolen zu beschreiben.

Strukturierte Ausgaben sind nichts Neues, aber sie werden mit proprietären APIs und LLM-Diensten immer wichtiger. Sie bilden eine Brücke zwischen dem sprunghaften und unvorhersehbaren „natürlichen Sprachbereich“ der LLMs und dem deterministischen und strukturierten Bereich der Softwareentwicklung. Strukturierte Ausgaben sind im Wesentlichen muss für alle, die komplexe LLM-Anwendungen entwickeln, bei denen LLM-Ausgaben in verschiedenen Komponenten geteilt oder „präsentiert“ werden müssen. Obwohl es nun endlich API-native Unterstützung gibt, sollten Entwickler auch die Verwendung von Bibliotheken wie Outlines in Betracht ziehen, da diese eine LLM/API-agnostische Möglichkeit bieten, mit strukturierter Ausgabe umzugehen.

Von admin

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert