Apprentissage machine évolutif en Python avec Dask et Kubernetes …
Tags: docker, datascience, machinelearning, scaleway
Published: 2019-08-24 17:41:52

---
title: Apprentissage machine évolutif en Python avec Dask et Kubernetes …
published: true
tags: docker, datascience, machinelearning, scaleway
canonical_url: https://medium.com/@abenahmed1/apprentissage-machine-%C3%A9volutif-en-python-avec-dask-et-kubernetes-201614e84e95
---

### Apprentissage machine évolutif en Python avec Dask et Kubernetes …

![](https://cdn-images-1.medium.com/max/1024/1*KBecEMQfFuZrti8yoWww5w.jpeg)

Dask est une bibliothèque flexible pour le calcul parallèle en Python. Dask fournit une interface de planification des tâches, permet le calcul distribué en Python avec accès à la pile PyData. Dask fonctionne avec une faible surcharge, une faible latence et une sérialisation minimale nécessaire pour des algorithmes numériques rapides et s’exécute de manière résiliente sur des clusters avec des milliers de cœurs. Dask peut s’installer et utiliser un ordinateur portable en un seul processus. Conçu pour l’informatique interactive, Dask fournit une rétroaction et des diagnostics rapides :

[Dask - Dask 2.1.0 documentation](https://docs.dask.org/en/latest/)

![](https://cdn-images-1.medium.com/max/487/0*o-Tia-fCzYMiVuve.png)

Il est possible de lancer un scheduler Dask, des Workers et un serveur de Notebook Jupyter sur un cluster Kubernetes facilement en utilisant Helm.

[Kubernetes - Dask 2.1.0 documentation](https://docs.dask.org/en/latest/setup/kubernetes.html)

Dask déploie des workers Dask sur un cluster Kubernetes en utilisant les API Kubernetes natives. Ceci afin de lancer dynamiquement des déploiements de workers de courte durée pendant la durée de vie d’un processus Python.

[Dask Kubernetes - Dask Kubernetes 0.9.0 documentation](https://kubernetes.dask.org/en/latest/)

> Actuellement, Dask est conçu pour être exécuté à partir d’un pod sur un cluster Kubernetes qui a les permissions de lancer d’autres pods. Cependant, Dask peut également fonctionner avec un cluster Kubernetes distant (configuré via un fichier kubeconfig) à condition qu’il soit possible d’ouvrir des connexions réseau avec tous les nœuds du cluster distants :

[Adding Dask and Jupyter to a Kubernetes Cluster](https://ramhiser.com/post/2018-05-28-adding-dask-and-jupyter-to-kubernetes-cluster/)

Pour cette expérience, je pars d’instance AMD EPYC chez Scaleway :

![](https://cdn-images-1.medium.com/max/1024/0*7hujJVsSBp2pQaPr.jpeg)

![](https://cdn-images-1.medium.com/max/1024/0*qyrKU4eRST7DVefX.png)

Deploiement de quatre noeuds pour la constitution rapide d’un cluster Kubernetes via Rancher encore une fois :

![](https://cdn-images-1.medium.com/max/1024/1*vjKYTf1kaDK6XziOCkY4IQ.jpeg)

accompagné de ce script au démarrage :

```
#!/bin/bash
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh
usermod -aG docker ubuntu
curl -s https://install.zerotier.com | bash
zerotier-cli join <NETWORK ID>
```

Déploiement du serveur Rancher :

![](https://cdn-images-1.medium.com/max/1024/1*RZJcnDjcr-7KRzZGEHxm5Q.jpeg)

qui une fois actif me permet de définir un cluster Kubernetes en mode HA :

![](https://cdn-images-1.medium.com/max/1024/1*I7HM4aGUoMbtQ_BSP0yJ9Q.jpeg)

Déploiement des noeuds du cluster :

![](https://cdn-images-1.medium.com/max/1024/1*EzjVAnL7Ls-GdbH7dAxOrA.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*YubG8K6vY3MM6pSg_76KGQ.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*Ac_CfHEsxdixNK890ifgOA.jpeg)

Le cluster Kubernetes est alors prêt :

![](https://cdn-images-1.medium.com/max/1024/1*ixQQDBVBx4lPsqFwvIhQpA.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*3QkRtHiEdnMx5OQMOqDoMw.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*7D4R-Tk8A61DBvGIUxKjsg.jpeg)

Pour profiter d’un service de Load Balancing dans ce cluster, comme précédemment je déploie MetalLB :

![](https://cdn-images-1.medium.com/max/1024/1*z2qNn5xhmsoGNjbRNxHlbw.jpeg)

avec cette configuration :

![](https://cdn-images-1.medium.com/max/1024/1*_DV6DJxV1jJ-uOQgfkOdew.jpeg)

qui résulte du plan d’adressage fournie par ZeroTier qui est déjà lié aux noeuds existants du cluster :

![](https://cdn-images-1.medium.com/max/1024/1*qwqb4qUqPz_8bRfw7M88Nw.jpeg)

Pour déployer Dask dans ce cluster, j’installe au préalable Helm :

![](https://cdn-images-1.medium.com/max/1024/1*Ho9Izx2YgfIVRgrBRf5KUQ.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*nLdjra7R729Iuf1epPXbFA.jpeg)

que l’on récupère dans son dépôt sur Github :

[helm/helm](https://github.com/helm/helm/releases)

![](https://cdn-images-1.medium.com/max/917/1*VsPwOtNGW609J9x3IzfPXw.jpeg)

Je peux procéder à l’installation de Dask dans ce cluster Kubernetes avec son Scheduler, ses Workers et son serveur de Notebook Jupyter Lab :

![](https://cdn-images-1.medium.com/max/546/1*2vZApgJ9qDSGAuaP9mxo8Q.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*Cn5PBnWkOLmcwAeapkDZ8g.png)

On peut alors voir les éléments déployés par Dask :

![](https://cdn-images-1.medium.com/max/1024/1*BHhwm1RK9j8jYLZGH4pFjw.png)

dans cette structure :

![](https://cdn-images-1.medium.com/max/1024/1*5RoH2a3QW1380koEPNLW8Q.jpeg)

Via les adresses IP fournies par MetalLB dans le cluster, je peux accéder au serveur Jupyter Lab :

![](https://cdn-images-1.medium.com/max/1024/1*PVwm1O6mYYSi4Tdet5O5qQ.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*xsxleBtY85LXvVFSaaR_uQ.jpeg)

mais également à l’interface web du Scheduler :

![](https://cdn-images-1.medium.com/max/1024/1*jp095-ln51Wd6tkAMFU0Jg.jpeg)

Les graphes dans l’interface web du Scheduler sont fournis via Bokeh, une bibliothèque de visualisation interactive :

![](https://cdn-images-1.medium.com/max/1024/1*GzGHUTTCVTHvJ2ho3XsFBg.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*8n6tOcxOTTsg4-3gEkT2lA.jpeg)

Des éléments d’information que l’on retrouve également sur le serveur Jupyter Lab :

![](https://cdn-images-1.medium.com/max/1024/1*TmGvdAcsTF8AH0rMAHTppQ.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*UACgkxj4_GENfdzqjvoy1g.jpeg)

Test rapide de Dask avec ce notebook qui crée un tableau et calcule sa moyenne :

![](https://cdn-images-1.medium.com/max/1024/1*zteh0gkZ7DEgKIacD3v6kw.jpeg)

avec visualisation des tâches qui en résultent :

![](https://cdn-images-1.medium.com/max/1024/1*Udbt6OpyZaIGSydoaZyA6Q.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*EBv_x3hb8zj40u7tnNy96w.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*ob_4hcDIBudQcty-G32ZdQ.jpeg)

Je peux modifier le nombre de workers Dask dans le cluster Kubernetes toujours via Helm via un fichier de configuration :

![](https://cdn-images-1.medium.com/max/1024/1*8SJdf7FunohO21rnFAbjiQ.png)<figcaption>config.yaml</figcaption>

Je mets ici à jour mon cluster Kubernetes avec quinze workers pour Dask :

![](https://cdn-images-1.medium.com/max/1024/1*7MpSAx6Ld20h1tzjDq4kiQ.png)

![](https://cdn-images-1.medium.com/max/1024/1*naKhfMMljMuzsnv_jyU_zQ.jpeg)

> Pour tester les capacités de calcul parallèle offerte par Dask, je vais reprendre ce Notebook sur la stratégie marketing des banques portugaises et qui utilise pour cela TPOT, un outil d’apprentissage machine automatisé en Python qui optimise les pipelines d’apprentissage machine en utilisant la programmation génétique :

[Home - TPOT](https://epistasislab.github.io/tpot/)

<iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fgiphy.com%2Fembed%2FL2lmcp4SsZUMYEc75x%2Ftwitter%2Fiframe&amp;url=https%3A%2F%2Fmedia.giphy.com%2Fmedia%2FL2lmcp4SsZUMYEc75x%2Fgiphy.gif&amp;image=https%3A%2F%2Fi.giphy.com%2Fmedia%2FL2lmcp4SsZUMYEc75x%2Fgiphy.gif&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=giphy" width="435" height="255" frameborder="0" scrolling="no"><a href="https://medium.com/media/6c65491e3e820a42bd51a0711d81b05e/href">https://medium.com/media/6c65491e3e820a42bd51a0711d81b05e/href</a></iframe>

Les données exploitées dans ce Notebook sont liées aux campagnes de marketing direct d’une institution bancaire portugaise. Les campagnes de marketing étaient basées sur des appels téléphoniques. Souvent, plus d’un contact avec le même client était nécessaire pour savoir si le produit (dépôt bancaire à terme) serait souscrit (‘oui’) ou non (‘non’) :

[EpistasisLab/tpot](https://github.com/EpistasisLab/tpot/tree/master/tutorials/Portuguese%20Bank%20Marketing)

J’installe au préalable Scikit-learn, une bibliothèque libre Python destinée à l’apprentissage automatique et conçue pour s’harmoniser avec d’autres bibliothèques libres Python, notamment NumPy et SciPy. Ainsi que Dask-ML qui fournit un apprentissage machine évolutif en Python à l’aide de Dask et de bibliothèques d’apprentissage machine populaires comme Scikit-Learn :

[Dask-ML - dask-ml 1.0.1 documentation](https://ml.dask.org/)

![](https://cdn-images-1.medium.com/max/1024/1*eO8sMnEJjsitvMpsl1S9nA.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*-pBTdwWgOqpjfCAnbsGT0g.png)

Je peux exécuter mon Notebook :

[Jupyter Notebook](https://hub.gke.mybinder.org/user/deep75-c46d056c-f9777745e6f9b5c-btjwzajc/notebooks/portuguese-bank-tpot.ipynb#)

<iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2cfbba4798f4409a0a2bf262fc835faa/href">https://medium.com/media/2cfbba4798f4409a0a2bf262fc835faa/href</a></iframe><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fgiphy.com%2Fembed%2FXck5Q2p5tdrSr2o9LZ%2Ftwitter%2Fiframe&amp;url=https%3A%2F%2Fmedia.giphy.com%2Fmedia%2FXck5Q2p5tdrSr2o9LZ%2Fgiphy.gif&amp;image=https%3A%2F%2Fi.giphy.com%2Fmedia%2FXck5Q2p5tdrSr2o9LZ%2Fgiphy.gif&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=giphy" width="435" height="250" frameborder="0" scrolling="no"><a href="https://medium.com/media/b5cb221c8657f83fe2bd87832397491d/href">https://medium.com/media/b5cb221c8657f83fe2bd87832397491d/href</a></iframe>

Dernier exemple avec ParallelPostFit et Scikit-learn pour paralléliser et distribuer les étapes de notation ou de prédiction via ce Notebook :


[Jupyter Notebook](https://hub.gke.mybinder.org/user/deep75-acb5803a-3b8608291763acd-d30z3nz0/notebooks/parallel-scikit-learn.ipynb)

<iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/790a120de5df256f34a0da40fab4a2b8/href">https://medium.com/media/790a120de5df256f34a0da40fab4a2b8/href</a></iframe>

![](https://cdn-images-1.medium.com/max/1024/1*EyLApMgT8bLU51QpaPjfkw.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*lnTlPSTsX2nyz9qJTkvbrg.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*tt0iwS6PWadhEGkWXSCV8Q.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*DEg6CVE1_C6g6CQR7KNW6A.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*s4cvoUP4gNFjHvfGXFr9Gw.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*i3xekz6XhYSQe6KIkwXfpQ.jpeg)

Il est possible de mettre à l’échelle le nombre de workers Dask directement depuis le serveur de Notebook Jupyter Lab :

![](https://cdn-images-1.medium.com/max/1004/1*sEz96zHul9FeiFt369NMGA.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*RGu3WtBsBj4REOGqiinM3g.jpeg)

L’utilisation du serveur Rancher permet de bénéficier du monitoring du cluster (et donc de ces workers Dash) via Grafana et Prometheus :

![](https://cdn-images-1.medium.com/max/1024/1*sQ1upwOwoobWaCgfmFIZeQ.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*h120M8K0cqpmXr_HjVoZ1A.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*1s0yBY0wQGh9Sdxb2mc-qQ.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*siCsJDVscPgTVIKpGzkZWg.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*UGPBy-ptds9arGfTuXRS1A.jpeg)

O n peut utiliser tout aussi facilement Dask pour constituer son cluster de Workers via Docker-compose localement sur une instance (chaque image Docker comprend Dask (y compris l’ordonnanceur distribué), Numpy et Pandas en plus d’une installation Miniconda, le tout sur la base d’une image Debian) :

- [dask/dask-docker](https://github.com/dask/dask-docker/blob/master/docker-compose.yml)
- [Docker Images - Dask 2.1.0 documentation](https://docs.dask.org/en/latest/setup/docker.html)

A suivre ! …

![](https://cdn-images-1.medium.com/max/378/1*TscAd70ffOqdWQgR4_83_g.jpeg)