Auteurs:
(1) Iason Ofeidis, Département de génie électrique et Yale Institute for Network Science, Yale University, New Haven {Contribution égale} ;
(2) Diego Kiedanski, Département de génie électrique et Yale Institute for Network Science, Yale University, New Haven {Contribution égale} ;
(3) Leandros TassiulasLevon Ghukasyan, Activeloop, Mountain View, Californie, États-Unis, Département de génie électrique et Yale Institute for Network Science, Yale University, New Haven.
Plusieurs bibliothèques et ensembles de données ont été sélectionnés pour comparer leurs fonctionnalités et leurs performances. Même si un effort a été fait pour être le plus compréhensible possible, le domaine du chargement de données est en constante évolution et de nouvelles bibliothèques et versions sont ajoutées chaque jour. À cet égard, nous nous attendons à ce que la liste suivante fournisse un bon aperçu des capacités actuelles des chargeurs de données, sans nécessairement revendiquer ou trouver le meilleur (qui changerait probablement entre le moment de la rédaction et le moment de la publication). Nous mettons tout le code source des expériences à la disposition du public et attendons que les résultats soient entièrement reproductibles.
Nous avons sélectionné sept bibliothèques pour réaliser nos expérimentations : PyTorch (Paszke et al., 2019), Torchdata (TorchData, 2021), Hub (Team, 2022a), FFCV (Leclerc et al., 2022), Webdatasets (Webdataset, 2013), Écureuil (Team, 2022b) et Deep Lake (Hambadzumyan et al., 2022). Une chose intéressante que nous avons découverte est que toutes les bibliothèques ne prennent pas en charge les mêmes fonctionnalités. Par exemple, nous ne pouvions pas exécuter FFCV avec un ensemble de données hébergé dans un bucket S3 pour réaliser nos expériences à distance. Comme nous l'avons mentionné dans la section 1, nous exécutons toutes nos expériences dans PyTorch. Nous avons envisagé de reproduire les expériences dans d'autres frameworks d'apprentissage automatique populaires, mais nous avons renoncé à cette idée puisque le deuxième candidat aurait été Tensorflow, mais des rumeurs courent selon lesquelles Google s'en éloignerait au profit de JAX. La figure 1 illustre la popularité des différents frameworks ML au cours des 12 derniers mois.
Concernant les ensembles de données, nous avons initialement opté pour deux ensembles de données classiques pour prendre en charge deux tâches d'apprentissage différentes : CIFAR-10 (Krizhevsky et al., 2009) pour la classification d'images, et CoCo (Lin et al., 2014) pour la détection d'objets. Lors de certaines expériences, nous avons observé un comportement étrange (les bibliothèques fonctionnent mieux que prévu) qui pourrait s'expliquer par
CIFAR-10 s'insère dans la mémoire[2]. Pour cette raison, nous avons construit un troisième ensemble de données nommé RANDOM, composé d'images couleur générées aléatoirement d'une taille de 256 x 256 pixels et d'une classe aléatoire sur 20. Ce troisième ensemble de données contient 45 000 images pour la formation, 5 000 pour la validation et 500 pour les tests. et il est considérablement plus grand que le CIFAR-10.
Nous avons utilisé les mêmes transformations pour toutes les bibliothèques afin de rendre les benchmarks comparables. La seule exception était FFCV, qui a sa propre implémentation des différentes transformations. Pour la classification des images, la pile de transformation était composée des éléments suivants : retournement horizontal aléatoire, normalisation, découpe, transformation en tenseur.
Pour la détection d'objets, nous nous sommes principalement appuyés sur la mise en œuvre des transformations par Albumentations (Buslaev et al., 2020). La pile ressemblait à ceci : recadrage de taille aléatoire, retournement horizontal aléatoire, normalisation, transformation en tenseur. Ces transformations s'appliquent à la fois aux images et aux cadres de délimitation.
Lorsque cela était possible, nous avons hébergé l'ensemble de données localement et dans un compartiment équivalent à S3. Cela nous a permis d'évaluer le ralentissement résultant de l'entraînement d'un flux de données sur le réseau. Nous fournirons une description détaillée du cadre de formation dans la section 4.
Étant donné que les tâches de formation les plus intensives impliquent l’utilisation de plusieurs GPU, nous avons également mené, dans la mesure du possible, les mêmes expériences dans un environnement comportant plusieurs unités GPU. Étant donné qu'au moment de l'exécution des expériences, toutes les bibliothèques n'avaient pas la prise en charge complète de PyTorch Lightning, nous avons décidé d'implémenter le multi-GPU à l'aide de la bibliothèque Distributed Data Parallel (DDP) (Li et al., 2020) de PyTorch.
Pour certains projets d’apprentissage automatique, nous pourrions avoir besoin d’accéder uniquement à un sous-ensemble d’un ensemble de données plus vaste. Dans ces cas-là, avoir la possibilité de filtrer rapidement les points de données requis sans avoir à parcourir l’ensemble des données peut réduire considérablement le temps total de formation. Certaines bibliothèques permettent un filtrage basé sur certaines fonctionnalités, comme la classe (pour les tâches de classification d'images). Nous avons exploré le gain (ou la perte) de vitesse lié à l'utilisation de la méthode de filtrage fournie par la bibliothèque (au cas où elle en proposerait une) par rapport à l'absence de filtrage du tout. Chaque fois que la bibliothèque ne proposait pas de méthode de filtrage, nous les implémentions naïvement, c'est-à-dire en analysant l'ensemble des données et en ne conservant que les éléments qui correspondent à la condition spécifiée. Le filtrage rapide n'est pas nécessairement trivial à mettre en œuvre car il nécessite le maintien d'une structure supplémentaire de type index pour éviter d'itérer sur tous les échantillons.
Enfin, le tableau 1 précise la compatibilité des différentes bibliothèques avec les différentes expériences et ensembles de données que nous avons explorés dans cet article.
Notre principale priorité lors de la construction des expériences était de trouver une métrique objective qui nous permettrait de comparer toutes les différentes bibliothèques d'une manière solide.
La mesure idéale aurait été la durée totale du travail de formation, car c'est ce pour quoi nous devons attendre et payer. Malheureusement, cela aurait considérablement limité le nombre d’expériences que nous pourrions mener. Après mûre réflexion, nous avons opté pour le nombre de points de données traités (images) par seconde, un résultat étayé par nos expériences numériques. Nous considérons deux variantes de cette métrique : une dans laquelle nous utilisons le modèle ML pour nous entraîner et nous effectuons une rétropropagation et une dans laquelle nous n'utilisons pas le modèle ML et parcourons uniquement les échantillons, en les copiant sur le GPU. La différence entre les deux métriques peut être appréciée à partir du pseudo-code de la boucle d'entraînement dans l'algorithme 1, où m désigne la variable de vitesse. Nous avons également collecté la durée totale d'exécution[3] et le temps nécessaire à l'initialisation des chargeurs de données. Cette dernière était motivée par le fait que certaines bibliothèques pouvaient effectuer des calculs coûteux en amont pour augmenter leur vitesse pendant la formation. Nous avons également fini par effectuer un échauffement pour calculer la vitesse. Ce point est abordé plus en détail à la sous-section 3.5.
Pour améliorer notre compréhension des mécanismes internes de chaque bibliothèque, nous avons décidé d'inspecter, en une seule exécution, le temps nécessaire à l'exécution de chaque lot ainsi qu'à l'initialisation du chargeur de données. La figure 3 représente pour une seule combinaison de paramètres [4], le temps pris par chaque bibliothèque dans les étapes décrites par l'algorithme 1. Toutes ces expériences impliquaient un seuil après 10 lots.
Il est intéressant de noter que le premier lot prend beaucoup plus de temps que les autres. Cela peut s'expliquer comme suit : étant donné que la plupart des chargeurs de données s'appuient sur un chargement paresseux des données à ce stade, les futurs appels bénéficieront de la prélecture, des données déjà en mémoire et de la parallélisation (faire des choses pendant que le GPU est occupé à effectuer des calculs).
La taille des bandes 1 à 9 fournit la meilleure indication de l'évolution de chaque bibliothèque depuis le temps nécessaire à une
un grand ensemble de données croît linéairement avec cette largeur. On peut observer que la plupart des bibliothèques ont une largeur uniforme, Deep Lake étant la plus courte (la plus rapide). En revanche, la seule bibliothèque qui montre des largeurs non homogènes est FFCV, où les bandes 1 à 3 sont si fines qu'elles ne sont pas visibles sur l'image.
La période de clôture prend à peu près le même temps pour toutes les bibliothèques, à l'exception de FFCV et Deep Lake, qui prennent considérablement plus de temps. Le temps passé à conclure dépend principalement du modèle et n'est pas nécessairement indicateur de l'évolution de chaque bibliothèque.
Sur la base de ce chiffre, nous avons décidé d'effectuer un échauffement lors du calcul de la vitesse. Cela se traduit par l'ignorance du temps pris par le premier lot dans tous les calculs de vitesse.
Cet article est disponible sur arxiv sous licence CC 4.0.
[2] C'est souvent quelque chose de souhaitable et d'attendu dans certaines publications de revues, mais nous avons constaté que ce n'était pas le cas dans plusieurs applications pratiques impliquant de petites équipes et des postes de travail internes.
[3] Il s'agit du temps écoulé entre le début de la simulation et le cutoff, qui en pratique n'était souvent que de 10 lots.
[4] Ensemble de données ALÉATOIRE, GPU unique, 0 nœud de calcul, taille de lot 64