Differenze tra le versioni di "AIE:Guida Utenti"

Da ISTI S2I2S Wiki.
Jump to navigation Jump to search
Riga 117: Riga 117:
 
# Creo uno script bash <code>drun.sh</code> per lanciare comandi dentro dei container nati dalla mia immagine. Questo è il contenuto di <code>drun.sh</code>:<syntaxhighlight lang="bash">
 
# Creo uno script bash <code>drun.sh</code> per lanciare comandi dentro dei container nati dalla mia immagine. Questo è il contenuto di <code>drun.sh</code>:<syntaxhighlight lang="bash">
 
#!/bin/bash
 
#!/bin/bash
TODO
+
 
</syntaxhighlight>
+
docker run \
 +
    --interactive --tty \
 +
    --rm \
 +
    --user $(id -u):$(id -g) \
 +
    --cpus 32 \
 +
    --gpus '"device=0,2"' \
 +
    --volume $PWD:$PWD \
 +
    --workdir $PWD \
 +
    <username>/my-project:latest \
 +
    $@
 +
   
 +
   
 +
</syntaxhighlight>dove:
 +
#* <code>--interactive --tty</code>: opzioni necessarie per processi interattivi (e.g., bash),
 +
#* <code>--rm</code>: rimuove il container alla terminazione del processo (i container saranno effimeri, se ne creerà uno nuovo ad ogni invocazione),
 +
#* <code>--user $(id -u):$(id -g)</code>: esegue il processo con uid:gid dell'utente sull'host,
 +
#* <code>--cpus 32</code>: limita l'utilizzo a 32 CPU,
 +
#* <code>--gpus '"device=0,2"'</code>: rende la prima e la terza GPU visibili al container,
 +
#* <code>--volume $PWD:$PWD</code>: monta la cartella corrente nel container allo stesso path (qualsiasi modifica all'interno di questa cartella è condivisa tra host e container),
 +
#* <code>--workdir $PWD</code>: cambia la cartella di lavoro alla cartella corrente nel container,
 +
#* <code><username>/my-project:latest</code>: utilizza questa immagine come base del container,
 +
#* <code>$@</code>: variabile bash che viene sostituita con tutti gli argomenti passati a questo script.
 
# Preparo del codice da lanciare. Ad esempio, due script python:<syntaxhighlight lang="bash">
 
# Preparo del codice da lanciare. Ad esempio, due script python:<syntaxhighlight lang="bash">
 
# due script di esempio da lanciare
 
# due script di esempio da lanciare
Riga 132: Riga 153:
 
EOF
 
EOF
 
</syntaxhighlight>
 
</syntaxhighlight>
# Lancio dei job nei containers. '''TODO'''
+
# Lancio dei job nei containers.<syntaxhighlight lang="bash">
 +
# mi assicuro che drun.sh sia eseguibile
 +
chmod +x drun.sh
 +
 
 +
# lancio script python
 +
./drun.sh python count_gpus.py
 +
./drun.sh python test.py
 +
 
 +
# lancio una bash nel container
 +
./drun.sh bash
 +
</syntaxhighlight>
 +
# '''NB:''' con questa configurazione, ogni modifica fatta all'infuori della cartella corrente <code>~/raid/my-project</code> non verrà mantenuta alla chiusura del container. Nel caso serva cambiare l'ambiente (installare/rimuovere pacchetti o software, etc.) si suggerisce di cambiare il <code>Dockerfile</code> e rieseguire la creazione dell'immagine (punto 3).  Questo workflow ha il vantaggio di rendere più facilmente riproducibile la creazione dell'ambiente di sviluppo/lancio e robusto a incidenti (se erroneamente viene cancellata l'immagine docker che stavo usando, mi basta ricostruirla con un <code>docker build</code> a partire dal <code>Dockerfile</code>).

Versione delle 22:33, 11 gen 2023

DRAFT: Questa pagina è una bozza.

Guida per gli utenti del Cluster di calcolo e NVIDIA DGX in AI@Edge.

Architettura Cluster

AI@Edge mette a disposizione:


Cluster di Calcolo

E' costituito da:

  • Un nodo frontend;
  • Quattro nodi di calcolo identici;
  • Un nodo di storage.

Il nodo frontend ha le seguenti caratteristiche:

CPU: 1 x AMD EPYC 7352 (24 cores, 48 threads)

System memory: 128GB

