Cet article est le deuxième d’une série consacrée à PySyft, une nouvelle bibliothèque python pour Federated Learning ( http://www.novagen.tech/pysyft-une-bibliotheque-python-pour-lapprentissage-federe ).

Chez Novagen , nos clients ont besoin de tirer le meilleur parti de leurs données.
Ils collectent des événements et des données à partir de millions d’appareils, généralement des smartphones. Il pourrait également s’agir d’enceintes intelligentes ou de voitures semi-autonomes.

Avec la récente réglementation RGPD, les entreprises sont sous pression pour préserver la confidentialité et la propriété des données des utilisateurs. Qu’ils aient quelques Go, To, ou soient route vers les Po, au delà de la volumétrie il faut composer avec des exigences multiples parmi lesquelles :

  • Respect de la vie privée,
  • La gouvernance de ses données,
  • Innovation : quels algorithmes, quelle stratégie…

Dans ce contexte, nous recherchons de nouvelles façons de travailler avec les données.

Nous avons donc étudié PySyft, une bibliothèque python, pour créer un modèle de deep learning sur des données décentralisées. Grâce à son approche d’apprentissage fédéré et à certaines techniques de cryptage telles que le cryptage multipartite sécurisé, PySyft permet aux data scientists de créer et de former un deep learning tout en préservant la confidentialité et la propriété des données de l’utilisateur.

Nous allons tenter de répondre à plusieurs incertitudes posées par PySyft :

  • Les performances en terme de vitesse d’apprentissage sont-elles comparables à celles utilisant un entraînement centralisé
  • Est-il possible d’utiliser toute type de donnée et sous quelle format ? des images, séries temporelles …?
  • Quel type de machine learning est compatible et donc quel types de problème peuvent être résolus? Arbre de décision, deep learning …?
  • Le rapport performance/temps d’entraînement est-il identique? La précision d’un même algorithme est-elle conservée?
  • PySyft est-il résilient et évolutif (scalable)? La rapidité d’apprentissage est-elle ralentie si l’on passe de 10 à 1000 à 1 000 000 d’appareils? Que se passe-t-il si certains appareils se déconnectent du réseau? L’entraînement déjà effectué sera-t-il perdu?
  • L’encryption de mon modèle est-elle assez fiable pour l’utiliser sur des millions d’appareils sans risque d’être volé?

Nous verrons par la suite que dans certains cas, pour des raisons de sécurité lors de l’encryption, nous devons faire appel à un tiers.

  • Comment se traduit cette contrainte à grande échelle?
  • Y-a-t-il une alternative à ce tiers? comment se traduit-elle? Est-elle fiable?

Dans cet article, nous nous concentrons uniquement sur la vitesse de PySyft.
Nous allons explorer différents scénarios.

Le reste des préoccupations sera abordé dans de prochains articles.

Configuration de référence :

Matériel : une instance t2.micro AWS
OS : Ubuntu 18.04.2
PyTorch version 1.0.1
Version PySyft de mai 2019 (évolution rapide)

Jeu de données : les données sur le cancer du sein provenant de la librairie Scikit learn. Taille de l’échantillon = 569, Nombre de features = 30

N’hésitez pas à forker ou cloner le dépôt github si vous voulez accéder au code pour répliquer ou améliorer nos tests : https://bitbucket.org/novagenlab/pysyft_benchmark/src/master/

Remarque : nous n’avons pas divisé les données en training, validation et test sets pour des raisons de commodité, mais vous pouvez le faire pour une application réelle. Nous nous concentrons uniquement sur le processus d’apprentissage (mises à jour des poids): comment le modèle est capable de cartographier les données et à quelle vitesse. Nous ne vérifions pas comment notre modèle généralise sur de nouvelles données.

Scénario 1 :

Pure Pytorch sur 1 machine :

Epoch 100 Précision d’entraînement totale 96.83% Perte totale 0.96 CPU time : utilisateur 3,15 s, sys : 65,6 ms, total : 3,21 s
Wall time: 3,32 s

Scénario de pur Pytorch

Scénario 2 :

Apprentissage fédéré avec PySyft sur la même machine avec 2 travailleurs et 1 client :
100 Époques formation totale précision 82,7 % perte totale 1.09
CPU time : utilisateur 2min 16s, système : 12.3 s, total : 2min 29s
Wall Time: 4min 51s.

PySyft sur la même machine

Nous pouvons remarquer que l’apprentissage est moins stable. On peut supposer que la mise à jour des poids est affectée par l’apprentissage fédéré. Il perd également 13% de précision pour le même nombre d’époques. D’autre part, le temps augmente de 8700%, ce qui posera certainement un problème si nous essayons d’augmenter le nombre de travailleurs. Le problème principal est que le flux de travail est synchrone. Chaque travailleur s’entraîne l’un après l’autre. Ce faisant, nous n’avons pas vraiment de parallélisme de notre puissance de calcul. Vous pouvez également le voir dans la différence entre le temps de mur et le temps de calcul. Le temps de calcul est inférieur à la moitié de celui du mur, cela suggère que notre processeur attend la moitié du temps du processus.

Si nous visons à pousser l’apprentissage plus loin de 100 à 200 époques :
200 Époques formation totale précision 85.06% perte totale 0.99
CPU Time : utilisateur 4min 35s, sys : 23,6 s, total : 4min 59s
Wall time : 9min 45s

Pysyft sur la même machine pour 200 époques.

Nous augmentons d’environ 2,3% la précision, toujours 11% de moins qu’avec PyTorch pur. Nous pouvons voir que dans la configuration actuelle, le modèle ne peut plus apprendre d’avantage après environ 150 époques. Nous explorerons plus tard quelques solutions pour y remédier.

Scénario 3 :

Apprentissage fédéré avec PySyft sur les 3 différentes machines : 2 machines pour les 2 travailleurs et une pour le client. Toutes les machines sont dans la région Irlande d’AWS.

100 Époques formation totale précision 82.77%
perte totale 1.09
Temps CPU : utilisateur 2min 8s, sys : 17.5 s, total : 2min 26s
Temps mural : 9min 31s

PySyft sur 3 machines différentes: 2 pour les travailleurs et 1 pour le client

Une chose à noter : les données sont divisées en 2 travailleurs comme suit :
worker_hospital_1_data = data [int (len (data) / 2):]
worker_hospital_2_data = data [: int (len (data) / 2]
En changeant l’emplacement des données entre les travailleurs, nous remarquons une très petite différence dans les performances: environ 0,17%. C’est peu mais il paraît utile de garder cela à l’esprit.

Époques 100 Total précision d'entraînement 82.60%
perte totale 1.109
Temps CPU : utilisateur 2min 9s, sys : 17.6 s, total : 2min 27s
Temps mural : 9min 18s

Scénario 4 :

Apprentissage fédéré avec PySyft sur les 3 différentes machines : 2 machines pour les 2 travailleurs et une pour le client. Tous les travailleurs sont dans la région AWS d’Irlande, le client est dans l’ouest des États-Unis (Californie du Nord).

Eh bien, c’est beaucoup trop lent…

Pour seulement 1 époque :
Temps CPU : utilisateur 2,03 s, sys : 151 ms, total : 2,18 s
Temps mural : 10min 28s

Nous pouvons en conclure que la proximité des travailleurs avec le client est très importante. Il pourrait être intéressant de créer un client local dans chaque région pour rester proche d’un groupe de travailleurs. Ensuite, une mise à jour plus importante peut être effectuée sur les poids du modèle de deep learning.. Cela devrait améliorer l’efficacité du processus d’apprentissage.

Même si nos travailleurs sont très éloignés, ils sont tous deux hébergés par AWS. Ce qui signifie que la bande passante est supposé être plus que correcte. Si, dans votre entreprise, vous utilisez différents fournisseurs de serveurs, la vitesse peut être considérablement affectée. En effet, les fournisseurs réduisent généralement votre bande passante si vos données sortent de leur matériel.

Essayons d’améliorer ou au moins de comprendre les paramètres qui ont une incidence sur la rapidité du processus d’apprentissage. Toutes les solutions proposées sont utilisées dans les conditions du scénario 3.

Solution 1 :

Ne pas mélanger les données pour augmenter la stabilité du processus d’apprentissage.
100 Époques formation totale précision 82.60%
perte totale 1.09
Temps CPU : utilisateur 2min 7s, sys : 17.9 s, total : 2min 25s
Temps mural: 9min 26s

PySyft sans mélange aléatoire des données

Nous pouvons remarquer une plus grande stabilité! Les performances et la vitesse sont inchangées.

Solution 2 :

Augmenter la taille des batchs pour accroître la vitesse avec moins de communications entre les travailleurs et le client.

J’ai changé la taille des batchs de 32 à 64 :
100 Époques formation totale précision 44.11%
perte totale 0.71
Temps CPU : utilisateur 1min 31s, sys : 12.2 s, total : 1min 43s
Temps mural : 7min 9s

PySyft avec une plus grande taille de batchs (64 au lieu de 32)

Nous pouvons observer qu’en doublant la taille des batchs (x2), la vitesse augmente d’environ 30%. En revanche, la précision passe de 91% (PyTorch) à 44% (PySyft) pour une taille de batchs identique.

Solution 3 :

Changer le matériel :
Sachant que la capacité du réseau semble être un problème, j’ai décidé de changer nos instances EC2 de t2.micro à t3.micro. Selon AWS, les performances réseau de t2.micro sont faibles à modérées, alors que celles de t3.micro sont supérieures à 5 Gbps.

100 Époques formation totale précision 82.77%
perte totale 1.09
Temps CPU : utilisateur 2min 2s, sy s: 7.01 s, total : 2min 9s
Temps mural : 7min 17s

Nous améliorons effectivement d’environ 30% (2 minutes) notre entraînement.

Solution 4 :

Envoyer le modèle et le récupérer uniquement à la fin de tous les batchs de chaque travailleurs.

Temps CPU : utilisateur 1min 22s, sys : 16.7 s, total : 1min 38s
Temps mural : 7min 48s

avec l’instance t3.micro:

Temps CPU : utilisateur 1min 2s, sys : 6.36 s, total : 1min 9s
Temps mural : 5min 28s

Les performances restent inchangées alors que nous améliorons la vitesse de ~ 74% (moins de 4 minutes).
Si nous voulons évaluer la précision à chaque étape mais la perte seulement après tous les batchs, nous perdons entre 20 et 30 secondes:

100 Époques formation totale précision 82.77%
perte totale 0.143
Temps CPU : utilisateur 1min 6s, sys : 6.21 s, total : 1min 12s
Temps mural : 5min 54s

PySyft avec matériel t3.micro + modèle et perte récupérée après toutes les batchs effectuées + précision calculée à chaque étape

Résumé :


Performances PySyft / PyTorch

Grâce à PySyft, nous sommes en mesure de former efficacement un modèle de deep learning sur des données décentralisées. Cela crée également de nouvelles contraintes:

  • la distance, les performances du réseau, le nombre de communications entre le client et leurs travailleurs (noeud de données) impactent la vitesse d’ apprentissage.
  • la mise à jour et le transport des fonctions des poids, modèle entre le client et ses travailleurs impactent la stabilité et la précision .

N’oubliez pas que nous n’avons effectué aucun pré-traitement via PySyft. Le temps d’apprentissage aurait peut-être beaucoup augmenté. Le module “Plan” dans PySyft permet d’envoyer la plupart des fonctions sur les données des travailleurs. Je mettrai à jour cet article plus tard, après quelques tests avec Plan.

Pour conclure, je pense que nous pouvons utiliser une architecture comme suit: chaque client a un groupe de travailleurs proches. Une fois que chaque client a envoyé le modèle et les commandes sur de nombreux travailleurs, nous récupérons et pondérons les poids du modèle entre les clients.


Architecture potentielle de PySyft à l’échelle

Nous avons également 2 mises à jour possibles dans le code source de PySyft :

  • Commandes asynchrones du client aux travailleurs. Il y a déjà quelques tentatives pour créer un apprentissage fédéré asynchrone dans PySyft. Vous pouvez vous inscrire ou même contribuer à cette Pull Request : https://github.com/OpenMined/PySyft/pull/2289
  • Un autre moyen d’améliorer les performances de vitesse consiste à compresser les fonctions complexes envoyées entre les travailleurs et le client en moins de messages qu’aujourd’hui. Le module pour cela s’appelle Plan dans la bibliothèque PySyft et a pour objectif d’amener PySyft à l’échelle. Il permet également d’envoyer certaines tâches de pré-traitement du client aux travailleurs. Il peut être utile d’avoir le contrôle du développement d’un algorithme du côté client.

Donc, si vous souhaitez améliorer PySyft, vous pouvez commencer à contribuer et à soutenir la communauté open-source. ici .

Dans l’article suivant, nous parlerons de l’amélioration de PySyft réalisée avec TrainConfig (proche de Plan) et asynchrone : [A VENIR] .

Si vous avez des questions concernant la bibliothèque, laissez un commentaire et je ferai de mon mieux pour vous répondre au plus vite.

Sacha DUMAY (sdumay@novagen.tech)