Déployer et valoriser son projet de data science
Présentation des techniques de déploiement et de valorisation des projets de data science.
Dérouler les slides ci-dessous ou cliquer ici pour afficher les slides en plein écran.
La notion de mise en production
Les chapitres précédents nous ont permis de construire un projet de data science à la fois conforme aux bonnes pratiques de développement et portable. Ce faisant, nous avons déjà largement réduit le coût de transition entre notre environnement de développement et un environnement de production. La notion de mise en production désigne précisément cette transition vers un environnement de production, c’est à dire un environnement dans lequel l’application sera déployée et donc accessible à ses utilisateurs potentiels, avec une haute disponibilité — idéalement, 24h sur 24.
Réaliser une mise en production nécessite d’effectuer un certain nombre de choix, plus ou moins contraints. D’abord, il est nécessaire de bien comprendre le besoin métier — qui seront les utilisateurs potentiels de notre application et quels sont leurs besoins — pour déterminer le format de valorisation pertinent pour celle-ci. Par exemple, le format adapté pour mettre à disposition un modèle entraîné de machine learning ne sera pas le même que l’on s’adresse au grand public — auquel cas on s’orientera certainement vers une application interactive simple d’utilisation1 — ou à une équipe interne de notre organisation qui voudrait effectuer de la prédiction à partir du modèle — cas dans lequel une API requêtable via un langage de programmation s’avèrera sans doute plus pertinente. Un second choix à effectuer concerne l’infrastructure de production sur laquelle va être déployée l’application. Si des considérations techniques entrent en compte pour déterminer l’infrastructure pertinente, ce choix est en général contraint pour le data scientist par ce qu’il a à sa disposition au sein de son organisation. Enfin, il est nécessaire de choisir les outils qui vont permettre l’industrialisation du projet : automatisation du déploiement, orchestration des traitements, monitoring de la solution en production, etc.
La diversité des réponses qui peuvent être apportées à chacun de ces choix illustre la complexité du sujet de la mise en production. Il serait bien illusoire de prétendre traiter ici ce sujet avec exhaustivité. Afin de restreindre cette complexité, nous allons effectuer à chaque étape des choix raisonnables, c’est à dire qui représentent des pratiques courantes dans le domaine de la data science. Ainsi, nous allons nous restreindre au cas du déploiement d’un modèle de machine learning, exposé via une API, car il s’agit d’une tâche fréquemment effectuée dans le monde de la data science et sur laquelle il est donc bon d’avoir quelques notions. Comme nous allons effectuer le déploiement sur le SSP Cloud, l’infrastructure de production sera un cluster Kubernetes
. Là encore, cette solution constitue un standard actuel de l’industrie. Enfin, pour ce qui est de l’industrialisation de notre projet, nous choisirons des solutions standards et open-source qui permettent d’implémenter l’approche CI/CD (intégration continue / déploiement continu), qui fait référence en la matière. Dans tous les cas, l’enjeu de ce cours est de transmettre les concepts sous-jacents à la mise en production plus que de former à telle ou telle technologie.
Par rapport au précédent, ce chapitre est assez technique et repose sur une vaste palette d’outils. Notre propos n’est cependant pas de dire que le data scientist doit maîtriser l’ensemble des concepts et outils présentés. Au contraire : avec la complexification des projets et des infrastructures, un ensemble de professions ont émergé — date engineer, dev ops, machine learning engineer, etc. — dont les rôles sont plus spécifiquement centrés sur l’industrialisation des projets. Néanmoins, nous sommes convaincus qu’il est essentiel que le data scientist possède des notions sur le sujet afin de pouvoir jouer le rôle d’interface entre le métier et les équipes techniques. Ce chapitre est une tentative de condenser ces différentes notions sous une forme la plus accessible possible.
Ce chapitre nous amènera à explorer plusieurs écosystèmes, pour lesquels on retrouve quelques buzz-words dont voici les définitions :
Terme | Définition |
---|---|
DevOps |
mouvement en ingénierie informatique et une pratique technique visant à l’unification du développement logiciel (dev) et de l’administration des infrastructures informatiques (ops) |
MLOps |
ensemble de pratiques qui vise à déployer et maintenir des modèles de machine learning en production de manière fiable et efficace |
CI/CD |
combinaison des pratiques d’intégration continue et de livraison continue ou de déploiement continu |
L’approche CI/CD
Définition
L’intégration continue est un ensemble de pratiques utilisées en génie logiciel consistant à vérifier à chaque modification de code source que le résultat des modifications ne produit pas de régression dans l’application développée. […] Elle permet d’automatiser l’exécution des suites de tests et de voir l’évolution du développement du logiciel.
La livraison continue est une approche d’ingénierie logicielle dans laquelle les équipes produisent des logiciels dans des cycles courts, ce qui permet de le mettre à disposition à n’importe quel moment. Le but est de construire, tester et diffuser un logiciel plus rapidement.
L’approche CI/CD garantit une automatisation et une surveillance continues tout au long du cycle de vie d’un projet.
Cela présente de nombreux avantages:
- on peut anticiper les contraintes de la mise en production grâce à des environnements normalisés partant d’image docker standardisées
- on peut tester les changements apportés à un livrable par un nouveau prototype
- on peut déterminer très rapidement l’introduction de bugs dans un projet.
Intégration continue
- Automatisation des phases de build et de test (data validation, model validation..)
- Mise à disposition des artifacts (forme “morte”)
Mise en oeuvre : GitHub Actions
Les actions Github
sont un ensemble de règles qui se suivent au format YAML
. Cela permet de définir différentes étapes du processus avec, pour chaque étape, des éléments de configuration. Elles permettent de partir d’une configuration minimale (ici une machine ubuntu
) et d’appliquer des instructions à la suite, par étape.
Exemple d’action impliquant exclusivement de l’intégration continue (application 14)
name: Python package
on: [push]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.9", "3.10", "3.11"]
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install pylint
pip install -r requirements.txt - name: Lint
run: |
pylint src --fail-under=6 - name: Test workflow
run: |
python main.py
L’intégration continue est aussi au coeur des fonctionnalités de Gitlab
. Il s’agissait même d’une fonctionnalité disponible des années avant Github
.
La syntaxe est différente mais le principe est le même : on part d’une machine à la configuration minimale depuis des serveurs mis à disposition et on teste la reproductibilité de son projet.
Déploiement
- Avantages de déployer sur une infra Cloud
- Fonctionnement basique de Kubernetes
- GitOps
- Implémentation : Kubernetes
Orchestration
- Modélisation d’un pipeline data sous forme de DAG
- Implémentation : argo-workflow
Une chaine de production implique plusieurs étapes qui peuvent éventuellement nécessiter plusieurs langages. Ces étapes peuvent être vues comme une suite de transformations.
La représentation de ces étapes peut être faite à l’aide des diagrammes acycliques dirigés (DAG):
Un workflow complet sera ainsi reproductible si on peut, en ayant accès aux inputs et à l’ensemble des règles de transformation, reproduire exactement les outputs. Si les inputs ou le code changent, on peut être en mesure de mettre à jour les outputs, si possible sans faire retourner les parties du projet non concernés.
Une première manière de développer est l’approche manuelle, qui est une tâche digne de Sisyphe:
- Ecriture du code
- Exécution du code jusqu’à sa fin
- Découverte d’une erreur ou mise à jour du code ou des données
- Relance le code dans son ensemble
Pour éviter ce cycle interminable, on est tenté d’écrire des bases intermédiaires et de ne faire tourner qu’une partie du code. Cette approche, si elle a l’avantage de faire gagner du temps, est néanmoins dangereuse car on peut facilement oublier de mettre à jour une base intermédiaire qui a changé ou au contraire refaire tourner une partie du code qui n’a pas été mise à jour.
Il existe des méthodes plus fiables pour éviter ces gestes manuels. Celles-ci sont inspirées de GNU Make et consistent à créer le chemin de dépendance de la chaine de production (lister l’environnement, les inputs et les outputs à produire), à déterminer les chemins affectés par un changement de code ou de données pour ne faire tourner à nouveau que les étapes nécessaires.
Application au ML : le MLOps
- Implémentation : MLFlow
Spécificités liées à la mise en prod de modèles de ML
- Entrainement : batch ou online
- Batch vs real-time prediction
- Feedback loops expérimentation/déploiement/monitoring
- Exposer le modèle via une API
Notions d’observabilité
- Drifts
- Quelles métriques monitorer
Amélioration continue
- Réentraînement : périodique vs continu
Footnotes
Pensons au cas récent de
ChatGPT
, qui doit en partie son succès au fait d’avoir réussi à exposer le modèle entraîné via une interface intuitive et réactive.↩︎