Storage: 4HDD in RAID 5

   /           200GB

   /home       500GB (contiene le home degli utenti ed e' esportata via NFS sul frontend e sui nodi di calcolo)

   /opt/share  9.8TB (contiene software condiviso ed e' esportata via NFS sul frontend e sui nodi di calcolo)


Ciascun nodo di calcolo ha le seguenti caratteristiche:

CPU: 2 x AMD EPYC 7413 (48 cores, no HT)

System memory: 512GB

GPU: 1 x NVIDIA A100 GPU

Storage: 440GB


Il nodo di storage dispone di

   2 SSD in RAID1 per il sistema operativo;

   4 SSD in RAID5 5.2TB dedicati al folder /datafast (esportata via NFS sul frontend e sui nodi di calcolo)

   8 HDD in RAID5 63.7TB dedicati al folder /data (esportata via NFS sul frontend e sui nodi di calcolo)


  

TODO: 4 nodi con XX caratteristiche, frontend che con SLURM comanda sotto nodi, lista mountpoints/paths di interesse (dati e software)

NVIDIA DGX A100

TODO caratteristiche DGX, lista mountpoints e path di interesse

Richiesta Creazione Utente sul Cluster

TODO Chi può accedere al momento.

TODO elenco amministratori per laboratiorio. Contattare tizio, caio e fornire le seguenti info...

Accesso e Utilizzo Cluster di calcolo

Una volta ottenuto l'utente

TODO Si accede al frontend

ssh <username>@edge-mst1.isti.cnr.it

E' obbligatorio l'utilizzo di slurm per lanciare jobs sul cluster. La documentazione ufficiale e' disponibile ai seguenti link:
https://slurm.schedmd.com/documentation.html
https://slurm.schedmd.com/tutorials.html


TODO Si richiede risorse con SLURM

srun/sbatch ...


Per un tutorial e alcuni esempi di utilizzo si può vedere la wiki: https://gitlab.com/w895/centro_calcolo_isti/-/wikis/home

Accesso e Utilizzo NVIDIA DGX A100

Si accede alla DGX via ssh con certificato preinstallato (nessuna password viene richiesta):

ssh <username>@edge-nd1.isti.cnr.it

È fortemente consigliato l'utilizzo di Docker (quiun tutorial) per creare l'ambiente con il software necessario e lanciare processi.

Si richiede:

  1. di taggare le proprie immagini docker con nomi nel formato <username>/<nome_immagine> (es: fabiocarrara/my-project:latest). Le immagini che non seguono questo standard possono essere cancellate periodicamente per recuperare spazio.
  2. di NON lanciare e tenere attivi job e/o servizi interattivi (es. jupyter notebooks, server http/flask, etc.). I processi che non seguono questo standard possono essere killati in qualsiasi momento.
  3. di aggiungere ad ogni invocazione di docker run le opzioni --user e --cpus come segue:
    docker run \
        ...
        --user $(id -u):$(id -g) \
        --cpus <X> \  # sostituire <X> con un numero di CPU consono al numero di GPU utilizzate
        ...
    
    L'opzione --user è necessaria per evitare che i processi girino come utente root. I processi che non seguono questo standard e girano come root possono essere killati in qualsiasi momento. L'opzione --cpus è fortemente consigliata per evitare di occupare erroneamente l'interezza delle CPU. Una euristica per specificare <X> è scegliere un valore compreso tra 8*nGPUs e 24*nGPUs dove nGPUs indica il numero di GPU richieste.

Esempio di workflow

  1. Creo una workdir per un nuovo progetto sui dischi non-SSD (dentro ~/raid/):
    mkdir ~/raid/my-project
    cd ~/raid/my-project
    
  2. Creo un file Dockerfile scegliendo un'immagine di partenza (FROM) e installando i miei requisiti software (RUN).
    cat << EOF > Dockerfile
    FROM nvcr.io/nvidia/pytorch:22.09-py3
    RUN pip install transformers
    EOF
    
  3. Costruisco la mia immagine:
    # sostituire <username> con il proprio nome utente
    docker build -t <username>/my-project:latest -f - < Dockerfile
    
  4. Creo uno script bash drun.sh per lanciare comandi dentro dei container nati dalla mia immagine. Questo è il contenuto di drun.sh:
    #!/bin/bash
    
    docker run \
        --interactive --tty \
        --rm \
        --user $(id -u):$(id -g) \
        --cpus 32 \
        --gpus '"device=0,2"' \
        --volume $PWD:$PWD \
        --workdir $PWD \
        <username>/my-project:latest \
        $@
    
    dove:
    • --interactive --tty: opzioni necessarie per processi interattivi (e.g., bash),
    • --rm: rimuove il container alla terminazione del processo (i container saranno effimeri, se ne creerà uno nuovo ad ogni invocazione),
    • --user $(id -u):$(id -g): esegue il processo con uid:gid dell'utente sull'host,
    • --cpus 32: limita l'utilizzo a 32 CPU,
    • --gpus '"device=0,2"': rende la prima e la terza GPU visibili al container,
    • --volume $PWD:$PWD: monta la cartella corrente nel container allo stesso path (qualsiasi modifica all'interno di questa cartella è condivisa tra host e container),
    • --workdir $PWD: cambia la cartella di lavoro alla cartella corrente nel container,
    • <username>/my-project:latest: utilizza questa immagine come base del container,
    • $@: variabile bash che viene sostituita con tutti gli argomenti passati a questo script.
  5. Preparo del codice da lanciare. Ad esempio, due script python:
    # due script di esempio da lanciare
    cat << EOF > count_gpus.py
    import torch
    num_of_gpus = torch.cuda.device_count()
    print(num_of_gpus)
    EOF
    
    cat << EOF > test.py
    import transformers
    print(transformers.__version__)
    EOF
    
  6. Lancio dei job nei containers.
    # mi assicuro che drun.sh sia eseguibile
    chmod +x drun.sh
    
    # lancio script python
    ./drun.sh python count_gpus.py
    ./drun.sh python test.py
    
    # lancio una bash nel container
    ./drun.sh bash
    
  7. NB: con questa configurazione, ogni modifica fatta all'infuori della cartella corrente ~/raid/my-project non verrà mantenuta alla chiusura del container. Nel caso serva cambiare l'ambiente (installare/rimuovere pacchetti o software, etc.) si suggerisce di cambiare il Dockerfile e rieseguire la creazione dell'immagine (punto 3). Questo workflow ha il vantaggio di rendere più facilmente riproducibile la creazione dell'ambiente di sviluppo/lancio e robusto a incidenti (se erroneamente viene cancellata l'immagine docker che stavo usando, mi basta ricostruirla con un docker build a partire dal Dockerfile).