Init
175
Cluster-Getting-Started.md
Normal file
@ -0,0 +1,175 @@
|
||||
# Lithium - ein HPC Cluster für die Fachhochschule Graubünden
|
||||
|
||||
## Hardware
|
||||
|
||||
Für Berechnungen in der Forschung und Lehre kann die Fachhochschule Graubünden seit Herbst 2023 auf einen High Performance Computing (HPC) Cluster zurückgreifen. Dieser wurde aufgebaut um die Lehre und Forschung bei grossen Datenmengen und rechenintensiven Aufgaben zu Untersützen und die Studierenden mit den Prinzipien des verteilten Rechnens bekannt zu machen.
|
||||
|
||||
Der HPC Cluster entspricht in seinem Aufbau einem [Beowulf Cluster][1]. Dieser nutzt spezialisierte Softwarebibliotheken aus dem [OpenHPC][2] Repository für das verteilte Rechnen. Zur Verwaltung des Clusters verwenden wir die Software [Warewulf][1] in einer sogenannten 'stateless' Konfiguration. Dadurch ist sichergestellt, dass die Knoten (einzelne Cluster Computer) softwaremässig identisch installiert und konfiguriert sind, was verhindert, dass es zu Versionsdifferenzen auf den einzelen Knoten kommt.
|
||||
|
||||
Der Cluster basiert auf einer von der Firma Sanitas gespendeten und vom DAViS/CDS auf Open Source Komponenten umgenutzten [Oracle Big Data Applicance X5-2L][4] mit sechs Nodes (Knoten).
|
||||
|
||||
Ein Node besteht aus den folgenden Komponenten
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>2 x CPU</th>
|
||||
<td>Xeon E5-2699 v3 @ 2.30GHz</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>RAM</th>
|
||||
<td>128 GB DDR-4</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Disks</th>
|
||||
<td>12 x 14 TB 7200 RPM SAS</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
und sieht so aus:
|
||||
|
||||

|
||||
|
||||
Der gesamte Cluster mit Netzwerkequipment so:
|
||||
|
||||

