Amélioration matérielle
Amélioration des performances via l’utilisation de CUDA
La machine que nous allons utiliser pour effectuer notre test d’utilisation de CUDA est celle sur laquelle nous rédigeons cet ouvrage. Elle possède des caractéristiques qui sembleront dépassées à un joueur passionné actuel et qui sont inférieures à celles des machines que nous utilisons dans nos laboratoires :
-
un processeur Intel i7 8700 (6 cœurs, 12 Mo de cache, 4.6 GHz max) ;
-
une mémoire de 32 Go DDR4-2666 ;
-
une GPU NVIDIA Geforce GTX 1070 (1920 cœurs, 6 Go DDR5, architecture Pascal) ;
-
un refroidissement de la CPU par air, mais de qualité (gros ventirad/radiateur NOCTUA avec deux ventilateurs : niveau "gamer amateur").
Grâce à l’utilisation de CUDA, nous allons pourtant accéder à un certain confort dans le traitement d’un dataset comme NMIST. On aurait d’ailleurs obtenu le même confort avec moitié moins de mémoire et un processeur moins puissant, car c’est la carte graphique qui va faire la plus grande partie du travail.
1. CUDA et TensorFlow 2 avec GPU
Les fonctions CUDA (pour Compute Unified Device Architecture) intègrent la gestion du parallélisme. Leurs threads peuvent se comprendre comme des accesseurs à des tenseurs physiques de dimension 1D, 2D ou 3D dans un mode batch (ce qui rajoute donc une quatrième dimension). Les streaming multiprocessor regroupent les cœurs CUDA (par groupe de 128 dans le cas de l’architecture Pascal, aujourd’hui accessible à tous mais maintenant dépassée, par exemple par l’architecture Turing). Une petite carte comme celle que nous utilisons délivre un nombre de téraflops en simple précision équivalent à la puissance d’un super ordinateur de 2003.
Nvidia décrit l’installation de ses logiciels dans son site developer zone : https://docs.nvidia.com/
Cette documentation Nvidia/CUDA est très complète. Vous avez globalement le choix entre installer votre configuration directement sous Linux, PC ou Mac ou utiliser une image Docker et une CLI (Command Line Interface) spécifique proposée par Nvidia. Mieux vaut avoir compris les principes d’installation de packages Python pour installer Tensorflow-gpu...
Encore un peu de tuning
1. Sauvegarder des modèles intermédiaires
Il vous a sans doute semblé maladroit de relancer les traitements pour sélectionner le bon modèle. Pour stocker les différentes versions des modèles au fur et à mesure, nous allons employer ici une technique très importante de TensorFlow : le callback. Cette technique possède de nombreuses applications, elle vous permet d’effectuer un calcul, de capter une information et/ou de prendre des décisions à chaque epoch.
Vous pourriez automatiser la méthode que nous allons décrire plus bas en utilisant les chekpoints de TensorFlow, mais nous avons préféré vous donner la manière de tout gérer par vous-même pour vous permettre d’étendre le système à votre convenance.
Pour sauver les modèles, nous utilisons le format HDF5 (Hierarchical Data Format). Ce format est accessible dans de nombreux contextes : Java, MATLAB, Scilab, Octave, OCaml, Mathematica, IDL, Python, R, Fortran, Julia, Spark… le package h5py a été installé avec TensorFlow.
Nous définissons une classe qui va abriter les opérations que nous voulons effectuer à chaque epoch. Cette classe hérite d’une classe nommée Callback issue de l’API Keras.
La variable epoch est accessible à tout moment, vous n’avez pas à créer votre propre compteur de cycles. Le calcul intervient en fin d’epoch (on_epoch_end).
Ici, nous allons lancer une évaluation du modèle à chaque epoch (sur le jeu de test, pour ne pas surcharger l’exemple, mais il aurait mieux fallu effectuer cette validation sur un jeu de validation distinct du jeu de test). Nous nommons les modèles en fonction de leur numéro d’epoch et sauvons le modèle complet, réutilisable dans d’autres contextes. Au vu de l’évaluation à chaque epoch on peut donc récupérer le modèle que l’on juge le meilleur.
import os
path = r.mon_path_log # /!\ remplacer par un chemin de votre choix par exemple
'.\logs'
class Print_epoch(tf.keras.callbacks.Callback):
def on_epoch_end(self, epoch, logs=None):
res...
Bibliographie du chapitre
"Version 4.2 NVIDIA CUDA™ NVIDIA CUDA C Programming Guide." 2012. http://developer.nvidia.com/cuda-gpus.