[PYTHON] J'ai essayé de rendre le deep learning évolutif avec Spark × Keras × Docker 2 Multi-host edition

J'ai essayé de rendre le deep learning évolutif avec Spark × Keras × Docker 2

Auparavant, je mettais Dist-keras sur Docker pour créer un apprentissage en profondeur évolutif. http://qiita.com/cvusk/items/3e6c3bade8c0e1c0d9bf

Le point de réflexion à ce moment-là était que la performance ne sortait pas, mais après un examen attentif, il semble que les réglages des paramètres étaient incorrects. Alors, après y avoir réfléchi, j'ai essayé différentes choses.

Synopsis jusqu'à la dernière fois

Pour une description de Dist-Keras lui-même, veuillez vous référer au précédent Post, mais le point est Keras fonctionnant sur un cluster Spark. J'ai fait de cette image une image Docker pour faciliter la mise à l'échelle.

Le Dockerfile est disponible sur GitHub. https://github.com/shibuiwilliam/distkeras-docker

Que faire cette fois

Cette fois, je voudrais vérifier Dist-Keras sur Docker sur un seul hôte et plusieurs hôtes pour améliorer les performances. La dernière fois, j'ai lancé plusieurs conteneurs sur un seul hôte pour créer un cluster Spark. Cette fois, je vais augmenter le motif.

C'est MNIST qui fonctionne. Le programme d'apprentissage MNIST est personnalisé et utilisé tel que fourni par dist-keras.

Configuration vérifiée

Validez sur un seul hôte et sur plusieurs hôtes. Dans chaque cas, la configuration est Spark Master + Worker, et le nombre de travailleurs et les spécifications des travailleurs sont ajustés. Dans le cas du multi-hôte, il y a deux serveurs. L'hôte utilise m4.xlarge d'AWS EC2 CentOS 7.3.

no hosts workers resources
1 single 1 1 processor, 2GB RAM
2 single 2 2 processors, 5GB RAM
3 single 3 1 processor, 3GB RAM
4 multihost 2 2 processors, 5GB RAM
5 multihost 2 3 processors, 8GB RAM
6 multihost 4 2 processors, 5GB RAM

Comment configurer un seul hôte

L'image d'un seul hôte ressemble à ceci. Le nombre de conteneurs Docker varie en fonction des conditions de vérification.

14.jpg

Dans le cas d'un seul hôte, démarrez plusieurs conteneurs Docker sur le même hôte.

# 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


Le maître Spark lance le maître et le worker Spark, et l'esclave Spark lance le worker uniquement.

# for spark master
${SPARK_HOME}/sbin/start-master.sh

# for spark worker
${SPARK_HOME}/sbin/start-slave.sh -c 1 -m 3G spark://spmaster:${SPARK_MASTER_PORT}

Ensuite, personnalisez le programme MNIST avec Spark Master. 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

Copiez le fichier d'origine, sauvegardez-le et appliquez les modifications suivantes.

cp mnist.py mnist.py.bk

Modifier 1 importation de la session Spark

Ajoutez ce qui suit au début.

from pyspark.sql import SparkSession

Modification 2 Réglage des paramètres

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 to True
local = True  # False to 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 # change to number of processors per worker
    num_executors = 3  # change to number of workers
else:
    # Tell master to use YARN.
    master = "yarn-client"
    num_executors = 20
    num_processes = 1
Modifier la mémoire de 3 Worker

Modifiez la mémoire du travailleur pour qu'elle corresponde aux critères de validation.

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", "4g") # change RAM size
conf.set("spark.locality.wait", "0")
conf.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer");

Vous pouvez ensuite l'exécuter sur le Spark Master avec python mnist.py.

Comment configurer plusieurs hôtes

La configuration multi-hôte ressemble à ceci.

23.jpg

Le multi-hôte nécessite que le conteneur Docker soit connecté via un réseau de superposition. Veuillez consulter les informations suivantes pour savoir comment créer un réseau Docker avec plusieurs hôtes. http://knowledge.sakura.ad.jp/knowledge/4786/ http://christina04.hatenablog.com/entry/2016/05/16/065853

Je n'écrirai ici que ma procédure. Préparez host1 et host2 dans EC2, installez etcd sur host1 et démarrez-le.

