Distributed TensorFlow a été publié (https://github.com/tensorflow/tensorflow/blob/master/tensorflow/core/distributed_runtime/README.md). Explication de la personne à l'intérieur est facile à comprendre, mais c'est un mécanisme qui prend en charge les opérations parallèles dans l'environnement distribué de TensorFlow.
Il est censé créer beaucoup d'images Docker et l'utiliser, mais pour moi au fond du calcul à basse température, pour le moment, j'exécute le serveur sur Ubuntu 14.04 (64 bits) de mon PC de bureau à la maison et le frappe depuis le MacBook. Je vais essayer.
Dans mon environnement domestique, le PC de bureau a un processeur plus petit et pas de GPU, donc cela ne vaut pas la peine en pratique, mais c'est une pratique.
Pour le moment (28 février 2016), vous devez créer à partir des sources. Suivez TensorFlow Official et essayez de la construction de l'environnement à la construction.
Tout d'abord, installez 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 sera installé dans ~ / bin, alors passez-le. Ensuite, installez les packages dépendants autres que bazel.
$ sudo apt-get install python-numpy swig python-dev
Supprimez TensorFlow lui-même de git et générez le serveur.
$ 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
Si vous oubliez "--jobs 2", la compilation a échoué en raison du manque de ressources.
Il semble qu'il soit nécessaire de créer TensorFlow lui-même qui prend en charge gRPC à partir de la source si nécessaire. Ce n'est pas nécessaire sur le serveur, mais nous allons le construire pour vérifier le fonctionnement. Sur Ubuntu 14.04 (64 bits), c'est comme indiqué.
$ 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
Il faudra longtemps. .. Eh bien, c'est un PC faible, donc il ne peut pas être aidé.
Démarrez le serveur sur le PC de bureau et essayez de frapper le serveur à partir du client du PC de bureau. Tutoriel C'est vrai.
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!'
J? ai compris.
Vient ensuite du PC portable. Il semble que le côté client doit également être reconstruit à partir des sources.
La procédure de construction est omise. Puisqu'il s'agit d'OSX, je pense qu'il devrait être géré selon ici. Dans mon cas, j'ai eu l'erreur "Je ne connais pas l'option de l'éditeur de liens telle que -Bsymbolic!", J'ai donc supprimé l'option du fichier BUILD à cet emplacement et elle est passée.
De plus, si vous importez un flux tensoriel après avoir installé la roue créée avec pip
ImportError: No module named core.framework.graph_pb2
Il est dit que. Après avoir étudié diverses choses, il est facile de l'éviter avec virtualenv, alors je l'ai essayé,
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
Il est désormais disponible au format. Huh. ..
J'ai également essayé de construire le serveur, mais le lien n'a pas réussi à cause de l'erreur suivante (Ajout: à partir du 3/4/2016, j'ai essayé git en tirant la dernière version et la construction est passée)
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
Maintenant, appelons desktop (home.local) depuis note.
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!'
Ça a marché. Vous pouvez désormais échanger des graphiques sur le réseau.
Eh bien, je vais l'utiliser.
Version TensorFlow avec le même traitement que chainer et apprentissage profond appris par approximation de fonction que j'ai téléchargé sur Qiita l'autre jour. (/ashitani/jupyter_examples/blob/master/tensorflow.ipynb) Parallélisons. Ce n'est pas une grosse charge au départ, donc ça ne sert à rien de le distribuer, mais c'est une pratique.
La configuration du cluster se compose de deux serveurs de paramètres (ps) et d'un serveur maître (maître) pour le travail.
L'argument de démarrage du serveur semble donner la configuration du cluster comme --cluster \ _spec et le nom du serveur et le numéro de tâche comme --job \ _name, --task \ _index.
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 &
D'après ce que je peux voir dans la documentation et l'aide, je devrais être capable de distinguer par job \ _name = ps, task \ _index = 0,1, mais ps1 que je veux attribuer au port 2224 échoue en essayant d'obtenir 2223, donc ps est inévitable. Renommé en ps \ _.
Vous disposez désormais d'un cluster de trois serveurs. C'est une mauvaise configuration donc ils fonctionnent tous sur la même machine, mais il semble facile de les affecter à différents conteneurs.
Séparez le serveur de paramètres avec un poids de $ W $ et un biais de $ b $ (qu'il soit significatif ou non). Le serveur maître est responsable de la représentation graphique des sessions et des erreurs.
Cela ressemble à ceci lorsque vous tracez la configuration de la machine et la division des serveurs dans le graphique.
Le code côté client ressemble à ceci:
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})
Le résultat était beaucoup plus lent que de le déplacer seul (rires). Sans surprise, la bande passante du réseau et la machine elle-même sont lentes.
Le nom du travail est juste pour la distinction, et il semble que ps n'est pas un serveur de paramètres. De même, n'importe qui peut lancer la session sur le serveur. Eh bien, il est généralement attribué en fonction du type de ressource, il serait donc pratique de pouvoir distinguer par son nom.
Je voulais vraiment essayer la parallélisation des données, mais ce n'est malheureusement pas le cas. Dans plusieurs sessions, par exemple, il semble que vous divisez le lot en petits morceaux et laissez chaque serveur apprendre, collecter les différentiels des paramètres sortis par chaque serveur et mettre à jour les paramètres en moyenne.
Cependant, j'ai eu une idée pour le moment. Ce qui est génial, c'est que tout le code est complet du côté client uniquement. C'est un peu gênant de former un cluster, mais j'attends cela avec impatience car j'envisage un mécanisme qui peut être facilement géré à l'aide de Kubernetes. Cela n'a rien à voir avec moi, qui a une faible puissance de feu (rires)
La construction a pris beaucoup de temps. J'étais particulièrement accro à la version OSX. Eh bien, l'image officielle de Docker sera bientôt créée et le côté client sera inclus dans la version binaire.
Jusqu'à présent, dépenser de l'argent sur les GPU était la norme pour accélérer l'apprentissage, mais vous passez au stade de combien d'argent vous pouvez investir dans l'environnement de cloud computing.
Quiconque a un passe-temps comme moi ne peut pas se le permettre, alors je chercherai un GPU bon marché. J'attends avec impatience le jour où une planche ou une boîte avec beaucoup d'Altera, qui est devenue moins chère, sera sur le marché.
J'ai écrit une suite.
Recommended Posts