Accélérer le développement Python avec Hydra de Facebook
Facebook Engineering (*) a créé le framework open source Hydra afin d’accélérer le développement d’applications Python complexes et de réduire l’écriture de code de configuration. Nous allons essayer de voir ici ce qu’il en est. Autrement dit, l’hydre vaut- elle le déplacement ?
Un regard neuf sur la configuration de projets de machine learning
Hydra ( https:// hydra. cc/) est un framework Python open- source, sous licence MIT, sorti récemment en version release et développé par Facebook AI Research. Il est censé simplifier le développement d’applications complexes en général et de recherche en Machine Learning en particulier. Ce nouveau framework léger fournit une puissante fonctionnalité de composition et de surcharge de configuration en ligne de commandes et via des fichiers de configuration. Hydra rend plus aisé l’ajout de fonctionnalités à des projets afin de les adapter à de nouveaux cas d’utilisation et besoins sans devoir pour autant réécrire des portions de code significatives. Il réduit significativement l’écriture de certaines formes de code d’expression standard dans les applications complexes, tel que la définition de flags en ligne de commande, la manipulation de fichiers de configuration et la configuration de connexion. Cela concerne des problématiques qui peuvent survenir lors de la modification d’une configuration, comme de devoir maintenir plusieurs copies sensiblement différentes de celle- ci ou d’ajouter une logique personnalisée afin de modifier des valeurs spécifiques. Hydra élimine ces problèmes en permettant la composition et la modification d’une configuration juste avant son exécution. En tant que partie intégrante de l’écosystème Pytorch ( https:// pytorch. org/ ecosystem/), Hydra aide concrètement les chercheurs de Pytorch et les développeurs à gérer plus facilement des projets de ML complexes. Étant néanmoins à visée très générale, il peut être employé dans d’autres domaines. Parmi les autres bénéfices présents ou à venir, le framework doit faciliter l’ajout de fonctionnalités aux projets pour créer de nouveaux cas d’usage, toujours sans devoir réécrire d’importantes portions de code. Le framework présente une architecture permettant de plugger par la suite d’autres fonctionnalités, que celles- ci soient fournies en interne chez Facebook ou qu’elles viennent de la communauté. De prochains plug- ins sont prévus pour permettre le lancement de codes depuis Amazon Web Services ou depuis d’autres Clouds, toujours à partir de la ligne de commande.
Les fonctionnalités du framework incluent :
• la complétion dynamique des instructions de la ligne de commande qui aide l’apprentissage et l’accessibilité des configurations complexes et réduit les fautes de frappe ;
• l’aptitude à charger des applications localement ou à distance, permettant ainsi aux utilisateurs de profiter de plus de ressources que celles qui ne sont disponibles qu’en local ;
• la possibilité d’exécuter plusieurs jobs ( processus en tâches de fond) avec arguments différents et une unique commande, éliminant ainsi le besoin d’écrire des scripts trop spécifiques.
Toutes ces fonctionnalités sont fort pratiques pour le développement d’applications complexes. Hydra accélère la création de telles applications tout en réduisant le nombre de bugs rencontrés et permet ainsi au code d’évoluer de façon plus naturelle, s’accordant ainsi aux exigences modernes du développement logiciel.
Un petit pas vers l’open Source
Hydra est couramment utilisé chez Facebook dans le prototypage de projets de recherche complexes. Facebook a placé le projet Hydra dans l’open Source en espérant que l’industrie du logiciel y ait recours pour accélérer le développement de code de recherche et d’applications complexes faciles à adapter aux nouvelles exigences et à améliorer de manière générale l’efficacité des chercheurs et des développeurs, et ce, plus particulièrement dans le domaine du machine learning. Hydra est d’ores et déjà disponible à l’utilisation de tout un chacun et son architecture à base de plugins est totalement adaptée au support futur de fonctionnalités additionnelles, que ce soit via du développement en interne ( par Facebook) ou des efforts réalisés par la communauté. En bref, Facebook, comme Google et consorts, a enfin compris l’intérêt de l’open Source et le profit qu’ils peuvent en retirer en y plaçant le projet Hydra, et c’est tant mieux pour tout le monde.
Une architecture souple et modulable
Hydra fournit une architecture à base de plug- ins favorisant l’ajout d’extensions futures, comme par exemple la possibilité d’exécuter votre code dans le Cloud de manière fluide, sans problème supplémentaire. L’un des principaux mécanismes employé pour réduire le code d’expression standard consiste à établir une norme quant à la manière de spécifier vos configurations d’applications. Ceci est particulièrement vrai pour les configurations composées de sources multiples qui constituent une hiérarchie et qui
peuvent être modifiés depuis la ligne de commande. Si, par exemple, vous avez un fichier de configuration config. yaml contenant un certain nombre d’options de configuration pour vos programmes, vous pouvez l’utiliser sans problème à travers Hydra :
hydra. main( config _ path=' config. yaml') def my _ app( cfg):
# utilisation d'options de configuration ( cfg) ...
Si pour une exécution spécifique vous souhaitez modifier une valeur de configuration, vous pouvez envoyer la nouvelle valeur à employer via la ligne de commande :
$ python my _ app. py db. user= root db. pass= 1234
Hydra simplifie également la gestion de groupes alternatifs d’options de configuration. Vous pouvez, par exemple, avoir deux fichiers de configuration, un pour connecter une base de données MYSQL et un autre pour une base de données Postgresql. À chaque exécution de votre programme, vous pourrez choisir quel fichier de configuration utiliser en le spécifiant en ligne de commande, comme ceci :
$ python my _ app. py db= postgresql $ python my _ app. py db= mysql db. timeout= 20
Les fichiers de configuration sont stockés dans un répertoire unique et organisés hiérarchiquement via le système de fichiers. Hydra duplique la hiérarchie du filesystem à travers la map du cfg qui est passée à votre application. Cela permet d’organiser vos options de configuration dans des espaces indépendants et de les composer en fonction de vos besoins. Par exemple, en plus des fichiers de configuration Postgresql et MYSQL, vous pouvez avoir des fichiers de configuration décrivant plusieurs schémas de base de données avec lesquels vous voulez travailler, puis décider au moment du chargement quelle combinaison de base de données et de schéma vous allez employer pour cette exécution spécifique :
$ python my _ app. py db= postgresql schema= school
$ python my _ app. py db= mysql schema= home
De façon pratique, Hydra utilise la complétion via la touche tabulation dans le shell afin de vous guider à travers les configurations et les sous- configurations que vous pouvez utiliser en ligne de commande, ce qui fait que vous n’êtes pas obligé de vous rappeler de toutes les combinaisons autorisées. En bonus supplémentaire, Hydra va créer un répertoire de sortie pour chaque exécution de votre programme et y copier la configuration active pour cette exécution en plus de tout fichier de sortie. C’est idéal lorsque vous voulez exécuter de multiples tests et conserver la trace des résultats afin de pouvoir les comparer à la fin. Enfin, Hydra inclue des simplifications pour la connexion afin de réduire le coût d’installation qui sont pleinement intégrées à la gestion de configuration.
import logging
# A logger for this file log = logging. getlogger( _ _ name _ _ ) @ hydra. main() def my _ app( _ cfg): log. info(" Info level message") log. debug(" Debug level message")
En effet, vous pouvez définir quel niveau de log de connexion afficher et passer de l’un à l’autre au niveau du fichier, soit via la ligne de commande, soit via les fichiers de configuration.
$ python my _ app. py hydra. verbose=[ _ _ main _ _ , hydra]
Comme mentionné plus haut, Facebook prévoit de développer les fonctionnalités d’hydra en tirant parti de son architecture sous forme de plug- ins. Hydra vous permet d’organiser la configuration passée à votre application de manière très simple. Voici un exemple de config pour un jeu de données ( dataset) dans le fichier config. yaml :
dataset: name: imagenet path: / datasets/ imagenet
Et voici une application Hydra simple dans un fichier my_ app. py qui charge cette configuration :
import hydra from omegaconf import Dictconfig @ hydra. main( config _ path=" config. yaml") def my _ app( cfg: Dictconfig) -> None:
print( cfg. pretty()) if _ _ name _ _ == " _ _ main _ _ ":
my _ app()
La ligne la plus intéressante ici est celle contenant le « décorateur » @ hydra. main(). Il prend comme paramètre config_ path, mentionnant le fichier config. yaml ci- dessus. Le programme affiche cfg. pretty(), l’objet de configuration qu’il récupère. Sans surprise, l’objet de configuration contient la configuration du jeu de données Imagenet. Voilà la sortie attendue de l’exécution du programme my_ app. py :
$ python my _ app. py dataset: name: imagenet path: / datasets/ imagenet
Nous pouvons maintenant modifier ce que l’on veut dans le fichier de configuration depuis la ligne de commande. Voici la sortie consécutive à la modification du dataset. path :
$ python my _ app. py dataset. path=/ datasets/ imagenet20k dataset: name: imagenet path: / datasets/ imagenet20k
Exemple d’organisation
À un moment donné, vous pouvez vouloir alterner entre deux jeux de données différents, chacun avec sa propre configuration. Vous pouvez aussi ajouter une section defaults dans votre fichier de configuration config. yaml, indiquant ainsi à Hydra comment organiser la configuration. Dans ce cas, nous voulons juste charger la configuration pour le dataset par défaut cifar10. Le fichier config. yaml devient alors : defaults:
- dataset: cifar10
L’application est pratiquement la même, la seule différence étant que le paramètre config path pointe maintenant sur le fichier conf/ config. yaml. En exécutant l’application, nous obtenons le chargement de la configuration cifar10 attendue :
$ python my_ app. py dataset:
name: imagenet path: / datasets/ cifar10
Mais nous pouvons aussi choisir d’employer imagenet :
$ python my _ app. py dataset= imagenet dataset: name: imagenet path: / datasets/ imagenet
Le fichier config. yaml peut être mis à jour afin de charger adam en tant qu’optimiseur par défaut, ainsi :
defaults:
- dataset: cifar10 - optimizer : adam
En exécutant l’application, nous obtenons une configuration unique contenant la réunion de cifar10 et d’adam :
$ python my _ app. py dataset: name: cifar10 path: / datasets/ cifar10 optimizer : beta : 0.01 lr : 0.1 type : adam
Hydra est encore tout récent et fait seulement ses premières armes. Avec l’aide de la communauté open source, peut- être que d’ici quelque temps il supportera le chargement d’applications AWS et GCP en leur permettant de profiter des mêmes fonctionnalités que pour Facebook AI. Ou peut- être, comme tant de projets, son existence ne durera- t- elle que le temps d’un rayon de soleil… Tout dépend s’il créé ou non un engouement dans la communauté open source. Seul l’avenir nous le dira. Si vous voulez l’essayer avec votre code Python, le framework Hydra est téléchargeable sur Github à cette adresse :
( https:// github. com/ facebookresearch/ hydra). ✖