yum -y install etcd

vi /etc/etcd/etcd.conf
systemctl enable etcd
systemctl start etcd

Ensuite, ajoutez les paramètres docker-network à l'hôte1 et à l'hôte2.

# edit docker-network file
vi /etc/sysconfig/docker-network

# for host1
DOCKER_NETWORK_OPTIONS='--cluster-store=etcd://<host1>:2379 --cluster-advertise=<host1>:2376'

# for host2
DOCKER_NETWORK_OPTIONS='--cluster-store=etcd://<host1>:2379 --cluster-advertise=<host2>:2376'

# from host2 to ensure network connection to host1 etcd is available
curl -L http://<host1>:2379/version
{"etcdserver":"3.1.3","etcdcluster":"3.1.0"}

Maintenant que la connexion réseau entre les dockers est possible, créez un réseau docker avec host1. Ici, créez un réseau docker appelé test1 sur le sous-réseau 10.0.1.0/24.


# for host1
docker network create --subnet=10.0.1.0/24 -d overlay test1

Enfin, exécutez docker network ls et c'est OK si le réseau test1 est ajouté.


NETWORK ID          NAME                DRIVER              SCOPE
feb90a5a5901        bridge              bridge              local
de3c98c59ba6        docker_gwbridge     bridge              local
d7bd500d1822        host                host                local
d09ac0b6fed4        none                null                local
9d4c66170ea0        test1               overlay             global

Ajoutez ensuite un conteneur Docker au réseau test1. Déployons un conteneur Docker sur chacun des hôtes host1 et host2.

# for host1 as spark master
docker run -it --net=test1 --ip=10.0.1.10 -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 spm -h spm distkeras /bin/bash

# for host2 as spark slave
docker run -it --net=test1 --ip=10.0.1.20 --link=spm: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 sps1 -h sps1 distkeras /bin/bash

Vous avez maintenant déployé deux conteneurs Docker sur le réseau test1 avec plusieurs hôtes. Après cela, démarrez le maître Spark et le worker Spark dans la même procédure que pour un seul hôte, éditez MNIST.py et exécutez python mnist.py.

Résultat de la vérification des performances

C'est le résultat de la vérification des performances de chaque configuration. Cette fois, nous mesurons le temps nécessaire pour terminer (secondes).

no. hosts workers resources time in second
1 single 1 1 processor, 2GB RAM 1615.63757
2 single 2 2 processors, 5GB RAM 1418.56935
3 single 3 1 processor, 3GB RAM 1475.84212
4 multihost 2 2 processors, 5GB RAM 805.382518
5 multihost 2 3 processors, 8GB RAM 734.290324
6 multihost 4 2 processors, 5GB RAM 723.878466

Les performances sont meilleures avec le multi-hôte. Je pense que la quantité de ressources gratuites fait simplement une différence dans les performances. La vérification 2 et la vérification 4 ont les mêmes paramètres pour la configuration du conteneur Docker et les ressources utilisées par les travailleurs, mais il y a toujours une différence de 600 secondes. La comparaison de la validation 1 et de la validation 2, ou de la validation 4 et de la validation 5 et de la validation 6 ne semble pas faire une grande différence dans le nombre de workers Spark et la quantité de ressources elles-mêmes. Si vous souhaitez améliorer considérablement les performances, il est préférable de le rendre multi-hôte obéissant.

[PostScript du 26/05/2017] Clustered avec Kubernetes. http://qiita.com/cvusk/items/42a5ffd4e3228963234d

Recommended Posts

