Help us understand the problem. What is going on with this article?

TensorFlowOnSparkをDocker runしてみた

More than 1 year has passed since last update.

TensorFlowOnSparkをDocker runしてみた

TensorFlowOnSparkのスタンドアローン版をDockerイメージにしてみました。

TensorFlowOnSparkはTensorFlowをSpark上で稼働させられるようにしたもので、Yahooが先週くらいに発表していました(2017/02/13)。
https://github.com/yahoo/TensorFlowOnSpark/wiki

出た当日にスタンドアローン版の構築を試してみました。
http://qiita.com/cvusk/items/39a1861715e21b1dc191
ついでにDockerfileにしましたのが今回です。
練習がてら。

TensorFlowOnSpark on Docker

ホストOSにはCentOS7.3を使っています。
Dockerのインストール、起動以外は以下のとおりです。

sudo yum -y install docker
sudo systemctl start docker
sudo systemctl enable docker

Dockerfileを作るディレクトリを用意します。

sudo su -
mkdir -p /opt/tfos
cd /opt/tfos

今回はUbuntuイメージを使います。
https://hub.docker.com/_/ubuntu/
事前にpullしておきます。

docker pull ubuntu

Dockerfileを作る

/opt/tfos/配下にDockerfileを作成し、以下を記入して保存します。
(2017/02/23 修正しました。)

FROM ubuntu
MAINTAINER cvusk

# insert hostname on environmental variable
ENV HOSTNAME tensorflow.spark

# install prerequisites
RUN apt-get -y update
RUN apt-get -y upgrade
RUN apt-get -y install apt-utils
RUN apt-get -y install software-properties-common python-software-properties
RUN add-apt-repository ppa:openjdk-r/ppa
RUN apt-get -y update
RUN apt-get -y install wget curl zip unzip vim openjdk-7-jre openjdk-7-jdk git python-pip python-dev python-virtualenv
ENV JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64

# git clone tensorflowonspark.git
WORKDIR /opt/
RUN git clone --recurse-submodules https://github.com/yahoo/TensorFlowOnSpark.git

WORKDIR /opt/TensorFlowOnSpark/
RUN git submodule init
RUN git submodule update --force
RUN git submodule foreach --recursive git clean -dfx

# environmental variable for tensorflowonspark home
ENV TFoS_HOME=/opt/TensorFlowOnSpark

