Quelle stratégie de découpage adopter pour un produit de ML maintenable dans le temps ? - Compte-rendu du talk de Pierre Baonla Bassom à La Duck Conf 2022

le 12/04/2022 par Jérémy SURGET
Tags: Software Engineering

Avez vous déjà entendu l’histoire de Netflix, qui a dépensé énormément d’argent dans un super système de recommandation, mais qui n’a jamais été déployé car trop complexe ?

Cette histoire n’est pas un cas isolé et se retrouve beaucoup plus souvent que vous ne le pensez. Entre les produits de ML qui ne sont jamais envoyés en production et ceux qui mettent 6 mois à être déployés, il y a une vraie perte de temps et d’argent lorsque les produits de ML ne sont pas bien pensés dès le départ.

Bien souvent, l’équipe dev et l’équipe data sont séparées en début de projet. Elles ne sont donc pas alignées sur les objectifs et peine à sortir des features liant le dev et la data. Ainsi, au moment d’intégrer le code de ML dans le code applicatif, cela ne se passe pas bien.

Cet article est le compte rendu du talk de Pierre Baonla Bassom, Architecte ML chez OCTO Technology, qui propose des méthodes simples et applicables pour bien découper son produit de ML et faire en sorte qu’il soit maintenable dans le temps

Avant de rentrer dans le vif du sujet, précisons la différence entre découplage et découpage :

Une fonction est couplée à une autre, lorsque celle-ci a besoin de l’autre pour fonctionner. Ces deux fonctions peuvent être issues de la même classe, dans ce cas la, elles sont couplées mais pas découpées :

Toujours dans le même cas, une fonction peut être dépendante d’une autre, mais sans être dans la même classe. Elles sont donc couplées mais découpés :

Pour illustrer l’article nous allons prendre le même exemple utilisé par Pierre pendant son talk : Mettons nous dans la peau d’une équipe produit qui construit un site d’articles de blog. Le site a besoin d'une section “Découverte” qui sera alimentée par des recommandations d’articles.

Nous avons donc deux parties :

  • Le site web en lui même, il s’agit du code applicatif
  • Le code de Machine Learning, pour le système de recommandation

Nous allons voir de manière concrète quand et comment faire évoluer l’architecture de notre projet au fur et à mesure des demandes métier et de l’évolution du produit.

1ère demande :  le métier voudrait un système de recommandation d'article journalier pour chaque utilisateur

Le premier réflexe du Tech lead à ce moment, c’est de vouloir se lancer dans une architecture microservices.

Mais, pourquoi ne pas commencer avec un monolithe ?

En se basant sur le livre “Monolith first” de Martin Fowler, Pierre rappelle les nombreux avantages de cette architecture : maîtriser la complexité.

Il a été démontré que la plupart des projets qui se lancent dans du microservices dès le début, échouent, pour deux raisons simples :

  • La complexité de déploiement
  • La création de plusieurs petites équipes qui ne sont pas alignées.

De son cotés, l’approche monolithe first a 3 principaux avantages :

  • L’émergence naturelle des contextes métier
  • Déploiement plus facile
  • Équipes alignées autour des mêmes objectifs

Malgré cela, le Tech Lead n’est toujours pas convaincu par cette approche, car de son expérience, un monolithe vieilli mal lorsque le projet prend de plus en plus d’ampleur ! Plus personne ne maîtrise complètement le code et l’effort de synchronisation pour déployer devient une véritable douleur.

Pierre rappelle qu’en vérité, les problèmes cités ne viennent pas du monolithe, mais bel et bien du couplage au sein de celui-ci.

Si il y a un fort couplage au sein du monolithe la mise à jour de certains composants nécessite des efforts de synchronisation conséquent. Il faut donc prendre le temps de réfléchir pour bien le découpler.

Mieux vaut donc se diriger vers une approche monolith first et bien découpler les composants pour permettre l’évolution autonome de ceux-ci et les découpages futurs.

Commencer par un monolithe, mais découpler les composants

2ème demande : Le métier aimerait faire évoluer le site avec de nouvelles recommandations à chaque connexion pour chaque utilisateur

L’équipe se retrouve débordée et n’arrive plus à délivrer de la valeur au bon rythme. Le retard s’accumule.

Dans cette situation il serait judicieux d’augmenter le nombre de développeurs sur le projet pour garder la cadence de delivery.

Néanmoins, Le teach lead n’est pas d’accord. Il est persuadé que  lorsqu’on ajoute des personnes à un projet on accroît le temps de delivery.

Il est vrai que selon la loi de Brooks : “Ajouter des personnes à un projet en retard, accroît son retard”

Pourtant selon l’étude Accelerate les entreprises les plus performantes peuvent ajouter des personnes à un projet pour augmenter la cadence de delivery en production. Cela est rendu possible car elles prennent la peine de bien découpler les différents éléments qui constituent leur architecture.

A contrario, les entreprises qui peinent à ajouter des développeurs sans réduire la cadence de delivery sont celles qui ont des briques d’architecture trop couplées entre elles.

Pierre propose donc de revisiter la loi de Brooks en y ajoutant une petit subtilité :

“Ajouter des personnes à un projet en retard et avec un couplage fort entre ses parties, accroît son retard”

Le découpage organisationnel est rendu possible par le découplage des composants. Il est donc concevable de découper l’équipe en 2, sans accroche, l’une pour la partie applicative et l’autre pour le système de recommandations.

Il est donc possible d’agrandir une équipe sans ralentir le projet lorsque les  composants d’une architecture sont bien découplés.

Possibilité d'agrandir et de découper les équipes lorsque les composants sont bien découplés

3ème demande : Le nombre d'utilisateurs augmente, le service de recommandation est de plus en plus sollicité, consomme énormément de ressources et a du mal à tenir la charge.

Le système de recommandation est tellement sollicité que des ralentissements sur l’application se font ressentir.

Ne serait-il pas le moment de sortir le service de recommandation du monolithe ?

En effet, le service de recommandation consomme beaucoup de ressources et il faudrait éviter que cela mette à mal l’application entière. Il est donc justifié d’isoler le service.

Le découpage organisationnel a déjà été réalisé à l’étape précédente et un soin particulier a été pris quant au découplage des composants. Au vu de toutes les précautions prises en amont, sortir le service se fait naturellement et sans douleur. Un découpage technique n’est donc qu’une formalité.

Le système de recommandation est sorti du monolithe et placé dans un service dédié sur un serveur aux performances adaptées

Takeaways

  • Commencez par un monolithe au début de vos projets. Pas besoin d’une architecture microservices compliquée, un monolithe fera l’affaire et sa simplicité permettra de mieux préparer l’avenir du projet.

  • Le découplage est un prérequis au découpage. Bien découpler son monolithe permet de mieux appréhender les découpages organisationnels et techniques.

  • Agrandir une équipe sans ralentir le projet est possible lorsque les composants d’une architecture  sont bien découplés.

  • Faire un découpage technique lorsque les besoins de performances sont très différents du reste de l’application.