Guide d’utilisation des GPUs

Introduction

Utilisation des GPUs

Cette documentation détaille l’installation des outils NVIDIA pour utiliser les GPUs au sein d’une machine virtuelle déployée sur le service de Cloud Computing de la plateforme SCIGNE. Elle se base sur l’utilisation d’une image Ubuntu 20.04.

Gabarits GPU

Il existe trois gabarits disposants d’un GPU:

  • g1.xlarge-4xmem (73730dea-ca08-47fb-ac0b-2ebd6dbe1465)
  • g2.xlarge-4xmem (242a578e-b314-4f33-83ea-b05f50f08960)
  • g4.xlarge-4xmem (00b54b02-63d0-4d15-927d-6e2f5a4d4920)

Tous les gabarits ont 8 cœurs, 64 Go de RAM et 40 Go de disque, et se différencient par les GPUs proposés :

Nom GPU
g1.xlarge-4xmem NVIDIA Tesla P100
g2.xlarge-4xmem NVIDIA GeForce RTX 2080 Ti
g4.xlarge-4xmem NVIDIA Tesla T4

Pour les besoins importants de disque, il est conseillé de créer un volume avec Cinder et de l’attacher au serveur. Ce point est détaillé dans le guide d’utilisation d’OpenStack.

Installation des outils NVIDIA

Afin d’exploiter efficacement le GPU disponible dans la machine virtuelle, il est nécessaire d’installer le pilote de la carte GPU et les outils CUDA.

Configuration du dépôt NVIDIA

Bien que les pilotes et outils NVIDIA soient disponibles dans les dépôts Ubuntu, nous recommandons d’utiliser le dépôt NVIDIA afin de bénéficier des dernières versions :

$ sudo wget -O /etc/apt/preferences.d/cuda-repository-pin-600 \
  https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/cuda-ubuntu2004.pin
$ sudo apt-key adv --fetch-keys \
  https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/7fa2af80.pub
$ sudo add-apt-repository \
  "deb https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/ /"
$ sudo apt -y upgrade

Il est nécessaire d’installer les logiciels nécessaires à la compilation des drivers et dépendances NVIDIA :

$ sudo apt install -y gcc g++ ubuntu-drivers-common libglfw3-dev libfreeimage-dev

Driver NVIDIA

Dans un premier temps, la liste des pilotes disponibles est affichiée avec :

$ ubuntu-drivers devices
== /sys/devices/pci0000:00/0000:00:05.0 ==
modalias : pci:v000010DEd00001EB8sv000010DEsd000012A2bc03sc02i00
vendor   : NVIDIA Corporation
model    : TU104GL [Tesla T4]
driver   : nvidia-driver-460 - third-party non-free
driver   : nvidia-driver-465 - third-party non-free recommended
driver   : nvidia-driver-450 - third-party non-free
driver   : nvidia-driver-450-server - distro non-free
driver   : nvidia-driver-455 - third-party non-free
driver   : nvidia-driver-460-server - distro non-free
driver   : nvidia-driver-418-server - distro non-free
driver   : xserver-xorg-video-nouveau - distro free builtin

Le pilote recommended est installé avec la commande suivante :

$ sudo apt install -y nvidia-driver-465

Pour prendre en compte les mises à jour et l’installation du nouveau pilote, le serveur est redémarré avec :

$ sudo shutdown -r now

Après le redémarrage du serveur, l’installation du pilote est vérifiée avec :

$ cat /proc/driver/nvidia/version
NVRM version: NVIDIA UNIX x86_64 Kernel Module  465.19.01  Fri Mar 19 07:44:41 UTC 2021
GCC version:  gcc version 9.3.0 (Ubuntu 9.3.0-17ubuntu1~20.04) 

CUDA

L’installation de CUDA est relativement simple :

$ sudo apt install -y cuda

L’installation de CUDA est vérifiée avec :

$ /usr/local/cuda/bin/nvcc -V
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2021 NVIDIA Corporation
Built on Sun_Mar_21_19:15:46_PDT_2021
Cuda compilation tools, release 11.3, V11.3.58
Build cuda_11.3.r11.3/compiler.29745058_0

Vérification

Il est fortement recommandé de vérifier le fonctionnement de CUDA. Pour cela, il faut compiler les exemples de code installés avec CUDA. Ces exemples sont très liés à la version de CUDA installée (v11.3 dans notre exemple) :