WORKDIR /opt/TensorFlowOnSpark/src/
RUN zip -r /opt/TensorFlowOnSpark/tfspark.zip /opt/TensorFlowOnSpark/src/*
WORKDIR /opt/TensorFlowOnSpark/

# setup spark
RUN sh /opt/TensorFlowOnSpark/scripts/local-setup-spark.sh
ENV SPARK_HOME=/opt/TensorFlowOnSpark/spark-1.6.0-bin-hadoop2.6
ENV PATH=/opt/TensorFlowOnSpark/src:${PATH}
ENV PATH=${SPARK_HOME}/bin:${PATH}
ENV PYTHONPATH=/opt/TensorFlowOnSpark/src


# install tensorflow, jupyter and py4j
RUN pip install pip --upgrade
RUN python -m pip install tensorflow
RUN pip install jupyter jupyter[notebook]
RUN pip install py4j


# download mnist data
RUN mkdir /opt/TensorFlowOnSpark/mnist
WORKDIR /opt/TensorFlowOnSpark/mnist/
RUN curl -O "http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz"
RUN curl -O "http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz"
RUN curl -O "http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz"
RUN curl -O "http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz"


# create shellscript for starting spark standalone cluster
RUN echo '${SPARK_HOME}/sbin/start-master.sh' >> ${TFoS_HOME}/spark_cluster.sh
RUN echo 'MASTER=spark://${HOSTNAME}:7077' >> ${TFoS_HOME}/spark_cluster.sh
RUN echo 'SPARK_WORKER_INSTANCES=2' >> ${TFoS_HOME}/spark_cluster.sh
RUN echo 'CORES_PER_WORKER=1' >> ${TFoS_HOME}/spark_cluster.sh
RUN echo 'TOTAL_CORES=$((${CORES_PER_WORKER}*${SPARK_WORKER_INSTANCES}))' >> ${TFoS_HOME}/spark_cluster.sh
RUN echo '${SPARK_HOME}/sbin/start-slave.sh -c $CORES_PER_WORKER -m 3G ${MASTER}' >> ${TFoS_HOME}/spark_cluster.sh
RUN echo '${SPARK_HOME}/sbin/start-slave.sh -c $CORES_PER_WORKER -m 3G ${MASTER}' >> ${TFoS_HOME}/spark_cluster.sh


ENV MASTER=spark://${HOSTNAME}:7077
ENV SPARK_WORKER_INSTANCES=2
ENV CORES_PER_WORKER=1
ENV TOTAL_CORES=2


# create shellscript for pyspark on jupyter and mnist data
WORKDIR /opt/TensorFlowOnSpark/

RUN echo "PYSPARK_DRIVER_PYTHON=\"jupyter\" PYSPARK_DRIVER_PYTHON_OPTS=\"notebook --no-browser --ip=* --NotebookApp.token=''\" pyspark  --master ${MASTER} --conf spark.cores.max=${TOTAL_CORES} --conf spark.task.cpus=${CORES_PER_WORKER} --py-files ${TFoS_HOME}/tfspark.zip,${TFoS_HOME}/examples/mnist/spark/mnist_dist.py --conf spark.executorEnv.JAVA_HOME=\"$JAVA_HOME\"" > ${TFoS_HOME}/pyspark_notebook.sh

RUN echo "${SPARK_HOME}/bin/spark-submit --master ${MASTER} ${TFoS_HOME}/examples/mnist/mnist_data_setup.py --output examples/mnist/csv --format csv" > ${TFoS_HOME}/mnist_data_setup.sh


やっていることとして、TensorFlowOnSparkスタンドアローン版の構築手順をDocker用に書き換えています。
https://github.com/yahoo/TensorFlowOnSpark/wiki/GetStarted_standalone

spark master、slaveの起動をシェルスクリプトにしておきたかったので、その変数のために環境変数にHOSTNAME=tensorflow.sparkを定義しています。
もうちょいかっこいい方法でホスト名を使いたいのですが・・・。

これをビルドします。

cd /opt/tfos
docker build -t tfos/tfos .

こんな感じにできあがります。

docker images

2017-02-22.PNG

動かしてみます

Dockerイメージができあがったら以下でrunします。

docker run -it -p 8889:8888 -h tensorflow.spark 5db5add35c10 /bin/bash

ポート番号は8889:8888(ホストOSのポート:コンテナのポート)で公開します。これはpyspark(Jupyter Notebook)用です。
ホスト名にtensorflow.sparkを指定しますが、これはDockerfileに書いたものを使っています。

2017-02-22_3.PNG

はい、起動しました。

/opt/TensorFlowOnSpark配下のspark_cluster.shを実行すると、このDockerコンテナがspark master兼slaveになります。
なお、slaveは2インスタンス起動しています。

cd /opt/TensorFlowOnSpark
sh ./spark_cluster.sh

2017-02-22_4.PNG

/opt/TensorFlowOnSpark/配下にMNISTのデータセットアップ用シェルスクリプトを用意しています。
これを実行して、MNISTのトレーニングとテストデータを生成します。

cd /opt/TensorFlowOnSpark/
sh ./mnist_data_setup.sh

/opt/TensorFlowOnSpark/配下にpysparkの起動用シェルスクリプトとしてpyspark_notebook.shを配置しています。

これを実行すると、pysparkがJupyter Notebookで起動します。

cd /opt/TensorFlowOnSpark/
sh ./pyspark_notebook.sh

2017-02-22_5.PNG

起動できました。
ブラウザで http://<ホストOSのIPアドレス>:8889 にアクセスします。

2017-02-22_6.PNG

このように、Jupyter Notebookにアクセスできます。

最後に・・・できなかったこと(誰か教えてくださいm(_ _)m) → 解決しました。

ここでMNISTのデモ用に用意されている TFOS_spark_demo.ipynb を実行したいのですが、com.yahoo.ml.tf がインポートできなくてエラーになります。
(T_T)

ググっても情報が出てきませんし、どなたか解決策をご存じないでしょうか・・・?
なんか半煮えな終わり方ですが、ひとまずTensorFlowOnSparkOnDockerを構築できました(?)。

解決しました。
PYTHONPATHの指定が足りなかったようです。
Dockerfileに ENV PYTHONPATH=/opt/TensorFlowOnSpark/src 追加しました。

これでMNISTのデモ@Jupyter Notebookも成功します。

2017-02-22_8.PNG

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away