Ús de GPU
Introducció
En aquest exemple, explorarem com enviar a Multivac un programa usant la GPU per a fer una xarxa neuronal.
Actualment només la partició de robòtica té gpu i la màquina sputnik. A l’script de configuració s’ha de tenir en compte que hem d’utilitzar tota la màquina i no és multiusuari, ja que no es pot compartir una gpu amb aquestes característiques.
Crearem un arxiu per exemple anomenat test_gpu.py amb finalitats demostratives.
Codi d’exemple
import tensorflow as tf
from tensorflow.keras import layers, models, datasets
# Requereix fer un pip install tensorflow[and-cuda]==2.15.1
# Volem utilitzar GPU?
volem_usar_gpu = True
# Si no volem usar la GPU, activem que faci la xarxa amb CPU
if not volem_usar_gpu:
tf.config.set_visible_devices([], 'GPU')
# Verificar i configurar les GPUS disponibles
gpus = tf.config.list_physical_devices('GPU')
print(gpus)
if gpus:
try:
# Configurem l'ús de memòria incremental
for gpu in gpus:
tf.config.experimental.set_memory_growth(gpu, True)
print("Les GPUS estan configurades per a l'ús de memòria incremental.")
except RuntimeError as e:
print(e)
else:
print("No s'ha detectat cap GPU, s'utilitzarà la CPU.")
# Carregar i preparar el dataset MNIST
(train_images, train_labels), (test_images, test_labels) = datasets.mnist.load_data()
train_images = train_images[..., tf.newaxis] / 255.0 # Afegir un canal per a les imatges en escala de grisos
test_images = test_images[..., tf.newaxis] / 255.0
# Definir l'arquitectura del model
model = models.Sequential([
layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)), # Primera capa convolucional
layers.MaxPooling2D((2, 2)), # Primera capa d'agrupament
layers.Conv2D(64, (3, 3), activation='relu'), # Segona capa convolucional
layers.MaxPooling2D((2, 2)), # Segona capa d'agrupament
layers.Conv2D(64, (3, 3), activation='relu'), # Tercera capa convolucional
layers.Flatten(), # Aplanar les característiques
layers.Dense(64, activation='relu'), # Capa oculta amb 64 neurones i activació ReLU
layers.Dense(10) # Capa de sortida amb 10 neurones (una per a cada classe), sense activació
])
# Compilar el model
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
# Entrenar el model
history = model.fit(train_images, train_labels, epochs=10, validation_data=(test_images, test_labels))
# Avaluar el model
test_loss, test_acc = model.evaluate(test_images, test_labels, verbose=2)
print(f'Precisió en el conjunt de prova: {test_acc}')
Execució
Crearem un virtual environment de python anomenat per exemple venv. Aquest pas només és necessari fer la primera vegada que es vol crear el venv, les altres vegades es pot reusar el mateix.
Es requereix instal·lar el paquet tensorflow: pip install tensorflow[and-cuda]==2.15.1
$ python3 -m venv venv
$ source venv/bin/activate
$ pip install tensorflow[and-cuda]==2.15.1
$ deactivate
Crearem un document amb els parametres de configuració, per exemple: test_gpu.slurm` que conté la configuració d’execució per a aquest script de gpu.
VERSION=1.3
JOB_NAME=test_gpu
NAME_OUTPUT=out
PARTITION=robotica
N_TASKS=1
CPUS_PER_TASK=16
MAIL_TYPE=END,FAIL
MAIL_USER=nom.usuari@upc.edu
MEMORY=15000M
BEGIN=now
TIME_LIMIT=23:59:59 # En aquest exemple tenim un límit de 24h
LOG_OUTPUT=log
FORCED_NODES=sputnik #Molt important forçar aquest node
EXCLUDED_NODES=
ROUTE=~/tests/gpu_example
COMMANDS=(
"hostname" #Per a saber a quina màquina s'ha executat
"source $ROUTE/venv/bin/activate"
"python3 $ROUTE/test_gpu.py"
"deactivate"
)
Aquest script el llançarem des de iocex usant la següent comanda:
multivac test_gpu.slurm
El resultat del nostre programa un cop finalitzada l’execució serà visible al mateix directori a on hem fet l’execució.