$ cd /usr/local/cuda/samples
$ export CUDA_PATH=/usr/local/cuda
$ sudo make

L’exécution des commandes suivantes permet de vérifier le bon fonctionnement du système :

$ ./bin/x86_64/linux/release/deviceQuery
./bin/x86_64/linux/release/deviceQuery Starting...

 CUDA Device Query (Runtime API) version (CUDART static linking)

Detected 1 CUDA Capable device(s)

Device 0: "NVIDIA Tesla T4"
  CUDA Driver Version / Runtime Version          11.3 / 11.3
  CUDA Capability Major/Minor version number:    7.5
  Total amount of global memory:                 15110 MBytes (15843721216 bytes)
  (040) Multiprocessors, (064) CUDA Cores/MP:    2560 CUDA Cores
  GPU Max Clock rate:                            1590 MHz (1.59 GHz)
  Memory Clock rate:                             5001 Mhz
  Memory Bus Width:                              256-bit
  L2 Cache Size:                                 4194304 bytes
  Maximum Texture Dimension Size (x,y,z)         1D=(131072), 2D=(131072, 65536), 3D=(16384, 16384, 16384)
  Maximum Layered 1D Texture Size, (num) layers  1D=(32768), 2048 layers
  Maximum Layered 2D Texture Size, (num) layers  2D=(32768, 32768), 2048 layers
  Total amount of constant memory:               65536 bytes
  Total amount of shared memory per block:       49152 bytes
  Total shared memory per multiprocessor:        65536 bytes
  Total number of registers available per block: 65536
  Warp size:                                     32
  Maximum number of threads per multiprocessor:  1024
  Maximum number of threads per block:           1024
  Max dimension size of a thread block (x,y,z): (1024, 1024, 64)
  Max dimension size of a grid size    (x,y,z): (2147483647, 65535, 65535)
  Maximum memory pitch:                          2147483647 bytes
  Texture alignment:                             512 bytes
  Concurrent copy and kernel execution:          Yes with 3 copy engine(s)
  Run time limit on kernels:                     No
  Integrated GPU sharing Host Memory:            No
  Support host page-locked memory mapping:       Yes
  Alignment requirement for Surfaces:            Yes
  Device has ECC support:                        Enabled
  Device supports Unified Addressing (UVA):      Yes
  Device supports Managed Memory:                Yes
  Device supports Compute Preemption:            Yes
  Supports Cooperative Kernel Launch:            Yes
  Supports MultiDevice Co-op Kernel Launch:      Yes
  Device PCI Domain ID / Bus ID / location ID:   0 / 0 / 5
  Compute Mode:
     < Default (multiple host threads can use ::cudaSetDevice() with device simultaneously) >

deviceQuery, CUDA Driver = CUDART, CUDA Driver Version = 11.3, CUDA Runtime Version = 11.3, NumDevs = 1
Result = PASS
$ ./bin/x86_64/linux/release/bandwidthTest 
[CUDA Bandwidth Test] - Starting...
Running on...

 Device 0: Tesla T4
 Quick Mode

 Host to Device Bandwidth, 1 Device(s)
 PINNED Memory Transfers
   Transfer Size (Bytes) Bandwidth(GB/s)
   32000000          13.0

 Device to Host Bandwidth, 1 Device(s)
 PINNED Memory Transfers
   Transfer Size (Bytes) Bandwidth(GB/s)
   32000000          13.2

 Device to Device Bandwidth, 1 Device(s)
 PINNED Memory Transfers
   Transfer Size (Bytes) Bandwidth(GB/s)
   32000000          239.7

Result = PASS

NOTE: The CUDA Samples are not meant for performance measurements. Results may vary when GPU Boost is enabled.

Dans les deux cas, le résultat (result) doit être PASS.

Intelligence artificielle

Le gabarit intégrant un GPU peut être utilisé avec des outils logiciels tel que TensorFlow ou PyTorch pour accélerer les codes d’apprentissage en intelligence artificielle.

Cette section détaille l’installation de TensorFlow, PyTorch, ainsi que les dépendances nécessaires à une utilisation optimale des gabarits proposant des GPUs NVIDIA.

Outils Python

TensorFlow et PyTorch sont disponibles via des bibliothèques Python. Afin d’utiliser des environnements indépendants, et simplifier l’installation des outils, l’usage d’un outil pour gérer les environnements virtuels, tel que virtualenv ou conda, est recommandé. Dans cette documentation, virtualenv est utilisé car il est bien plus léger que conda. L’outil pip est également installé, puisqu’il permet d’installer les paquets TensorFlow et PyTorch.

