Zuvor habe ich Dist-keras auf Docker gestellt, um ein skalierbares Deep Learning zu erstellen. http://qiita.com/cvusk/items/3e6c3bade8c0e1c0d9bf
Der Reflexionspunkt zu dieser Zeit war, dass die Leistung nicht herauskam, aber nach sorgfältiger Überprüfung scheint es, dass die Parametereinstellungen falsch waren. Nachdem ich darüber nachgedacht hatte, versuchte ich verschiedene Dinge.
Eine Beschreibung von Dist-Keras selbst finden Sie im vorherigen Beitrag. Der Punkt ist jedoch, dass Keras auf einem Spark-Cluster ausgeführt wird. Ich habe dies zu einem Docker-Bild gemacht, um das Skalieren zu vereinfachen.
Die Docker-Datei ist auf GitHub verfügbar. https://github.com/shibuiwilliam/distkeras-docker
Dieses Mal möchte ich Dist-Keras auf Docker auf einem einzelnen Host und mehreren Hosts überprüfen, um die Leistung zu verbessern. Beim letzten Mal habe ich mehrere Container auf einem einzelnen Host gestartet, um einen Spark-Cluster zu erstellen. Dieses Mal werde ich das Muster erhöhen.
Es ist MNIST, das läuft. Das MNIST-Lernprogramm wird angepasst und verwendet, wie es von dist-keras bereitgestellt wird.
Validieren Sie auf einem einzelnen Host und mehreren Hosts. In jedem Fall lautet die Konfiguration Spark Master + Worker, und die Anzahl der Mitarbeiter und die Arbeiterspezifikationen werden angepasst. Bei Multi-Hosts gibt es zwei Server. Der Host verwendet m4.xlarge von 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 |
Das Bild für einen einzelnen Host sieht folgendermaßen aus. Die Anzahl der Docker-Container schwankt abhängig von den Überprüfungsbedingungen.
Starten Sie bei einem einzelnen Host mehrere Docker-Container auf demselben Host.
# 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
Spark Master startet Spark Master und Worker und Spark Slave startet nur Worker.
# 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}
Passen Sie dann das MNIST-Programm mit Spark Master an. Der MNIST-Beispielcode wird von Dist-Keras bereitgestellt. Das Verzeichnis lautet / opt / dist-keras / examples und enthält die folgenden Beispieldaten und -programme.
[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
Kopieren Sie die Originaldatei, sichern Sie sie und übernehmen Sie die folgenden Änderungen.
cp mnist.py mnist.py.bk
Fügen Sie am Anfang Folgendes hinzu.
from pyspark.sql import SparkSession
Ändern Sie die Spark-Parameter für diese Umgebung. Die Absicht der Änderung ist wie folgt.
# 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
Ändern Sie den Arbeitsspeicher des Arbeiters entsprechend den Validierungskriterien.
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");
Sie können es dann auf dem Spark Master mit python mnist.py
ausführen.
Die Multi-Host-Konfiguration sieht folgendermaßen aus.
Für Multi-Host muss der Docker-Container über ein Overlay-Netzwerk verbunden sein. Weitere Informationen zum Erstellen eines Docker-Netzwerks mit mehreren Hosts finden Sie im Folgenden. http://knowledge.sakura.ad.jp/knowledge/4786/ http://christina04.hatenablog.com/entry/2016/05/16/065853
Ich werde hier nur meine Prozedur schreiben. Bereiten Sie Host1 und Host2 in EC2 vor, installieren Sie etcd auf Host1 und starten Sie es.
yum -y install etcd
vi /etc/etcd/etcd.conf
systemctl enable etcd
systemctl start etcd
Fügen Sie als Nächstes die Docker-Netzwerkeinstellungen zu Host1 und Host2 hinzu.
# 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"}
Nachdem die Netzwerkverbindung zwischen Dockern möglich ist, erstellen Sie ein Docker-Netzwerk mit host1. Erstellen Sie hier ein Docker-Netzwerk mit dem Namen test1 im Subnetz 10.0.1.0/24.
# for host1
docker network create --subnet=10.0.1.0/24 -d overlay test1
Führen Sie abschließend "Docker-Netzwerk ls" aus und es ist in Ordnung, wenn das test1-Netzwerk hinzugefügt wird.
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
Fügen Sie dann dem test1-Netzwerk einen Docker-Container hinzu. Stellen wir einen Docker-Container für Host1 und Host2 bereit.
# 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
Sie haben jetzt zwei Docker-Container im test1-Netzwerk mit mehreren Hosts bereitgestellt.
Starten Sie danach den Spark-Master und den Spark-Worker auf dieselbe Weise wie für einen einzelnen Host, bearbeiten Sie MNIST.py und führen Sie python mnist.py
aus.
Dies ist das Ergebnis der Überprüfung der Leistung jeder Konfiguration. Dieses Mal messen wir die Zeit, die für die Fertigstellung benötigt wird (Sekunden).
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 |
Mit Multi-Host ist die Leistung besser. Ich denke, dass die Menge an freien Ressourcen einfach einen Unterschied in der Leistung macht. Verifikation 2 und Verifikation 4 haben dieselben Einstellungen für die Docker-Containerkonfiguration und die von den Mitarbeitern verwendeten Ressourcen, es besteht jedoch immer noch ein Unterschied von 600 Sekunden. Der Vergleich von Validierung 1 und Validierung 2 oder Validierung 4 und Validierung 5 und Validierung 6 scheint keinen großen Unterschied in der Anzahl der Spark-Mitarbeiter und der Menge der Ressourcen selbst zu machen. Wenn Sie die Leistung erheblich verbessern möchten, ist es besser, sie gehorsam für mehrere Hosts zu verwenden.
[26.05.2017 Nachtrag] Mit Kubernetes geclustert. http://qiita.com/cvusk/items/42a5ffd4e3228963234d
Recommended Posts