Nous avons eu l’occasion de présenter le résultat de nos recherches lors de la 34e Conférence internationale IEEE/ACM sur le génie logiciel automatisé (ASE’19).
Présentation (PDF)
En tant que leader mondial dans la production de jeux vidéo, nous savons à quel point la production de jeux AAA nécessite des efforts et du temps. Cela nécessite souvent des centaines de développeurs, de testeurs, d’artistes, d’ingénieurs du son qui, collectivement, produisent des dizaines de milliers de dispersées dans des centaines de milliers de fichiers.
Une vidéo présentant le type de jeux produits par Ubisoft (Diapositive 2)
Nos processus pour créer ces jeux sont en constante évolution pour répondre aux attentes changeantes de nos millions de joueurs. Par exemple, le paradigme GaaS (Game as a Service) exige l’ajout constant de nouveaux contenus de haute qualité qui ne peuvent pas perturber le code ou créer de nouveaux bogues.
Pour améliorer notre processus de création, nous utilisons des techniques connues dans le monde du logiciel-service (SaaS), des points de repère de la littérature scientifique sur le génie logiciel et nos propres recherches (MSR’18, ). Nous collaborons aussi activement avec plusieurs universités canadiennes (Concordia Montréal, Polytechnique Montréal, ÉTS, McGill, UQAC) et la fondation Mozilla, afin d’automatiser davantage nos processus.
Les bogues et les régressions ralentissent la production de nouveaux contenus et doivent donc être éliminés le plus rapidement possible. Au cours du processus de développement d’un logiciel, du code est ajoué et modifié, des bogues sont trouvés et corrigés. Pour corriger un bogue, nous devons généralement modifier le code existant. Une façon de représenter un code qui va au-delà de ce texte est l’arbre de la syntaxe abstraite (Abstract Syntax Tree), ou ASA. L’ASA est une arborescence contenant toutes les balises du code. Voici les ASA en CPP et en C# pour int foo = 3;.
Bien que le code soit le même, puisque chaque langage de programmation est différent, la représentation de l’ASA diffère d’une langue à l’autre. Grâce aux 30 ans d’expérience d’Ubisoft en matière de développement, nous disposons d’un gigantesque ensemble de données de transformation d’ASA à partir duquel nous pouvons apprendre à corriger des bogues qui ont été corrigés dans le passé.
Une vidéo présentant des corrections ASA (Diapositive 61)
Alors qu’intuitivement nous pourrions penser que la correction d’un bogue ne nécessite qu’une seule transformation d’ASA, nous pouvons voir que les corrections peuvent nécessiter plusieurs tentatives. Ces tentatives sont nécessaires soit parce que le bogue est difficile à corriger, soit parce que le correctif lui-même introduit une nouvelle régression et doit être… corrigé.
Il existe plusieurs techniques universitaires et industrielles qui visent à tirer les leçons de ces transformations et nous en avons proposé une l’année dernière appelée CLEVER, ou « Combining Levels of Bug Prevention and Resolution techniques », ce qui signifie « Combinaison de niveaux de techniques de prévention et de résolution des bogues » [1].
De MSR’18 : *Les figures 1, 2 et 3 donnent un aperçu de l’approche CLEVER, qui consiste en deux processus parallèles. Dans le premier processus (Figures 1 et 2), CLEVER gère les événements qui se produisent sur les systèmes de suivi de projet pour extraire les validations d’introduction de fautes et les validations de leurs corrections correspondantes. Pour des raisons de simplicité, dans la suite de ce document, nous nous référons aux validations utilisées
pour les corrections en tant que validations de correction. Nous utilisons le terme validation de défaut pour désigner une validation qui introduit une faute.
Le composant de suivi de projet de CLEVER est à l’écoute des événements de clôture de bogues (ou de problèmes) des projets Ubisoft. Actuellement, CLEVER est testé sur 12 gros projets d’Ubisoft. Ces projets partagent de nombreuses dépendances. Nous les avons regroupés en fonction de leurs dépendances dans le but d’améliorer la précision de CLEVER. Cette étape de regroupement est importante afin d’identifier les défauts qui peuvent exister en raison des dépendances tout en améliorant la qualité des correctifs proposés. Dans le second processus (Figure 3), CLEVER intercepte les modifications de code entrantes […] Une fois la modification interceptée, nous traitons le code et les paramètres de processus associés à cette contribution . […]. Le résultat est un vecteur de caractéristiques (étape 4) qui est utilisé pour classer la contribution comme risquée ou non risquée. Si la contribution est classée comme non risquée, le processus s’arrête et la contribution peut être transférée du poste de travail du développeur vers le dépôt de code. Les contributions risquées, par contre, sont analysées plus en détail afin de réduire le nombre de faux positifs (contributions saines qui sont détectées comme étant risquées). Pour ce faire, nous extrayons d’abord les blocs de code qui sont modifiés par le développeur, puis nous les comparons aux blocs de code des contributions qui ont introduits des bogues dans le passé.*
D’autres chercheurs ont envisagé d’utiliser la traduction par machine neuronale (neural machine translation, ou NMT) pour apprendre les bogues et les traduire en fixe, un peu comme traduire le français en anglais. Un bon exemple a été publié par Michele Tufano et al [2].
En raison de la base sur laquelle ces approches s’appuient, nous pensons que les NMT sont mal adaptées pour apprendre à corriger des bogues, du moins les bogues de jeux vidéo complexes selon nos expérimentations internes. En effet, les NMT ne considèrent que deux versions du code, les versions boguées et corrigées, et non les chaînes de corrections.
Nous proposons une nouvelle façon d’utiliser l’apprentissage profond pour gérer les chaînes de corrections. L’approche fonctionnerait de façon à transformer un ASA en graph et à l’intégrer dans l’espace latent. Ensuite, dans l’espace latent de notre encodeur à apprentissage profond, nous pouvons effectuer une méthode KNN et trouver des bogues connus qui sont similaires à l’ASA proposé. Il fonctionne de manière similaire à un chercheur de clones à apprentissage profond qui se concentrerait uniquement sur les validations de défauts. Ensuite, nous pouvons suivre les chaînes de correction que nous avons trouvées et les appliquer à l’ASA proposé.
Un avantage supplémentaire est la traçabilité des correctifs suggérés, puisqu’ils sont extraits et liés à des corrections humaines. Nous pouvons donc lier les bogues passés et leurs solutions à n’importe quelle recommandation de correctifs. Cela permettrait aux développeurs de comprendre pourquoi un correctif spécifique est proposé et le contexte entourant sa création.
Une autre façon d’identifier les régressions dans les jeux est d’entraîner des robots à jouer aux jeux et à rapporter leurs résultats. Ce sera le sujet d’un article de fond à venir.
La présentation annotée et les vidéos présentées à l’ASE peuvent être consultées ici:
Références
[1] Mathieu Nayrolles et Abdelwahab Hamou-Lhadj. 2018. « CLEVER: combining code metrics with clone detection for just-in-time fault prevention and resolution in large industrial projects. » dans Proceedings of the 15th International Conference on Mining Software Repositories (MSR ’18). ACM, New York, NY, États-Unis, 153-164. DOI: https://doi.org/10.1145/3196398.3196438
[2] Michele Tufano, Jevgenija Pantiuchina, Cody Watson, Gabriele Bavota et Denys Poshyvanyk en 2019. « On learning meaningful code changes via neural machine translation. » dans Proceedings of the 41st International Conference on Software Engineering (ICSE ’19). IEEE Press, Piscataway, NJ, États-Unis, 25-36. DOI: https://doi.org/10.1109/ICSE.2019.00021.
Auteur
Mathieu Nayrolles (Ubisoft La Forge)