$ sudo apt install -y python3-pip python3-testresources python3-virtualenv

cuDNN

Afin de bénéficier des accélérations sur les GPUs pour l’apprentissage automatique, il est nécessaire d’installer la bibliothèque cudaNN. Vous pouvez l’installer avec les commandes suivantes (les trois dernières lignes sont nécessaires pour corriger un bug dans avec TensorFlow) :

$ sudo apt install -y libcudnn8
$ sudo ln -s /usr/local/cuda-11.3/targets/x86_64-linux/lib/libcusolver.so.11 \
/usr/local/cuda-11.3/targets/x86_64-linux/lib/libcusolver.so.10
$ echo 'export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH' >> ~/.bashrc
$ source ~/.bashrc

Tensorflow

L’installation de TensorFlow se déroule assez simplement, en utilisant un environnement virtuel et pip :

$ cd ~
$ virtualenv tf
$ source tf/bin/activate
(tf) $ pip3 install tensorflow

Le résultat est vérifié avec :

(tf) $ python3 -c "from tensorflow.python.client import device_lib; device_lib.list_local_devices()"
2021-05-01 18:47:03.153101: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcudart.so.11.0
2021-05-01 18:47:03.990233: I tensorflow/core/platform/cpu_feature_guard.cc:142] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations:  AVX2 FMA
To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
2021-05-01 18:47:03.990941: I tensorflow/compiler/jit/xla_gpu_device.cc:99] Not creating XLA devices, tf_xla_enable_xla_devices not set
2021-05-01 18:47:03.991548: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcuda.so.1
2021-05-01 18:47:04.012319: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:941] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-05-01 18:47:04.013017: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1720] Found device 0 with properties: 
pciBusID: 0000:00:05.0 name: NVIDIA Tesla T4 computeCapability: 7.5
coreClock: 1.59GHz coreCount: 40 deviceMemorySize: 14.75GiB deviceMemoryBandwidth: 298.08GiB/s
2021-05-01 18:47:04.013045: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcudart.so.11.0
2021-05-01 18:47:04.015191: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcublas.so.11
2021-05-01 18:47:04.015233: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcublasLt.so.11
2021-05-01 18:47:04.015982: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcufft.so.10
2021-05-01 18:47:04.016149: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcurand.so.10
2021-05-01 18:47:04.016580: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcusolver.so.10
2021-05-01 18:47:04.017210: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcusparse.so.11
2021-05-01 18:47:04.017357: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcudnn.so.8
2021-05-01 18:47:04.017441: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:941] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-05-01 18:47:04.018146: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:941] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-05-01 18:47:04.018806: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1862] Adding visible gpu devices: 0
2021-05-01 18:47:04.018839: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcudart.so.11.0
2021-05-01 18:47:04.428115: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1261] Device interconnect StreamExecutor with strength 1 edge matrix:
2021-05-01 18:47:04.428170: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1267]      0 
2021-05-01 18:47:04.428178: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1280] 0:   N 
2021-05-01 18:47:04.428411: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:941] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-05-01 18:47:04.429094: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:941] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-05-01 18:47:04.429802: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:941] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-05-01 18:47:04.430485: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1406] Created TensorFlow device (/device:GPU:0 with 13970 MB memory) -> physical GPU (device: 0, name: NVIDIA Tesla T4, pci bus id: 0000:00:05.0, compute capability: 7.5)

PyTorch

L’installation de PyTorch est réalisée avec la commande ci-dessous. La version des différents outils à installer est obtenue sur le site de PyTorch :

$ virtualenv torch
$ source torch/bin/activate
(torch) $ pip3 install torch==1.8.1+cu111 torchvision==0.9.1+cu111 torchaudio==0.8.1 \
-f https://download.pytorch.org/whl/torch_stable.html

Elle est vérifiée avec :

(torch) $ python3 -c "import torch; print(torch.rand(5, 3))"
tensor([[0.7061, 0.2096, 0.7064],
        [0.6548, 0.5531, 0.8631],
        [0.2996, 0.8940, 0.7171],
        [0.8309, 0.1354, 0.1753],
        [0.1878, 0.3823, 0.6253]])

(torch) $ python3 -c "import torch; print(torch.cuda.is_available())"
True