Inferenz von Textgenerierungsmodellen
Auf JupyterHub
Im ersten Teil unseres Tutorials über LLMs werden wir lernen, wie man ein Texterzeugungsmodell von Huggingface auf JupyterHub verwendet. Wenn du einen lokalen Rechner mit installiertem CUDA hast, sollten alle Schritte gleich sein, aber es kann schwierig sein, die richtige Umgebung zu installieren.
Starte also ein Jupyter-Notebook und wähle den Standard-Kernel. Stelle sicher, dass du beim Start von JupyterHub eine GPU ausgewählt hast. Wenn du transformers installieren musst, verwende pip in deiner Standard-Python-Umgebung:
pip install transformers
Torch sollte vorinstalliert sein (JupyterHub) oder in Ihrer Modulkette (PALMA). Auf einem lokalen Rechner kann es schwierig sein, CUDA und dann Torch in der richtigen Umgebung zu installieren.
Hier können wir sehen, ob CUDA verfügbar ist und auf wie viel VRAM wir zugreifen können. Dieses Notizbuch ist für die Verwendung von nur einer GPU geschrieben, normalerweise cuda:0
, sollte aber auch mit cpu
laufen.
Das Huggingface-Caching-Mysterium
Huggingface bietet eine sehr einfache Schnittstelle für Modelle. Das Paket transformers lädt sie automatisch herunter, aber man weiß nicht, wo diese Modelle auf der Festplatte liegen und sie können riesig sein! Wir sollten also vorsichtig sein, wenn wir die Modelle laden.
Wir haben verschiedene Optionen, wo wir unsere Modelle laden können:
- Der Standard-Cache von Huggingface ist ein versteckter Ordner
~/.cache/huggingface/models
. Da die Modelle aber sehr groß sind, kann dies leicht die Partitionen sprengen! - Wenn du PALMA verwendest (oder einen PALMA-User hast), kannst du
/scratch/tmp/$USER/huggingface/models/
verwenden und es später entfernen - Ansonsten können wir für kleine Modelle (!) einfach ein nicht verstecktes Cache-Verzeichnis (z.B.
~/huggingface/models
) verwenden und später wieder entfernen. Wenn ihr hier Fehler bekommt, kann das an den Berechtigungen liegen. Verwenden Sie dann den Standard-Cache von Huggingface. - Für größere Modelle kannst du auch einen OpenStack Usershare /cloud/wwu1/{group}/{share}/cache verwenden (aber PALMA scratch könnte schneller sein)
- Oder wir lassen es einfach so, wie es ist, aber sind uns dessen bewusst!
Merke dir jetzt, wo du dein Modell gespeichert hast, denn du wirst das Cache-Verzeichnis später noch brauchen. Wir werden weiterhin das Modell in und aus cache_dir = "/cloud/wwu1/d_reachiat/incubai/cache"
laden. Unten siehst du, wie du das kleinste Pythia-Modell herunterladen und starten kannst. Pythia ist eine Sammlung von Open Source LLMs für die Texterzeugung, ähnlich wie GPT (Closed Source) oder Llama (eingeschränkte Lizenz).
Nun können wir mit dem Prompting fortfahren. Das bedeutet, wir geben dem Modell einen Satz, auf dessen Grundlage es neuen Text generiert, der logisch an den gegebenen Eingangssatz anschließen sollte.
Wie du sehen wirst, ist der von unserem kleinen Pythia-Modell generierte Text repetitiv und nicht sehr gut. Eine Änderung einiger Parameter kann helfen, aber die hier für Testzwecke verwendeten kleinen Modelle sind nicht geeignet, um gute Parameter zu finden.
Um mehr über Textgenerationsstrategien zu erfahren, kannst du die Huggingface-Seite über Textgenerationsstrategien besuchen.
Nun kannst du auf die folgende Weise einen Prompt verwenden:
Um diesen Prozess zu vereinfachen, können wir eine Pipeline bauen. Das erste Argument der Pipeline ist die Aufgabe, für die wir die Pipeline verwenden wollen, in unserem Fall Textgenerierung. Die anderen Eingaben sind das zuvor definierte Modell und der Tokenizer, sowie die Argumente der model.generate
Funktion von oben und unser spezifiziertes device.
Wenn du einige Prompts in einer Textdatei hast, kannst du diese Textdatei laden und eine Pipeline zur Verarbeitung verwenden. Es ist effizienter, die Pipeline über die Daten iterieren zu lassen, als eine Schleife über die Pipeline zu verwenden.
Nun waren wir hoffentlich in der Lage:
- ein Textgenerationsmodell herunterzuladen
- das Modell aus einem selbstdefinierten Cache zu laden
- mehrere Prompts zu verwenden, um das Modell zu testen
Benutze ein Python-Skript
Um größere Modelle auf PALMA zu implementieren, müssen wir alles in ein Python-Skript umwandeln. Die Skripte finden Sie unter 2_2_LLMs/text-generation/scripts/
. Du kannst nun testen, ob das Skript auch läuft, indem du den folgenden Befehl in das Terminal eingibst:
python pythia.py --cache_dir /cloud/wwu1/d_reachiat/incubai/cache --size 70m --prompt "My sample prompt"
Du könntest auch mit mehreren prompts experimentieren, wie denen in ~/2_2_LLMs/text-generation/data/prompts.txt
und einer Ausgabedatei mit
python pythia.py --cache_dir /cloud/wwu1/d_reachiat/incubai/cache --size 70m --prompt_file ../data/prompts.txt --out_file out.csv
wo du eine schöne csv deiner prompts und des vom Modell generierten generierten Text bekommen kannst.
Wenn du das Skript ausführst, bekommst du Informationen über den GPU-Speicher (VRAM) Verbrauch des Modells. Du musst einen CUDA-Overhead von etwa 1 GB hinzufügen, um den erwarteten Speicherverbrauch zu finden. Daher ist das 6.9b-Modell von Pythia zu groß für JupyterHub. Während du die Pipeline ausführst, kannst du ein Terminal öffnen und nvidia-smi
eingeben, um den Speicherverbrauch zu finden.
Wechsel auf PALMA
Falls alles gut gegangen ist, möchten wir zu PALMA wechseln. Wir wollen dort die GPU-Partitionen nutzen, um größere Modelle zu betreiben, als wir es im JupyterHub können. Anfangs eignet sich die gpuexpress Partition gut zum Testen.
Wenn du noch nie mit PALMA gearbeitet hast, kannst du unser Tutorial in 2_1_PALMA lesen. Auch das HPC Wiki gibt einen guten Überblick darüber, wie man PALMA benutzt.
Installation der Anforderungen
Jetzt wollen wir die Shell-Skripte im Ordner 2_2_LLMs/text-generation/jobs
verwenden, um Text aus unseren Modellen zu generieren.
Wir verwenden eine spezielle “Toolchain”, um CUDA nutzen zu können. Die folgende Toolchain ist geeignet:
Du kannst diese Toolchain finden, indem du module spider PyTorch
tippst. Da der Login-Knoten jedoch eine andere Architektur hat, musst du ein Jobskript erstellen, um den richtigen Namen und die CUDA-Version auf der anderen Architektur zu finden.
Wenn du diese Befehle in der Kommandozeile eingibst, siehst du, dass das letzte Modul nicht auf dem Login-Knoten verfügbar ist. Deshalb müssen wir, um weitere Pakete zu installieren, in dieser Toolchain sein. Um sicherzustellen, dass die richtigen Python- und PyTorch-Versionen verwendet werden, installieren wir das Paket transformers über pip mit einem Job-Skript namens install.sh. Da wir Torch 1.10 verwenden (eine ziemlich alte Version) müssen wir darauf achten, eine geeignete Version von transformers zu verwenden, zum Beispiel transformers==4.33.1
.
Anschließend können wir das Installationsskript auf der richtigen Architektur mit dem Befehl sbatch install.sh
im Verzeichnis /2_2_LLMs/text-generation/jobs/
ausführen. Wenn der Job abgeschlossen ist, überprüfe die Ausgabedatei mit vi, um sicherzustellen, dass keine neue Torch-Version installiert wurde (was viele Konflikte verursachen könnte).
Falls etwas schiefgelaufen ist, entferne die installierten Pakete in deinem Home-Verzeichnis (da sie durch die Flag --user
in ~/.local/
installiert wurden, kannst du die Ordner dort entfernen).
Das Modell vorbereiten und ausführen
Jetzt sollte hoffentlich alles gut gegangen sein. Überprüfe nun das Skript pythia-70m-test.sh
. Wenn du dein Modell in deinem usershare hast, solltest du es im Skript als Modellverzeichnis verwenden. Wenn du keinen usershare hast, kannst du das gesamte Modellverzeichnis in dein Scratch-Verzeichnis kopieren. Zum Beispiel auf PALMA (!) verwende
cp -r ~/cloud/wwu1/u_jupyterhub/home/<first letter of username>/<username>/.cache/huggingface/models/models--EleutherAI--pythia-70m-deduped $WORK/2_2_LLMs/text-generation/models/
wenn du den Standard Huggingface Cache benutzt hast (siehe Huggingface Cache oben). Es gibt keine schöne Möglichkeit, die Huggingface Modelle direkt herunterzuladen, also falls nötig, starte ein Skript (siehe oben), das die Modelle in das Scratch-Verzeichnis herunterlädt, aber nicht startet (oder aufgrund von Limits abstürzt).
Jetzt sollten die Daten in deinem Scratch-Verzeichnis sein. Wir sollten bereit sein, das erste kleine Modell zu starten. Gehe zurück zu ~/incubaitor/2_2_LLMs/text-generation/jobs/
und starte den Job mit dem Befehl sbatch pythia-70m-test.sh
.
In der Ausgabedatei kannst du lesen, ob alles gut gelaufen ist, zum Beispiel über vi slurm-pythia-test-1b-express.out
. Außerdem sollte die Ausgabedatei auf deiner Scratch-Partition sein. Du solltest die Inhalte der Ausgabedatei lesen können mit vi /scratch/tmp/<username>/pythia-70m-express.csv
oder auf diese Datei zugreifen können, indem du sie zu $WORK/transfer
kopierst, wenn du die PALMA Nextcloud Integration vorbereitet hast und sie über die Web-Schnittstelle herunterlädst (noch in Entwicklung).
Für weitere Informationen über den Datentransfer besuche die HPC Dokumentation.
Wenn du mit den Ergebnissen zufrieden bist, teste, ob du auch die 1b
Version auf die gleiche Weise zum Laufen bekommen kannst.
Passe das Skript an deine Bedürfnisse an
Wenn du etwas im Skript ändern möchtest oder andere Funktionen des Modells testen möchtest, kannst du auch mit den kleinen Modellen im JupyterHub spielen. Falls Ressourcen verfügbar sind, kannst du auch das jupyter.sh
Skript auf PALMA starten und auf deinem eigenen Rechner herumspielen.
Wenn du bereit bist, kannst du diese Änderungen in der Datei pythia.py
vornehmen (der beste Weg wäre, sie in dein privates Git zu kopieren, Änderungen vorzunehmen, die Änderungen zu PALMA zu ziehen und das Skript zu Testzwecken auf einem kleinen Modell auszuführen).
Dann, wenn Ressourcen verfügbar sind, kannst du versuchen, Inferenzen auf einem größeren Modell auf Palma durchzuführen. Siehe die Jobscripts für das 6.9b und 12b Modell.
Llama-2 und andere Modelle
Der Llama Text-Generator wird von Meta bereitgestellt. Um die Huggingface-Version herunterzuladen, musst du dich bei Meta für die Verwendung der Llama-2 Modelle registrieren und einen Zugangskey von Huggingface haben. Nachdem du dieses Modell zum Beispiel auf JupyterHub heruntergeladen und in deiner Benutzerfreigabe oder Scratch-Verzeichnis gecacht hast, kannst du darauf auf PALMA zugreifen. Das kleinste Modell könnte zu groß für JupyterHub sein und deinen Kernel abstürzen lassen, aber es könnte eine bequeme Möglichkeit sein, es herunterzuladen.
Wenn du das hast, sieh dir das llama.py
Skript und das entsprechende Jobskript an. Die einzige Änderung in der Python-Datei ist die Modellauswahl. So kannst du dein Skript für jedes Huggingface text-generation
Modell, das du verwenden möchtest, ändern.
Jenseits der Textgenerierung
Es gibt viele andere Arten von Modellen auf Huggingface. Sie alle arbeiten mit ähnlichen Pipelines. Du kannst auf der Modellkarte (oben rechts </> Use in transformers
) nachsehen, wie die Modelle geladen und eine Pipeline aufgebaut werden kann. Für die Pipeline solltest du aufgrund der Caching-Probleme einen ähnlichen Ansatz wie oben verwenden. (Denke daran, beim downloaden local_files_only=False
zu setzen!)
Dann musst du überprüfen, wie die Pipeline mit Inputs versorgt wird und wie die Outputs aussehen. Dies sollte ebenfalls auf der Modellkarte bereitgestellt werden. Beispielsweise kann das Folgende für Textklassifikation verwendet werden. Stelle sicher, dass das Caching korrekt durchgeführt wird.
Du kannst auch mehrere Fragen (bei mehreren Texten) verwenden, indem du über die pipeline iterierst.
Jetzt kannst du Huggingface-Modelle verwenden! Weitere Modelle zur Audio- oder Bilderkennung benötigen zusätzliche Pakete wie OpenCV, die ebenfalls in der Toolchain von PALMA vorhanden sein können.