Mit dem Wachstum von LLM-Modellen wie ChatGPT kam es bei Unternehmen zu einem Ansturm auf die Kommerzialisierung sprachbasierter Deep-Learning-Anwendungen. Unternehmen wie Duolingo und Blinkist entwickeln pädagogische Chat-Anwendungen, Firmen wie Cocounsel entwickeln Modelle zur Dokumentenanalyse und einige, wie MedGPT, entwickeln sogar Spezialmodelle, die beispielsweise medizinische Diagnosen durchführen können. In einem früheren Artikel habe ich darüber geschrieben, wie jemand ChatGPT und Prompt Engineering nutzen kann, um einen leistungsstarken Dokumentenanalysator zu erstellen.
Um leistungsfähigere und domänenspezifische LLM-Anwendungen zu unterstützen, haben Technologieanbieter zahlreiche Cloud-Lösungen zur Verfügung gestellt. OpenAI, das Unternehmen hinter ChatGPT, hat beispielsweise Benutzern eine einfache, aber leistungsstarke API zur Feinabstimmung zur Verfügung gestellt, mit der Benutzer ihre eigenen Sprachmodelle auf Basis der GPT3-Technologie erstellen können. Um nicht zu übertreffen, stellte Google sein Bison-Text-Modell, das weithin als leistungsfähiger Konkurrent von GPT 3 und GPT 3.5 gilt, zur Feinabstimmung über die Google Cloud-Plattform zur Verfügung. In einem früheren Artikel habe ich darüber geschrieben, wie man die Feinabstimmungs-API verwendet, um ein Domänenexperten-LLM zu erstellen.
So leistungsstark diese Dienste auch sein können, ein Unternehmen, das eine ernsthafte Investition in LLM-Technologie erwägt, möchte lernen, seine eigenen Modelle mithilfe von Open-Source-Technologien zu trainieren. Im Vergleich zur Verwendung dieser vom Anbieter bereitgestellten Endpunkte bietet das Training Ihres eigenen Modells die folgenden Vorteile :
In diesem Artikel nehmen wir ein beliebtes und leistungsfähiges Open-Source-LLM-Modell, trainieren es anhand unserer eigenen Daten, ähnlich wie wir es in einem früheren Artikel getan haben, und validieren die Ergebnisse. Während das Beispiel, mit dem wir uns befassen, nichtkommerziell ist und auf öffentlichen Informationen basiert, können die Techniken problemlos auf kommerzielle Unternehmungen angewendet werden. Wir werden uns im Abschnitt „Expert LLM Model“ mit konkreten Vorschlägen dazu befassen, welche kommerziellen Anwendungen mit dieser Technik erstellt werden können, wo wir das Problem definieren, das wir in diesem Artikel lösen werden.
Für das heutige Experiment verlassen wir uns auf Flan-T5 Large, ein von Google veröffentlichtes großes Sprachmodell. Obwohl dies nicht die Technologie ist, die Bard zugrunde liegt, wird dieses Modell allgemein als konkurrenzfähig zu GPT-basierten Technologien angesehen. Das Beeindruckende an den Flan T5-Modellen ist jedoch, dass sie mit weitaus weniger Parametern zufriedenstellende Ergebnisse erzielen als GPT-basierte Modelle. Selbst die XL-Version des Modells hat beispielsweise nur 3 Milliarden Parameter, verglichen mit GPT3, das 175 Milliarden hat.
Aufgrund dieser Kompaktheit ist es relativ kostengünstig, diese Modelle auf Cloud-Computing-Ressourcen zu trainieren und zu speichern. Darüber hinaus wird die Flan-T5-Modellfamilie mit der Apache-Lizenz veröffentlicht, die eine kommerzielle Nutzung ermöglicht und potenzielle Lizenzprobleme reduziert, die mit einigen anderen Open-Source-LLMs einhergehen. Facebooks LLaMa beispielsweise steht weiterhin nur für Forschungszwecke und nichtkommerzielle Zwecke zur Verfügung.
Um diesen Artikel zu schreiben, habe ich mit einigen verschiedenen Aufgabenklassen experimentiert, um die Wirksamkeit der Technologie zu testen. Im Allgemeinen scheint Flan-T5, insbesondere die XL-Variante, über hervorragende Fähigkeiten zum Verstehen natürlicher Sprache zu verfügen, ähnlich wie einige der GPT-Modelle auf dem Markt. Allerdings ist das Modell beim Zeichnen abstrakter Verbindungen etwas unzureichend und hat einige Probleme bei der Generierung langer Ausgaben. Deshalb sollte man darauf achten, das richtige Modell für die richtige Aufgabe auszuwählen.
Replicate ist ein Platform-as-a-Service-Unternehmen, das es Menschen ermöglicht , GPUs für das Training und den Betrieb großer KI-Modelle zu einem erschwinglichen Preis zu mieten. Dank der Suite von KI-Modellverwaltungstools können sich Benutzer auf die Arbeit mit Daten konzentrieren, anstatt Serverressourcen zu verwalten.
Um diesen Artikel zu schreiben, habe ich verschiedene PaaS-Angebote für KI-Schulungen ausprobiert, darunter AWS SageMaker, Google Colab und PaperSpace Gradient. Replicate war mit Abstand die am einfachsten zu nutzende Plattform und bot im Vergleich zu den anderen genannten Diensten sehr wettbewerbsfähige Preise.
Python ist die Lingua Franca des Data Engineering. Das umfangreiche Ökosystem ermöglicht es Programmierern, Daten schnell zu erfassen, zu analysieren und zu verarbeiten. Die meisten großen KI-Trainingsplattformen bieten erstklassige Unterstützung für Python, was unsere Arbeit erheblich erleichtert. Aufgrund der hervorragenden Integration von Replicate werden wir heute unseren gesamten Code in Python schreiben.
Da die Flan-T5-Modellfamilie viel besser darin ist, Text zu verstehen als Text zu generieren, möchten wir eine Aufgabe wählen, die viele Eingaben, aber wenig Ausgaben erfordert. Klassifikatoren natürlicher Sprache sind ein perfekter Anwendungsfall für diese Art von Szenario. Deshalb werden wir heute eine Dramatiker-ID erstellen. Konkret werden wir Musterpassagen von William Shakespeare oder Anton Tschechow vorstellen und prüfen, ob wir dem Modell beibringen können, den Dramatiker anhand des Schreibstils und der Wortwahl zu identifizieren.
Da es sich um ein öffentliches Tutorial handelt, wählen wir natürlich bewusst ein Modell mit öffentlichen und leicht zugänglichen Daten. Dies lässt sich jedoch leicht auf einen kommerziellen Kontext übertragen . Hier sind einige Beispiele, bei denen Klassifikatoren natürlicher Sprache nützlich sein können:
Um die Trainingsdaten zu erstellen, können wir einige Stücke von Anton Tschechow und William Shakespeare von Project Gutenberg herunterladen. Um die Datenaufnahme einzurichten, können wir das folgende Python-Skript ausführen.
import requests import openai import replicate import os import pandas as pd import random texts = { 'chekhov': 'https://www.gutenberg.org/files/7986/7986-0.txt', 'chekhov_2': 'https://www.gutenberg.org/cache/epub/1755/pg1755.txt', 'shakespeare_midsummer': 'https://www.gutenberg.org/cache/epub/1514/pg1514.txt', 'shakespeare_romeo_juliet': 'https://www.gutenberg.org/cache/epub/1112/pg1112.txt', 'shakespeare_macbeth': 'https://www.gutenberg.org/cache/epub/2264/pg2264.txt', 'shakespeare_hamlet': 'https://www.gutenberg.org/cache/epub/2265/pg2265.txt', }
Nun erstellen wir den Trainingsdatenordner und laden die Texte herunter:
if not os.path.exists('training_text'): os.mkdir('training_text') for name, url in texts.items(): print(name) res = requests.get(url) with open(os.path.join('training_text', '%s.txt' % name), 'w') as fp_write: fp_write.write(res.text)
Sie sollten einige Ausgaben wie diese sehen, um zu zeigen, dass es erfolgreich war:
chekhov chekhov_2 shakespeare_midsummer shakespeare_romeo_juliet shakespeare_macbeth Shakespeare_hamlet
Sie können auch den Ordner „training_text“ überprüfen, um sicherzustellen, dass die Dateien ordnungsgemäß heruntergeladen wurden.
Jetzt wollen wir diese Dateien wieder in den Speicher einlesen und sie in eine Liste von Zeilen aufteilen. Wenn wir schon dabei sind, zählen wir die Anzahl der Zeilen in jeder Datei.
lines_by_file = {} for fn in os.listdir('training_text'): if not fn.endswith('.txt'): continue with open(os.path.join('training_text', fn)) as fp_file: lines_by_file[fn.split('.')[0]] = '\n'.join(fp_file.readlines()) print(fn, len(lines_by_file[fn.split('.')[0]]))
Sie sollten eine Ausgabe wie die folgende sehen:
shakespeare_midsummer.txt 120198 shakespeare_romeo_juliet.txt 179726 shakespeare_macbeth.txt 140022 shakespeare_hamlet.txt 204169 chekhov.txt 419063 chekhov_2.txt 148324
Jetzt kommt der spaßige Teil. Wir wollen die Zeilen in echte Trainingsdaten aufteilen. Dazu entfernen wir zunächst die ersten und letzten 1000 Zeilen, die von Einleitungs-, Kopf- und Fußzeileninhalten eingenommen werden. Dann erfassen wir jeweils 50 Zeilen des verbleibenden Textes. Anschließend wandeln wir die 50 Zeilen in ein Eingabeaufforderungs- und Vervollständigungspaar um.
train_data = [] for k in lines_by_file: is_chekhov = 'chekhov' in k useful_lines = lines_by_file[k].split('\n')[1000:-1000] prompt_fmt = "Which playwright wrote the following passage? \n ==== \n %s \n ====" for i in range(0, len(useful_lines), 50): training_set = useful_lines[i: i+50] train_data.append({ 'prompt': prompt_fmt % '\n'.join(training_set), 'completion': 'Anton Chekhov' if is_chekhov else 'William Shakespeare' })
Jetzt haben wir das Problem klar definiert: Stellen Sie anhand von 50 Textzeilen aus einem Theaterstück fest, ob der Dramatiker Anton Chekov oder William Shakespeare ist. Wir sind noch nicht fertig. Wir müssen die Daten für das Training in das JSONL-Format (JSON Lines) schreiben und möchten außerdem einige Beispiele für Testzwecke reservieren. Führen Sie den folgenden Code wie folgt aus:
df = pd.DataFrame(train_data) df_chekhov = df[df['completion'] == 'Anton Chekhov'] df_shakespeare = df[df['completion'] == 'William Shakespeare'] chekhov_test_indices = random.sample(df_chekhov.index.tolist(), 15) shakespeare_test_indices = random.sample(df_shakespeare.index.tolist(), 15) df_chekhov_test = df_chekhov.loc[chekhov_test_indices] df_shakespeare_test = df_shakespeare.loc[shakespeare_test_indices] df_chekhov_train = df_chekhov.loc[[i for i in df_chekhov.index if i not in chekhov_test_indices]] df_shakespeare_train = df_shakespeare.loc[[i for i in df_shakespeare.index if i not in shakespeare_test_indices]] pd.concat([df_chekhov_train, df_shakespeare_train]).to_json('chekhov_shakespeare_train.jsonl', orient='records', lines=True) pd.concat([df_chekhov_test, df_shakespeare_test]).to_json('chekhov_shakespeare_test.jsonl', orient='records', lines=True)
Wenn Sie den gesamten Korpus zum Training nutzen möchten, können Sie natürlich auch einfach laufen
pd.DataFrame(train_data).to_json('output.jsonl', orient='records', lines=True)
.
Wir müssen zwei Dinge tun, bevor wir das Training aufrufen können: Erstens müssen wir die Trainingsdaten an einen Ort hochladen, auf den die Replikation zugreifen kann. Eine sehr einfache Möglichkeit wäre, die Datei in einen Google Cloud Bucket hochzuladen, den Bucket und die Datei öffentlich zu machen und die URL im Format https://storage.googleapis.com/<bucket_name>/<file_name>
anzugeben https://storage.googleapis.com/<bucket_name>/<file_name>
.
Als nächstes müssen wir ein Ziel erstellen. Melden Sie sich dazu einfach bei Replicate an (was über Github OAuth möglich ist) und erstellen Sie ein neues Modell. Sobald das Modell erstellt und benannt wurde, können Sie Ihr Modell in diesen Bereich verschieben.
Sobald alles eingerichtet ist, können Sie das Training wie folgt starten:
training = replicate.trainings.create( version="[flant5-large location]", input={ "train_data": "[Data Location]", }, destination="[Destination]" ) print(training)
Sie sollten eine Ausgabe sehen, die Ihnen mitteilt, dass das Training beginnt. Warten Sie ein paar Minuten und überprüfen Sie das Training noch einmal, indem Sie den folgenden Code ausführen:
training.reload() print(training)
Sie können den Trainingsfortschritt auch auf der Replicate-Website überwachen. Sobald das Training abgeschlossen ist, können Sie das Trainingsobjekt neu laden, um den Ausgabenamen zu erhalten, und mit dem nächsten Schritt fortfahren.
Seien Sie gewarnt, dass es Zeiträume gibt, in denen die GPU-Ressourcen knapp sind und Sie möglicherweise die Fehlermeldung „Training fehlgeschlagen“ erhalten. Wenn Ihnen das passiert, warten Sie einfach ein paar Stunden und versuchen Sie es erneut. Es herrscht ein GPU-Mangel, und PaaS-Anbieter sind nicht davor gefeit!
In Ordnung! Nachdem wir nun unser fein abgestimmtes Modell haben, müssen wir es testen. Denken Sie daran, dass wir 15 Passagen von Tschechow und Shakespeare zum Testen reserviert haben. Wir können sie hier wie folgt verwenden:
for _, row in df_chekhov_test.iterrows(): output = replicate.run( training.output["version"], input={"prompt": row['prompt']} ) for s in output: print(s, end="", flush=True) print('')
Nach einer kurzen Startphase sollten Sie sehen, wie die Ausgabe auf der Konsole gedruckt wird. Das Modell sollte äußerst genau sein und jedes Mal „Anton Tschechow“ zurückgeben. Versuchen wir es mit Shakespeare:
for _, row in df_shakespeare_test.iterrows(): output = replicate.run( training.output["version"], input={"prompt": row['prompt']} ) for s in output: print(s, end="", flush=True) print('')
Ähnlich wie im Tschechow-Beispiel sollten Sie sehen, dass das Modell Shakespeare jedes Mal identifizieren kann.
Sehen wir uns zur Sicherheit einmal an, ob das Basismodell Shakespeare oder Tschechow identifizieren kann:
for _, row in df_shakespeare_test.iterrows(): output = replicate.run( "[base flant5-large location]", input={"prompt": row['prompt']} ) for s in output: print(s, end="", flush=True) print('') for _, row in df_chekhov_test.iterrows(): output = replicate.run( "[base flant5-large location]", input={"prompt": row['prompt']} ) for s in output: print(s, end="", flush=True) print('')
Sie sollten feststellen, dass das Basismodell den Dramatiker für dieselben Passagen nicht zuverlässig identifizieren kann. Dies zeigt, dass unsere Feinabstimmung dem Modell zuverlässig neue Informationen lieferte und wir uns einen Klassifikator für Dramatiker in natürlicher Sprache erstellt haben!
Im heutigen Artikel haben wir einen einfachen Klassifikator für natürliche Sprache trainiert, der auf Flan-T5 basiert, einem großen Sprachmodell von Google. Aufgrund seiner kompakten Größe und freizügigen Lizenz kann Flan-T5 auf privater Infrastruktur trainiert und eingesetzt werden, was es von vielen anderen beliebten Modellen auf dem Markt, wie z. B. ChatGPT, unterscheidet.
Während das heutige Beispiel auf öffentlichen Daten basierte und eindeutig nichtkommerziell war, kann dieser Machbarkeitsnachweis problemlos auf viele andere kommerzielle Anwendungen übertragen werden, wie oben beschrieben. Wenn Sie eine Idee zu LLMs haben, die Sie gerne in die Realität umgesetzt sehen möchten, können Sie gerne ein Gespräch beginnen, indem Sie meine GitHub- oder LinkedIn- Seite besuchen. Lesen Sie auch gerne meine vorherigen LLM-Artikel, darunter einen über den Aufbau eines Dokumentanalysators mit ChatGPT und den Aufbau eines Domain Expert LLM mit der Fine Tuning API von OpenAI .
Viel Spaß beim Hacken!