Seit dem Erscheinen von ChatGPT haben viele Open-Source-LLMs (Language Learning Models) das Licht der Welt erblickt, doch keines hat bisher die Zufriedenheit und Zuverlässigkeit von OpenAI erreicht. Wenn Sie LLMs in Ihrer App verwenden oder selbst eine entwickeln möchten, ist OpenAI nach wie vor die beste Wahl. Das Unternehmen bietet ein großartiges Geschäftsmodell für seine API-Sprachmodelle an, wobei die kostengünstigste und leistungsstärkste Option, gpt-3.5-turbo-0125, weit verbreitet ist. Tatsächlich können Sie die Kosten noch weiter senken, indem Sie geschickt mit der API-Abfrage umgehen. Der Schlüssel dazu liegt im Prompt Engineering, also der richtigen Gestaltung der Eingabe und der gewünschten Ausgabe.
Werfen wir einen schnellen Blick auf den aktuellen Stand im März 2024. Für diesen Blog verwenden wir das gpt-3.5-turbo-0125-Sprachmodell. Sie können auch andere Modelle verwenden, aber dieses ist für uns das kostengünstigste, insbesondere da wir mit vielen Textdaten arbeiten werden. Schauen wir uns die Spezifikationen wie Preisgestaltung, Token-Grenzen und mehr an.
Bevor wir beginnen, werfen wir einen Blick darauf, wie OpenAI die Token berechnet, wenn eine API-Abfrage durchgeführt wird.
# Importieren der OpenAI-Klasse aus dem openai-Modul
from openai import OpenAI
# Erstellung einer Instanz der OpenAI-Klasse mit dem bereitgestellten API-Schlüssel
client = OpenAI(api_key=open_ai_key)
# Festlegung der Benutzereingabe auf den String "Hi"
user_input = "Hi"
# Erstellung einer Chat-Fertigstellung mit dem OpenAI-Client und der Benutzereingabe
response = client.chat.completions.create(
model="gpt-3.5-turbo-0125", # Festlegung des Modells auf "gpt-3.5-turbo-0125"
messages=[{"role": "user", "content": user_input}]
)
# Ausgabe der Antwort aus der Chat-Fertigstellung
print(response.choices[0].message.content)
######## AUSGABE ########
Hello! How can I help you today?
######## AUSGABE ########
Sie könnten denken, dass die Eingabe von „Hi“ als einzelnes Token nur 7-9 Token als Antwort erzeugen würde. Aber das ist nicht der Fall. Wenn wir die Nutzungsdetails der Antwort ausgeben, sehen wir Folgendes:
# Ausgabe der Nutzung der Antwort
print(response.usage)
######## AUSGABE ########
CompletionUsage(completion_tokens=9, prompt_tokens=8, total_tokens=17)
######## AUSGABE ########
Bitte beachten Sie, dass prompt_tokens, das sich auf die Eingabetoken bezieht, 8 beträgt. Dies liegt daran, dass bei jeder Übermittlung von Text an die API automatisch 7 zusätzliche Token hinzugefügt werden. „` Der Wert von **completion\_tokens** ist der erwartete Wert und stellt die Token in der von dem Modell generierten Antwort dar.
Auf der Grundlage dessen, was wir gelernt haben, schreiben wir eine Funktion, die eine Benutzereingabe als Eingabe akzeptiert und vier Dinge zurückgibt: die API-Antwort, die Kosten der Eingabetoken, die Kosten der Ausgabetoken und die Gesamtkosten.
def openai_chat(user_prompt):
# Erstellung einer Chat-Fertigstellung mit dem OpenAI-Client
response = client.chat.completions.create(
# Festlegung des Modells auf "gpt-3.5-turbo-0125"
model="gpt-3.5-turbo-0125",
messages=[{"role": "user", "content": user_prompt}]
)
# Antwort aus der Chat-Fertigstellung
answer = response.choices[0].message.content
# Berechnung des Preises für die Eingabetoken
input_price = response.usage.prompt_tokens * (0.5 / 1e6)
# Berechnung des Preises für die Ausgabetoken
output_price = response.usage.completion_tokens * (1.5 / 1e6)
# Berechnung des Gesamtpreises
total_price = input_price + output_price
# Rückgabe der Antwort, des Eingabepreises, des Ausgabepreises und des Gesamtpreises
return {
"answer": answer,
"input_price": f"$ {input_price}",
"output_price": f"$ {output_price}",
"total_price": f"$ {total_price}"
}
Lassen Sie uns sehen, wie diese Funktion funktioniert, indem wir sie mit einer einfachen, kurzen Eingabe ausprobieren.
# Aufruf unserer Funktion mit der Eingabe
openai_chat("What is the capital of China?")
####### AUSGABE #######
{
answer: 'The capital of China is Beijing.',
input_price: '$ 7e-06',
output_price: '$ 1.05e-05',
total_price: '$ 1.75e-05'
}
####### AUSGABE #######
Die Ausgabe unserer Funktion sollte klar sein. Um zu klären, dass der Preis basierend auf der Preistabelle berechnet wird, die ich Ihnen früher für das gpt-3.5-turbo-0215-Modell gezeigt habe.
# Frage zu einem Dokument mit 100.000 Wörtern
openai_chat(100K_words_document_and_one_question)
####### AUSGABE #######
{
answer: 'According to the given context ...',
input_price: '$ 0.18',
output_price: '$ 0.02',
total_price: '$ 0.20'
}
####### AUSGABE #######
Für eine große Menge an Text (100.000 Wörter) und eine Frage betragen die geschätzten Kosten nur etwa 0,20 $. Dies zeigt, wie effizient das gpt-3.5-turbo-Modell sein kann. Nun, da wir unsere Funktion bereit haben, lassen Sie uns sehen, wie wir die Kosten für die Verwendung der OpenAI-API minimieren können.
Clustering mit der OpenAI-API
Stellen Sie sich vor, Sie haben eine riesige Liste von Nachrichtenschlagzeilen und möchten diese gruppieren. Während die Verwendung von Einbettungen eine Option ist, nehmen wir an, dass Sie die OpenAI-Sprachmodell-API verwenden möchten, da sie die Bedeutung auf menschliche Weise erfassen kann. Bevor wir die Vorlagenvorlage zur Kostenminimierung erstellen, werfen wir einen Blick auf unsere Liste mit Nachrichtenschlagzeilen.
# Liste mit Nachrichtenschlagzeilen
news_headlines = [
"donald trump is ... surprise when he arrives",
"Emirates airlines ... takeover of Etihad Airways",
"The US is considering ... troops to Afghanistan",
...
]
# Länge der Nachrichtenliste
len(news_headlines)
####### AUSGABE #######
1256
####### AUSGABE #######
Wir haben über 1.200 Nachrichtenschlagzeilen. Bevor wir die Vorlagenvorlage erstellen, fassen wir sie zu einer einzigen Zeichenfolge mit einem bestimmten Format zusammen. Dadurch kann das Sprachmodell sie effizienter verarbeiten.
formatierte_nachrichten = "Given the news headlines:\n"
# Schleife durch alle Nachrichtenschlagzeilen und Formatierung in einer einzigen Zeichenfolge
for i in range(0,len(user_input)):
formatierte_zeichenkette += f"s{i}: {user_input[i]}\n"
# Ausgabe der formatierten Nachrichten
print(formatierte_nachrichten)
####### AUSGABE #######
s0: donald trump is ... surprise when he arrives
s1: Emirates airlines ... takeover of Etihad Airways
s2: The US is considering ... troops to Afghanistan
...
s1256: Virat Kholi is ready ... against Srilanka
####### AUSGABE #######
Ich habe die Nachrichtenschlagzeilen in einer kürzeren Form dargestellt, wie z. B. s0, s1, s2 usw. Der Grund dafür ist, dass das Sprachmodell bei der Gruppierung einfach diese kurzen Abkürzungen (z. B. s35 für die 35. Nachrichtenschlagzeile) verwenden kann, anstatt die vollständige Schlagzeile in jeder Gruppe auszuschreiben.
vorlagen_vorlage = f'''{formatierte_nachrichten}
Ich habe diese Nachrichtenschlagzeilen und möchte, dass Sie eine Gruppierung durchführen.
Sie müssen mir in diesem Format antworten:
cluster1: s1,s3 ...
cluster2: s2, s6 ...
...
Schreiben Sie es einfach so, beginnend mit s0,s1,s2 ...
Schreiben Sie nichts anderes als das Format
'''
Als Nächstes habe ich meine Vorlagenvorlage definiert. Diese Vorlage gibt das Format der Antwort an, die ich vom Sprachmodell erhalten möchte, sowie einige zusätzliche Informationen zur Klarstellung. Der Schlüssel hier ist, dass wir das Modell nicht auffordern, die vollständigen Schlagzeilen auszuschreiben, sondern nur die kurzen Abkürzungen zu verwenden.
Alles, was wir tun müssen, ist, diese Vorlagenvorlage an die Funktion zu übergeben, die wir zuvor erstellt haben, und zu sehen, wie sie in Bezug auf die Preisgestaltung und die Qualität der Antwort abschneidet.
# Aufruf unserer Funktion mit der Vorlagenvorlage
ergebnisse = openai_chat(vorlagen_vorlage)
# Ausgabe der Antwort
print(ergebnisse['answer'])
####### AUSGABE #######
cluster1: s5, s67, s55, s134, s764 ...
cluster2: s64, s21, s896, s445, s12 ...
...
cluster7: s12, s853, s414, s244, s712 ...
####### AUSGABE #######
Ich habe die Antwort hier gekürzt, aber das Sprachmodell hat unsere 1.256 Nachrichtenschlagzeilen erfolgreich in sieben Gruppen eingeteilt. Sie können die Vorlagenvorlage weiter bearbeiten, um die gewünschte Anzahl von Gruppen anzugeben. Lassen Sie uns sehen, wie viel uns diese Aufgabe gekostet hat.
# Ausgabe der vollständigen Ergebnisse
print(ergebnisse)
####### AUSGABE #######
{
answer: 'cluster1: s5, s67, ...',
input_price: '$ 0.020',
output_price: '$ 0.003',
total_price: '$ 0.023'
}
####### AUSGABE #######
Die Gesamtkosten für diese Aufgabe betragen 0,023 $. Wenn wir diese Vorlagenvorlage nicht verwendet hätten, hätten wir wahrscheinlich mehr als das Doppelte der Eingabekosten ausgegeben. Dies liegt daran, dass wir alle Schlagzeilen als Eingabe gesendet hätten und die Ausgabekosten von 1,50 $ pro Million Token auf die vollständigen Schlagzeilen angewendet worden wären, die in der Antwort zurückgegeben worden wären. Hier ist eine Zusammenfassung, wie viel wir durch den Einsatz dieser Methode gespart haben:
Diese Methode wird entscheidend sein, da sie Ihre Guthaben exponentiell spart, wenn Sie mit größeren Datenmengen arbeiten. Wir müssen jedoch ein wenig codieren, um die kurzen Abkürzungen den tatsächlichen Schlagzeilen zuzuordnen.
# Aufteilung der Antwortzeichenkette in einzelne Zeilen
antworten = ergebnis['antwort'].split("\n")
# Erstellung einer Wörterbuch-Komprehension zur Extrahierung von Schlüssel-Wert-Paaren aus jeder Zeile
clusters = {line.split(": ")[0].strip(): [i.strip() for i in line.split(": ")[1].split(",")] for line in antworten if line.strip()}
# Ersetzen der Schlüssel (s01, s02, s03 usw.) durch die tatsächlichen Schlagzeilen aus 'news_headlines'
for k, v in clusters.items():
clusters[k] = [news_headlines[int(i[1:])] for i in v]
Der obige Code ordnet die Antwort des OpenAI-Modells den tatsächlichen Nachrichtenschlagzeilen zu. Hier ist ein Beispiel für das Ergebnis:
# Ausgabe von clusters
print(clusters)
####### AUSGABE #######
{
'cluster1': ["Sea levels ... change", "Arabian sea .. pollution", ...],
'cluster2': ["fifa has banned ... ", "Ronaldo has been ... a row", ...}
...
}
####### AUSGABE #######
Rechtschreibprüfung mit der OpenAI-API
Angenommen, Sie haben ein längeres Textdokument und möchten eine Rechtschreibprüfungs-App als Web-App erstellen. Während es viele NLP-Techniken (Natural Language Processing) für diese Aufgabe gibt, sind Sprachmodelle, insbesondere die von OpenAI, an einer Vielzahl von Daten ausgebildet worden, was sie zu einer potenziell besseren Wahl macht. Wieder einmal ist der Schlüssel, bei unserer Vorlagenvorlage strategisch vorzugehen. Wir möchten, dass die API-Antwort falsch geschriebene Wörter hervorhebt und ihre korrekten Schreibweisen vorschlägt, anstatt den gesamten korrigierten Text als Ausgabe bereitzustellen. Werfen wir einen Blick auf unsere Eingabe:
# Meine Eingabe, die Rechtschreibfehler enthält
benutzer_eingabe = '''As the sun beganned to set on the horizen, casting a
warm gloy across the ... '''
# Ausgabe der Gesamtzahl der Wörter
print(len(benutzer_eingabe.split()))
####### AUSGABE #######
500.000
####### AUSGABE #######
Wir haben ein 500.000-Wörter-Dokument mit Rechtschreibfehlern, die korrigiert werden müssen. Unser nächster Schritt besteht darin, eine Vorlagenvorlage zu erstellen, die das API-Modell anleitet, Antworten bereitzustellen, die sich ausschließlich auf die problematischen Wörter konzentrieren.
vorlagen_vorlage = f'''Given the input text:
user input: {benutzer_eingabe}
output must be in this format:
misspelled_word:corrected_word
...
output must not contain any other information than the format
'''
Innerhalb der Vorlagenvorlage haben wir das gewünschte Antwortformat ausdrücklich definiert. Das API-Modell sollte falsch geschriebene Wörter hervorheben und ihre korrekten Schreibweisen vorschlagen. Wir haben auch angegeben, dass keine zusätzlichen Informationen in der Antwort enthalten sein sollten, da wir einen Code verwenden werden, um diese Wörter im ursprünglichen benutzer\_eingabe zu ersetzen.
Alles, was wir tun müssen, ist, diese Vorlagenvorlage an die Funktion zu übergeben, die wir zuvor erstellt haben, und zu sehen, wie sie in Bezug auf die Preisgestaltung und die Qualität der Antwort abschneidet.
# Aufruf unserer Funktion mit der Vorlagenvorlage
ergebnisse = openai_chat(vorlagen_vorlage)
# Ausgabe der Antwort
print(ergebnisse['answer'])
####### AUSGABE #######
beganned: began
horizen: horizon
gras: grass
...
####### AUSGABE #######
Ich habe die Antwort hier gekürzt, aber das API-Modell hat die falsch geschriebenen Wörter erfolgreich identifiziert und ihre korrekten Schreibweisen bereitgestellt. Lassen Sie uns sehen, wie viel uns diese Aufgabe gekostet hat.
# Ausgabe der vollständigen Ergebnisse
print(ergebnisse)
####### AUSGABE #######
{
answer: 'beganned: began \n horizen: horizon ...',
input_price: '$ 0.33333',
output_price: '$ 0.005135',
total_price: '$ 0.33812'
}
####### AUSGABE #######
Die Gesamtkosten für diese Aufgabe betragen 0,33812 $, wenn 500.000 Wörter 8.000-10.000 Rechtschreibfehler enthalten. Wenn wir diese Vorlagenvorlage nicht verwendet hätten, hätten wir wahrscheinlich mehr als das Doppelte der Eingabekosten ausgegeben. Dies liegt daran, dass wir den gesamten Text als Eingabe gesendet hätten und die Ausgabekosten von 1,50 $ pro Million Token auf den gesamten Text angewendet worden wären, der in der Antwort zurückgegeben worden wäre. Hier ist eine Zusammenfassung, wie viel wir durch den Einsatz dieser Methode gespart haben:
Selbst bei einem relativ kleinen Text von 500 Wörtern sind die Kosteneinsparungen bemerkbar. Stellen Sie sich die finanziellen Vorteile vor, wenn Sie mit großen Datenmengen arbeiten!
Wir müssen jedoch ein wenig codieren, um die falsch geschriebenen Wörter durch ihre korrekten Versionen zu ersetzen.
# Aufteilung der Antwortzeichenkette in einzelne Zeilen
antwort = ergebnis['antwort'].split("\n")
# Erstellung einer Listen-Komprehension zur Extrahierung von Schlüssel-Wert-Paaren aus jeder Zeile
ergebnis = [(line.split(":")[0], line.split(":")[1]) for line in antwort if line.strip()]
# Ersetzen der falsch geschriebenen Wörter durch die korrigierten Wörter
for wort, korrigiertes_wort in ergebnis:
korrigierte_benutzer_eingabe = benutzer_eingabe.replace(wort, korrigiertes_wort)
Der obige Code ersetzt die falsch geschriebenen Wörter durch ihre korrekten Versionen. Hier ist das Ergebnis:
# Ausgabe von korrigierte_benutzer_eingabe
print(korrigierte_benutzer_eingabe)
####### AUSGABE #######
As the sun began to set on the horizon, casting
warm glow across the ...
####### AUSGABE #######
Textbereinigung mit der OpenAI-API
Die Vorlagenvorlage, die wir für die Rechtschreibprüfung verwendet haben, kann auch für die Textbereinigung verwendet werden, bei der wir nur die Wörter hervorheben möchten, die entweder bereinigt oder vollständig entfernt werden sollen.
Wir möchten, dass die API-Antwort falsch geschriebene Wörter hervorhebt und ihre korrekten Schreibweisen vorschlägt, anstatt den gesamten korrigierten Text als Ausgabe bereitzustellen. Werfen wir einen Blick auf unsere Eingabe:
# Meine Eingabe, die Bereinigungsfehler enthält
benutzer_eingabe = '''The rugge9d pathw&ay winded through the th!ck f0r3st,
obfusca+ting the way forward. The creaking of branches
and rustling of leaves added an ... '''
# Ausgabe der Gesamtzahl der Wörter
print(len(benutzer_eingabe.split()))
####### AUSGABE #######
1.000.000
####### AUSGABE #######
Wir haben ein 1.000.000-Wörter-Dokument, das bereinigt werden muss. Unser nächster Schritt besteht darin, eine Vorlagenvorlage zu erstellen, die das API-Modell anleitet, Antworten bereitzustellen, die sich ausschließlich auf die problematischen Wörter konzentrieren.
vorlagen_vorlage = f'''Given the input text:
user input: {benutzer_eingabe}
output must be in this format:
uncleaned_word:cleaned_word
...
if no replacement for uncleaned_word exist then use this format
uncleaned_word:
output must not contain any other information than the format
'''
Innerhalb der Vorlagenvorlage haben wir das gewünschte Antwortformat ausdrücklich definiert. Das API-Modell sollte unsaubere Wörter hervorheben und ihre bereinigten Versionen vorschlagen, und wenn keine Ersetzung für unsaubere Wörter existiert, dann sollte es durch eine leere Zeichenkette ersetzt werden. Wir haben auch angegeben, dass keine zusätzlichen Informationen in der Antwort enthalten sein sollten, da wir einen Code verwenden werden, um diese Wörter im ursprünglichen benutzer\_eingabe zu ersetzen.
Alles, was wir tun müssen, ist, diese Vorlagenvorlage an die Funktion zu übergeben, die wir zuvor erstellt haben, und zu sehen, wie sie in Bezug auf die Preisgestaltung und die Qualität der Antwort abschneidet.
# Aufruf unserer Funktion mit der Vorlagenvorlage
ergebnisse = openai_chat(vorlagen_vorlage)
# Ausgabe der Antwort
print(ergebnisse['answer'])
####### AUSGABE #######
rugge9d: rugged
th!ck: thick
f0r3st: forest
obfusca+ting: obfuscating
s;ense: sense
...
####### AUSGABE #######
Ich habe die Antwort hier gekürzt, aber das API-Modell hat die unsauberen Wörter erfolgreich identifiziert und ihre bereinigten Versionen bereitgestellt. Lassen Sie uns sehen, wie viel uns diese Aufgabe gekostet hat.
# Ausgabe der vollständigen Ergebnisse
print(ergebnisse)
####### AUSGABE #######
{
answer: 'rugge9d: rugged \n th!ck: thick ...',
input_price: '$ 0.6665',
output_price: '$ 0.099',
total_price: '$ 0.7665'
}
####### AUSGABE #######
Die Gesamtkosten für diese Aufgabe betragen 0,7665 $, wenn 1.000.000 Wörter 20.000-30.000 Bereinigungsfehler enthalten. Wenn wir diese Vorlagenvorlage nicht verwendet hätten, hätten wir wahrscheinlich mehr als das Doppelte der Eingabekosten ausgegeben. Hier ist eine Zusammenfassung, wie viel wir durch den Einsatz dieser Methode gespart haben:
Bei der Arbeit mit einem 1.000.000-Wörter-Dokument sind die Kosteneinsparungen bemerkbar. Stellen Sie sich die finanziellen Vorteile vor, wenn Sie mit großen Datenmengen arbeiten!
Wir müssen jedoch ein wenig codieren, um die unsauberen Wörter durch ihre bereinigten Versionen zu ersetzen.
# Aufteilung der Antwortzeichenkette in einzelne Zeilen
antwort = ergebnis['antwort'].split("\n")
# Erstellung einer Listen-Komprehension zur Extrahierung von Schlüssel-Wert-Paaren aus jeder Zeile
ergebnis = [(line.split(": ")[0], line.split(": ")[1]) for line in antwort if line.strip()]
# Ersetzen der unsauberen Wörter durch die bereinigten Wörter
for wort, korrigiertes_wort in ergebnis:
bereinigte_benutzer_eingabe = benutzer_eingabe.replace(wort, korrigiertes_wort)
Der obige Code ersetzt die unsauberen Wörter durch ihre bereinigten Versionen. Hier ist das Ergebnis:
# Ausgabe von bereinigte_benutzer_eingabe
print(bereinigte_benutzer_eingabe)
####### AUSGABE #######
The rugged pathway winded through the thick forest,
obfuscating the way forward. The creaking of branches
and rustling of leaves added an ...
####### AUSGABE #######
LLM-basierte NLP
Ich habe eine NLP-Bibliothek (Natural Language Processing) entwickelt, die LLM-APIs (Language Learning Models) verwendet, um verschiedene Aufgaben auszuführen. Sie enthält über 30 Funktionen, von denen viele mit ähnlichen Kostenoptimierungsstrategien wie oben beschrieben arbeiten. Sie können die Bibliothek und ihre Vorlagenvorlagen in meinem GitHub-Repository erkunden: