[PYTHON] Versuchen Sie, Distributed TensorFlow auf der Google Cloud Platform auszuführen

Übrigens habe ich den Mechanismus des verteilten Tensorflusses mit letztes Mal und vorherigen gelernt. Lassen Sie es uns endlich auf der Google Cloud Platform (GCP) ausführen. Wenn Sie viele vCPU-Instanzen erstellen, indem Sie den freien Frame von \ $ 300 einfügen, können Sie die Skalen hoher Feuerkraft auch für die Armen sehen. Das war meine Motivation.

Als ich es zum ersten Mal brach, stellte ich fest, dass das kostenlose Konto von GCP auf 8 vCPUs pro Region begrenzt war, also nicht so hoch. Dieses Mal wurde jeder Schnittstelle eine vCPU und dem Master-Server eine vCPU zugewiesen, sodass sie mit sechs vCPUs parallelisiert wird. Trotzdem ist es natürlich schneller.

Erstellen eines Docker-Images

Ich möchte es auf der Container Engine von GCP ausführen, also erst ein Docker-Image erstellen.

Erstellen Sie ein Container-Image tf \ _server für den Worker, das nur den neulich erstellten Tensorflow-Server enthält, und ein Container-Image tf \ _if für die Schnittstelle.

Zuerst hat tf \ _server gerade die Binärdatei von grpc \ _tensorflow \ _server nach / bin / des einfachen Ubuntu-Images kopiert. Ich habe es in docker.io/ashipong/tf_server aufgelistet.

Fügen wir etwas mehr tf \ _if hinzu. Kopieren Sie die Distributed Tensorflow-Version von whl, die mit bazel und erstellt wurde

$ sudo apt-get install python python-pip python-dev
$ pip install tensorflow-0.7.1-py2-none-any.whl

Ich konnte den Distributed-kompatiblen TensorFlow selbst installieren. Es wäre praktisch, wenn Sie mit einem Jupyter-Notebook darauf zugreifen könnten. Installieren Sie also auch Jupyter. Stellen Sie auch den Notebook-Server ein. Beschreiben Sie ~ / .jupyter / jupyter \ _notebook \ _config.py gemäß hier. Das Passwort lautet "Distributed_tensorflow". Da die IP nicht eingeschränkt und gefährlich ist, sollten diejenigen, die dieses Bild veröffentlichen, alle möglichen Vorsichtsmaßnahmen treffen, z. B. die IP der Zugriffsquelle einschränken und das Kennwort so schnell wie möglich neu schreiben.

こちらも同様にdockerhubに上げました。docker.io/ashipong/tf_ifです。

Praxis des verteilten TensorFlow unter Docker unter OSX

Lassen Sie uns überprüfen, ob es mit dem Docker-Image genauso funktioniert. Erstens gibt es nur einen GRPC-Server.

$ docker run -d -p 2222:2222 ashipong/tf_server /bin/grpc_tensorflow_server  --cluster_spec='master|localhost:2222' --job_name=master --task_index=0 &

Richten Sie einen Server mit und vom Client aus ein.

import tensorflow as tf
c = tf.constant("Hello, distributed TensorFlow on docker!")
sess = tf.Session("grpc://192.168.99.100:2222")
sess.run(c)

Zugriff wie. 192.168.99.100 ist die IP-Adresse der Docker-Maschine. Es hat richtig funktioniert.

Was ist als nächstes, wenn sich zwei Container auf dem Server befinden? Richten Sie einen Servercontainer wie unten gezeigt ein.

$ docker run -d -p 2222:2222 --name tf_master ashipong/tf_server /bin/grpc_tensorflow_server --cluster_spec='master|192.168.99.100:2222,slave|192.168.99.100:2223' --job_name=master --task_index=0 &
$ docker run -d -p 2223:2222 --name tf_slave ashipong/tf_server /bin/grpc_tensorflow_server --cluster_spec='master|192.168.99.100:2222,slave|192.168.99.100:2223' --job_name=slave --task_index=0 &