|
||||
|
||||
Für die Intranode-Kommunikation beim Rechnen über RDMA (zum Beispiel MPI) kommt ein High Performance Interconnect auf Basis von Infiniband QDR (40 Gbps) zum Einsatz. Für die Verwaltung der Nodes (SSH, TFTP etc.) steht ein dediziertes 10 GB Ethernet Netz zur Verfügung.
|
||||
|
||||
Im Hardwarevergleich steht unser Rechner hier:
|
||||
|
||||
| | Notebook | Lithium | CSCS Alps
|
||||
|----------------------|-----------|-----------|-----------
|
||||
| **Physische Cores** | 4 Cores | 216 Cores | 65536 Cores
|
||||
| **Memory (RAM)** | 16 GB | 768 GB | ?
|
||||
| **Speicherplatz** | 1 TB | 504 TB | 10 PB
|
||||
| **Energieverbrauch** | 60 W | 5-6 KW | 5-10 MW
|
||||
| **Interconnect** | 1 Gb/s | 40 Gb/s | 200 Gb/s
|
||||
|
||||
Das bedeutet, dass wir hardwaremässig sehr viel kleiner sind als Cluster im Bereich der [Top500][10]. Auf der Anwenderseite sind wir jedoch sehr ähnlich ausgerüstet wie die grossen HPC Forschungscluster. Auf Lithium findet man daher unter anderem folgende Komponenten:
|
||||
|
||||
* Slurm für das Job Scheduling
|
||||
* BeeGFS (paralleles Filesystem) auf dem Scratchlaufwerk /scratch
|
||||
* MPICH für das verteilte Rechnen
|
||||
* Warewulf für die Clusteradministration
|
||||
|
||||
Im gesamten sind über 300 HPC spezifische Softwarepakete installiert.
|
||||
|
||||
## Architektur
|
||||
|
||||
Der Fachhochschulcluster besteht aus sechs Knoten (engl. Nodes). Dabei sind die einzelnen Nodes über ein Low Latency, High Bandwith [RDMA Netzwerk][5] miteinander verbunden. Dieses Netzwerk kommt hauptsächlich während einer Berechnung zum Einsatz.
|
||||
|
||||
Einer der sechs Nodes ist als "Master", respektive "Headnode" oder "Loginnode" konfiguriert. Dieser ist während einer Berechnung für Koordinations- und Steueraufgaben zuständig und wird zudem zur Verwaltung des Clusters verwendet. Auf diesem Node wird prinzipiell *nicht* gerechnet.
|
||||
|
||||
Die eigentliche Rechenaufgabe wird für die parallele Abarbeitung auf die Computenodes verteilt. Nach Abschluss der Berechnung werden die Resultate entweder automatisch durch das verwendete Skript oder manuell über das /scratch oder Homelaufwerk zurück an den Masternode geschickt.
|
||||
|
||||
Der Fachhochschule Cluster ist wie folgt aufgebaut:
|
||||
|
||||
<img src="./images/cluster/Clusterarchitektur.png" alt="Cluster Architektur" width="600"/>
|
||||
|
||||
|
||||
## Zugriff auf den Cluster
|
||||
|
||||
Auf den Cluster kann nur mit SSH zugegriffen werden. Momentan können sich alle Mitarbeitenden des SIIs und alle Studierenden des Studiengangs CDS darauf einloggen. Für den Login braucht es einen SSH Client und einen FHGR Account. Der Zugriff mit SSH funktioniert so:
|
||||
|
||||
```
|
||||
ssh <FH Benutzername>@lithium.fhgr.ch
|
||||
```
|
||||
Falls Du den Cluster verwenden möchtest, jedoch nicht zum SII oder CDS Studiengang gehörst, melde dich bitte beim DAViS Admin (thomas.keller@fhgr.ch).
|
||||
|
||||
## Starten der Computenodes
|
||||
|
||||
Um Energie zu sparen, werden unbenutzte Computenodes automatisch heruntergefahren. Um eine Berechnung zu starten, ist es daher notwendig, dass die Computenodes gebootet sind und sich im Slurmstate 'IDLE' befinden. Sollte der Status mit dem Befehl ```sinfo --all``` als 'down' angezeigt werden, dann müssen die Computenodes gestartet werden. Das Starten aller Nodes ist mit dem folgenden Befehl möglich:
|
||||
|
||||
```
|
||||
sudo /usr/local/bin/start-computeNodes.bash
|
||||
```
|
||||
Nach einigen Minuten, sollte der Status des Clusters von 'DOWN' auf 'IDLE' wechseln. Sollte einer der folgenden Status anzeigt werden 'IDLE\*' (mit Stern), 'DRAINED', 'DRAINING', 'FAIL', 'FAILING', 'FUTURE', 'POWER_DOWN', 'UNKNOWN', 'RESERVED' dann informiere bitte, den DAViS Administrator.
|
||||
|
||||
|
||||
## Job Scheduler und Partitionen
|
||||
|
||||
Da ein Cluster auch ein Mehrbenutzersystem ist, können dessen Resourcen 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. Auf lithium.fhgr.ch werden die Jobs durch [Slurm][6] verwaltet.
|
||||
|
||||
Grundsätzlich folgt Slurm auf Lithium 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. Momentan sind die folgenden Partitionen konfiguriert:
|
||||
|
||||
| Anwendergruppe / Partitionen | Debug | Studierende | Mitarbeitende
|
||||
|------------------------------|-------|--------------|---------------
|
||||
| Studierende | 5 Min | 3 h | kein Zugriff
|
||||
| Mitarbeitende | 5 Min | kein Zugriff | 12 h
|
||||
|
||||
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 oder absichtlich 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 Zitverlust bei einem Stromausfall.
|
||||
|
||||
Falls Du deutlich mehr als die oben erwähnten Zeitspannen für eine Berechnung brauchst, melde dich beim DAViS Admin.
|
||||
|
||||
## Clusterfilesystem und Homeverzeichnis
|
||||
|
||||
Auf dem Cluster wird das Homeverzeichnis von jedem Benutzer automatisch mit [NFS][9] auf die Computenodes exportiert. Das heisst, dass auf jedem Node, egal ob Master oder Computenode die Daten des Homeverzeichnisses zur Verfügung stehen. Übrigens: auf deinem Homeverzeichnis steht jedem Anwender 80 GB Speicherplatz zur Verfügung. Wieviel Speicherplatz Du bereits belegt hast, kannst Du mit dem Befehl `quota -fs /` ausfindig machen.
|
||||
|
||||
Des weiteren gibt es unter dem Verzeichnis `/scratch` ein geshartes Filesystem mit einer Grösse von ca. 500 TB. Hier kommt BeeGFS, ein paralleles Filesysteme zum Einsatz das Speicherplatz von allen Computenodes unter dem Mountpoint (Verzeichnis) `/scratch` vereint. Daher kann es nur genutzt werden wenn alle Computenodes gestartet sind. Wie das Homverzeichnis ist auch das /scratch Laufwerk von allen Nodes zugreifbar.
|
||||
|
||||
Bitte beachte, dass Dateien unter dem Verzeichnis `/scratch` von allen Clusterbenutzern gelesen aber nur vom Dateieigentümer verändert werden können.
|
||||
|
||||
## Stromverbrauch und Energiesparmodus
|
||||
|
||||
Mit dem Befehl
|
||||
|
||||
```
|
||||
sudo /usr/local/bin/get-powerUsage.bash
|
||||
```
|
||||
kann der momentane Stromverbrauch des Clusters in Erfahrung gebracht werden. Dabei ist der Stromverbrauch des High Performance Transports (in unserem Falle Infiniband) nicht mit eingerechnet.
|
||||
|
||||
Der Energiesparmodus wird aktiviert, falls der letzte Slurm Job vor mehr als 90 Minuten abgeschlossen wurde oder die Clusternodes erst kürzlich gebootet wurden. Solange Slurmjobs ausgeführt werden, werden die belegeten Clusternodes nicht in einen Energiestparmodus versetzt oder ausgeschaltet.
|
||||
|
||||
## Installation von zusätzlicher Software
|
||||
|
||||
Viele Machinlearning und Deeplearning Frameworks oder Python Module können über Anaconda, Miniconda oder Apptainer installiert werden. Für Anhaltspunkte wie das gemacht werden kann, siehe die Anleitung [Softwareinstalltionen auf den Workstations][8]
|
||||
|
||||
## Erste Schritte auf dem Cluster
|
||||
|
||||
Mit dem Befehl srun kann ein Slurmjob auf dem Cluster ausgeführt werden. Als simples Beispiel dient hier der Befehl 'hostname', der den Namen des lokalen Rechners anzeigt.
|
||||
|
||||
```
|
||||
srun -p students -n $((36*5)) -N5 hostname
|
||||
```
|
||||
Mit der Option `-p` wird die Partition ausgewählt, im obigen Fall die 'students' Partition. Mit der Option `-n` teilen wir Slurm mit, wieviele parallele Tasks (Prozesse) wir ausführen wollen. Da wir pro Computenode 36 physische Cores haben (Hyperthreading ist deaktiviert) können wir auf dem Cluster maximal 180 Prozesse starten. Die Option `-N` teilt Slurm mit wieviele Computenodes für die Berechnung verwendet werden sollen. Im obigen Fall sollten wir daher genau 180 Zeilen Output erhalten.
|
||||
|
||||
Mit dem Befehl ```squeue``` kann angezeigt werden welche Jobs momentan ausgeführt werden und welche Jobs auf Ressourcen warten.
|
||||
|
||||
Für nicht-interaktive und länger laufende Jobs ist es sinnvoll `sbatch` zu verwenden. Damit muss nicht gewartet werden bis der Cluster frei wird, sondern der Jobscheduler informiert den Anwender per Mail sobald das Skript zur Ausführung kommt.
|
||||
|
||||
Dafür 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:
|
||||
|
||||
```
|
||||
#!/bin/bash
|
||||
|
||||
#SBATCH --nodes=5 ## Number of computenodes
|
||||
#SBATCH --output="slurm-%j.out" ## Logfile
|
||||
#SBATCH --time=240:00 ## Time limit. Should be equal or smaller than the partitions time limit
|
||||
#SBATCH --job-name="test-mpi" ## Job name. This will be used in naming directories for the job.
|
||||
#SBATCH --partition=staff ## Partition to launch job in
|
||||
#SBATCH --cpus-per-task=1 ## The number of threads the code will use
|
||||
#SBATCH --ntasks-per-node=1 ## Number of tasks (processes/threads) to run
|
||||
#SBATCH --mail-type=BEGIN,END ## Sends a Email when Job starts and when the Job ends
|
||||
#SBATCH --mail-user=<mail address> ## Mail Address
|
||||
|
||||
|
||||
# Load an environment
|
||||
module load py3-mpi4py
|
||||
|
||||
# Execute the python script and pass the argument '90'
|
||||
srun python3 my-mpiProg.py 90
|
||||
```
|
||||
|
||||
|
||||
|
||||
[1]: https://de.wikipedia.org/wiki/Beowulf_(Cluster) "Beowulf Cluster"
|
||||
[2]: https://openhpc.community/ "OpenHPC"
|
||||
[3]: https://warewulf.org/ "Warewulf"
|
||||
[4]: https://docs.oracle.com/en/servers/x86/x86-server-x5-2l/ "Handbücher"
|
||||
[5]: https://en.wikipedia.org/wiki/Remote_direct_memory_access
|
||||
[6]: https://slurm.schedmd.com/
|
||||
[7]: https://slurm.schedmd.com/sched_config.html
|
||||
[8]: https://gitea.fhgr.ch/kellerthomas/docs-cds/src/branch/master/Installation-Tensorflow.md
|
||||
[9]: https://de.wikipedia.org/wiki/Network_File_System
|
||||
[10]:https://top500.org/
|
||||
[11]:https://www.tensorflow.org/guide/checkpoint
|
||||
248
Cluster-PySpark-Howto.md
Normal file
@ -0,0 +1,248 @@
|
||||
# PySpark auf dem HPC Cluster
|
||||
|
||||
In diesem Beispiel verwenden wir Magpie um einen Sparkcluster innerhalb des Lithium HPC Clusters aufzubauen.
|
||||
|
||||
## Zielpublikum
|
||||
|
||||
Dieses Dokument ist für fortgeschrittene Anwender gedacht. Du solltest daher mit den Grundsätzen unseres HPC Clusters vertraut sein (siehe [Cluster Howto][1]) und Übung im Umgang mit der Linux Konsole und SSH haben.
|
||||
|
||||
Diese Anleitung ist eine ausgedeutsche und auf unsere Umgebung zugeschnittene Version der offiziellen [Magpie Dokumentation][2]
|
||||
|
||||
## Grundsätzliches Vorgehen
|
||||
|
||||
- Installation der Softwarekomponenten für Spark
|
||||
- Konfiguration dieser Softwarekomponenten
|
||||
- Mit Slurm ein Magpie Batchskript aufgeben
|
||||
- Zugriff auf den Cluster mit SSH
|
||||
|
||||
## Installation und Konfiguration von Spark
|
||||
|
||||
Klonen der neusten Magpie Skripte ab Github:
|
||||
|
||||
```
|
||||
mkdir spark && cd spark
|
||||
git clone https://github.com/LLNL/magpie.git
|
||||
cd magpie/misc/
|
||||
vim magpie-download-and-setup.sh
|
||||
```
|
||||
Passe im File `magpie-download-and-setup.sh` die folgenden Parameter an und lösche "#" bei Bedarf vor diesen Einträgen:
|
||||
|
||||
```
|
||||
SPARK_DOWNLOAD="Y"
|
||||
INSTALL_PATH="$HOME/spark"
|
||||
PRESET_LAUNCH_SCRIPT_CONFIGS="Y"
|
||||
LOCAL_DIR_PATH="/tmp/$USER"
|
||||
NETWORKFS_DIR_PATH="/scratch/$USER"
|
||||
```
|
||||
Danach das Skript mit dem Befehl `./magpie-download-and-setup.sh` ausführen. Während des eher gemächlichen Downloads von Spark kann die Zeit genutzt werden, um herauszufinden welche Version von Python und Java die verwendete Spark Version (in unserem Fall 3.3.2) voraussetzt.
|
||||
|
||||
Diese Informationen können wir am Zuverlässigsten von der offiziellen Spark Webseite entnehmen. Im Falle von Spark 3.3.2 ist diese Information unter https://spark.apache.org/docs/3.3.2/ zu finden. Daher können wir folgende Prerequisits notieren:
|
||||
|
||||
* Java 17
|
||||
* Python 3.7 und neuer
|
||||
|
||||
Diese Softwarepakete installieren wir mit Miniconda - Lizenzvereinbarungen akzeptieren und Installationsorte übernehmen:
|
||||
```
|
||||
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
|
||||
bash Miniconda3-latest-Linux-x86_64.sh
|
||||
rm Miniconda3-latest-Linux-x86_64.sh
|
||||
```
|
||||
Nach Abschluss der Installation die Datei `.bashrc` neu laden
|
||||
```
|
||||
. ~/.bashrc
|
||||
```
|
||||
Jetzt können wir eine Conda Environment anlegen und die entsprechenden Versionen von Java und Python installieren. Ìn unserem Beispiel mit **Spark 3.3.2** sieht das so aus:
|
||||
|
||||
```
|
||||
conda create -y -n spark
|
||||
conda activate spark
|
||||
conda install -y python=3.11.4
|
||||
conda install -y -c conda-forge openjdk=17.0.8
|
||||
```
|
||||
Danach mit den Befehlen (innerhalb der conda env)
|
||||
```
|
||||
type -p python
|
||||
dirname $(dirname $(readlink -f $(type -p java)))
|
||||
```
|
||||
die **jeweiligen Speicherorte des Python und Java executable anzeigen lassen und notieren**. Die Pfade sollten die Verzeichniselement miniconda3/envs enthalten. Nachdem das Skript `./magpie-download-and-setup.sh` seine Arbeit abgeschlossen hat, wechseln wir mit folgenden Befehlen zurück ins Verzeichnis `~/spark` und führen "magpie.sbatch-srun-spark" aus:
|
||||
```
|
||||
cd $HOME/spark
|
||||
cp magpie/submission-scripts/script-sbatch-srun/magpie.sbatch-srun-spark .
|
||||
```
|
||||
Im Submission-Skript `magpie.sbatch-srun-spark` passen wir nun die folgenden Zeilen an; je nach benötigten Resourcen, können die Parameter zu den SBATCH Befehlen individuell angepasst werden.
|
||||
|
||||
**Achtung: die Rautenzeichen müssen bestehen bleiben.**
|
||||
```
|
||||
#SBATCH --nodes=5
|
||||
#SBATCH --time=180:00
|
||||
#SBATCH --job-name="spark-test"
|
||||
#SBATCH --partition=staff ODER #SBATCH --partition=students
|
||||
export MAGPIE_JOB_TYPE="interactive"
|
||||
export JAVA_HOME="<gemäss des Outputs mit type -a java, siehe oben>"
|
||||
export MAGPIE_PYTHON="<gemäss des Outputs mit type -a python, siehe oben>"
|
||||
export SPARK_LOCAL_SCRATCH_DIR="/tmp/${USER}/sparkscratch/"
|
||||
|
||||
```
|
||||
|
||||
Als nächstes können wir nun das Magpie Skript als Slurmjob an den HPC Cluster übergeben. Zuerst überprüfen wir nochmals, ob das Cluster Lithium online ist und Ressourcen frei sind:
|
||||
|
||||
```
|
||||
sinfo --all
|
||||
```
|
||||
Falls genügend Nodes (in unserem Beispiel fünf) im Status 'Idle' erscheinen, können wir sofern wir uns noch im Verzeichnis "/home/-user-@edu.local/spark" befinden, den Slurmjob mit dem Befehl
|
||||
|
||||
```
|
||||
sbatch -k magpie.sbatch-srun-spark
|
||||
```
|
||||
dem Slurm Scheduler übergeben. Mit dem Befehl `squeue` können wir den Status unseres Batchjobs in Erfahrung bringen. Idealerweise ist dieser auf 'R' (running) oder 'PD' (pending).
|
||||
|
||||
Ob unser Sparkcluster bereits gestartet ist, erfahren wir im Slurmjob Logfile im Verzeichnis `spark`. Zum Beispiel mit folgendem Befehl mit der Nummer des Bashjobs für *:
|
||||
|
||||
```
|
||||
cat $HOME/spark/slurm-*.out
|
||||
```
|
||||
Im Erfolgsfalle sollten unter anderem die untenstehenden Angaben im Logfile angezeigt werden:
|
||||
|
||||
```
|
||||
.
|
||||
.
|
||||
.
|
||||
* ssh computenode1
|
||||
* export JAVA_HOME="$HOME/miniconda3/envs/spark/bin"
|
||||
* export SPARK_HOME="$HOME/spark/spark-3.4.1-bin-hadoop3"
|
||||
* export SPARK_CONF_DIR="/tmp/$USER/spark/spark-test/*/spark/conf"
|
||||
*
|
||||
* Then you can do as you please. For example to run a job:
|
||||
*
|
||||
* $SPARK_HOME/bin/spark-submit --class <class> <jar>
|
||||
*
|
||||
*******************************************************
|
||||
*******************************************************
|
||||
* Executing Pre Run Scripts
|
||||
*******************************************************
|
||||
*******************************************************
|
||||
* Entering Magpie interactive mode
|
||||
*******************************************************
|
||||
*******************************************************
|
||||
* Run
|
||||
*
|
||||
* ssh computenode1 kill -s 10 6636
|
||||
*
|
||||
* to exit 'interactive' mode early.
|
||||
*******************************************************
|
||||
```
|
||||
|
||||
In diesem Logfile interessiert uns hauptsächlich wie wir nun auf die PySpark Shell zugreifen können. Wie in der `slurm-*. out` Datei erwähnt, können wir uns nun mit den folgenden Befehlen aus dem Logfile einloggen:
|
||||
|
||||
```
|
||||
ssh computenode1
|
||||
export JAVA_HOME="$HOME/miniconda3/envs/spark/bin"
|
||||
export SPARK_HOME="$HOME/spark/spark-3.4.1-bin-hadoop3"
|
||||
export SPARK_CONF_DIR="/tmp/$USER/spark/spark-test/*/spark/conf"
|
||||
conda activate spark
|
||||
```
|
||||
Danach kann ein beliebiger PySpark Befehl ausgeführt werden. Zum Beispiel eine Sparkshell:
|
||||
|
||||
```
|
||||
$SPARK_HOME/bin/pyspark
|
||||
```
|
||||
## Installation von SparkNLP auf PySpark
|
||||
|
||||
Wie auch andere Python-Bibliotheken kann beispielsweise auch die auf Spark-basierende NLP-Library [SparkNLP][3] über die aufgesetzte virtuelle Umgebung "spark" via pip oder conda installiert werden. Für SparkNLP werden als Ergänzung der Miniconda-Basisumgebung noch folgende Bibliotheken benötigt:
|
||||
|
||||
* NumPy
|
||||
|
||||
Nach der Installation von Numpy kann nun auch SparkNLP in der virtuellen Umgebung "spark" mit folgendem Befehl installiert werden:
|
||||
|
||||
```
|
||||
pip install spark-nlp
|
||||
```
|
||||
|
||||
### SparkNLP mit einem vortrainierten Modell
|
||||
|
||||
Starten des Batchjobs:
|
||||
|
||||
```
|
||||
sbatch -k magpie.sbatch-srun-spark
|
||||
```
|
||||
Danach folgt der übliche Ablauf um Pyspark zu starten, jedoch müssen wir gleichzeitig die [jar-packages][3] von SparkNLP beim Aufstarten von Pyspark laden:
|
||||
**Achtung: Die Version des Package muss mit der installierten SparkNLP Version übereinstimmen. (hier SparkNLP 5.1.1)**
|
||||
|
||||
```
|
||||
ssh computenode1
|
||||
export JAVA_HOME="$HOME/miniconda3/envs/spark/bin"
|
||||
export SPARK_HOME="$HOME/spark/spark-3.4.1-bin-hadoop3"
|
||||
export SPARK_CONF_DIR="/tmp/$USER/spark/spark-test/*/spark/conf"
|
||||
conda activate spark
|
||||
|
||||
$SPARK_HOME/bin/pyspark --packages com.johnsnowlabs.nlp:spark-nlp_2.12:5.1.1
|
||||
```
|
||||
|
||||
#### Beispiel
|
||||
|
||||
Nach erfolgreichem Start von SparkNLP und der Sparkshell können wir ein vortrainiertes Modell zu einem Named Entity Recognition-Task mit folgendem [Beispielcode][4] verwenden:
|
||||
```
|
||||
import json
|
||||
import numpy as np
|
||||
|
||||
import sparknlp
|
||||
import pyspark.sql.functions as F
|
||||
|
||||
from pyspark.ml import Pipeline
|
||||
from pyspark.sql import SparkSession
|
||||
from sparknlp.annotator import *
|
||||
from sparknlp.base import *
|
||||
from sparknlp.pretrained import PretrainedPipeline
|
||||
from pyspark.sql.types import StringType, IntegerType
|
||||
|
||||
# If you change the model, re-run all the cells below
|
||||
# Other applicable models: ner_dl, ner_dl_bert
|
||||
MODEL_NAME = "ner_dl_bert"
|
||||
|
||||
text_list = ["""William Henry Gates III (born October 28, 1955) is an American business magnate, software developer, investor, and philanthropist. He is best known as the co-founder of Microsoft Corporation. During his career at Microsoft, Gates held the positions of chairman, chief executive officer (CEO), president and chief software architect, while also being the largest individual shareholder until May 2014. He is one of the best-known entrepreneurs and pioneers of the microcomputer revolution of the 1970s and 1980s. Born and raised in Seattle, Washington, Gates co-founded Microsoft with childhood friend Paul Allen in 1975, in Albuquerque, New Mexico; it went on to become the world's largest personal computer software company. Gates led the company as chairman and CEO until stepping down as CEO in January 2000, but he remained chairman and became chief software architect. During the late 1990s, Gates had been criticized for his business tactics, which have been considered anti-competitive. This opinion has been upheld by numerous court rulings. In June 2006, Gates announced that he would be transitioning to a part-time role at Microsoft and full-time work at the Bill & Melinda Gates Foundation, the private charitable foundation that he and his wife, Melinda Gates, established in 2000.[9] He gradually transferred his duties to Ray Ozzie and Craig Mundie. He stepped down as chairman of Microsoft in February 2014 and assumed a new post as technology adviser to support the newly appointed CEO Satya Nadella.""", """The Mona Lisa is a 16th century oil painting created by Leonardo. It's held at the Louvre in Paris."""]
|
||||
|
||||
|
||||
documentAssembler = DocumentAssembler().setInputCol('text').setOutputCol('document')
|
||||
|
||||
tokenizer = Tokenizer().setInputCols(['document']).setOutputCol('token')
|
||||
|
||||
# ner_dl and onto_100 model are trained with glove_100d, so the embeddings in
|
||||
# the pipeline should match
|
||||
if (MODEL_NAME == "ner_dl") or (MODEL_NAME == "onto_100"):
|
||||
embeddings = WordEmbeddingsModel.pretrained('glove_100d').setInputCols(["document", 'token']).setOutputCol("embeddings")
|
||||
|
||||
# Bert model uses Bert embeddings
|
||||
if MODEL_NAME == "ner_dl_bert":
|
||||
embeddings = BertEmbeddings.pretrained(name='bert_base_cased', lang='en').setInputCols(['document', 'token']).setOutputCol('embeddings')
|
||||
|
||||
ner_model = NerDLModel.pretrained(MODEL_NAME, 'en').setInputCols(['document', 'token', 'embeddings']).setOutputCol('ner')
|
||||
|
||||
ner_converter = NerConverter().setInputCols(['document', 'token', 'ner']).setOutputCol('ner_chunk')
|
||||
|
||||
nlp_pipeline = Pipeline(stages=[documentAssembler, tokenizer, embeddings, ner_model, ner_converter])
|
||||
|
||||
df = spark.createDataFrame(text_list, StringType()).toDF("text")
|
||||
result = nlp_pipeline.fit(df).transform(df)
|
||||
|
||||
```
|
||||
|
||||
Die Resultate des verwendeten Modells sind nun geordnet in einem verschachtelten RDD-Dataframe gespeichert. Die Inhalte dieses Dataframe können wir mit unterschiedlichsten Spark Methoden ausgeben:
|
||||
|
||||
```
|
||||
#Gibt den vollständigen Inhalt als String aus
|
||||
result.collect()
|
||||
|
||||
#Zeigt eine Übersicht zur RDD-Struktur
|
||||
result.show()
|
||||
|
||||
#Zeigt die Token bzw. Wörter zusammen mit den vorausgesagten NER-Labels in einer Tabelle
|
||||
result.select('token.result','ner.result').show(truncate=100)
|
||||
```
|
||||
|
||||
tbc
|
||||
|
||||
|
||||
[1]: https://gitea.fhgr.ch/kellerthomas/docs-cds/src/branch/master/Cluster-Howto.md
|
||||
[2]: https://github.com/LLNL/magpie/blob/master/doc/README.spark
|
||||
[3]: https://sparknlp.org/api/python/getting_started/index.html
|
||||
[4]: https://colab.research.google.com/github/JohnSnowLabs/spark-nlp-workshop/blob/master/tutorials/streamlit_notebooks/NER_EN.ipynb
|
||||
204
Installation-Tensorflow.md
Normal file
@ -0,0 +1,204 @@
|
||||
# Softwareinstalltionen auf den Workstations
|
||||
|
||||
Da es sich bei allen Rechnern um **Mehrbenutzersysteme** handelt, ist der Zugriff mit **su oder sudo auf den Workstations abgeschaltet**. Um zusätzliche Software für Berechnungen wie Tensorflow zu installieren, gibt es folgende zwei Möglichkeiten:
|
||||
|
||||
- Apptainer
|
||||
- Miniconda
|
||||
|
||||
|
||||
*Hinweis: Docker ist auf den HPC Workstations nicht verfügbar. Docker-Container können jedoch mit der Software 'Apptainer' ausgeführt werden*
|
||||
|
||||
## Apptainer
|
||||
|
||||
Apptainer (ehemals Singularity) ist ein *Containersystem* das für den Einsatz auf HPC Systemen optimiert ist. Apptainer unterstützt verschiedene Clustertechnologien wie Infiniband, SLURM oder MPI. Da Apptainer den OCI Standard unterstützt, können neben Apptainerimages auch Images von Dockerhub oder Nvidia (https://catalog.ngc.nvidia.com/containers) unter Apptainer ausgeführt werden.
|
||||
|
||||
Auf unseren Workstations kann damit in einem Container eine Runtime für GPU und CPU Berechnungen mit Tensorflow, Pytorch, etc. ausgeführt werden.
|
||||
|
||||
Neben diesen vorbereiteten Images ist es auch möglich, einen Container von Grund auf neu zu bauen, falls es kein entsprechendes Image mit der benötigten Software gibt. Da dies jedoch ein aufwendigeres Unterfangen ist, wird an dieser Stelle nur auf die Dokumentation verwiesen. Diese ist unter https://apptainer.org/docs/user/main/quick_start.html#building-images-from-scratch zu finden.
|
||||
|
||||
## Miniconda
|
||||
|
||||
Miniconda ist eine virtuelle Environment (offiziell eine Distribution) über die im Homeverzeichnis mit dem Paketmanager `conda` Software für die Programmierung im Data Science Bereich installiert werden kann. Wie Miniconda und Pakete für Tensorflow installiert werden können, ist im Abschnitt *Installation von Software mit Miniconda* und *Installieren von Tensorflow mit Conda* beschrieben
|
||||
|
||||
### Installieren von Tensorflow mit Apptainer
|
||||
|
||||
Damit Tensorflow die GPUs auf den Workstations zur Berechnung nutzt, **müssen verschiedene Komponenten** im Container und auf der Workstation vorhanden sein. Grundsätzlich sind dies:
|
||||
|
||||
| 
|
||||
|:--:
|
||||
| Software Stack für Docker/Apptainer GPU Berechnungen
|
||||
|
||||
Auf den Workstations bereits installiert sind:
|
||||
|
||||
* GPU Treiber (Nvidia Treiber)
|
||||
* CUDA
|
||||
|
||||
Wie aus der Grafik ersichtlich ist, brauchen wir im Container Tensorflow. Dieses könnten wir von Hand in den Container installieren, z.B. in dem Fall, wenn eine spezifizierte Version benötigt wird. Es gibt jedoch eine grosse Pallette an vorgefertigten Images von Dockerhub oder Nvidia. Um uns das Ingeunieursleben etwas zu erleichtern, verwenden wir folgend einen vorgefertigten Container.
|
||||
|
||||
Falls uns jedoch im Container noch ein bestimmtes Softwarepaket fehlt, ist es möglich, mit Hilfe einer Container-Sandbox dieses zu installieren und danach ein modifiziertes und auf unsere Bedürfnisse angepasstes Containerimage zu generieren.
|
||||
|
||||
Auf einer der oben erwähnten Workstations mit SSH einloggen und mit dem folgenden Befehl eine Verzeichnishierarchie für den Buildvorgang erstellen:
|
||||
|
||||
```
|
||||
mkdir -p ~/build-apptainer/sandboxes/ && cd ~/build-apptainer
|
||||
```
|
||||
Container mit bereits installierter Tensorflowsoftware können von Dockerhub oder von der Nvidia-Registry bezogen werden. Dabei wird das Docker Imageformat automatisch ins Apptainerformat (.sif) umgewandelt. Im nachfolgenden Beispiel benutzen wir die Docker-Registry:
|
||||
|
||||
```
|
||||
apptainer pull tensorflow-2.12.0-gpu.sif docker://tensorflow/tensorflow:2.12.0-gpu
|
||||
```
|
||||
|
||||
Der vorherige Befehl speichert das Tensorflowimage im Homeverzeichnis unter build-apptainer ab. Falls Apptainer sich beim Download des Images über mangelnden Speicherplatz beklagt, gibt es unter dem Abschnitt "Troubleshooting" Tipps, wie in einem solchen Fall vorgegangen werden kann.
|
||||
|
||||
Als nächstes bauen wir ein neues Tensorflowimage und installieren als Beispiel das Paket nvidia-profiler in das Image nach. Dazu benutzen wir als Basis das bereits heruntergeladene Tensorflowimage (tensorflow-dockerhub.sif) das wir bereits mit `aptainer pull` in unser Homeverzeichnis gespeichert haben:
|
||||
|
||||
```
|
||||
apptainer build --sandbox sandboxes/tensorflow ./tensorflow-2.12.0-gpu.sif
|
||||
apptainer exec --fakeroot --writable sandboxes/tensorflow/ apt-get update
|
||||
apptainer exec --writable --fakeroot sandboxes/tensorflow/ apt install -y nvidia-profiler
|
||||
```
|
||||
Da auf den Homedirectories eine Diskquota von 80GB aktiviert ist, kann es sein, dass wir dadurch zu wenig Speicherplatz haben um das Image zu bauen. Daher speichern wir das neu erstellte Tensorflowimage unter /scratch:
|
||||
|
||||
```
|
||||
mkdir -p "/scratch/${USER}/"
|
||||
apptainer build "/scratch/${USER}/tensorflow-2.12.0-gpu-modified.sif" sandboxes/tensorflow/
|
||||
```
|
||||
Danach können wir interaktiv im Container arbeiten. Apptainer mountet das Homeverzeichnis automatisch in den Container, daher stehen unsere Skripts die wir für eine Berechnung brauchen automatisch zur Verfügung.
|
||||
|
||||
Mit dem Befehl ```apptainer shell``` können wir ein Apptainerimage öffnen und darin arbeiten.
|
||||
|
||||
```
|
||||
apptainer shell --nv "/scratch/${USER}/tensorflow-2.12.0-gpu-modified.sif"
|
||||
```
|
||||
Jetzt könne wir überprüfen ob die GPUs im Container korrekt erkannt werden:
|
||||
|
||||
```
|
||||
python3 <<- EOF
|
||||
import tensorflow as tf
|
||||
print(tf.config.list_physical_devices('GPU')[0])
|
||||
EOF
|
||||
```
|
||||
Der Output sollte dann, je nach Anzahl GPUs, wie folgt aussehen:
|
||||
|
||||
> PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU')
|
||||
|
||||
|
||||
|
||||
## Installation von Software mit Miniconda
|
||||
|
||||
```
|
||||
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
|
||||
bash Miniconda3-latest-Linux-x86_64.sh
|
||||
rm Miniconda3-latest-Linux-x86_64.sh
|
||||
```
|
||||
Danach die .bashrc nochmals neu laden (dies ist nur einmalig nötig)
|
||||
```
|
||||
. ~/.bashrc
|
||||
```
|
||||
|
||||
Neue virtuelle Umgebung erstellen und aktivieren
|
||||
```
|
||||
conda create --name <ENVNAME>
|
||||
conda activate <ENVNAME>
|
||||
```
|
||||
Die verfügbaren virtuellen Umgebungen können mit `conda env list` angezeigt werden.
|
||||
|
||||
Jetzt kann Software, zum Beispiel Pandas oder Tensorflow, wie folgt installiert werden:
|
||||
|
||||
```
|
||||
conda search <PKGNAME>
|
||||
conda install <PKGNAME>
|
||||
```
|
||||
|
||||
Mit conda installierte Pakete können bei Bedarf mit dem 'update' Befehl aktualisiert werden. Für Python 3 wäre das:
|
||||
|
||||
```conda update python3```
|
||||
|
||||
Update aller Pakete in der momentan aktivierten Conda Environment:
|
||||
|
||||
```conda update --all```
|
||||
|
||||
Update von Conda selbst:
|
||||
|
||||
```conda update -n base -c defaults conda```
|
||||
|
||||
## Installieren von Tensorflow mit Conda
|
||||
|
||||
Als erstes erstellen wir eine Conda Environment die Python 3.9 enthält:
|
||||
|
||||
```
|
||||
conda create --name tf -y python=3.9
|
||||
conda activate tf
|
||||
```
|
||||
|
||||
Damit Tensorflow die GPUs nutzen kann, müssen die Treiber korrekt installiert sein. Dies können wir mit dem Befehl `nvidia-smi` überprüfen:
|
||||
|
||||
| 
|
||||
|:--:
|
||||
| Output im Falle von korrekt erkannter GPU
|
||||
|
||||
Danach installieren wir das Cuda Toolkit und CuDNN:
|
||||
|
||||
```
|
||||
conda install -c conda-forge -y cudatoolkit=11.8.0
|
||||
pip install nvidia-cudnn-cu11==8.6.0.163
|
||||
CUDNN_PATH=$(dirname $(python -c "import nvidia.cudnn;print(nvidia.cudnn.__file__)"))
|
||||
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$CONDA_PREFIX/lib/:$CUDNN_PATH/lib
|
||||
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH#:}
|
||||
```
|
||||
|
||||
Mit den letzten drei Befehlen werden die Variabeln **LD_LIBRARY_PATH** und **CUDNN_PATH** gesetzt. Tensorflow funktioniert nur richtig, wenn diese Variabeln korrekte Pfade enthalen. Deren Output sieht in etwa so aus (kann je nach OS, eingeloggtem Benutzer und Version etwas abweichen):
|
||||
|
||||
`echo $LD_LIBRARY_PATH`
|
||||
|
||||
> /home/$USER@edu.local/miniconda3/envs/tf/lib/:/home/$USER@edu.local/miniconda3/envs/tf/lib/python3.9/site-packages/nvidia/cudnn/lib:/home/$USER@edu.local/miniconda3/envs/tf/lib/:/home/$USER@edu.local/miniconda3/envs/tf/lib/python3.9/site-packages/nvidia/cudnn/lib
|
||||
|
||||
`echo $CUDNN_PATH`
|
||||
|
||||
> /home/$USER@edu.local/miniconda3/envs/tf/lib/python3.9/site-packages/nvidia/cudnn
|
||||
|
||||
Damit wir diese Variabeln nicht in jeder Terminalsession erneut setzen müssen, können diese mit den Befehlen
|
||||
```
|
||||
mkdir -p $CONDA_PREFIX/etc/conda/activate.d
|
||||
echo 'CUDNN_PATH=$(dirname $(python -c "import nvidia.cudnn;print(nvidia.cudnn.__file__)"))' >> $CONDA_PREFIX/etc/conda/activate.d/env_vars.sh
|
||||
echo 'LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$CONDA_PREFIX/lib/:$CUDNN_PATH/lib' >> $CONDA_PREFIX/etc/conda/activate.d/env_vars.sh
|
||||
echo 'export LD_LIBRARY_PATH=${LD_LIBRARY_PATH#:}' >> $CONDA_PREFIX/etc/conda/activate.d/env_vars.sh
|
||||
```
|
||||
permanent in der Conda Environment gespeichert werden.
|
||||
|
||||
Mit pip installieren wir nun Tensorflow:
|
||||
```
|
||||
pip install --upgrade pip
|
||||
pip install tensorflow==2.12.*
|
||||
python3 -c "import tensorflow as tf; print(tf.config.list_physical_devices('GPU'))"
|
||||
```
|
||||
Wenn alles richtig funktioniert, gibt der letzte Befehl Informationen zu den GPUs aus. Dies sieht, abhängig von der verbauten Hardware, etwa so aus:
|
||||
|
||||
| 
|
||||
|:--:
|
||||
| Korrekt erkannte GPUs in Python
|
||||
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
Auf den Workstations ist eine Quota von 80GB pro Person und Homeverzeichnis gesetzt. Beim erstellen von Apptainerimages, ist es möglich, dass diese Quota überschritten wird und es folglich zu Abbrüchen und Fehlermeldungen kommt.
|
||||
|
||||
Mit dem Befehl `quota -s` kann angezeigt werden, wieviel Speicherplatz auf dem Homeverzeichnis übrig ist. Falls die Quota aufgebraucht ist, kann mit dem Befehl
|
||||
|
||||
```
|
||||
apptainer cache clean -D 30
|
||||
```
|
||||
Apptainerimages die älter als 30 Tage sind gelöscht werden.
|
||||
|
||||
Falls immer noch zuwenig Speicherplatz im Homeverzeichnis vorhanden ist, kann mit dem Befehl
|
||||
```
|
||||
du -sh .[^..]* * | sort -h
|
||||
```
|
||||
herausgefunden werden in welchem Unterzeichnis die meisten Daten belegt werden.
|
||||
|
||||
Daten die im Verzeichnis **/scratch** abgelegt werden, unterliegen übrigens keiner Quota.
|
||||
|
||||
|
||||
### Tensorflow Performance analysieren
|
||||
|
||||
https://www.tensorflow.org/guide/gpu_performance_analysis
|
||||
60
Lab-Login-Tutorial.md
Normal file
@ -0,0 +1,60 @@
|
||||
# Anleitung zum Einloggen ins CDS-Lab
|
||||
|
||||
*Diese Anleitung gilt für Windows 11. Anleitungen für Linux und MacOS werden mit der Zeit dazukommen.*
|
||||
|
||||
1. Falls nicht schon auf dem System vorhanden, die Windows PowerShell installieren https://www.microsoft.com/store/productId/9MZ1SNWT0N5D
|
||||
|
||||
2. Sich via PulseSecure mit dem VPN der FHGR verbinden.
|
||||
|
||||
3. PowerShell starten.
|
||||
|
||||
4. Folgenden Befehl eingeben:
|
||||
|
||||
```
|
||||
ssh benutzername@maschine.fhgr.ch
|
||||
```
|
||||
|
||||
**Zuteilung der Maschinen nach Jahrgang der Studierenden**
|
||||
- 2021: mercury
|
||||
- 2022: nickel
|
||||
- 2023: palladium
|
||||
|
||||

|
||||
|
||||
5. Falls der gewählte host, in diesem Beispiel `palladium.fhgr.ch` noch nicht auf der Liste der von eurem Computer bekannten hosts ist, wird er jetzt hinzugefügt. Es erscheint folgende Nachricht, bei der ihr **«yes»** eintippen sollt:
|
||||
|
||||

|
||||
|
||||
6. Danach erscheint folgende "Warnung", dh. ihr habt alles richtig gemacht, und es wird nach eurem Passwort gefragt.
|
||||
|
||||

|
||||
|
||||
7. Gebt nun euer FHGR-Passwort ein.
|
||||
|
||||
8. Falls ihr euch zum ersten Mail ins System einloggt, wird nun euer home directory erstellt:
|
||||
|
||||

|
||||
|
||||
9. Ansonsten erscheint direkt die folgende Meldung:
|
||||
|
||||

|
||||
|
||||
10. Falls das System ein Update benötigt, erscheint folgende (oder ähnliche) Nachricht:
|
||||
|
||||

|
||||
|
||||
Ihr müsst **nichts** unternehmen, da die Updates jeweils zentral von der IT getätigt werden!
|
||||
|
||||
11. Falls kein Update nötig ist, seht ihr direkt folgende boilerplate Nachricht, ansonsten follgt diese nach der obigen Update-Nachricht:
|
||||
|
||||

|
||||
|
||||
12. Darunter steht euer Benutzername, eingeloggt auf der gewählten Maschine. Im Beispiel sieht das so aus:
|
||||
|
||||

|
||||
|
||||
13. Ihr seid nun bereit zur Nutzung des CDS-Labs.
|
||||
|
||||
## Fragen?
|
||||
|
||||
Wendet euch bitte an den Systemadministrator (<thomas.keller@fhgr.ch>)
|
||||
19
README.md
@ -1,3 +1,18 @@
|
||||
# infrastruktur-dok
|
||||
## Hardwareübersicht Studiengang CDS
|
||||
|
||||
Dokumentation der CDS Studiengang IT-Infrastruktur
|
||||
| Typ | Hostname | Berechnungsart | Zugriff | Bemerkung
|
||||
| ------------- |----------------| ----------| ----| ---------
|
||||
| Workstation | mercury.fhgr.ch | GPU bound | ssh mit FHGR Credentials|
|
||||
| Workstation | nickel.fhgr.ch | GPU bound | ssh mit FHGR Credentials|
|
||||
| Workstation | palladium.fhgr.ch| GPU bound | ssh mit FHGR Credentials|
|
||||
| Cluster | lithium.fhgr.ch | CPU bound | ssh mit FHGR Credentials |
|
||||
|
||||
|
||||
|
||||
### Ausgemustert
|
||||
|
||||
| Typ | Hostname | Berechnungsart | Zugriff | Bemerkung
|
||||
| ------------- |----------------| ----------| ----| ---------
|
||||
| Workstation | krypton.fhgr.ch | GPU bound | ssh mit FHGR Credentials | Ausser Betrieb
|
||||
| Workstation | helium.fhgr.ch | GPU bound | ssh mit FHGR Credentials | Ausser Betrieb
|
||||
| Workstation | iridium.fhgr.ch | GPU bound | ssh mit FHGR Credentials | Ausser Betrieb
|
||||
67
Workstations-CDS.md
Normal file
@ -0,0 +1,67 @@
|
||||
# CDS Workstations
|
||||
|
||||
## Übersicht
|
||||
|
||||
Der Studiengang CDS stellt seinen Studierenden folgende IT-Infrastruktur zur Verfügung:
|
||||
|
||||
| Typ | Hostname | Berechnungsart | Zugriff | Bemerkung
|
||||
| ------------- |----------------| ----------| ----| ---------
|
||||
| Workstation | mercury.fhgr.ch | GPU bound | ssh mit FHGR Credentials|
|
||||
| Workstation | nickel.fhgr.ch | GPU bound | ssh mit FHGR Credentials|
|
||||
| Workstation | helium.fhgr.ch | GPU bound | ssh mit FHGR Credentials | Abschaltung per 30.6.23
|
||||
| Workstation | lithium.fhgr.ch | GPU bound | ssh mit FHGR Credentials | Abschaltung per 30.6.23
|
||||
| Workstation | krypton.fhgr.ch | GPU bound | ssh mit FHGR Credentials | Abschaltung per 30.6.23
|
||||
|
||||
## Softwareinstalltionen auf den Workstations
|
||||
|
||||
Da es sich bei allen Rechnern um **Mehrbenutzersysteme** handelt, ist der Zugriff mit **su oder sudo auf den Workstations abgeschaltet**. Zusätzliche Software für Berechnungen, wie Tensorflow, können jedoch im Home des Benutzers installiert werden und zwar mit
|
||||
|
||||
- Miniconda
|
||||
- Apptainer
|
||||
|
||||
*Hinweis: Docker ist auf den HPC Workstations nicht verfügbar. Dockercontainer können jedoch mit Apptainer ausgeführt werden*
|
||||
|
||||
|
||||
## Installation mit Miniconda
|
||||
|
||||
```
|
||||
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
|
||||
bash Miniconda3-latest-Linux-x86_64.sh
|
||||
rm Miniconda3-latest-Linux-x86_64.sh
|
||||
```
|
||||
Neue Virtuelle Umgebung erstellen und aktivieren
|
||||
```
|
||||
coda create --name <ENVNAME>
|
||||
conda activate <ENVNAME>
|
||||
```
|
||||
Virtuelle Umgebungen anzeigen: `conda env list`
|
||||
|
||||
Software suchen und installieren
|
||||
```
|
||||
conda search <PKGNAME>
|
||||
conda install <PKGNAME>
|
||||
```
|
||||
|
||||
Upate von Python:
|
||||
|
||||
```conda update python3```
|
||||
|
||||
Update aller Pakete:
|
||||
|
||||
```conda update --all```
|
||||
|
||||
Update von Conda:
|
||||
|
||||
```conda update -n base -c defaults conda```
|
||||
|
||||
## Apptainer
|
||||
|
||||
Apptainer (ehemals Singularity) ist ein *Containersystem* das für den Einsatz auf HPC Systemen optimiert ist. Apptainer unterstützt verschiedene Clustertechnologien wie Infinband, SLURM und MPI. Da Apptainer den OCI Standard unterstützt, können neben Apptainerimages auch Container von Dockerhub oder Nvidia (https://catalog.ngc.nvidia.com/containers) unter Apptainer ausgeführt werden.
|
||||
|
||||
Auf unsren Workstations kann damit in einem Container eine Runtime für GPU und CPU Berechnungen mit Frameworks wie Tensorflow, Conda etc. ausgeführt werden.
|
||||
|
||||
## GPU Berechnungen mit Apptainer
|
||||
|
||||
Damit Tensorflow die GPUs auf den Workstations zur Berechnung nutzt, müssen verschiedene Komponenten im Container und der Workstation vorhanden sein. Grundsätzlich sind dies:
|
||||
|
||||
|
||||
BIN
images/cluster/Cluster.png
Normal file
|
After Width: | Height: | Size: 344 KiB |
298
images/cluster/Clusterarchitektur.drawio
Normal file
@ -0,0 +1,298 @@
|
||||
<mxfile host="app.diagrams.net" modified="2023-09-05T14:24:09.558Z" agent="Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/117.0" etag="ohOYGRx74R8A3_-iqdB2" version="21.7.2" type="device">
|
||||
<diagram name="Page-1" id="okKH00xu-Q76sZOU3yRa">
|
||||
<mxGraphModel dx="1400" dy="2062" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
<mxCell id="-ApnyZZP5jAH9naTh88D-63" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.875;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0.16;exitY=0.55;exitDx=0;exitDy=0;exitPerimeter=0;curved=1;endArrow=none;endFill=0;strokeWidth=6;fontSize=16;fontStyle=0" edge="1" parent="1" source="-ApnyZZP5jAH9naTh88D-61" target="-ApnyZZP5jAH9naTh88D-22">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="1008" y="-121" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="-ApnyZZP5jAH9naTh88D-73" value="<font style="font-size: 18px;"><b style="font-size: 18px;">SSH</b></font>" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];fontSize=18;labelBackgroundColor=none;" vertex="1" connectable="0" parent="-ApnyZZP5jAH9naTh88D-63">
|
||||
<mxGeometry x="-0.568" y="4" relative="1" as="geometry">
|
||||
<mxPoint x="-1" y="18" as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="-ApnyZZP5jAH9naTh88D-25" value="" style="rounded=1;whiteSpace=wrap;html=1;strokeWidth=9;fillColor=#CCCCCC;fontColor=#333333;strokeColor=#333333;glass=0;shadow=0;gradientColor=#666666;labelPosition=center;verticalLabelPosition=middle;align=center;verticalAlign=middle;fontSize=19;" vertex="1" parent="1">
|
||||
<mxGeometry x="340" y="230" width="1270" height="620" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="DeRy2OjbTxsYnWNSGUsd-11" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=3;endArrow=none;endFill=0;" parent="1" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="537" y="428" />
|
||||
<mxPoint x="537" y="428" />
|
||||
</Array>
|
||||
<mxPoint x="537" y="468" as="sourcePoint" />
|
||||
<mxPoint x="537" y="414.5" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="DeRy2OjbTxsYnWNSGUsd-17" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=10;startArrow=none;startFill=0;endArrow=none;endFill=0;" parent="1" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="537" y="562" />
|
||||
<mxPoint x="537" y="562" />
|
||||
</Array>
|
||||
<mxPoint x="537" y="508" as="sourcePoint" />
|
||||
<mxPoint x="537" y="587" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="DeRy2OjbTxsYnWNSGUsd-12" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=3;endArrow=none;endFill=0;" parent="1" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="757" y="408" />
|
||||
<mxPoint x="757" y="408" />
|
||||
</Array>
|
||||
<mxPoint x="757" y="468" as="sourcePoint" />
|
||||
<mxPoint x="757" y="414.1666666666665" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="DeRy2OjbTxsYnWNSGUsd-18" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=10;endArrow=none;endFill=0;" parent="1" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="757" y="562" />
|
||||
<mxPoint x="757" y="562" />
|
||||
</Array>
|
||||
<mxPoint x="757" y="508" as="sourcePoint" />
|
||||
<mxPoint x="757" y="587" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="DeRy2OjbTxsYnWNSGUsd-13" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=3;endArrow=none;endFill=0;" parent="1" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="978" y="468" as="sourcePoint" />
|
||||
<mxPoint x="979" y="414.5" as="targetPoint" />
|
||||
<Array as="points">
|
||||
<mxPoint x="979" y="468" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="DeRy2OjbTxsYnWNSGUsd-19" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=10;endArrow=none;endFill=0;" parent="1" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="978" y="559" />
|
||||
<mxPoint x="978" y="559" />
|
||||
</Array>
|
||||
<mxPoint x="978" y="505" as="sourcePoint" />
|
||||
<mxPoint x="978" y="586.5" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="DeRy2OjbTxsYnWNSGUsd-15" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=3;endArrow=none;endFill=0;" parent="1" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="1405" y="428" />
|
||||
<mxPoint x="1405" y="428" />
|
||||
</Array>
|
||||
<mxPoint x="1405" y="468" as="sourcePoint" />
|
||||
<mxPoint x="1405" y="414.5" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="DeRy2OjbTxsYnWNSGUsd-21" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=10;endArrow=none;endFill=0;" parent="1" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="1405" y="572" />
|
||||
<mxPoint x="1405" y="572" />
|
||||
</Array>
|
||||
<mxPoint x="1405" y="508" as="sourcePoint" />
|
||||
<mxPoint x="1405" y="587" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="DeRy2OjbTxsYnWNSGUsd-14" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=3;endArrow=none;endFill=0;" parent="1" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="1195" y="418" />
|
||||
<mxPoint x="1195" y="418" />
|
||||
</Array>
|
||||
<mxPoint x="1195" y="468" as="sourcePoint" />
|
||||
<mxPoint x="1195" y="414.83333333333326" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="DeRy2OjbTxsYnWNSGUsd-20" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=10;endArrow=none;endFill=0;" parent="1" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="1195.5" y="574" />
|
||||
<mxPoint x="1195.5" y="574" />
|
||||
</Array>
|
||||
<mxPoint x="1195.5" y="510" as="sourcePoint" />
|
||||
<mxPoint x="1195.5" y="589" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="DeRy2OjbTxsYnWNSGUsd-8" value="<font style="font-size: 18px;"><b><font style="font-size: 18px;">Ethernet</font>&nbsp;&nbsp; </b></font>" style="line;strokeWidth=7;html=1;perimeter=backbonePerimeter;points=[];outlineConnect=0;labelPosition=left;verticalLabelPosition=middle;align=right;verticalAlign=middle;fontSize=24;fillColor=default;labelBackgroundColor=none;fontColor=#1A1A1A;" parent="1" vertex="1">
|
||||
<mxGeometry x="440" y="407" width="1071" height="10" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="DeRy2OjbTxsYnWNSGUsd-16" value="<div style="font-size: 19px;" align="right"><font style="font-size: 19px;"><b style="font-size: 18px;"><font style="font-size: 18px;">Infiniband&nbsp;&nbsp;&nbsp; <br></font></b></font></div>" style="line;strokeWidth=15;html=1;perimeter=backbonePerimeter;points=[];outlineConnect=0;horizontal=1;labelBackgroundColor=none;labelPosition=left;verticalLabelPosition=middle;align=right;verticalAlign=middle;gradientColor=none;gradientDirection=west;fontColor=#1A1A1A;" parent="1" vertex="1">
|
||||
<mxGeometry x="453" y="588" width="1059" height="10" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="-ApnyZZP5jAH9naTh88D-3" value="" style="image;html=1;image=img/lib/clip_art/computers/Server_128x128.png;labelBackgroundColor=none;fontColor=#333333;fontStyle=1;labelPosition=center;verticalLabelPosition=bottom;align=center;verticalAlign=top;fontSize=14;" vertex="1" parent="1">
|
||||
<mxGeometry x="469" y="451" width="128" height="64" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="-ApnyZZP5jAH9naTh88D-4" value="" style="image;html=1;image=img/lib/clip_art/computers/Server_128x128.png;labelBackgroundColor=none;fontColor=#FF0000;fontStyle=1;labelPosition=left;verticalLabelPosition=bottom;align=right;verticalAlign=top;fontSize=18;" vertex="1" parent="1">
|
||||
<mxGeometry x="693" y="451" width="128" height="64" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="-ApnyZZP5jAH9naTh88D-5" value="" style="image;html=1;image=img/lib/clip_art/computers/Server_128x128.png;labelBackgroundColor=none;fontColor=#FF0000;fontStyle=1;labelPosition=center;verticalLabelPosition=bottom;align=center;verticalAlign=top;fontSize=18;" vertex="1" parent="1">
|
||||
<mxGeometry x="912" y="451" width="128" height="64" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="-ApnyZZP5jAH9naTh88D-6" value="" style="image;html=1;image=img/lib/clip_art/computers/Server_128x128.png;labelBackgroundColor=none;fontColor=#FF0000;fontStyle=1;labelPosition=center;verticalLabelPosition=bottom;align=center;verticalAlign=top;fontSize=18;" vertex="1" parent="1">
|
||||
<mxGeometry x="1129" y="451" width="128" height="64" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="-ApnyZZP5jAH9naTh88D-7" value="" style="image;html=1;image=img/lib/clip_art/computers/Server_128x128.png;labelBackgroundColor=none;fontColor=#FF0000;fontStyle=1;labelPosition=center;verticalLabelPosition=bottom;align=center;verticalAlign=top;fontSize=18;" vertex="1" parent="1">
|
||||
<mxGeometry x="1340" y="451" width="128" height="64" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="-ApnyZZP5jAH9naTh88D-97" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=none;endFill=0;strokeWidth=15;" edge="1" parent="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="709" y="788.3333333333335" as="sourcePoint" />
|
||||
<mxPoint x="1229" y="789.3333333333335" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="-ApnyZZP5jAH9naTh88D-102" value="Infiniband" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];labelBackgroundColor=none;fontSize=20;fontColor=#1A1A1A;fontStyle=1" vertex="1" connectable="0" parent="-ApnyZZP5jAH9naTh88D-97">
|
||||
<mxGeometry x="0.1466" y="-2" relative="1" as="geometry">
|
||||
<mxPoint x="-24" y="18" as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="-ApnyZZP5jAH9naTh88D-99" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=none;endFill=0;strokeWidth=15;" edge="1" parent="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="790" y="788" as="sourcePoint" />
|
||||
<mxPoint x="639" y="600" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="-ApnyZZP5jAH9naTh88D-20" value="" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=7;endArrow=none;endFill=0;fontSize=17;fontColor=#1A1A1A;curved=1;" edge="1" parent="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="835.5686725453247" y="-36" as="sourcePoint" />
|
||||
<mxPoint x="979" y="213" as="targetPoint" />
|
||||
<Array as="points">
|
||||
<mxPoint x="979" y="-36" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="-ApnyZZP5jAH9naTh88D-30" value="SSH" style="edgeLabel;html=1;align=center;verticalAlign=top;resizable=0;points=[];fontSize=18;labelPosition=center;verticalLabelPosition=bottom;labelBackgroundColor=none;fontStyle=1" vertex="1" connectable="0" parent="-ApnyZZP5jAH9naTh88D-20">
|
||||
<mxGeometry x="0.36" y="2" relative="1" as="geometry">
|
||||
<mxPoint x="-30" y="53" as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="-ApnyZZP5jAH9naTh88D-8" value="<font color="#333333">Masternode</font>" style="image;html=1;image=img/lib/clip_art/computers/Server_128x128.png;labelBackgroundColor=none;fontColor=#FF0000;fontStyle=1;labelPosition=right;verticalLabelPosition=top;align=left;verticalAlign=bottom;strokeWidth=5;imageBorder=none;fontSize=18;" vertex="1" parent="1">
|
||||
<mxGeometry x="916" y="212" width="128" height="64" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="-ApnyZZP5jAH9naTh88D-29" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=7;endArrow=none;endFill=0;fontSize=15;" edge="1" parent="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="978" y="408.5" as="sourcePoint" />
|
||||
<mxPoint x="978" y="273" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="-ApnyZZP5jAH9naTh88D-15" value="<font color="#003366" style="font-size: 18px;">Ethernet Switch</font>" style="image;html=1;image=img/lib/clip_art/networking/Switch_128x128.png;labelBackgroundColor=none;fontColor=#0000FF;fontSize=18;fontStyle=1;labelPosition=right;verticalLabelPosition=middle;align=left;verticalAlign=middle;imageBorder=none;imageBackground=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="930.5" y="300" width="99" height="90" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="-ApnyZZP5jAH9naTh88D-22" value="<font size="1"><b style="font-size: 26px;">Fachhochschulnetz</b></font>" style="ellipse;shape=cloud;whiteSpace=wrap;html=1;fillColor=#0050ef;strokeColor=#001DBC;strokeWidth=9;fontColor=#ffffff;gradientColor=default;" vertex="1" parent="1">
|
||||
<mxGeometry x="430" y="-270" width="706" height="420" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="-ApnyZZP5jAH9naTh88D-31" value="Clusternetz" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontSize=26;fontColor=#4D4D4D;fontStyle=1" vertex="1" parent="1">
|
||||
<mxGeometry x="430" y="260" width="140" height="70" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="-ApnyZZP5jAH9naTh88D-33" value="" style="image;html=1;image=img/lib/clip_art/computers/Netbook_128x128.png" vertex="1" parent="1">
|
||||
<mxGeometry x="836" y="-30" width="80" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="-ApnyZZP5jAH9naTh88D-34" value="" style="image;html=1;image=img/lib/clip_art/computers/Netbook_128x128.png" vertex="1" parent="1">
|
||||
<mxGeometry x="690" y="-190" width="87" height="110" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="-ApnyZZP5jAH9naTh88D-47" value="<font color="#333333" style="font-size: 15px;">Computenode</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="891" y="514" width="60" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="-ApnyZZP5jAH9naTh88D-48" value="<font color="#333333" style="font-size: 15px;">Computenode</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="452" y="515" width="60" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="-ApnyZZP5jAH9naTh88D-49" value="<font color="#333333" style="font-size: 15px;">Computenode</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="1107" y="514" width="60" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="-ApnyZZP5jAH9naTh88D-50" value="<font color="#333333" style="font-size: 15px;">Computenode</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="673" y="513" width="60" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="-ApnyZZP5jAH9naTh88D-52" value="<font color="#333333" style="font-size: 15px;">Computenode</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="1316" y="514" width="60" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="-ApnyZZP5jAH9naTh88D-61" value="<font size="1"><b style="font-size: 27px;">VPN</b></font>" style="ellipse;shape=cloud;whiteSpace=wrap;html=1;fillColor=#0050ef;strokeColor=#001DBC;strokeWidth=9;fontColor=#ffffff;gradientColor=default;" vertex="1" parent="1">
|
||||
<mxGeometry x="1143" y="-270" width="359" height="270" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="-ApnyZZP5jAH9naTh88D-62" value="" style="image;html=1;image=img/lib/clip_art/computers/Netbook_128x128.png" vertex="1" parent="1">
|
||||
<mxGeometry x="1289" y="-125" width="87" height="110" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="-ApnyZZP5jAH9naTh88D-79" value="BeeGFS" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=none;endFill=0;strokeWidth=7;labelPosition=center;verticalLabelPosition=top;align=center;verticalAlign=bottom;labelBackgroundColor=none;horizontal=0;fontSize=14;fontStyle=1;fontColor=#333333;" edge="1" parent="1">
|
||||
<mxGeometry x="-0.3244" y="-25" relative="1" as="geometry">
|
||||
<mxPoint x="1195" y="674" as="sourcePoint" />
|
||||
<mxPoint x="1195" y="597" as="targetPoint" />
|
||||
<Array as="points">
|
||||
<mxPoint x="1195" y="597" />
|
||||
</Array>
|
||||
<mxPoint y="1" as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="-ApnyZZP5jAH9naTh88D-80" value="JBOD" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.database;whiteSpace=wrap;gradientColor=default;verticalAlign=top;labelPosition=center;verticalLabelPosition=bottom;align=center;fontSize=15;fontStyle=1;fontColor=#333333;strokeColor=#333333;fillColor=#B3B3B3;" vertex="1" parent="1">
|
||||
<mxGeometry x="1167.5" y="675" width="56" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="-ApnyZZP5jAH9naTh88D-81" value="BeeGFS" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=none;endFill=0;strokeWidth=7;labelPosition=center;verticalLabelPosition=top;align=center;verticalAlign=bottom;labelBackgroundColor=none;horizontal=0;fontSize=14;fontStyle=1;fontColor=#333333;" edge="1" parent="1">
|
||||
<mxGeometry x="-0.3244" y="-25" relative="1" as="geometry">
|
||||
<mxPoint x="757" y="674" as="sourcePoint" />
|
||||
<mxPoint x="757" y="597" as="targetPoint" />
|
||||
<Array as="points">
|
||||
<mxPoint x="757" y="597" />
|
||||
</Array>
|
||||
<mxPoint y="1" as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="-ApnyZZP5jAH9naTh88D-82" value="JBOD" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.database;whiteSpace=wrap;gradientColor=default;verticalAlign=top;labelPosition=center;verticalLabelPosition=bottom;align=center;fontSize=15;fontStyle=1;fontColor=#333333;strokeColor=#333333;fillColor=#B3B3B3;" vertex="1" parent="1">
|
||||
<mxGeometry x="729.5" y="675" width="56" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="-ApnyZZP5jAH9naTh88D-83" value="BeeGFS" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=none;endFill=0;strokeWidth=7;labelPosition=center;verticalLabelPosition=top;align=center;verticalAlign=bottom;labelBackgroundColor=none;horizontal=0;fontSize=14;fontStyle=1;fontColor=#333333;" edge="1" parent="1">
|
||||
<mxGeometry x="-0.3244" y="-25" relative="1" as="geometry">
|
||||
<mxPoint x="537" y="674" as="sourcePoint" />
|
||||
<mxPoint x="537" y="597" as="targetPoint" />
|
||||
<Array as="points">
|
||||
<mxPoint x="537" y="597" />
|
||||
</Array>
|
||||
<mxPoint y="1" as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="-ApnyZZP5jAH9naTh88D-84" value="JBOD" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.database;whiteSpace=wrap;gradientColor=default;verticalAlign=top;labelPosition=center;verticalLabelPosition=bottom;align=center;fontSize=15;fontStyle=1;fontColor=#333333;strokeColor=#333333;fillColor=#B3B3B3;" vertex="1" parent="1">
|
||||
<mxGeometry x="509.5" y="675" width="56" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="-ApnyZZP5jAH9naTh88D-86" value="JBOD" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.database;whiteSpace=wrap;gradientColor=default;verticalAlign=top;labelPosition=center;verticalLabelPosition=bottom;align=center;fontSize=15;fontStyle=1;fontColor=#333333;strokeColor=#333333;fillColor=#B3B3B3;" vertex="1" parent="1">
|
||||
<mxGeometry x="1377.5" y="675" width="56" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="-ApnyZZP5jAH9naTh88D-87" value="BeeGFS" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=none;endFill=0;strokeWidth=7;labelPosition=center;verticalLabelPosition=top;align=center;verticalAlign=bottom;labelBackgroundColor=none;horizontal=0;fontSize=14;fontStyle=1;fontColor=#333333;" edge="1" parent="1">
|
||||
<mxGeometry x="-0.3244" y="-25" relative="1" as="geometry">
|
||||
<mxPoint x="1405" y="674" as="sourcePoint" />
|
||||
<mxPoint x="1405" y="597" as="targetPoint" />
|
||||
<Array as="points">
|
||||
<mxPoint x="1405" y="597" />
|
||||
</Array>
|
||||
<mxPoint y="1" as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="-ApnyZZP5jAH9naTh88D-89" value="BeeGFS" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=none;endFill=0;strokeWidth=7;labelPosition=center;verticalLabelPosition=top;align=center;verticalAlign=bottom;labelBackgroundColor=none;horizontal=0;fontSize=14;fontStyle=1;fontColor=#333333;" edge="1" parent="1">
|
||||
<mxGeometry x="-0.3244" y="-25" relative="1" as="geometry">
|
||||
<mxPoint x="978" y="674" as="sourcePoint" />
|
||||
<mxPoint x="978" y="597" as="targetPoint" />
|
||||
<Array as="points">
|
||||
<mxPoint x="978" y="597" />
|
||||
</Array>
|
||||
<mxPoint y="1" as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="-ApnyZZP5jAH9naTh88D-90" value="JBOD" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.database;whiteSpace=wrap;gradientColor=default;verticalAlign=top;labelPosition=center;verticalLabelPosition=bottom;align=center;fontSize=15;fontStyle=1;fontColor=#333333;strokeColor=#333333;fillColor=#B3B3B3;" vertex="1" parent="1">
|
||||
<mxGeometry x="950.5" y="675" width="56" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="-ApnyZZP5jAH9naTh88D-101" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=none;endFill=0;strokeWidth=15;" edge="1" parent="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="1162" y="789.0666666666671" as="sourcePoint" />
|
||||
<mxPoint x="1301.5333333333333" y="598" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="-ApnyZZP5jAH9naTh88D-96" value="Infiniband Switch" style="image;html=1;image=img/lib/clip_art/networking/Switch_128x128.png;labelBackgroundColor=none;fontColor=#003366;fontSize=18;fontStyle=1;aspect=fixed;" vertex="1" parent="1">
|
||||
<mxGeometry x="1229" y="721.34" width="141" height="140" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="-ApnyZZP5jAH9naTh88D-103" value="Infiniband Switch" style="image;html=1;image=img/lib/clip_art/networking/Switch_128x128.png;labelBackgroundColor=none;fontColor=#003366;fontSize=18;fontStyle=1;aspect=fixed;" vertex="1" parent="1">
|
||||
<mxGeometry x="570" y="721.34" width="141" height="140" as="geometry" />
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
BIN
images/cluster/Clusterarchitektur.png
Normal file
|
After Width: | Height: | Size: 102 KiB |
BIN
images/cluster/Clusternode-Front.png
Normal file
|
After Width: | Height: | Size: 70 KiB |
BIN
images/console-nvidia-smi.png
Normal file
|
After Width: | Height: | Size: 89 KiB |
BIN
images/docker-nvidia-gpu-arch.png
Normal file
|
After Width: | Height: | Size: 133 KiB |
BIN
images/lab-login-1.png
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
BIN
images/lab-login-2.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
images/lab-login-3.png
Normal file
|
After Width: | Height: | Size: 8.4 KiB |
BIN
images/lab-login-4.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
images/lab-login-5.png
Normal file
|
After Width: | Height: | Size: 48 KiB |
BIN
images/lab-login-6.png
Normal file
|
After Width: | Height: | Size: 49 KiB |
BIN
images/lab-login-7.png
Normal file
|
After Width: | Height: | Size: 63 KiB |
BIN
images/lab-login-8.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
images/tensorflow-python-test.png
Normal file
|
After Width: | Height: | Size: 24 KiB |