En février 2017, Yahoo! A publié une bibliothèque qui distribue TensorFlow avec Spark. http://yahoohadoop.tumblr.com/post/157196317141/open-sourcing-tensorflowonspark-distributed-deep
Personnellement, j'ai joué avec Docker, mais qu'en est-il de Keras? Donc, cette fois, je vais exécuter Dist-Keras, qui distribue Keras avec Spark, avec Docker.
L'objectif est d'utiliser la bibliothèque d'apprentissage en profondeur de manière évolutive. En utilisant GPGPU, je pense que l'apprentissage en profondeur se concentre sur la mise à l'échelle.
Cependant, si nous combinons la mise à l'échelle, qui nécessite les performances des dispositifs informatiques pour accélérer le traitement, et la montée en charge, qui nécessite le nombre de dispositifs informatiques, nous devrions être en mesure d'effectuer un traitement plus rapide. De plus, je pense personnellement que les pauvres qui n'ont pas de GPU feront de leur mieux à la montée en puissance (celui-ci est plus urgent (rires)). Par conséquent, j'ai installé Keras, une bibliothèque d'apprentissage en profondeur, dans le conteneur Docker, démarré plusieurs conteneurs et essayé de distribuer la charge par montée en puissance parallèle. Comme il n'est pas possible de monter en charge avec Keras normal, cette fois, nous utiliserons une bibliothèque qui exécute Keras avec Spark.
Keras on Spark
Il semble qu'il existe deux bibliothèques qui distribuent Keras avec Spark.
Le premier est Elephas, qui semble exister depuis environ un an. http://maxpumperla.github.io/elephas/
L'autre est Dist-Keras, qui est publié par le CERN (Organisation européenne de recherche nucléaire!). http://joerihermans.com/work/distributed-keras/ https://db-blog.web.cern.ch/blog/joeri-hermans/2017-01-distributed-deep-learning-apache-spark-and-keras
CERN est l'histoire originale de SERN de STEINS; GATE. Le CERN semble connaître Rintaro Okabe. http://gigazine.net/news/20140623-ama-cern/
Cette fois, je vais exécuter Dist-Keras du CERN avec Docker et exécuter MNIST. J'ai choisi Dist-Keras simplement parce qu'il a été mis à jour récemment et que cela a fonctionné.
J'ai aussi touché Elephas à mi-chemin, donc je vais peut-être recommencer bientôt.
La raison pour laquelle Dist-Keras s'exécute sur Docker est que les conteneurs sont plus faciles à configurer que les machines virtuelles. Il est normal d'avoir plusieurs EC2, mais c'est un problème si le coût est élevé, j'ai donc démarré 3 conteneurs de Docker dans une machine virtuelle. L'un est un maître / travailleur Spark (esclave) et les autres sont des travailleurs. Il sera configuré comme ceci.
Dist-Keras Le CERN est enthousiasmé par Dist-Keras, alors lisez la suite.
https://db-blog.web.cern.ch/blog/joeri-hermans/2017-01-distributed-deep-learning-apache-spark-and-keras
Je vais traduire certains d'entre eux.
Distributed Keras Distributed Keras est un framework d'apprentissage en profondeur distribué créé à l'aide d'Apache Spark et de Keras. Le but est d'améliorer considérablement le temps d'apprentissage de l'apprentissage automatique et de permettre d'analyser des ensembles de données qui dépassent la capacité de la mémoire. Le projet a démarré en août 2016 en collaboration avec CMS.
Architecture Fondamentalement, le processus d'apprentissage est transmis au worker Spark par la fonction Lambda. Cependant, lors du passage de plusieurs paramètres, tels que le numéro de port du serveur de paramètres, nous les avons tous enveloppés dans des objets et les avons transformés en fonctions d'apprentissage qui pourraient utiliser les paramètres nécessaires à Spark. Pour avoir une vue d'ensemble de l'ensemble, expliquons-nous avec la figure suivante. L'objet d'apprentissage démarre d'abord le serveur de paramètres avec le pilote Spark. Ensuite, démarrez le processus de travail. Il contient tous les paramètres et processus nécessaires pour entraîner le modèle Keras. En outre, afin de préparer un nombre nécessaire de travailleurs pour un traitement parallèle, l'ensemble de données est divisé par une capacité prédéterminée. Cependant, lors du traitement de Big Data, il est souhaitable d'augmenter les éléments du traitement parallèle. Ce faisant, vous pouvez éviter une situation dans laquelle un travailleur est inactif alors qu'un autre travailleur moins capable n'a pas fini de tourner le lot (c'est ce qu'on appelle le problème de la difficulté). Dans ce cas, accédez à la Documentation Spark En tant que tel, il est recommandé de définir l'élément de distribution sur 3.
Cependant, il peut arriver que vous deviez envisager d'utiliser des éléments distribués plus volumineux. Fondamentalement, le traitement distribué est proportionnel au nombre de partitions (nombre de divisions). Par exemple, supposons que vous affectiez 20 travailleurs à une tâche et que vous définissiez l'élément de distribution sur 3. Spark divise l'ensemble de données en 60 fragments. Et avant que les travailleurs puissent commencer à traiter les partitions, ils doivent d'abord charger toutes les bibliothèques Python nécessaires pour traiter la tâche, puis désérialiser et compiler le modèle Keras. Ce processus représente une surcharge importante. En tant que telle, cette technique n'est utile que lorsqu'il s'agit de grands ensembles de données sur des systèmes non hétérogènes qui nécessitent une longue surcharge de préchauffage (c'est-à-dire que chaque travailleur a une charge de matériel ou une valeur différente).
Dist-Keras Instrallation Dist-Keras est publié sur Github. https://github.com/cerndb/dist-keras
Spark et Keras doivent être installés avant d'installer Dist-Keras. La méthode d'installation de ceux-ci est la suivante. https://spark.apache.org/docs/latest/index.html https://keras.io/ja/
Pour installer Dist-Keras, utilisez la commande suivante.
## if you need git, run "yum -y install git" beforehand
git clone https://github.com/JoeriHermans/dist-keras
cd dist-keras
pip install -e .
Je l'ai essayé sur la machine virtuelle CentOS 7.3 et le conteneur Docker (CentOS 7.3), et j'ai pu l'installer sans me coincer.
Eh bien, cela fait longtemps, mais ce que nous faisons cette fois-ci, c'est d'exécuter Dist-Keras dans un conteneur Docker et de distribuer l'apprentissage du modèle Keras parmi les conteneurs. Nous déploierons à nouveau la configuration suivante.
Dist-Keras on Docker Dist-Keras n'a ni fichier Docker ni image Docker, donc je l'ai fait moi-même. https://github.com/shibuiwilliam/distkeras-docker
git clone téléchargera le Dockerfile et spark_run.sh.
git clone https://github.com/shibuiwilliam/distkeras-docker.git
Accédez au répertoire distkeras-docker et effectuez une construction de docker.
cd distkeras-docker
docker build -t distkeras .
Cela prendra du temps, mais attendons lentement. Les principales choses que fait docker build sont:
--Installation des outils nécessaires --Installation et configuration de Python et Jupyter Notebook --Installation et configuration de Standalone Spark --Installation de Dist keras
Le conteneur de base est CentOS. Spark est 2.1.0 et Keras est 2.0.2, tous deux utilisant la dernière version.
Déplaçons-le dès que la construction du docker est terminée. Cette fois, nous allons démarrer 3 conteneurs Docker pour évoluer.
# docker dist-keras for spark master and slave
docker run -it -p 18080:8080 -p 17077:7077 -p 18888:8888 -p 18081:8081 -p 14040:4040 -p 17001:7001 -p 17002:7002 \
-p 17003:7003 -p 17004:7004 -p 17005:7005 -p 17006:7006 --name spmaster -h spmaster distkeras /bin/bash
# docker dist-keras for spark slave1
docker run -it --link spmaster:master -p 28080:8080 -p 27077:7077 -p 28888:8888 -p 28081:8081 -p 24040:4040 -p 27001:7001 \
-p 27002:7002 -p 27003:7003 -p 27004:7004 -p 27005:7005 -p 27006:7006 --name spslave1 -h spslave1 distkeras /bin/bash
# docker dist-keras for spark slave2
docker run -it --link spmaster:master -p 38080:8080 -p 37077:7077 -p 38888:8888 -p 38081:8081 -p 34040:4040 -p 37001:7001 \
-p 37002:7002 -p 37003:7003 -p 37004:7004 -p 37005:7005 -p 37006:7006 --name spslave2 -h spslave2 distkeras /bin/bash
Il se compose de Spark master / worker (spmaster), worker 1 (spslave1) et worker 2 (spslave2). Exécutez le maître et le nœud de calcul Spark avec spmaster, et joignez spslave1 et spslave2 en tant que nœuds de calcul (esclave) au cluster Spark.
Les scripts de démarrage Spark Master et Worker sont fournis respectivement sous la forme /opt/spark_master.sh et /opt/spark_slave.sh. Puisqu'il est déplacé vers le répertoire / opt / lorsque chaque conteneur est démarré, le maître et le travailleur peuvent être démarrés en y exécutant des commandes.
#Exécuter sur Spark Master
#Le maître et le travailleur démarrent, le travailleur rejoint le cluster
sh spark_master.sh
# Spark spslave1,Courir en 2
#Le travailleur démarre et rejoint le cluster principal
sh spark_slave.sh
Vous avez maintenant un maître et trois nœuds de calcul dans votre cluster Spark. Vous pouvez le vérifier sur la console Spark Master. http://<spark master>:18080
Dans ce domaine, j'aimerais démarrer plusieurs unités à la fois avec Docker compose ou Swarm, mais c'est aussi mon devoir à une date ultérieure.
Essayons MNIST avec Dist-Keras. L'exemple de code MNIST est fourni par Dist-Keras. Le répertoire est / opt / dist-keras / examples, qui contient les exemples de données et programmes suivants.
[root@spm examples]# tree
.
|-- cifar-10-preprocessing.ipynb
|-- data
| |-- atlas_higgs.csv
| |-- mnist.csv
| |-- mnist.zip
| |-- mnist_test.csv
| `-- mnist_train.csv
|-- example_0_data_preprocessing.ipynb
|-- example_1_analysis.ipynb
|-- kafka_producer.py
|-- kafka_spark_high_throughput_ml_pipeline.ipynb
|-- mnist.ipynb
|-- mnist.py
|-- mnist_analysis.ipynb
|-- mnist_preprocessing.ipynb
|-- spark-warehouse
`-- workflow.ipynb
Cette fois, mnist.py est exécuté, mais certains codes doivent être modifiés en fonction de l'environnement.
Copiez le fichier d'origine, sauvegardez-le et appliquez les modifications suivantes.
cp mnist.py mnist.py.bk
Ajoutez ce qui suit au début.
from pyspark.sql import SparkSession
Modifiez les paramètres Spark pour cet environnement. L'intention du changement est la suivante.
--Utilisation de Spark2 --Utilisation de l'environnement local --Définir l'URL principale dans l'environnement local
# Modify these variables according to your needs.
application_name = "Distributed Keras MNIST"
using_spark_2 = True # False→True
local = True # False→True
path_train = "data/mnist_train.csv"
path_test = "data/mnist_test.csv"
if local:
# Tell master to use local resources.
# master = "local[*]" comment out
master = "spark://spm:7077" # add
num_processes = 1
num_executors = 3 # 1→3
else:
# Tell master to use YARN.
master = "yarn-client"
num_executors = 20
num_processes = 1
Changez la mémoire du travailleur de 4G à 2G. Ce n'est pas un changement obligatoire car il est simplement adapté à votre environnement.
conf = SparkConf()
conf.set("spark.app.name", application_name)
conf.set("spark.master", master)
conf.set("spark.executor.cores", `num_processes`)
conf.set("spark.executor.instances", `num_executors`)
conf.set("spark.executor.memory", "2g") # 4G→2G
conf.set("spark.locality.wait", "0")
conf.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer");
Vous êtes maintenant prêt. Déplaçons MNIST.
python mnist.py
Vous pouvez vérifier l'état d'exécution sur la console Spark Master. http://<spark master>:18080
Bien sûr, vous pouvez également ouvrir des détails tels que Jobs et Executer.
Écran des travaux
Écran de l'exécuteur
Les données sont chargées dans 3 travailleurs et MNIST est en cours de formation. À propos, le modèle de MNIST est le suivant.
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_1 (Conv2D) (None, 26, 26, 32) 320
_________________________________________________________________
activation_1 (Activation) (None, 26, 26, 32) 0
_________________________________________________________________
conv2d_2 (Conv2D) (None, 24, 24, 32) 9248
_________________________________________________________________
activation_2 (Activation) (None, 24, 24, 32) 0
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 12, 12, 32) 0
_________________________________________________________________
flatten_1 (Flatten) (None, 4608) 0
_________________________________________________________________
dense_1 (Dense) (None, 225) 1037025
_________________________________________________________________
activation_3 (Activation) (None, 225) 0
_________________________________________________________________
dense_2 (Dense) (None, 10) 2260
_________________________________________________________________
activation_4 (Activation) (None, 10) 0
=================================================================
Total params: 1,048,853.0
Trainable params: 1,048,853.0
Non-trainable params: 0.0
_________________________________________________________________
Le programme sera terminé dans environ 30 minutes.
Le résultat d'essayer avec 3 ouvriers est le suivant.
Training time: 1497.86584091
Accuracy: 0.9897
Number of parameter server updates: 3751
Avec un temps d'apprentissage de moins de 25 minutes, la précision était de 0,9897. Comme ci comme ça.
À propos, le résultat d'essayer avec un seul travailleur est le suivant.
Training time: 1572.04011703
Accuracy: 0.9878
Number of parameter server updates: 3751
~~ ・ ・ ・ 3 ouvriers ou 1 ouvrier ne peuvent prendre qu'environ 1 minute (-_-;) ~~
~~ Est-ce le choix de Steins Gate ... ~~
Cette fois, j'ai démarré le conteneur Docker sur le même serveur, mais je pense que la répartition de charge d'origine est réalisée sur les serveurs. À l'avenir, j'aimerais démarrer le conteneur Dist-Keras sur plusieurs serveurs et ECS, configurer un cluster Spark et répartir la charge.
[PostScript 2017/04/16] Nous avons vérifié comment améliorer les performances. http://qiita.com/cvusk/items/f54ce15f8c76a396aeb1
[PostScript du 26/05/2017] Clustered avec Kubernetes. http://qiita.com/cvusk/items/42a5ffd4e3228963234d
Recommended Posts