Update Workstations-Getting-Started.md

This commit is contained in:
Thomas Keller 2024-08-27 18:09:36 +02:00
parent 4e3efc279d
commit 6f9f45a323

View File

@ -26,15 +26,14 @@ Alle Workstations für das Studium sind nach dem folgenden Muster aufgebaut:
|---|---|
|Login auf den Workstation|Für das Login mit SSH verwendest Du deinen FH Graubünden Benutzernamen und Passwort|
|Homeverzeichnis und Quota|Dein Homeverzeichnis ist auf 80 GB Speicherplatz beschränkt. Welche Möglichkeiten Du hast falls dein Homeverzeichnis voll belegt ist, siehst Du hier [Troubleshooting](https://gitea.fhgr.ch/CDS/infrastruktur-dok/src/branch/main/Installation-Tensorflow.md#troubleshooting)|
|Speicherplatz unter ```/scratch```|Für temporäre Dateien die die Quota von 80 GB überschreiten, kann unter /scratch Speicherplatz verwendet werden. In diesem Verzeichnis bitte **keine vertrauliche Daten** ablegen |
|Speicherplatz unter ```/scratch```|Für temporäre Dateien die die Quota von 80 GB überschreiten, kann unter /scratch Speicherplatz verwendet werden. In diesem Verzeichnis bitte **keine vertrauliche Daten** ablegen, da auf /scratch standardmässig jederman Zugriff auf alle Daten hat (gleich wie /tmp) |
|Slurm für den Zugriff auf die GPUs|Die GPUs können nur mit Slurm verwendet werden. Wie das funktioniert steht im Abschnitt [Job Scheduler und Partitionen](#job-scheduler-und-partitionen)|
|Installation zusätzlicher Software|Python Module, Entwicklungs Bibliotheken etc. können über die Software Anaconda/Miniconda oder Pip installiert werden. Wie das am Beispiel von Tensorflow funktioniert ist im Dokument [Installation Tensorflow](https://gitea.fhgr.ch/CDS/infrastruktur-dok/src/branch/main/Installation-Tensorflow.md) beschrieben|
|Verwendung von Containeren|Für die Arbeit mit Containern ist die Software Apptainer installiert. Wie mit Apptainer Software installiert werden kann (auch für Software die Rootrechte benötigt) ist im Dokument [Softwareinstalltionen auf den Workstations](https://gitea.fhgr.ch/CDS/infrastruktur-dok/src/branch/main/Installation-Tensorflow.md) beschrieben oder in der [Apptainer Dokumentation](https://apptainer.org/docs/user/latest/)|
|Installation zusätzlicher Software|Python Module, Entwicklungs Bibliotheken etc. können über die Programme Anaconda/Miniconda oder Pip installiert werden. Wie das am Beispiel von Tensorflow funktioniert ist im Dokument [Installation Tensorflow](https://gitea.fhgr.ch/CDS/infrastruktur-dok/src/branch/main/Installation-Tensorflow.md) beschrieben. Zusätzliche Software kann auch über einen Container installiert werden, siehe gleich im nächsten Punkt.|
|Verwendung von Containeren|Für die Arbeit mit Containern ist die Container Plattform Apptainer installiert. Wie mit Apptainer Software installiert werden kann (auch für Software die Rootrechte benötigt) ist im Dokument [Softwareinstalltionen auf den Workstations](https://gitea.fhgr.ch/CDS/infrastruktur-dok/src/branch/main/Installation-Tensorflow.md) beschrieben oder in der [Apptainer Dokumentation](https://apptainer.org/docs/user/latest/)|
## Job scheduling mit Slurm
## Job Scheduler und Partitionen
Da alle Workstation an der FH Mehrbenutzersysteme sind, können deren Resourcen (wie die GPUs) nicht jederzeit frei verwendete werden. Daher kommt ein Jobscheduler zum Einsatz, der Rechenjobs mit den zur Verfügung stehenden Ressourcen möchglichst optimal zur Ausführung bringt. Daher musst Du bei einer Berechnung mit GPUs zwingend [Slurm](https://slurm.schedmd.com/quickstart.html) verwenden.
Da alle GPU Workstation an der FH Mehrbenutzersysteme sind, können deren Resourcen nicht jederzeit frei verwendete werden. Daher kommt ein Jobscheduler zum Einsatz, der Rechenjobs mit den zur Verfügung stehenden Ressourcen möchglichst effizient zur Ausführung bringt. Daher musst Du bei einer Berechnung mit GPUs zwingend den Job Scheduler [Slurm](https://slurm.schedmd.com/quickstart.html) verwenden.
Grundsätzlich folgt Slurm auf den Workstations dem [FIFO mit Backfill][7] Prinzip. Vereinfacht gesagt bedeutet das, dass der erste eingereichte Job zuerst abgearbeitet wird. Weiter wird die Ressourcennutzung durch sogenannte Partitionen eingeschränkt. Diese bestimmen wie lange ein Benutzer einen Slurm-Job ausführen darf. Die möglichen Partitionen kannst Du dir mit dem Befehl ```sinfo``` anzeigen lassen. Typischerweise gibt es für die Studierenden die foglenden zwei Partition:
@ -42,19 +41,19 @@ Grundsätzlich folgt Slurm auf den Workstations dem [FIFO mit Backfill][7] Prinz
|-------|--------------|----|
| Debug | Zum Testen und Experimentieren| 5 Min|
| Students| Für lange laufende Berechnungen| 7 Tage|
|Staff| Für lange laufende Berechnungen| 14 Tage |
Slurm weiss nicht, wann dein Job sich beendet hat. Da die wenigsten Berechnungen im Studium sieben Tage oder mehr dauern, solltest Du deinen Slurmjob nachdem deine Berechnung abgeschlossen, ist von Hand beenden (Mit `squeue` (Zeigt die Job ID an) und `scancel` beenden). Besser noch, Du gibts beim Starten des Batchjobs die ungefähre Laufzeit deiner Berechnung an. Dies kannst Du mit dem Parameter `--time=` angeben. Zum Beispiel `--time=1:30:00` für einen Slurmjob der maximal 1 Stunde und 30 Minuten laufen soll. Damit Slurm deine Berechnung nicht vorzeitig abbricht, addiere zur Schätzung der Laufzeit deiner Berechnung noch eine zeitliche Sicherheitsmarge dazu.
Slurm weiss nicht, wann dein Job sich beendet (hat). Da die wenigsten Berechnungen im Studium sieben Tage oder mehr dauern, solltest Du deinen Slurmjob nachdem deine Berechnung abgeschlossen, ist von Hand beenden (Mit dem Befehl `squeue`, der dir die Job ID anzeigt und danach mit `scancel <JOB_ID>`, der den Job effektiv beendet). Anstatt für jeden Rechenjob die Maximalzeit zu verwenden, kannst Du beim Starten des Batchjobs die ungefähre Laufzeit mit dem Parameter `--time=` angeben. Zum Beispiel `srun -p students --time=1:30:00 python3 deeplearning.py` für einen Slurmjob der maximal 1 Stunde und 30 Minuten laufen soll. Damit Slurm deine Berechnung nicht vorzeitig abbricht, addiere zur Schätzung der Laufzeit deiner Berechnung noch eine zeitliche Sicherheitsmarge dazu.
Falls deine Berechnung weniger als sieben Tage benögtigt, sind dir deine Mitstudierenden sicherlich dankbar, wenn Du den Slurmjob beendest sobald deine Berechnung abgeschlossen ist. Ansonsten bleibt die GPU für 7 Tage blockiert.
Eine Berechnung die länger als die durch die Partition vorgegebene Zeit läuft wird **abgebrochen**. Diese Limite ist dazu da, damit ein Benutzer nicht irrtümlich den Cluster für eine unbegrenzte Zeit blockieren kann. Daher empfiehlt es sich dringend, im Skript sogenannte 'Checkpoints' zu implementieren. Wie Checkpoints im Falle von Tensorflow oder Keras implementiert werden, findest Du [hier][11]. Checkpoints schützen übrigens auch vor einem Datenverlust der Berechnung bei einem Stromausfall oder Diskausfall.
Eine Berechnung die länger als die durch die Partition vorgegebene Zeit läuft wird **abgebrochen**. Diese Limite ist dazu da, damit ein Job nicht irrtümlich die Workstation für lange Zeit unnötig blockiert. Daher empfiehlt es sich, im Skript sogenannte 'Checkpoints' zu implementieren, die den Zwischenstand einer lange laufenden Berechnung speichern. Wie Checkpoints im Falle von Tensorflow oder Keras implementiert werden, findest Du [hier][11]. Checkpoints sind natürlich auch bei einem Stromausfall oder Diskausfall sehr nützlich.
Falls Du deutlich mehr als die oben erwähnten Zeitspannen für eine Berechnung brauchst oder ein Slurmjob die GPUs für sehr lange Zeit blockiert, melde dich bitte beim [DAViS Admin](mailto:davis-admin@fhgr.ch).
## Slurm Commands
## Einige grundlegende Slurm Commands
Slurm auf den Workstations wird zwingend benötigt, falls deine Berechnung auf der GPU ausgeführt werden soll. Jobs, die nur auf der CPU rechnen, müssen Slurm nicht verwenden. Bei sehr intensiver und lange anhaltender CPU Belegung, empfehlen wir jedoch eine Nutzung von Slurm, damit eine parallel laufende GPU Berechnung nicht gestört wird indem die CPU oder Memory Resourcen komplett belegt werden.
Wie bereits erwähnt, wird Slurm auf den Workstations zwingend benötigt, wenn eine Berechnung auf der GPU ausgeführt werden soll. Jobs, die nur auf der CPU rechnen, müssen Slurm nicht verwenden. Bei sehr intensiver und lange anhaltender CPU oder RAM Belegung empfehlen wir jedoch eine Nutzung von Slurm, damit eine parallel laufende GPU Berechnung nicht gestört wird.
Welche Hardware-Resourcen wir auf dem Rechner zur Verfügung haben, können wir mit dem Befehl
@ -70,17 +69,17 @@ Mit dem Befehl `srun` kann ein Slurmjob auf der Workstation ausgeführt werden.
srun -G a100:1 -p debug -n 64 factor 1234567890123456789012345678901234567890
```
Mit der Option `-p` wird die Partition ausgewählt, im obigen Fall die 'debug' Partition. Mit der Option `-n` teilen wir Slurm mit, wieviele parallele Tasks (Prozesse) wir ausführen wollen. Da wir pro Computenode 64 hyperthreading Cores zur Verfügung haben, können wir den Parameter `-n` auf maximal 64 Tasks setzen. Die Option `-G a100:1` fordert eine Nvidia A100 GPU für die Berechnung an. Sobald die Computerresource frei ist, wird der Befehl `srun` ausgeführt und es werden auf der CPU 64 Prozesse gestartet. Sobald die Berechnung abgeschlossen ist, wird das Ergebnis auf der Kommandozeile ausgegeben.
Mit der Option `-p` wird die Partition ausgewählt, im obigen Fall die 'debug' Partition. Mit der Option `-n` teilen wir Slurm mit, wieviele parallele Tasks (Prozesse) wir ausführen wollen. Da wir pro Computenode 64 hyperthreading Cores zur Verfügung haben, können wir den Parameter `-n` auf maximal 64 Tasks setzen. Die Option `-G a100:1` fordert eine Nvidia A100 GPU für die Berechnung an. Sobald die Computerresource frei ist, wird der Befehl `srun` ausgeführt und es werden auf der CPU 64 Prozesse gestartet. Das Ergebnis wird nach Beendigung der Berechnung auf der Kommandozeile ausgegeben.
Übrigens: im obigen Befehl, ist die Option `-G a100:1` nicht nötig und nur als Beispiel aufgeführt, da der Befehl `factor` die GPU nicht nutzen kann.
Für nicht-interaktive und länger laufende Jobs ist es sinnvoll den Befehl `sbatch` zu verwenden. Damit muss nicht gewartet werden bis die Workstation frei wird, sondern der Jobscheduler übernimmt das Skript und bringt es zur Ausführung sobald die Hardwareresourcen frei sind. An welcher Reihe sich mein Job in der Jobqueue befindet, kann mit dem Befehl
Für nicht-interaktive und länger laufende Jobs ist es sinnvoll den Befehl `sbatch` zu verwenden. Damit muss nicht gewartet werden bis die Workstation frei wird, sondern der Jobscheduler übernimmt das Skript und bringt es zur Ausführung sobald die Hardwareresourcen frei sind. An welcher Reihe sich ein Job in der Jobqueue befindet, kann mit dem Befehl
```squeue -l```
angezeigt werden.
Ein weiterer Vorteil von *sbatch* ist, dass der Job beim Unterbruch der Netzwerkverbindung nicht abgebrochen wird wie zum Beispiel mit *srun*. Wenn Du trotz den Vorteilen von *sbatch* mit *srun* oder andere interaktive Befehlen arbeiten möchtest, dann empfiehlt es sich ![screen](https://wiki.ubuntuusers.de/Screen/) zu nutzen, damit bei einem Netzwerkunterbruch dein Befehl nicht abgebrochen wird.
Ein weiterer Vorteil von *sbatch* ist, dass der Job beim Unterbruch der Netzwerkverbindung nicht abgebrochen wird wie zum Beispiel mit *srun*. Wenn Du trotz den Vorteilen von *sbatch* mit *srun* oder anderen interaktive Befehlen arbeiten möchtest, dann empfiehlt es sich ![screen](https://wiki.ubuntuusers.de/Screen/) zu nutzen, damit bei einem Netzwerkunterbruch dein Befehl nicht abgebrochen wird.
Für *sbatch* muss ein Shellskript geschrieben werden das einerseits einen Abschnitt enthält mit Informationen für Slurm (diese Befehle sind mit `#SBATCH` gekenntzeichnet) andererseits einen Abschnitt der den Befehl zum Starten der Berechnungen enthält. Dies könnte zum Beispiel so aussehen:
@ -95,11 +94,11 @@ Für *sbatch* muss ein Shellskript geschrieben werden das einerseits einen Absch
#SBATCH --cpus-per-task=1 ## Die Anzahl Threads die Slurm starten soll
#SBATCH --ntasks-per-node=64 ## Die Anzahl Prozesse die gestartet werden sollen
# Ausführen des effektiven Befehls in der Shell. Bei einer Berechnung würde hier typischerweise ein Python Skript aufgerufen werden
### Ausführen des effektiven Befehls in der Shell. Bei einer Machine Learning Aufgabe würde hier typischerweise ein Python Skript aufgerufen werden
srun -G a100:1 -p students -n 64 factor 1234567890123456789012345678901234567890
```
Ob das Skript nun aktiv ist (oder einfach nur hängt ohne etwas zu machen) ist nicht immer ganz eindeutig festzustellen. Jedoch sieht man mit dem Befehl ```top``` oder ```sudo nvtop``` ob das gestartete Skript CPU oder GPU Resourcen verwendet. Weiter kann in den Logfiles die im sbatch Skript angegeben wurden nachgeschaut werden ob es Fehler bei der Skriptausführung gegeben hat. Zum Beispiel für den Job 101 mit dem Befehl `cat slurm-101*`.
Ob das Skript nun aktiv ist (oder einfach nur hängt ohne etwas zu machen) ist nicht immer ganz eindeutig festzustellen. Jedoch sieht man mit den Befehlen ```top``` oder ```sudo nvtop``` ob das gestartete Skript CPU oder GPU Resourcen verwendet. Weiter kann in den Logfiles die im sbatch Skript angegeben wurden nachgeschaut werden ob es Fehler bei der Skriptausführung gegeben hat. Zum Beispiel für den Job 101 mit dem Befehl `cat slurm-101*`.
Es ist auch möglich eine interaktive Slurm Session zu nutzen. Dazu kann zum Beispiel der folgende Befehl am Workstation Prompt eingegeben werden:
@ -133,6 +132,7 @@ Daher könnten wir für den obigen Fall den folgenden Slurmjob auf dem Rechner z
salloc -p students --time=00:03:00 -n 32 --mem=515654
```
Leider zeigt `scontrol show node` momentan noch nicht an, ob die GPUs belegt oder frei sind.
@ -143,7 +143,7 @@ Im folgenden Beispiel verwenden wir das MNIST Datenset um ein einfaches Tensorfl
### Login auf einer der Workstations
`ssh <username>@mercury.fhgr.ch`
### Einrichten einer Execution Environment für Tensorflow mit Apptainer
### Einrichten einer Execution Environment für Tensorflow mit einem Apptainer Container
```
mkdir -p ~/build-apptainer/sandboxes/ && cd ~/build-apptainer
apptainer pull tensorflow-2.16.1-gpu.sif docker://tensorflow/tensorflow:2.16.1-gpu
@ -172,13 +172,11 @@ EOF
exit
```
In der letzten Ausgabezeile unseres Skripts sollte im Falle eines Erfolgs nun
In der letzten Ausgabezeile unseres Skripts sollte im Falle eines Erfolgs nun `PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU')`
`PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU')`
stehen. Falls anstatt der obigen Meldung ein Index Error erscheint wie zum Beispiel 'IndexError: list index out of range', hat der Zugriff auf die GPU nicht geklappt.
stehen. Falls anstatt der obigen Meldung ein Index Error erscheint (IndexError: list index out of range), hat der Zugriff auf die GPU nicht geklappt.
Als nächstes berechnen wir ein kleines [Machine Learning Model](https://www.tensorflow.org/tutorials/quickstart/beginner). Dazu kopieren wir den folgenden Code in eine Datei im Homeverzeichnis mit dem Namen *ml.py*:
Als nächstes berechnen wir ein kleines [Machine Learning Modell](https://www.tensorflow.org/tutorials/quickstart/beginner). Dazu kopieren wir den folgenden Code in eine Datei im Homeverzeichnis mit dem Namen *ml.py*:
```
# https://www.tensorflow.org/tutorials/quickstart/beginner