J'ai essayé de rendre le deep learning évolutif avec Spark × Keras × Docker 2 Multi-host edition
J'ai essayé de rendre le deep learning évolutif avec Spark × Keras × Docker
"Deep Learning from scratch" Mémo d'auto-apprentissage (n ° 16) J'ai essayé de créer SimpleConvNet avec Keras
"Deep Learning from scratch" Mémo d'auto-apprentissage (n ° 17) J'ai essayé de créer DeepConvNet avec Keras
J'ai essayé de faire d'Othello AI que j'ai appris 7,2 millions de mains par apprentissage profond avec Chainer
J'ai essayé de mettre en œuvre un apprentissage en profondeur qui n'est pas profond avec uniquement NumPy
J'ai essayé de faire un signal avec Raspeye 4 (édition Python)
J'ai essayé de déplacer GAN (mnist) avec keras
J'ai essayé d'intégrer Keras dans TFv1.1
J'ai essayé le deep learning
J'ai essayé de créer Othello AI avec tensorflow sans comprendre la théorie de l'apprentissage automatique ~ Battle Edition ~
J'ai essayé d'extraire le dessin au trait de l'image avec Deep Learning
J'ai essayé d'implémenter Cifar10 avec la bibliothèque SONY Deep Learning NNabla [Nippon Hurray]
J'ai essayé de déplacer l'apprentissage automatique (détection d'objet) avec TouchDesigner
J'ai essayé d'implémenter Grad-CAM avec keras et tensorflow
J'ai essayé de créer une application OCR avec PySimpleGUI
[Deep Learning from scratch] J'ai essayé d'expliquer le décrochage
J'ai essayé de faire une simulation de séparation de source sonore en temps réel avec l'apprentissage automatique Python
J'ai essayé de créer diverses "données factices" avec Python faker
J'ai essayé d'implémenter ListNet d'apprentissage de rang avec Chainer
J'ai capturé le projet Toho avec Deep Learning ... je le voulais.
J'ai essayé de créer une interface graphique à trois yeux côte à côte avec Python et Tkinter
J'ai essayé d'implémenter Perceptron Part 1 [Deep Learning from scratch]
J'ai essayé d'implémenter SSD avec PyTorch maintenant (édition du modèle)
J'ai essayé d'implémenter Deep VQE
Faites de l'art ASCII avec l'apprentissage en profondeur
J'ai essayé l'apprentissage automatique avec liblinear
J'ai essayé l'apprentissage en profondeur avec Theano
Introduction au Deep Learning ~ Dropout Edition ~
Faites sourire les gens avec le Deep Learning
J'ai essayé d'apprendre LightGBM avec Yellowbrick
[5e] J'ai essayé de créer un certain outil de type Authenticator avec python
J'ai essayé de résoudre l'édition du débutant du livre des fourmis avec python
[2nd] J'ai essayé de créer un certain outil de type Authenticator avec python
J'ai essayé l'apprentissage par renforcement profond (Double DQN) avec ChainerRL
J'ai essayé de faire un processus d'exécution périodique avec Selenium et Python
J'ai essayé de créer une application de notification de publication à 2 canaux avec Python
J'ai essayé de créer une application todo en utilisant une bouteille avec python
[4th] J'ai essayé de créer un certain outil de type Authenticator avec python
[1er] J'ai essayé de créer un certain outil de type Authenticator avec python
J'ai essayé de faire une étrange citation pour Jojo avec LSTM
J'ai essayé de créer une fonction de similitude d'image avec Python + OpenCV
J'ai essayé de créer un mécanisme de contrôle exclusif avec Go
J'ai essayé de créer Othello AI avec tensorflow sans comprendre la théorie de l'apprentissage automatique ~ Introduction ~
J'ai essayé de créer Othello AI avec tensorflow sans comprendre la théorie de l'apprentissage automatique ~ Implémentation ~
J'ai essayé d'implémenter Autoencoder avec TensorFlow
J'ai essayé de commencer avec Hy
J'ai créé un capteur d'ouverture / fermeture (lien Twitter) avec TWE-Lite-2525A
J'ai essayé d'apprendre avec le Titanic de Kaggle (kaggle②)
[Deep Learning from scratch] J'ai essayé d'implémenter la couche sigmoïde et la couche Relu
Mayungo's Python Learning Episode 2: J'ai essayé de mettre des caractères avec des variables
J'ai essayé de créer un LINE BOT "Sakurai-san" avec API Gateway + Lambda
J'ai écrit un diagramme de configuration du système avec des diagrammes sur Docker
(Apprentissage automatique) J'ai essayé de comprendre attentivement la régression linéaire bayésienne avec l'implémentation
J'ai essayé de faire la reconnaissance de caractères manuscrits de Kana Partie 2/3 Création et apprentissage de données
J'ai essayé d'implémenter CVAE avec PyTorch
J'ai créé une API Web
J'ai essayé de résoudre TSP avec QAOA