Distributed TensorFlow wurde veröffentlicht (https://github.com/tensorflow/tensorflow/blob/master/tensorflow/core/distributed_runtime/README.md). Erklärung der Person im Inneren ist leicht zu verstehen, unterstützt jedoch parallele Operationen in der verteilten Umgebung von TensorFlow.
Es soll eine Menge Docker-Images erstellen und verwenden, aber für mich, der ich mich mit Low-Heat-Computing beschäftige, starte ich den Server vorerst auf Ubuntu 14.04 (64 Bit) meines Heim-Desktop-PCs und rufe ihn vom MacBook aus auf. Ich werde versuchen.
In meiner häuslichen Umgebung hat der Desktop-PC eine kleinere CPU und keine GPU, daher lohnt es sich in der Praxis nicht, aber es ist eine Übung.
Zu diesem Zeitpunkt (28. Februar 2016) müssen Sie aus dem Quellcode erstellen. Folgen Sie TensorFlow Official und versuchen Sie es von der Erstellung der Umgebung bis zur Erstellung.
Installieren Sie zuerst Bazel.
$ sudo add-apt-repository ppa:webupd8team/java
$ sudo apt-get update
$ sudo apt-get install oracle-java8-installer
$ sudo apt-get install pkg-config zip g++ zlib1g-dev unzip
$ wget https://github.com/bazelbuild/bazel/releases/download/0.2.0/bazel-0.2.0-installer-linux-x86_64.sh
$ chmod +x ./bazel-0.2.0-installer-linux-x86_64.sh
$ ./bazel-0.2.0-installer-linux-x86_64.sh --user
Bazel wird in ~ / bin installiert, also geben Sie es durch. Installieren Sie als Nächstes andere abhängige Pakete als bazel.
$ sudo apt-get install python-numpy swig python-dev
Löschen Sie TensorFlow selbst aus git und erstellen Sie den Server.
$ git clone --recurse-submodules https://github.com/tensorflow/tensorflow
$ cd tensorflow
$ ./configure
$ bazel build --jobs 2 -c opt //tensorflow/core/distributed_runtime/rpc:grpc_tensorflow_server
Wenn Sie "--jobs 2" vergessen, ist der Build aufgrund fehlender Ressourcen fehlgeschlagen.
Es scheint notwendig zu sein, TensorFlow selbst zu erstellen, das gRPC bei Bedarf von der Quelle unterstützt. Es ist auf dem Server nicht erforderlich, aber wir werden es erstellen, um den Vorgang zu überprüfen. Unter Ubuntu 14.04 (64 Bit) entspricht dies den Anweisungen.
$ sudo pip install wheel
$ bazel build --jobs 2 -c opt //tensorflow/tools/pip_package:build_pip_package
$ bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg
$ sudo pip install /tmp/tensorflow_pkg/tensorflow-0.7.1-py2-none-any.whl
Es wird lange dauern. .. Nun, es ist ein schwacher PC, also kann man ihm nicht helfen.
Starten Sie den Server auf dem Desktop-PC und versuchen Sie, den Server vom Client des Desktop-PCs aus zu erreichen. Tutorial Richtig.
bash@desktop(server)
$ bazel-bin/tensorflow/core/distributed_runtime/rpc/grpc_tensorflow_server --cluster_spec='local|localhost:2222' --job_name=local --task_index=0 &
bash@desktop(client)
$ python
>>> import tensorflow as tf
>>> c = tf.constant("Hello, distributed TensorFlow!")
>>> sess = tf.Session("grpc://localhost:2222")
>>> sess.run(c)
'Hello, distributed TensorFlow!'
Ich hab es geschafft.
Als nächstes kommt vom Notebook-PC. Es scheint, dass die Client-Seite auch von der Quelle neu erstellt werden muss.
Die Erstellungsprozedur wird weggelassen. Da es sich um OSX handelt, sollte es meiner Meinung nach gemäß [hier] behandelt werden (https://www.tensorflow.org/versions/r0.7/get_started/os_setup.html#installation-for-mac-os-x). In meinem Fall wurde die Fehlermeldung "Ich kenne die Linker-Option wie -Bsymbolic nicht!" Angezeigt. Daher habe ich die Option aus der BUILD-Datei an diesem Speicherort entfernt und sie wurde übergeben.
Wenn Sie nach dem Einbau des erstellten Rads mit pip einen Tensorfluss importieren
ImportError: No module named core.framework.graph_pb2
Es wurde gesagt, dass. Nachdem ich verschiedene Dinge untersucht habe, ist es einfach, sie mit virtualenv zu vermeiden, also habe ich es versucht,
bash@note(client)
$ virtualenv -p /usr/local/bin/python distributed_tensorflow
$ . distributed_tensorflow/bin/activate
$ pip install /tmp/tensorflow_pkg/tensorflow-0.7.1-py2-none-any.whl
Es ist jetzt in verfügbar. Huh. ..
Ich habe auch versucht, den Server zu erstellen, aber der Link wurde aufgrund des folgenden Fehlers nicht übergeben.
duplicate symbol __ZNK10tensorflow17BuildGraphOptions11DebugStringEv in:
bazel-out/local_darwin-opt/bin/tensorflow/core/distributed_runtime/libsimple_graph_execution_state.a(simple_graph_execution_state.o) bazel-out/local_darwin-opt/bin/tensorflow/core/distributed_runtime/libbuild_graph_options.a(build_graph_options.o)
ld: 1 duplicate symbol for architecture x86_64
Rufen wir nun den Desktop (home.local) von note aus auf.
bash@note(client)
$ python
>>> import tensorflow as tf
>>> c = tf.constant("Hello, distributed TensorFlow!")
>>> sess = tf.Session("grpc://home.local:2222")
>>> sess.run(c)
'Hello, distributed TensorFlow!'
Es funktionierte. Jetzt können Sie Diagramme über das Netzwerk austauschen.
Nun, ich werde es benutzen.
TensorFlow-Version mit der gleichen Verarbeitung wie Chainer und Deep Learning, die durch Funktionsnäherung gelernt wurden, die ich neulich auf Qiita hochgeladen habe. (/ashitani/jupyter_examples/blob/master/tensorflow.ipynb) Lassen Sie uns parallelisieren. Es ist zunächst keine große Last, daher macht es keinen Sinn, sie zu verteilen, aber es ist eine Übung.
Die Clusterkonfiguration besteht aus zwei Parameterservern (ps) und einem Master-Server (Master) für die Arbeit.
Das Serverstartargument scheint die Clusterkonfiguration als --cluster \ _spec und den Servernamen und die Aufgabennummer als --job \ _name, --task \ _index anzugeben.
grpc_tensorflow_server --cluster_spec='master|localhost:2222,ps|localhost:2223,ps_|localhost:2224' --job_name=master --task_index=0 &
grpc_tensorflow_server --cluster_spec='master|localhost:2222,ps|localhost:2223,ps_|localhost:2224' --job_name=ps --task_index=0 &
grpc_tensorflow_server --cluster_spec='master|localhost:2222,ps|localhost:2223,ps_|localhost:2224' --job_name=ps_ --task_index=0 &
Soweit ich aus der Dokumentation und Hilfe ersehen kann, sollte ich in der Lage sein, nach Job \ _name = ps, Task \ _index = 0,1 zu unterscheiden, aber ps1, das ich Port 2224 zuweisen möchte, schlägt fehl, wenn versucht wird, 2223 abzurufen, sodass ps unvermeidbar ist Umbenannt in ps \ _.
Jetzt haben Sie einen Cluster von drei Servern. Da die Konfiguration schlecht ist, werden sie alle auf demselben Computer ausgeführt, aber es scheint einfach, sie verschiedenen Containern zuzuweisen.
Trennen Sie den Parameterserver mit einem Gewicht von $ W $ und einem Bias von $ b $ (ob sinnvoll oder nicht). Der Master-Server ist für die grafische Darstellung von Sitzungen und Fehlern verantwortlich.
So sieht es aus, wenn Sie die Maschinenkonfiguration und die Aufteilung der Server in der Grafik darstellen.
Der Code auf der Clientseite sieht folgendermaßen aus:
python@note(client)
import tensorflow as tf
import numpy as np
def get_batch(n):
x = np.random.random(n)
y = np.exp(x)
return x,y
def leaky_relu(x,alpha=0.2):
return tf.maximum(alpha*x,x)
x_ = tf.placeholder(tf.float32, shape=[None, 1])
t_ = tf.placeholder(tf.float32, shape=[None, 1])
with tf.device("/job:ps/task:0"):
W1 = tf.Variable(tf.zeros([1,16]))
W2 = tf.Variable(tf.zeros([16,32]))
W3 = tf.Variable(tf.zeros([32,1]))
with tf.device("/job:ps_/task:0"):
b1 = tf.Variable(tf.zeros([16]))
b2 = tf.Variable(tf.zeros([32]))
b3 = tf.Variable(tf.zeros([1]))
with tf.device("/job:master/task:0"):
h1 = leaky_relu(tf.matmul(x_,W1)+b1)
h2 = leaky_relu(tf.matmul(h1,W2)+b2)
y = leaky_relu(tf.matmul(h2,W3)+b3)
e = tf.nn.l2_loss(y-t_)
opt=tf.train.AdamOptimizer()
train_step=opt.minimize(e)
with tf.Session("grpc://home.local:2222") as sess:
sess.run(tf.initialize_all_variables())
for i in range(10000):
x0,t0 = get_batch(100)
x = x0.astype(np.float32).reshape(100,1)
t = t0.astype(np.float32).reshape(100,1)
sess.run(train_step,feed_dict={x_: x, t_:t})
if i%100==0:
print "loss,", sess.run(e,feed_dict={x_: x, t_:t})
Das Ergebnis war viel langsamer als das alleinige Bewegen (lacht). Es überrascht nicht, dass die Netzwerkbandbreite und die Maschine selbst langsam sind.
Der Name des Jobs dient nur zur Unterscheidung, und es scheint, dass ps kein Parameterserver ist. Ebenso kann jeder die Sitzung auf den Server werfen. Nun, normalerweise wird es nach dem Ressourcentyp zugewiesen, daher wäre es praktisch, nach Namen unterscheiden zu können.
Ich wollte unbedingt Datenparallelisierung ausprobieren, aber leider nicht. In mehreren Sitzungen scheint es beispielsweise so zu sein, dass Sie den Stapel in kleine Teile aufteilen und jeden Server lernen lassen, die Unterschiede der von jedem Server ausgegebenen Parameter erfassen, mitteln und die Parameter aktualisieren.
Allerdings habe ich vorerst ein Gefühl bekommen. Was großartig ist, ist, dass der gesamte Code nur auf der Clientseite vollständig ist. Es ist etwas mühsam, einen Cluster zu bilden, aber ich freue mich darauf, weil ich über einen Mechanismus nachdenke, der mit Kubernetes einfach verwaltet werden kann. Es hat nichts mit mir zu tun, der wenig Feuerkraft hat (lacht)
Der Bau hat viel Zeit in Anspruch genommen. Ich war besonders süchtig nach der OSX-Version. Nun, das offizielle Docker-Image wird in Kürze erstellt und die Client-Seite wird in die Binärversion aufgenommen.
Bisher war das Ausgeben von Geld für GPUs der Hauptstrom, um das Lernen zu beschleunigen. Sie befinden sich jedoch in einem Stadium, in dem Sie feststellen können, wie viel Geld Sie in die Cloud-Computing-Umgebung stecken können.
Jeder, der ein Hobby wie ich hat, kann es sich nicht leisten, also suche ich nach einer billigen GPU. Ich freue mich auf den Tag, an dem das Board oder die Box mit viel Altera, das billiger geworden ist, auf den Markt kommt.
Ich habe eine Fortsetzung geschrieben.
Recommended Posts