Beide Container öffnen einen Server an Port 2222. Auf der Hostseite werden wir eine Verbindung zu 2222,2223 herstellen. Da Container über die [Virtual Network Function] von Docker (http://qiita.com/Arturias/items/75828479c1f9eb8d43fa) verbunden werden können, werden die IP und der Port von der Hostseite aus in cluster_spec beschrieben. Nun, ich kann es nicht gut schreiben, aber ist es so?

docker.png

Auf diese Weise können Sie die Anzahl der Container in einer Umgebung, in der Docker verwendet werden kann, nacheinander erhöhen. Wie Sie aus der obigen Prozedur ersehen können, kann cluster_spec von jedem Container aus auf die IP und den Port aller Container zugreifen, aus denen der TensorFlow-Cluster besteht. Muss in Form geschrieben sein. Wenn Sie jeden Container auf einem anderen Computer ausführen möchten, müssen Sie ein Netzwerk einrichten, damit die auf verschiedenen Computern ausgeführten Container miteinander kommunizieren können.

Distributed MNIST

Wie erwartet steigt in dem Modell, das sich funktionell $ y = exp (x) $ annähert, das bis zu [vorherigem] verwendet wurde (http://qiita.com/ashitani/items/dbe76cb9194d60ead9de), die Last erheblich an, selbst wenn die Anzahl der Chargen erhöht wird. Da es so etwas nicht gibt, denke ich, wäre es besser, ein Modell mit etwas größeren Daten zu haben. Deshalb habe ich versucht, den Standard MNIST zu parallelisieren. Hier ist eine einzelne Version, [hier](https://github.com/ashitani/DistributedTensorFlowSample/blob/ master / gcp / mnist / mnist_distributed.py) ist die verteilte Version des Codes.

Grundsätzlich habe ich nur das angewendet, was ich in Letztes Mal auf MNIST getan habe. Ich habe viele Sammlungen, kann aber möglicherweise effizienter schreiben.

Zu GCP (Ergebnisse)

Lassen Sie es uns nun endlich mit GCP ausführen. Wir werden zuerst mit den Ergebnissen beginnen. Wie eingangs erwähnt, habe ich 8 Cluster mit 1 vCPU erstellt und if (Schnittstelle) bzw. 6 Master und Worker zugewiesen. Der Jobname und der Name des Clusters (Pod) sind identisch.

Die Komposition ist wie folgt, wenn sie in ein Bild geschrieben wird.

gcp.png

Infolgedessen sieht es für eine Single so aus.

# python mnist_single.py
step 00000, training accuracy 0.123, loss 1762.99, time 1.253 [sec/step]
step 00010, training accuracy 0.218, loss 1308.50, time 1.293 [sec/step]
step 00020, training accuracy 0.382, loss 1191.41, time 1.223 [sec/step]
step 00030, training accuracy 0.568, loss 1037.45, time 1.235 [sec/step]
step 00040, training accuracy 0.672, loss 939.53, time 1.352 [sec/step]
step 00050, training accuracy 0.742, loss 853.92, time 1.303 [sec/step]
...

Die verteilte Version sieht so aus. Übergeben Sie den Namen des Computers, auf dem der Master-Server ausgeführt wird, als Argument. Diesmal hat es den gleichen Namen wie master.

# python mnist_distributed.py master
step 00000, training accuracy 0.130, loss 1499.24, time 0.433 [sec/step]
step 00010, training accuracy 0.597, loss 839.25, time 0.405 [sec/step]
step 00020, training accuracy 0.828, loss 437.39, time 0.478 [sec/step]
step 00030, training accuracy 0.893, loss 220.44, time 0.438 [sec/step]
step 00040, training accuracy 0.902, loss 219.77, time 0.383 [sec/step]
step 00050, training accuracy 0.942, loss 131.92, time 0.370 [sec/step]
...

Es geht um 3x Geschwindigkeit. Da es 6 Personen gibt, kann es nicht 6-mal schneller sein, aber wenn es 3-mal schneller ist, ist es eine große Sache, weil es so anders ist, als das Flugzeug rot zu streichen und Ecken hinzuzufügen. Ein tieferes Netz zeigt seinen wahren Wert. Es scheint, dass die Dispersionsplatte für den Konvergenzgrad besser ist, aber dieses Mal habe ich nicht mit dem Keim der Zufallszahl übereinstimmend, also lasst uns einfach passieren.

Bei meinem Macbook Pro dauerte die Einzelversion übrigens etwa 0,8 Sekunden. Sie können es schneller als Macbook Pro machen, zumindest kostenlos. (Nun, die Geschwindigkeit der GCP hängt vom Grad der Überlastung ab.)

Zu GCP (Verfahren)

Notieren Sie sich nun die GCP-Schritte, die zu den oben genannten führen. Da Docker ein Cloud-Anfänger ist, der irgendwie angefangen hat, mache ich vielleicht dumme Sachen, aber bitte vergib mir.

Erstellen Sie zunächst ein Projekt aus dem GCP-Web. Danach ist es eine Operation vom Client.

Lassen Sie uns zuerst die ID in die Umgebungsvariable einfügen. Verknüpfen Sie Ihre Maschine mit Ihrem Projekt.

$ export PROJECT_ZONE=YOUR_ZONE
$ export PROJECT_ID=YOUR_PROJECT
$ gcloud config set project ${PROJECT_ID}
$ gcloud config set compute/zone ${PROJECT_ZONE}

Verschieben Sie als Nächstes das zuvor erstellte Container-Image in das Container-Register.

$ docker tag ashipong/tf_server asia.gcr.io/${PROJECT_ID}/tf_server
$ gcloud docker push asia.gcr.io/${PROJECT_ID}/tf_server
$ docker tag ashipong/tf_if asia.gcr.io/PROJECT_ID/tf_if
$ gcloud docker push asia.gcr.io/${PROJECT_ID}/tf_if

Erstellen Sie einen Containercluster in der Container Engine. Der Name ist tf.

$ gcloud container clusters create tf --num-nodes 8 --machine-type n1-standard-1
$ gcloud container clusters get-credentials tf

Erstellen Sie Pods mit 1 if, 1 Master und 6 Workern im Cluster. Der Pod ist eine master.yml-Datei wie die folgende

master.yml


apiVersion: v1
kind: Pod
metadata:
  name: master
  labels:
    app: tfserver
spec:
  containers:
    - name: master
      command: ["/bin/grpc_tensorflow_server"]
      args: ["--cluster_spec=master|master:2222,worker0|worker0:2222,worker1|worker1:2222,worker2|worker2:2222,worker3|worker3:2222,worker4|worker4:2222,worker5|worker5:2222,","--job_name=master","--task_index=0"]
      image: asia.gcr.io/${PROJECT_ID}/tf_server
      ports:
        - containerPort: 2222
  nodeSelector:
    app: master

Mach so etwas wie

$ kubectl create -f master.yml

Sie können es so machen, aber es ist schwierig, sich auf alle vorzubereiten, also habe ich [Generierungsskript] erstellt (https://github.com/ashitani/DistributedTensorFlowSample/blob/master/gcp/create_tf_servers.py). Infolgedessen war die Einstellung von nodeSelector nicht erforderlich, aber ich dachte, dass es besser wäre, Knoten und Pod während des Debuggens zuzuordnen, und beschriftete daher die Knotenseite und den zugehörigen Knoten und Pod. Dieser Bereich wird auch mit dem Generierungsskript erstellt.

Dieses Mal habe ich eine Kapsel mit einem anderen Namen erstellt: worker0, worker1, .... Es wäre cool, wenn der Worker auf einen Pod eingestellt und die Anzahl der Container während der Beobachtung der Last erhöht oder verringert werden könnte, aber der aktuelle grpc_tensorflow_server muss beim Start alle anderen Mitglieder im Argument cluster_spec beschreiben. Wenn Sie die Anzahl der Container später ändern, müssen Sie alle Server neu starten. Ich denke, dass ein ausgefeilterer Mechanismus von der Hauptfamilie oder irgendwo in diesem Bereich freigegeben wird.

Wie auch immer, ich werde den Knoten mit dem Skript der folgenden Generation beschriften und den Pod einrichten.

$ python ./create_tf_servers.py

Überprüfen Sie, ob der Pod generiert wurde.

$ kubectl get pods
NAME      READY     STATUS    RESTARTS   AGE
if        1/1       Running   0          1m
master    1/1       Running   0          1m
worker0   1/1       Running   0          1m
worker1   1/1       Running   0          1m
worker2   1/1       Running   0          1m
worker3   1/1       Running   0          1m
worker4   1/1       Running   0          1m
worker5   1/1       Running   0          1m

Das Letzte, worauf ich süchtig war, war die Namensauflösung zwischen den einzelnen Pods. Richten Sie normalerweise DNS ein? Diesmal habe ich aufgegeben und in Hosts geschrieben. Es ist das coolste.

Unten sehen Sie die den Pods zugewiesenen IPs.

$ kubectl get pods -o=yaml |grep podIP

Von hier aus habe ich vi direkt gestartet und bearbeitet. Es ist das coolste.

$ kubectl exec -it master vi /etc/hosts

Nachdem wir endlich fertig sind, melden Sie sich bei if an und führen Sie das Skript aus.

$ kubectl exec -it if /bin/bash
# apt-get install git
# cd home
# git clone https://github.com/ashitani/DistributedTensorFlowSample
# cd DistributedTensorFlowSample/gcp/mnist
# python mnist_distributed.py master

Bash scheint in ca. 5 Minuten eine Zeitüberschreitung zu haben. Ist es so etwas wie exec / bin / bash? Wenn if, jupyter notebook gestartet wird, denke ich, dass Sie den Dienst veröffentlichen und von dort aus eingeben sollten, aber diesmal wird er vergehen.

Wenn Sie ein GCP-Benutzer sind, werden Sie es wahrscheinlich intelligenter machen, aber ich habe es geschafft, es zum Laufen zu bringen, also werde ich damit aufhören. Mit 8 vCPUs ist es die Grenze der Motivation (lacht)

Schließlich

Damit ist die Post-Trilogie zu Ichiou Distributed Tensoflow abgeschlossen.

Dieses Mal habe ich einen Cluster auf GCP erstellt und versucht, die datenparallele Version von MNIST auszuführen. Leider konnte ich die explosive Geschwindigkeit mit der kostenlosen Stufe nicht so sehr erleben, aber wenn ich das Geld hätte (lacht), könnte ich die Anzahl der Instanzen erhöhen und Spaß haben.

Wenn die Geschwindigkeit ungefähr x10 beträgt, reicht meiner Meinung nach eine GPU aus. Wenn Sie jedoch x100 oder einen schnelleren Bereich anstreben, müssen Sie GPU und Cluster zusammen verwenden. Ich kann nicht auf die GPU-Instanz von GCP warten.

Um es noch schneller zu machen, wäre die Hardware und die unmittelbare Zukunft FPGA. Neulich gab es eine großartige Aussage von Google Bitte machen Sie es billiger, weil Sie die Zuverlässigkeit des Speichers verringern können. Um es extrem auszudrücken, ich denke, es bedeutet, die Qualitätskontrolle der Lagerfabrik vor Ort zu übernehmen. Ich denke, dass einer der Gründe, warum FPGAs teuer sind, die Elementausbeute ist, aber da das tiefe neuronale Netz oft so konfiguriert ist, dass es gegen lokale Unterbrechungen resistent ist, wird es als FPGA für tiefes Lernen bezeichnet, das extrem billig ist, anstatt die Ausbeute zu senken. Wird es nicht bald auf den Markt kommen? Ich erwarte es ohne Erlaubnis.

Recommended Posts

Versuchen Sie, Distributed TensorFlow auf der Google Cloud Platform auszuführen
Versuchen Sie, Tensorflow auf Docker + Anaconda auszuführen
Versuchen Sie es mit verteiltem Tensorfluss
Anzeigen von Wettervorhersagen auf M5Stack + Google Cloud Platform
Probieren Sie StyleGAN mit Google Colaboratory aus
Erstellen Sie eine Ubuntu-Python-Entwicklungsumgebung auf der Google Cloud Platform
Versuchen Sie, Jupyter Notebook auf einem Mac auszuführen
Versuchen Sie Daten parallel zu Distributed TensorFlow
Versuchen Sie es mit Bash unter Windows 10 2 (TensorFlow-Installation)
Versuchen Sie, die PlaidML-Bildbeurteilung auf einem Mac auszuführen
Versuchen Sie, Kobukis 3D-Simulator auf ROS auszuführen
Versuchen Sie, Google Chrome mit Python und Selenium auszuführen
Ich habe versucht, YOLO v3 mit Google Colab auszuführen
[GoogleCloudPlatform] Verwenden Sie die Google Cloud-API mit der API-Clientbibliothek
Versuchen Sie, Pyston 0.1 auszuführen
Ausführung von MINST in TensorFlow 2.0 und Visualisierung in TensorBoard (Version 2019)
Herstellen einer Verbindung zu Cloud SQL PostgreSQL auf der Google Cloud Platform aus einer lokalen Umgebung mit Java