From 52373613c2cb8520c3cf9d9bbccb58e560a98af3 Mon Sep 17 00:00:00 2001 From: Beth Dean Date: Mon, 3 Dec 2018 11:09:04 -0800 Subject: [PATCH 01/26] adding dlaas benchmarking tutorial --- .../tutorials/dlaas-benchmarks.rst | 182 ++++++++++++++++++ 1 file changed, 182 insertions(+) create mode 100644 source/clear-linux/tutorials/dlaas-benchmarks.rst diff --git a/source/clear-linux/tutorials/dlaas-benchmarks.rst b/source/clear-linux/tutorials/dlaas-benchmarks.rst new file mode 100644 index 00000000..0ff9e1a7 --- /dev/null +++ b/source/clear-linux/tutorials/dlaas-benchmarks.rst @@ -0,0 +1,182 @@ +.. _dlaas-benchmarks: + +Deep Learning as a Service Benchmarking +####################################### + +This tutorial details the steps needed to run benchmarking workloads in |CL-ATTR| using TensorFlow and on Kubeflow with the |CL| Deep Learning as a Service Stack. + +Prerequisites +============= + +For this tutorial, we'll be using a system that has |CL| installed using the :ref:`bare-metal-install` getting started guide. It is possible to follow these instructions on other OS systems but we're limiting the scope of this document to |CL|. + +Ensure you have the "containers-basic" bundle installed, this will provide Docker, which is required for TensorFlow benchmarking. Use the :command:`swupd` utility with the `bundle-list` option and check for "containers-basic" in the list: + +.. code-block:: bash + + sudo swupd bundle-list + +If you need to install the containers-basic bundle, use :command:`swupd` to do so. + +.. code-block:: bash + + sudo swupd bundle-add containers-basic + + +To run Kubernetes on |CL|, please refer to the :ref:`kubernetes` tutorial to ensure it is correctly installed and configured. + +We have validated these steps against the following software package versions + + * |CL| 26240 + * Docker 18.06.1 + * Kubernetes 1.11.3 + * Go 1.11.12 + + +TensorFlow Benchmarks +===================== + +This section describes running the `TensorFlow benchmarks`_ as run by the TensorFlow community. These steps provide a template to run other benchmarks, providing they can invoke TensorFlow. + +Download and run the docker image from hub.docker.com. The next commands will take place in the running container. Replace with the name of the image. + +First, clone the benchmark repository + +.. code-block:: bash + + docker exec -t bash -c ‘git clone http://github.com/tensorflow/benchmarks -b cnn_tf_v1.11_compatible’ + +Next, execute the benchmark script to run the benchmark + +.. code-block:: bash + + docker exec -i bash -c ‘python benchmarks/scripts/tf_cnn_benchmarks/tf_cnn_benchmarks.py --device=cpu --model=resnet50 --data_format=NWHC ’. + +You can replace the model with one of your choice supported by the TensorFlow benchmarks. + + + +Kubeflow Benchmarks +=================== + +The benchmark workload will run in a Kubernetes (k8s) container. We will use Kubeflow and deploy three nodes for this tutorial, to get a decent return. + +k8s setup ++++++++++ + +Please follow the instructions in the :ref:`kubernetes` tutorial to get set up on |CL|. The k8s community also has `instructions`_ if you are using Ubuntu instead of |CL|. + + +k8s networking +++++++++++++++ + +We have used `flannel`_ as the network provider for these tests. If you are comfortable with another network layer, there is nothing that will prevent you from using that. +Refer to the Kubernetes `networking documentation`_ for setup. + + +Images +We will need to create a docker image that will include launcher.py similar to Dockerfile.cpu to include DLaaS and put the benchmarks repo in the right location. This is the one i used in my testing. + +FROM hub.docker.intel.com/verticals/dlaas:latest +RUN mkdir -p /opt +RUN git clone https://github.com/tensorflow/benchmarks.git /opt/tf-benchmarks +COPY launcher.py /opt +RUN chmod u+x /opt/* +ENTRYPOINT ["/opt/launcher.py"] + + +This will build an image which can be consumed directly by TFJob from kubeflow. +AR: Currently we are working to create these images as part of our normal release cycles. + + +Ksonnet ++++++++ + +Kubeflow uses Ksonnet to manage deployments, so we need to install that before setting up Kubeflow. On |CL|, follow these steps: + +.. code-block:: bash + + swupd bundle-add go-basic-dev + export GOPATH=$HOME/go + export PATH=$PATH:$GOPATH/bin + go get github.com/ksonnet/ksonnet + cd $GOPATH/src/github.com/ksonnet/ksonnet + make install + + +.. For other OS, follow steps in: https://www.kubeflow.org/docs/guides/components/ksonnet/ . + +After the ksonnet installation is complete, ensure that binary `ks` is accessible across the environment. + + +Kubeflow +======== +Once you have k8s running on your nodes, you can setup Kubeflow by following these instructions from their `quick start guide`_. + +.. code-block:: bash + + export KUBEFLOW_SRC=$HOME/kflow + export KUBEFLOW_TAG=”v0.3.2” + export KFAPP=”kflow_app” + export K8S_NAMESPACE=”kubeflow” + mkdir ${KUBEFLOW_SRC} + cd ${KUBEFLOW_SRC} + curl https://raw.githubusercontent.com/kubeflow/kubeflow/${KUBEFLOW_TAG}/scripts/download.sh | bash + ${KUBEFLOW_SRC}/scripts/kfctl.sh init ${KFAPP} --platform none + cd ${KFAPP} + ${KUBEFLOW_SRC}/scripts/kfctl.sh generate k8s + +Now you have all the required kubeflow packages, and you can deploy the primary one for our purposes: tf-job-operator. + +.. code-block:: bash + + kubectl create namespace ${K8S_NAMESPACE} + ks env add default --namespace "${K8S_NAMESPACE}" + ks apply default -c tf-job-operator + +This creates the CustomResourceDefinition(CRD) endpoint to launch a TFJob. + +Running the Deep Learning as a Service TFJob +++++++++++++++++++++++++++++++++++++++++++++ + +The jsonnet template files for `ResNet50`_ and `Alexnet`_ are available in the |CL| Deep Learning Stack repository. Download and copy these files into + +.. code-block:: console + + ${KUBEFLOW_SRC}/${KFAPP}/vendor/kubeflow/examples/prototypes/ + +Next, generate Kubernetes manifests for the workloads and apply them to create and run them using these commands + +.. code-block:: bash + + ks generate dlaas-resnet50 dlaasresnet50 --name=dlaasresnet50 + ks generate dlaas-alexnet dlaasalexnet --name=dlaasalexnet + ks apply default -c dlaasresnet50 + ks apply default -c dlaasalexnet + +This will replicate and deploy three test setups in your k8s cluster. + + +Results +======= +You will need to parse the logs of the k8s pod to get the performance numbers. The pods will still be around post completion and will be in ‘Completed’ state. You can get the logs from any of the pods to inpsect the benchmark results. + +.. To-Dos +.. This is a list of to-do’s to the engineering team to get this moving in the right direction. +.. Make kubeflow docker images along with release images. +.. Second downstream docker file for MKL. +.. Another set of jsonnet files for MKL. +.. Trim down the base DLaaS image to contain tensorflow bundle and nothing else. +.. CI will throw benchmarks into the repo and be able to test it. +.. The downstream dockerfile will generate another image with benchmarks repo and launcher.py file in the right locations. +.. Dynamic generation of ksonnet template files for a matrix of batch_size, model and replicas. + + + +.. _TensorFlow benchmarks: https://www.tensorflow.org/guide/performance/benchmarks +.. _instructions: https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/ +.. _flannel: https://github.com/coreos/flannel +.. _networking documentation: https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/#pod-network +.. _quick start guide: https://www.kubeflow.org/docs/started/getting-started/ +.. _ResNet50: https://github.intel.com/verticals/DLaaS/blob/master/kubeflow/dlaas-resnet50.jsonnet +.. _Alexnet: https://github.intel.com/verticals/DLaaS/blob/master/kubeflow/dlaas-alexnet.jsonnet From f9118344c86483d97c79e8904b89e00f945aac56 Mon Sep 17 00:00:00 2001 From: Beth Dean Date: Mon, 3 Dec 2018 13:45:06 -0800 Subject: [PATCH 02/26] updated Images section, removed incorrect github links --- .../tutorials/dlaas-benchmarks.rst | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/source/clear-linux/tutorials/dlaas-benchmarks.rst b/source/clear-linux/tutorials/dlaas-benchmarks.rst index 0ff9e1a7..04e201b8 100644 --- a/source/clear-linux/tutorials/dlaas-benchmarks.rst +++ b/source/clear-linux/tutorials/dlaas-benchmarks.rst @@ -75,18 +75,21 @@ Refer to the Kubernetes `networking documentation`_ for setup. Images -We will need to create a docker image that will include launcher.py similar to Dockerfile.cpu to include DLaaS and put the benchmarks repo in the right location. This is the one i used in my testing. +++++++ -FROM hub.docker.intel.com/verticals/dlaas:latest -RUN mkdir -p /opt -RUN git clone https://github.com/tensorflow/benchmarks.git /opt/tf-benchmarks -COPY launcher.py /opt -RUN chmod u+x /opt/* -ENTRYPOINT ["/opt/launcher.py"] +We will need to create a docker image that will include launcher.py to include the |CL| Deep Learning Stack, and put the benchmarks repo in the right location. From the docker image, run the following + +.. code-block:: bash + + mkdir -p /opt + git clone https://github.com/tensorflow/benchmarks.git /opt/tf-benchmarks + cp launcher.py /opt + chmod u+x /opt/* + +Your entry point then becomes "/opt/launcher.py". -This will build an image which can be consumed directly by TFJob from kubeflow. -AR: Currently we are working to create these images as part of our normal release cycles. +This will build an image which can be consumed directly by TFJob from kubeflow. We are working to create these images as part of our release cycle. Ksonnet @@ -139,7 +142,7 @@ This creates the CustomResourceDefinition(CRD) endpoint to launch a TFJob. Running the Deep Learning as a Service TFJob ++++++++++++++++++++++++++++++++++++++++++++ -The jsonnet template files for `ResNet50`_ and `Alexnet`_ are available in the |CL| Deep Learning Stack repository. Download and copy these files into +The jsonnet template files for ResNet50 and Alexnet are available in the |CL| Deep Learning Stack repository. Download and copy these files into .. code-block:: console From 15a1eeedebb3b0089b2c17cca91979a4de654ba8 Mon Sep 17 00:00:00 2001 From: Beth Dean Date: Mon, 3 Dec 2018 14:10:40 -0800 Subject: [PATCH 03/26] removing link reference syntax for invalid link --- source/clear-linux/tutorials/dlaas-benchmarks.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/source/clear-linux/tutorials/dlaas-benchmarks.rst b/source/clear-linux/tutorials/dlaas-benchmarks.rst index 04e201b8..c9451503 100644 --- a/source/clear-linux/tutorials/dlaas-benchmarks.rst +++ b/source/clear-linux/tutorials/dlaas-benchmarks.rst @@ -181,5 +181,3 @@ You will need to parse the logs of the k8s pod to get the performance numbers. T .. _flannel: https://github.com/coreos/flannel .. _networking documentation: https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/#pod-network .. _quick start guide: https://www.kubeflow.org/docs/started/getting-started/ -.. _ResNet50: https://github.intel.com/verticals/DLaaS/blob/master/kubeflow/dlaas-resnet50.jsonnet -.. _Alexnet: https://github.intel.com/verticals/DLaaS/blob/master/kubeflow/dlaas-alexnet.jsonnet From 0a652c4f70eeb2bc564439f3aee5fc078c3b83fa Mon Sep 17 00:00:00 2001 From: Beth Dean Date: Tue, 4 Dec 2018 08:51:47 -0800 Subject: [PATCH 04/26] updating docker image links --- source/clear-linux/tutorials/dlaas-benchmarks.rst | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/source/clear-linux/tutorials/dlaas-benchmarks.rst b/source/clear-linux/tutorials/dlaas-benchmarks.rst index c9451503..0f10bc12 100644 --- a/source/clear-linux/tutorials/dlaas-benchmarks.rst +++ b/source/clear-linux/tutorials/dlaas-benchmarks.rst @@ -38,7 +38,9 @@ TensorFlow Benchmarks This section describes running the `TensorFlow benchmarks`_ as run by the TensorFlow community. These steps provide a template to run other benchmarks, providing they can invoke TensorFlow. -Download and run the docker image from hub.docker.com. The next commands will take place in the running container. Replace with the name of the image. +The |CL| Deep Learning Stack is available in two versions. First, a version that includes TensorFlow* optimized for Intel Architecture, and second, a version that includes the TensorFlow* framework optimized using Intel® Math Kernel Library for Deep Neural Networks (Intel® MKL-DNN) primitives. + +Download and run either the `TensorFlow`_ or the `TensorFlow with MKL-DNN`_ docker image from hub.docker.com. The next commands will take place in the running container. Replace with the name of the image. First, clone the benchmark repository @@ -165,9 +167,8 @@ Results You will need to parse the logs of the k8s pod to get the performance numbers. The pods will still be around post completion and will be in ‘Completed’ state. You can get the logs from any of the pods to inpsect the benchmark results. .. To-Dos -.. This is a list of to-do’s to the engineering team to get this moving in the right direction. + .. Make kubeflow docker images along with release images. -.. Second downstream docker file for MKL. .. Another set of jsonnet files for MKL. .. Trim down the base DLaaS image to contain tensorflow bundle and nothing else. .. CI will throw benchmarks into the repo and be able to test it. @@ -181,3 +182,5 @@ You will need to parse the logs of the k8s pod to get the performance numbers. T .. _flannel: https://github.com/coreos/flannel .. _networking documentation: https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/#pod-network .. _quick start guide: https://www.kubeflow.org/docs/started/getting-started/ +.. _TensorFlow: https://hub.docker.com/r/clearlinux/stacks-dlaas-oss/ +.. _TensorFlow with MKL-DNN: https://hub.docker.com/r/clearlinux/stacks-dlaas-mkl/ From c0397f38fdd648bb1541f09a712b476e35c9a0be Mon Sep 17 00:00:00 2001 From: Beth Dean Date: Tue, 4 Dec 2018 10:44:54 -0800 Subject: [PATCH 05/26] updating mark on TensorFlow --- source/clear-linux/tutorials/dlaas-benchmarks.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/clear-linux/tutorials/dlaas-benchmarks.rst b/source/clear-linux/tutorials/dlaas-benchmarks.rst index 0f10bc12..0174b402 100644 --- a/source/clear-linux/tutorials/dlaas-benchmarks.rst +++ b/source/clear-linux/tutorials/dlaas-benchmarks.rst @@ -3,7 +3,7 @@ Deep Learning as a Service Benchmarking ####################################### -This tutorial details the steps needed to run benchmarking workloads in |CL-ATTR| using TensorFlow and on Kubeflow with the |CL| Deep Learning as a Service Stack. +This tutorial details the steps needed to run benchmarking workloads in |CL-ATTR| using TensorFlow* and on Kubeflow with the |CL| Deep Learning as a Service Stack. Prerequisites ============= From 86c9fb9ddec3abc9748344123b0f937b246c2e68 Mon Sep 17 00:00:00 2001 From: Michael Vincerra Date: Tue, 4 Dec 2018 18:06:03 -0800 Subject: [PATCH 06/26] Edits and revisions include: - Revised Prerequisites section as list and simplified - Added cloud-native-basic to capture kubermetes - please advise - Revised all contents for Sphinx syntax - Applied trademarks/branding where necessary Signed-off-by: Michael Vincerra --- .../tutorials/dlaas-benchmarks.rst | 180 +++++++++++------- 1 file changed, 107 insertions(+), 73 deletions(-) diff --git a/source/clear-linux/tutorials/dlaas-benchmarks.rst b/source/clear-linux/tutorials/dlaas-benchmarks.rst index 0174b402..a5a1f71f 100644 --- a/source/clear-linux/tutorials/dlaas-benchmarks.rst +++ b/source/clear-linux/tutorials/dlaas-benchmarks.rst @@ -1,122 +1,145 @@ -.. _dlaas-benchmarks: +.. _dlaas: -Deep Learning as a Service Benchmarking -####################################### +Deep Learning as a Service +########################## -This tutorial details the steps needed to run benchmarking workloads in |CL-ATTR| using TensorFlow* and on Kubeflow with the |CL| Deep Learning as a Service Stack. +This tutorial explains how to run benchmarking workloads in |CL-ATTR| using +TensorFlow* and Kubeflow with the Clear Linux* Deep Learning Stack. + +Release notes +============= + +View current `release notes for the Clear Linux Deep Learning Stack`_. Prerequisites ============= -For this tutorial, we'll be using a system that has |CL| installed using the :ref:`bare-metal-install` getting started guide. It is possible to follow these instructions on other OS systems but we're limiting the scope of this document to |CL|. +* |CL| is installed on host system. If not, :ref:`bare-metal-install` +* `containers-basic` bundle is installed +* `cloud-native-basic` bundle is installed (includes kubernetes) -Ensure you have the "containers-basic" bundle installed, this will provide Docker, which is required for TensorFlow benchmarking. Use the :command:`swupd` utility with the `bundle-list` option and check for "containers-basic" in the list: +In |CL|, `containers-basic` provides Docker*, which is required for +TensorFlow benchmarking. Use the :command:`swupd` utility to check if +`containers-basic` and `cloud-native-basic` are present: .. code-block:: bash - sudo swupd bundle-list + sudo swupd bundle-list -If you need to install the containers-basic bundle, use :command:`swupd` to do so. +If you need to install the `containers-basic` or `cloud-native-basic`, enter: .. code-block:: bash - sudo swupd bundle-add containers-basic + sudo swupd bundle-add containers-basic - -To run Kubernetes on |CL|, please refer to the :ref:`kubernetes` tutorial to ensure it is correctly installed and configured. +To ensure that kubernetes is correctly installed and configured, +:ref:`kubernetes`. We have validated these steps against the following software package versions - * |CL| 26240 - * Docker 18.06.1 - * Kubernetes 1.11.3 - * Go 1.11.12 +* |CL| 26240--lowest version permissible. +* Docker 18.06.1 +* Kubernetes 1.11.3 +* Go 1.11.12 - -TensorFlow Benchmarks +TensorFlow benchmarks ===================== -This section describes running the `TensorFlow benchmarks`_ as run by the TensorFlow community. These steps provide a template to run other benchmarks, providing they can invoke TensorFlow. +This section describes running the `TensorFlow benchmarks`_ as run by the +TensorFlow community. These steps provide a template to run other +benchmarks, providing they can invoke TensorFlow. -The |CL| Deep Learning Stack is available in two versions. First, a version that includes TensorFlow* optimized for Intel Architecture, and second, a version that includes the TensorFlow* framework optimized using Intel® Math Kernel Library for Deep Neural Networks (Intel® MKL-DNN) primitives. +The |CL| Deep Learning Stack is available in two versions: -Download and run either the `TensorFlow`_ or the `TensorFlow with MKL-DNN`_ docker image from hub.docker.com. The next commands will take place in the running container. Replace with the name of the image. +* `TensorFlow`_ includes TensorFlow optimized for Intel® architecture +* `TensorFlow with MKL-DNN`_ includes the TensorFlow* framework optimized + using Intel® Math Kernel Library for Deep Neural Networks (Intel® MKL-DNN) -First, clone the benchmark repository +Download and run either of these from the `Clear Linxu Docker Hub page`_. +The next commands will take place in the running container. -.. code-block:: bash +.. note:: - docker exec -t bash -c ‘git clone http://github.com/tensorflow/benchmarks -b cnn_tf_v1.11_compatible’ + Replace with the name of the image. -Next, execute the benchmark script to run the benchmark +#. First, clone the benchmark repository: -.. code-block:: bash + .. code-block:: bash - docker exec -i bash -c ‘python benchmarks/scripts/tf_cnn_benchmarks/tf_cnn_benchmarks.py --device=cpu --model=resnet50 --data_format=NWHC ’. + docker exec -t bash -c ‘git clone http://github.com/tensorflow/benchmarks -b cnn_tf_v1.11_compatible’ -You can replace the model with one of your choice supported by the TensorFlow benchmarks. +#. Next, execute the benchmark script to run the benchmark + .. code-block:: bash + docker exec -i bash -c ‘python benchmarks/scripts/tf_cnn_benchmarks/tf_cnn_benchmarks.py --device=cpu --model=resnet50 --data_format=NWHC ’. -Kubeflow Benchmarks + .. note:: + + You can replace the model with one of your choice supported by the + TensorFlow benchmarks. + +Kubeflow benchmarks =================== -The benchmark workload will run in a Kubernetes (k8s) container. We will use Kubeflow and deploy three nodes for this tutorial, to get a decent return. +The benchmark workload will run in a Kubernetes container. We will use Kubeflow and deploy three nodes for this tutorial to get a decent return. -k8s setup -+++++++++ +Kubernetes setup +**************** -Please follow the instructions in the :ref:`kubernetes` tutorial to get set up on |CL|. The k8s community also has `instructions`_ if you are using Ubuntu instead of |CL|. +Follow the instructions in the :ref:`kubernetes` tutorial to get set up on +|CL|. The kubernetes community also has `instructions for creating a cluster`_. +Kubernetes networking +********************* -k8s networking -++++++++++++++ - -We have used `flannel`_ as the network provider for these tests. If you are comfortable with another network layer, there is nothing that will prevent you from using that. -Refer to the Kubernetes `networking documentation`_ for setup. +We have used `flannel`_ as the network provider for these tests. If you are +comfortable with another network layer, refer to the Kubernetes +`networking documentation`_ for setup. Images -++++++ +****** -We will need to create a docker image that will include launcher.py to include the |CL| Deep Learning Stack, and put the benchmarks repo in the right location. From the docker image, run the following +We need to create a docker image that includes `launcher.py` to +include the |CL| Deep Learning Stack, and put the benchmarks repo in the +right location. From the docker image, run the following: .. code-block:: bash - mkdir -p /opt - git clone https://github.com/tensorflow/benchmarks.git /opt/tf-benchmarks - cp launcher.py /opt - chmod u+x /opt/* + mkdir -p /opt + git clone https://github.com/tensorflow/benchmarks.git /opt/tf-benchmarks + cp launcher.py /opt + chmod u+x /opt/* -Your entry point then becomes "/opt/launcher.py". +Your entry point now becomes "/opt/launcher.py". + +This will build an image which can be consumed directly by TFJob from +kubeflow. We are working to create these images as part of our release +cycle. -This will build an image which can be consumed directly by TFJob from kubeflow. We are working to create these images as part of our release cycle. +ksonnet* +******** - -Ksonnet -+++++++ - -Kubeflow uses Ksonnet to manage deployments, so we need to install that before setting up Kubeflow. On |CL|, follow these steps: +Kubeflow uses ksonnet* to manage deployments, so we need to install that before setting up Kubeflow. On |CL|, follow these steps: .. code-block:: bash - swupd bundle-add go-basic-dev - export GOPATH=$HOME/go - export PATH=$PATH:$GOPATH/bin - go get github.com/ksonnet/ksonnet - cd $GOPATH/src/github.com/ksonnet/ksonnet - make install - - -.. For other OS, follow steps in: https://www.kubeflow.org/docs/guides/components/ksonnet/ . - -After the ksonnet installation is complete, ensure that binary `ks` is accessible across the environment. + swupd bundle-add go-basic-dev + export GOPATH=$HOME/go + export PATH=$PATH:$GOPATH/bin + go get github.com/ksonnet/ksonnet + cd $GOPATH/src/github.com/ksonnet/ksonnet + make install +After the ksonnet installation is complete, ensure that binary `ks` is +accessible across the environment. Kubeflow -======== -Once you have k8s running on your nodes, you can setup Kubeflow by following these instructions from their `quick start guide`_. +******** + +Once you have Kubernetes running on your nodes, you can setup Kubeflow by following these instructions from their `quick start guide`_. .. code-block:: bash @@ -142,29 +165,33 @@ Now you have all the required kubeflow packages, and you can deploy the primary This creates the CustomResourceDefinition(CRD) endpoint to launch a TFJob. Running the Deep Learning as a Service TFJob -++++++++++++++++++++++++++++++++++++++++++++ +============================================ -The jsonnet template files for ResNet50 and Alexnet are available in the |CL| Deep Learning Stack repository. Download and copy these files into +The jsonnet template files for ResNet50 and Alexnet are available in the |CL| +Deep Learning Stack repository. Download and copy these files into: .. code-block:: console - ${KUBEFLOW_SRC}/${KFAPP}/vendor/kubeflow/examples/prototypes/ + ${KUBEFLOW_SRC}/${KFAPP}/vendor/kubeflow/examples/prototypes/ Next, generate Kubernetes manifests for the workloads and apply them to create and run them using these commands .. code-block:: bash - ks generate dlaas-resnet50 dlaasresnet50 --name=dlaasresnet50 - ks generate dlaas-alexnet dlaasalexnet --name=dlaasalexnet - ks apply default -c dlaasresnet50 - ks apply default -c dlaasalexnet + ks generate dlaas-resnet50 dlaasresnet50 --name=dlaasresnet50 + ks generate dlaas-alexnet dlaasalexnet --name=dlaasalexnet + ks apply default -c dlaasresnet50 + ks apply default -c dlaasalexnet -This will replicate and deploy three test setups in your k8s cluster. +This will replicate and deploy three test setups in your Kubernetes cluster. Results ======= -You will need to parse the logs of the k8s pod to get the performance numbers. The pods will still be around post completion and will be in ‘Completed’ state. You can get the logs from any of the pods to inpsect the benchmark results. +You need to parse the logs of the Kubernetes pod to get the performance +numbers. The pods will still be around post completion and will be in +‘Completed’ state. You can get the logs from any of the pods to inspect the +benchmark results. .. To-Dos @@ -178,9 +205,16 @@ You will need to parse the logs of the k8s pod to get the performance numbers. T .. _TensorFlow benchmarks: https://www.tensorflow.org/guide/performance/benchmarks -.. _instructions: https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/ +.. _instructions for creating a cluster: https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/ .. _flannel: https://github.com/coreos/flannel .. _networking documentation: https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/#pod-network .. _quick start guide: https://www.kubeflow.org/docs/started/getting-started/ .. _TensorFlow: https://hub.docker.com/r/clearlinux/stacks-dlaas-oss/ + .. _TensorFlow with MKL-DNN: https://hub.docker.com/r/clearlinux/stacks-dlaas-mkl/ + +.. _release notes for the Clear Linux Deep Learning Stack: https://github.com/clearlinux/dockerfiles/tree/master/stacks/dlaas + +.. _Clear Linux Docker Hub page: https://hub.docker.com/u/clearlinux/ + + From 42907213203199806162c7fb0a832e54e4eed6e9 Mon Sep 17 00:00:00 2001 From: Kristal Dale Date: Thu, 29 Nov 2018 13:21:21 -0800 Subject: [PATCH 07/26] Update mixer concept page - Update concept page to include a comparative overview of mixer and mixin - Added images to illustrated differences between mixer and mixin - Add related links - Corrected label for deploy-at-scale.rst so that it could be linked from mixer concept page Signed-off-by: Kristal Dale --- .../concepts/figures/mixer-about-1.png | Bin 0 -> 37066 bytes .../concepts/figures/mixer-about-2.png | Bin 0 -> 35047 bytes source/clear-linux/concepts/mixer-about.rst | 86 +++++++++++++++--- source/clear-linux/guides/deploy-at-scale.rst | 2 +- 4 files changed, 75 insertions(+), 13 deletions(-) create mode 100644 source/clear-linux/concepts/figures/mixer-about-1.png create mode 100644 source/clear-linux/concepts/figures/mixer-about-2.png diff --git a/source/clear-linux/concepts/figures/mixer-about-1.png b/source/clear-linux/concepts/figures/mixer-about-1.png new file mode 100644 index 0000000000000000000000000000000000000000..8120a068aa1bc738dd23c3b2d91d5447a464a00c GIT binary patch literal 37066 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

UB!l`J%yQljH@{*>A~Cu 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 PaAAliz1`}Mhi3i-#!+2L literal 0 HcmV?d00001 diff --git a/source/clear-linux/concepts/figures/mixer-about-2.png b/source/clear-linux/concepts/figures/mixer-about-2.png new file mode 100644 index 0000000000000000000000000000000000000000..83f0337592a5f0b351cb704205b46cea96fde725 GIT binary patch literal 35047 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 D`s7HJ literal 0 HcmV?d00001 diff --git a/source/clear-linux/concepts/mixer-about.rst b/source/clear-linux/concepts/mixer-about.rst index 1caf3764..58799554 100644 --- a/source/clear-linux/concepts/mixer-about.rst +++ b/source/clear-linux/concepts/mixer-about.rst @@ -3,21 +3,83 @@ Mixer ##### -Mixing refers to composing a custom, versioned image of |CL-ATTR| for a -specific use case. While upstream |CL| provides options to install bundles -for various capabilities, some developers and OSVs may wish to either -augment the operating system with functionality from their own packages -or modify the structure of current bundles. Mixing offers a method to add -capabilities while retaining the ability to stay up to date with an upstream -version of |CL|. +|CL-ATTR| is a powerful, modular, and customizable OS. Upstream |CL| offers +many images for different deployment environments and use-cases. There are +hundreds of bundles that will meet most, if not all, of your OS and software +needs. -Mixing is a multi-step process that starts with installing the mixer bundle -using swupd. You will also need a working knowledge of -:abbr:`RPMs (RPM Package Manager files)` and how |CL| bundles work. For a -detailed guide on how to create a |CL| mix, visit :ref:`mixer`. +However, if you need additional customization or content, |CL| provides the +mixer tool to customize the OS. With mixer, there are two approaches to +customization: + +* :ref:`create-mix` +* :ref:`create-mixin` + +Which approach you choose will depend on the level of customization that you +need. + +.. _create-mix: + +Create a mix +============ + +The first approach is to use the mixer tool to create a derivative of the |CL| +that contains your custom software. This is known as creating a mix. In your +mix, you can + +* Use any existing upstream bundles with no modification. +* Redefine what goes into existing bundles. +* Create completely new, custom bundles with your own custom packages. + +With mixer you are not required to incorporate every upstream release into your +mix. You decide which upstream versions to update your derivative to, as +illustrated in Figure 1. + +.. figure:: figures/mixer-about-1.png + :scale: 75% + :alt: Creating a custom mix. + + Figure 1: With a custom mix, you add your custom bundle and decide which + upstream versions to update your mix to, on your own release cycle. + +Creating your own mix forks away from the |CL| upstream and requires that you +act as your own OSV. There is a greater level of responsibility, requiring +more infrastructure and processes to adopt. However, with this approach, you +have a higher degree of control and customization of your custom |CL|. + + +.. _create-mixin: + +Create a mixin +============== + +The second approach is to use the mixin tool, a light wrapper for mixer, to +create custom bundles and sideload them into your upstream version of |CL|. +This is known as a mixin. A mixin is useful when you need to add custom or 3rd +party content but want to keep on the upstream update cycle, as shown in +Figure 2. You can also create new bundles using upstream packages. + +.. figure:: figures/mixer-about-2.png + :scale: 75% + :alt: Creating a custom mix. + + Figure 2: With a mixin you can add custom bundles, but stay on upstream. + +Mixin is primarily intended for end users. It is easier to adopt as it does +not require breaking from upstream or acting as an OSV. With mixin + +* You are responsible for maintaining and testing your custom bundle(s). +* You retain access to all upstream bundles and updates. +* You can easily revert your system back to the upstream version. Related topics ============== -* :ref:`swupd-about` +|CL| provides flexibility in how you customize your OS. Learn more about mixer +and related topics to decide which customization approach is best for you. + +* :ref:`mixer` +* :ref:`mixin` * :ref:`bundles-about` +* :ref:`swupd-about` +* :ref:`deploy-at-scale` diff --git a/source/clear-linux/guides/deploy-at-scale.rst b/source/clear-linux/guides/deploy-at-scale.rst index 2f0bced2..5b3867df 100644 --- a/source/clear-linux/guides/deploy-at-scale.rst +++ b/source/clear-linux/guides/deploy-at-scale.rst @@ -1,4 +1,4 @@ -.. _deploy-at-scale.rst: +.. _deploy-at-scale: Deploy at Scale ############### From 14286bf230d1b42d587518a7a909477d37da0aaa Mon Sep 17 00:00:00 2001 From: Kevin Putnam Date: Thu, 29 Nov 2018 14:21:56 -0800 Subject: [PATCH 08/26] adding autoproxy content --- .../guides/maintenance/autoproxy.rst | 18 ++++ .../guides/maintenance/autoproxy_about.txt | 43 ++++++++++ .../guides/maintenance/autoproxy_guide.txt | 77 ++++++++++++++++++ .../maintenance/figures/autoproxy_0.png | Bin 0 -> 24307 bytes .../guides/maintenance/maintenance.rst | 1 + 5 files changed, 139 insertions(+) create mode 100644 source/clear-linux/guides/maintenance/autoproxy.rst create mode 100644 source/clear-linux/guides/maintenance/autoproxy_about.txt create mode 100644 source/clear-linux/guides/maintenance/autoproxy_guide.txt create mode 100644 source/clear-linux/guides/maintenance/figures/autoproxy_0.png diff --git a/source/clear-linux/guides/maintenance/autoproxy.rst b/source/clear-linux/guides/maintenance/autoproxy.rst new file mode 100644 index 00000000..b5131ab7 --- /dev/null +++ b/source/clear-linux/guides/maintenance/autoproxy.rst @@ -0,0 +1,18 @@ +.. _autoproxy: + +Autoproxy +######### + +.. rst-class:: content-collapse + +About +===== + +.. include:: autoproxy_about.txt + +.. rst-class:: content-collapse + +Guide +===== + +.. include:: autoproxy_guide.txt \ No newline at end of file diff --git a/source/clear-linux/guides/maintenance/autoproxy_about.txt b/source/clear-linux/guides/maintenance/autoproxy_about.txt new file mode 100644 index 00000000..80dcaa4e --- /dev/null +++ b/source/clear-linux/guides/maintenance/autoproxy_about.txt @@ -0,0 +1,43 @@ +The |CL-ATTR| is the first Linux distribution to support autoproxy. The OS +can discover a Proxy Auto-Config (PAC) script and use it to automatically +resolve the proxy needed for a given connection. With Autoproxy, you can use +|CL| inside any proxy environment without having to manually +configure the proxies. + +Corporate and private networks can be very complex, needing to restrict and +control network connections for security reasons. The typical side effects +are limited or blocked connectivity and requiring manual configuration of +proxies to perform the most mundane tasks such as cloning a repo or checking +for updates. With Clear Linux, all of the work is done behind the scenes to +effortlessly use your network and have connections “just work”. + +This feature removes massive complications in network connectivity due to +proxy issues. You can automate tasks like unit testing without worrying +about the proxy not being set and you can remove unset proxies from the +equation when dealing with network unavailability across systems. + +How Autoproxy works +------------------- + +We designed autoproxy around general tools provided by nearly any Linux +distribution with a few minor additions and modifications. We leveraged the +DHCP and network information provided from systemd and created a +PAC-discovery daemon. The daemon uses the information to resolve a URL for a +PAC file. The daemon then passes the URL into PACrunner*. PACrunner +downloads the PAC file and uses the newly implemented Duktape* engine to +parse it. + +.. figure:: figures/autoproxy_0.png + :width: 400px + + Figure 1: Autoproxy Flow + +From that point on, any cURL* or network requests query PACrunner for the +correct proxy to use. We modified the cURL library to communicate with +PACrunner over DBus. However, cURL will ignore PACrunner and run normally if +no PAC file is loaded or if you set any proxies manually. Thus, your +environment settings are respected and no time is wasted trying to resolve a +proxy. + +More importantly: all these steps happen in the background, very quickly, and +with no user interaction. \ No newline at end of file diff --git a/source/clear-linux/guides/maintenance/autoproxy_guide.txt b/source/clear-linux/guides/maintenance/autoproxy_guide.txt new file mode 100644 index 00000000..3422a747 --- /dev/null +++ b/source/clear-linux/guides/maintenance/autoproxy_guide.txt @@ -0,0 +1,77 @@ +Autoproxy allows |CL| to operate seamlessly behind a proxy +because, :ref:`swupd-guide` and other |CL| tools are implemented on +top of libcurl. Tools that do not use libcurl, like git, must +be configured independently. + +If you encounter problems with autoproxy functioning, use +:command:`pacdiscovery` and :command:`FindProxyForURL` to +help troubleshoot assuming a familiarity with PAC files and WPAD. + +.. note:: + + Learn more about WPAD, PAC files, and PAC functions at `findproxyforurl`_. + +.. _findproxyforurl: http://findproxyforurl.com/ + +Running :command:`pacdiscovery` with no arguments will immediately indicate + +1. if there is a problem resolving the :command:`WPAD` host name resolution: + + .. code:: console + + $ pacdiscovery + failed getaddrinfo: No address associated with hostname + Unable to find wpad host + +2. or if the :command:`pacrunner` service is disabled (masked). + + .. code:: console + + $ pacdiscovery + PAC url: http://autoproxy.your.domain.com/wpad.dat + Failed to create proxy config: Unit pacrunner.service is masked. + +Unmask the :command:`pacrunner` service by running: + +.. code:: console + + $ systemctl unmask pacrunner.service + +:command:`FindProxyForURL` with :command:`busctl` can also indicate if the +:command:`pacrunner.service` is masked. + +.. code:: console + + $ busctl call org.pacrunner /org/pacrunner/client org.pacrunner.Client FindProxyForURL ss "http://www.google.com" "google.com" + Unit pacrunner.service is masked. + dig wpad, dig wpad. + +:command:`FindProxyForURL` returns the URL and port of the proxy server when +an external URL and host are provided as arguments. + +.. code:: console + + $ busctl call org.pacrunner /org/pacrunner/client org.pacrunner.Client FindProxyForURL ss "http://www.google.com" "google.com" + s "PROXY proxy.your.domain.com:" + +If a proxy server is not avialable, or if :command:`pacrunner` is running +without a PAC file, :command:`FindProxyForURL` will return "DIRECT". + +.. code:: console + + $ busctl call org.pacrunner /org/pacrunner/client org.pacrunner.Client FindProxyForURL ss "http://www.google.com" "google.com" + s "DIRECT" + +Once :command:`pacdiscovery` is able to look up :command:`WPAD`, restart the +:command:`pacrunner` service: + +.. code:: console + + $ systemctl stop pacrunner + $ systemctl restart pacdiscovery + +.. note:: + + A "domain" or "search" entry in :file:`/etc/resolv.conf` is required for short + name lookups to resolve. The :file:`resolv.conf` man page has additional + details. \ No newline at end of file diff --git a/source/clear-linux/guides/maintenance/figures/autoproxy_0.png b/source/clear-linux/guides/maintenance/figures/autoproxy_0.png new file mode 100644 index 0000000000000000000000000000000000000000..7a02cd81f27692f24b8e30b672a95655d8bbae6e GIT binary patch literal 24307 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 DVa;3x literal 0 HcmV?d00001 diff --git a/source/clear-linux/guides/maintenance/maintenance.rst b/source/clear-linux/guides/maintenance/maintenance.rst index aafd0cd2..3d89fa54 100644 --- a/source/clear-linux/guides/maintenance/maintenance.rst +++ b/source/clear-linux/guides/maintenance/maintenance.rst @@ -10,6 +10,7 @@ completed. .. toctree:: :maxdepth: 2 + autoproxy developer-workstation swupd-search enable-user-space From 4d54feeaf7b97586fb96b9e9bcd0d52c0c87d5ff Mon Sep 17 00:00:00 2001 From: Michael Vincerra Date: Mon, 3 Dec 2018 10:24:48 -0800 Subject: [PATCH 09/26] Escapes http://address:port because it's an example, not link. Signed-off-by: Michael Vincerra --- .../bare-metal-install-beta/bare-metal-install-beta.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/clear-linux/get-started/bare-metal-install-beta/bare-metal-install-beta.rst b/source/clear-linux/get-started/bare-metal-install-beta/bare-metal-install-beta.rst index 4661b423..07cce2a5 100644 --- a/source/clear-linux/get-started/bare-metal-install-beta/bare-metal-install-beta.rst +++ b/source/clear-linux/get-started/bare-metal-install-beta/bare-metal-install-beta.rst @@ -517,7 +517,7 @@ instruction. Figure 16: :guilabel:`Configure the network proxy` #. Enter the desired proxy address and port using conventional syntax, - such as: http://address:port. + such as: \http://address:port. #. Navigate to :guilabel:`Confirm` and select :kbd:`Enter`. From 7089de89fc56c1bc06ee6f27675102aab3a5f896 Mon Sep 17 00:00:00 2001 From: Kevin Putnam Date: Mon, 3 Dec 2018 14:03:14 -0800 Subject: [PATCH 10/26] Update mixer-about.rst Made a bunch of changes but didn't want to stomp on existing. --- source/clear-linux/concepts/mixer-about.rst | 34 ++++++++++----------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/source/clear-linux/concepts/mixer-about.rst b/source/clear-linux/concepts/mixer-about.rst index 58799554..fb24f479 100644 --- a/source/clear-linux/concepts/mixer-about.rst +++ b/source/clear-linux/concepts/mixer-about.rst @@ -4,35 +4,32 @@ Mixer ##### |CL-ATTR| is a powerful, modular, and customizable OS. Upstream |CL| offers -many images for different deployment environments and use-cases. There are +many images to support different environments and use-cases. There are hundreds of bundles that will meet most, if not all, of your OS and software needs. However, if you need additional customization or content, |CL| provides the -mixer tool to customize the OS. With mixer, there are two approaches to -customization: +mixer tool. There are two ways to customize the OS using the mixer depending +on the level of customization you need: -* :ref:`create-mix` -* :ref:`create-mixin` - -Which approach you choose will depend on the level of customization that you -need. +1. :ref:`create-mix` to create a distinct derivative of the |CL| that + contains your custom software. +2. :ref:`create-mixin` using a lightweight wrapper of mixer to add custom + bundles to be included with an upstream version of the |CL|. .. _create-mix: Create a mix ============ -The first approach is to use the mixer tool to create a derivative of the |CL| -that contains your custom software. This is known as creating a mix. In your -mix, you can +When creating a mix, you can * Use any existing upstream bundles with no modification. * Redefine what goes into existing bundles. * Create completely new, custom bundles with your own custom packages. -With mixer you are not required to incorporate every upstream release into your -mix. You decide which upstream versions to update your derivative to, as +With mixer you are not required to incorporate every upstream release into +your mix. You decide which upstream versions to update your derivative to, as illustrated in Figure 1. .. figure:: figures/mixer-about-1.png @@ -53,9 +50,9 @@ have a higher degree of control and customization of your custom |CL|. Create a mixin ============== -The second approach is to use the mixin tool, a light wrapper for mixer, to -create custom bundles and sideload them into your upstream version of |CL|. -This is known as a mixin. A mixin is useful when you need to add custom or 3rd +The second option is to use the mixin tool, a light wrapper for mixer, to +create custom bundles and sideload them into your upstream version of |CL|. +A mixin is useful when you need to add custom or 3rd party content but want to keep on the upstream update cycle, as shown in Figure 2. You can also create new bundles using upstream packages. @@ -75,8 +72,9 @@ not require breaking from upstream or acting as an OSV. With mixin Related topics ============== -|CL| provides flexibility in how you customize your OS. Learn more about mixer -and related topics to decide which customization approach is best for you. +|CL| provides flexibility in how you customize your OS. Learn more about +mixer and related topics to decide which customization approach is best for +you. * :ref:`mixer` * :ref:`mixin` From 4e116ac32cb72406a856a17f3df183cace5d77fa Mon Sep 17 00:00:00 2001 From: Kevin Putnam Date: Tue, 4 Dec 2018 11:33:50 -0800 Subject: [PATCH 11/26] updates based on feedback --- source/clear-linux/concepts/mixer-about.rst | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/source/clear-linux/concepts/mixer-about.rst b/source/clear-linux/concepts/mixer-about.rst index fb24f479..84d40a0b 100644 --- a/source/clear-linux/concepts/mixer-about.rst +++ b/source/clear-linux/concepts/mixer-about.rst @@ -9,13 +9,12 @@ hundreds of bundles that will meet most, if not all, of your OS and software needs. However, if you need additional customization or content, |CL| provides the -mixer tool. There are two ways to customize the OS using the mixer depending -on the level of customization you need: +mixer tool. We provide two different ways to develop and extend the OS, depending on your needs: 1. :ref:`create-mix` to create a distinct derivative of the |CL| that contains your custom software. -2. :ref:`create-mixin` using a lightweight wrapper of mixer to add custom - bundles to be included with an upstream version of the |CL|. +2. :ref:`create-mixin` to add custom bundles but also keep updating the OS + from upstream. .. _create-mix: @@ -50,9 +49,9 @@ have a higher degree of control and customization of your custom |CL|. Create a mixin ============== -The second option is to use the mixin tool, a light wrapper for mixer, to -create custom bundles and sideload them into your upstream version of |CL|. -A mixin is useful when you need to add custom or 3rd +The second option is to use the :command:`mixin` tool, a light wrapper for +mixer, to create custom bundles and sideload them into your upstream version +of |CL|. A mixin is useful when you need to add custom or 3rd party content but want to keep on the upstream update cycle, as shown in Figure 2. You can also create new bundles using upstream packages. From c4e32466a15c8f0266a2d26a1f9234cee3657dad Mon Sep 17 00:00:00 2001 From: George T Kramer Date: Tue, 4 Dec 2018 12:25:12 -0800 Subject: [PATCH 12/26] Add OpenSSL 1.1 support for image validation Clear Linux ships OpenSSL 1.1. As a part of this transition from OpenSSL 1.0, a new option needs passed to the command used to validate the chain of trust. Signed-off-by: George T Kramer --- .../guides/maintenance/validate-signatures.rst | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/source/clear-linux/guides/maintenance/validate-signatures.rst b/source/clear-linux/guides/maintenance/validate-signatures.rst index 65668884..54bbfe4d 100644 --- a/source/clear-linux/guides/maintenance/validate-signatures.rst +++ b/source/clear-linux/guides/maintenance/validate-signatures.rst @@ -57,7 +57,14 @@ used for illustrative purposes. You may use any image of |CL| you choose. .. code-block:: console - openssl smime -verify -in clear-$(curl https://download.clearlinux.org/latest)-installer.img.xz-SHA512SUMS.sig -inform der -content sha512sum.out -CAfile ClearLinuxRoot.pem + openssl smime -verify -purpose any -in clear-$(curl https://download.clearlinux.org/latest)-installer.img.xz-SHA512SUMS.sig -inform der -content sha512sum.out -CAfile ClearLinuxRoot.pem + + .. note:: + + The `-purpose any` option is required when using OpenSSL 1.1. If using + an earlier version of OpenSSL, omit this option to perform signature + validation. The `openssl version` command may be used to determine the + version of OpenSSL in use. #. The output should contain ``Verification successful``. If the output contains ``bad_signature`` anywhere, then the image is not trustworthy. @@ -101,7 +108,14 @@ these steps manually when performing a ``swupd update``. .. code-block:: console - openssl smime -verify -in Manifest.MoM.sig -inform der -content Manifest.MoM -CAfile Swupd_Root.pem + openssl smime -verify -purpose any -in Manifest.MoM.sig -inform der -content Manifest.MoM -CAfile Swupd_Root.pem + + .. note:: + + The `-purpose any` option is required when using OpenSSL 1.1. If using + an earlier version of OpenSSL, omit this option to perform signature + validation. The `openssl version` command may be used to determine the + version of OpenSSL in use. .. note:: From 88ce699f98abef3cc97d3762fb21b51c0f738dbe Mon Sep 17 00:00:00 2001 From: Kevin Putnam Date: Tue, 4 Dec 2018 13:54:15 -0800 Subject: [PATCH 13/26] incorporating additional feedback --- source/clear-linux/concepts/mixer-about.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/clear-linux/concepts/mixer-about.rst b/source/clear-linux/concepts/mixer-about.rst index 84d40a0b..485ea846 100644 --- a/source/clear-linux/concepts/mixer-about.rst +++ b/source/clear-linux/concepts/mixer-about.rst @@ -9,7 +9,7 @@ hundreds of bundles that will meet most, if not all, of your OS and software needs. However, if you need additional customization or content, |CL| provides the -mixer tool. We provide two different ways to develop and extend the OS, depending on your needs: +mixer tool. Depending on your needs, the mixer tool allows you to: 1. :ref:`create-mix` to create a distinct derivative of the |CL| that contains your custom software. From b4aa772811decf3321b4731312ceaa250be19682 Mon Sep 17 00:00:00 2001 From: Beth Dean Date: Tue, 4 Dec 2018 14:13:25 -0800 Subject: [PATCH 14/26] updating to latest name for docker images --- .../tutorials/dlaas-benchmarks.rst | 31 +++++++------------ 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/source/clear-linux/tutorials/dlaas-benchmarks.rst b/source/clear-linux/tutorials/dlaas-benchmarks.rst index a5a1f71f..c1d1690f 100644 --- a/source/clear-linux/tutorials/dlaas-benchmarks.rst +++ b/source/clear-linux/tutorials/dlaas-benchmarks.rst @@ -19,7 +19,7 @@ Prerequisites * `cloud-native-basic` bundle is installed (includes kubernetes) In |CL|, `containers-basic` provides Docker*, which is required for -TensorFlow benchmarking. Use the :command:`swupd` utility to check if +TensorFlow benchmarking. Use the :command:`swupd` utility to check if `containers-basic` and `cloud-native-basic` are present: .. code-block:: bash @@ -37,23 +37,16 @@ To ensure that kubernetes is correctly installed and configured, We have validated these steps against the following software package versions -* |CL| 26240--lowest version permissible. -* Docker 18.06.1 -* Kubernetes 1.11.3 -* Go 1.11.12 -TensorFlow benchmarks -===================== +The |CL| Deep Learning Stack is available in two versions. First, a version that includes TensorFlow* optimized for Intel Architecture, the `Eigen`_ version, and a version that includes the TensorFlow* framework optimized using Intel® Math Kernel Library for Deep Neural Networks (Intel® MKL-DNN) primitives, the `Intel MKL`_ version. -This section describes running the `TensorFlow benchmarks`_ as run by the -TensorFlow community. These steps provide a template to run other -benchmarks, providing they can invoke TensorFlow. +TensorFlow* Single and Multi Node Benchmarks +============================================ -The |CL| Deep Learning Stack is available in two versions: +This section describes running the `TensorFlow benchmarks`_ in single node. For multi node testing replicate these steps for each node. These steps provide a template to run other benchmarks, providing they can invoke TensorFlow. + +Download and run either the `Eigen`_ or the `Intel MKL-DNN`_ docker image from hub.docker.com. The next commands will take place in the running container. Replace with the name of the image. -* `TensorFlow`_ includes TensorFlow optimized for Intel® architecture -* `TensorFlow with MKL-DNN`_ includes the TensorFlow* framework optimized - using Intel® Math Kernel Library for Deep Neural Networks (Intel® MKL-DNN) Download and run either of these from the `Clear Linxu Docker Hub page`_. The next commands will take place in the running container. @@ -79,8 +72,8 @@ The next commands will take place in the running container. You can replace the model with one of your choice supported by the TensorFlow benchmarks. -Kubeflow benchmarks -=================== +Kubeflow Multinode benchmarks +============================= The benchmark workload will run in a Kubernetes container. We will use Kubeflow and deploy three nodes for this tutorial to get a decent return. @@ -209,12 +202,10 @@ benchmark results. .. _flannel: https://github.com/coreos/flannel .. _networking documentation: https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/#pod-network .. _quick start guide: https://www.kubeflow.org/docs/started/getting-started/ -.. _TensorFlow: https://hub.docker.com/r/clearlinux/stacks-dlaas-oss/ -.. _TensorFlow with MKL-DNN: https://hub.docker.com/r/clearlinux/stacks-dlaas-mkl/ +.. _Eigen: https://hub.docker.com/r/clearlinux/stacks-dlaas-oss/ +.. _Intel MKL-DNN: https://hub.docker.com/r/clearlinux/stacks-dlaas-mkl/ .. _release notes for the Clear Linux Deep Learning Stack: https://github.com/clearlinux/dockerfiles/tree/master/stacks/dlaas .. _Clear Linux Docker Hub page: https://hub.docker.com/u/clearlinux/ - - From caa1e3379009400858bc967d1d653c8d5b6318c0 Mon Sep 17 00:00:00 2001 From: Beth Dean Date: Wed, 5 Dec 2018 10:30:57 -0800 Subject: [PATCH 15/26] updating instructions, adding link to jssonet files, re-writing instructions for adding launcher.py to docker image for clarity. --- .../tutorials/dlaas-benchmarks.rst | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/source/clear-linux/tutorials/dlaas-benchmarks.rst b/source/clear-linux/tutorials/dlaas-benchmarks.rst index c1d1690f..28e4f3ab 100644 --- a/source/clear-linux/tutorials/dlaas-benchmarks.rst +++ b/source/clear-linux/tutorials/dlaas-benchmarks.rst @@ -37,6 +37,10 @@ To ensure that kubernetes is correctly installed and configured, We have validated these steps against the following software package versions +* |CL| 26240--lowest version permissible. +* Docker 18.06.1 +* Kubernetes 1.11.3 +* Go 1.11.12 The |CL| Deep Learning Stack is available in two versions. First, a version that includes TensorFlow* optimized for Intel Architecture, the `Eigen`_ version, and a version that includes the TensorFlow* framework optimized using Intel® Math Kernel Library for Deep Neural Networks (Intel® MKL-DNN) primitives, the `Intel MKL`_ version. @@ -48,9 +52,6 @@ This section describes running the `TensorFlow benchmarks`_ in single node. For Download and run either the `Eigen`_ or the `Intel MKL-DNN`_ docker image from hub.docker.com. The next commands will take place in the running container. Replace with the name of the image. -Download and run either of these from the `Clear Linxu Docker Hub page`_. -The next commands will take place in the running container. - .. note:: Replace with the name of the image. @@ -75,7 +76,7 @@ The next commands will take place in the running container. Kubeflow Multinode benchmarks ============================= -The benchmark workload will run in a Kubernetes container. We will use Kubeflow and deploy three nodes for this tutorial to get a decent return. +The benchmark workload will run in a Kubernetes container. We will use Kubeflow and deploy three nodes for this tutorial to show resource management and get sufficient output data for evaluation. Kubernetes setup **************** @@ -94,7 +95,7 @@ comfortable with another network layer, refer to the Kubernetes Images ****** -We need to create a docker image that includes `launcher.py` to +We need to add `launcher.py` to our docker image to include the |CL| Deep Learning Stack, and put the benchmarks repo in the right location. From the docker image, run the following: @@ -160,7 +161,7 @@ This creates the CustomResourceDefinition(CRD) endpoint to launch a TFJob. Running the Deep Learning as a Service TFJob ============================================ -The jsonnet template files for ResNet50 and Alexnet are available in the |CL| +The `jsonnet template files`_ for ResNet50 and Alexnet are available in the |CL| Deep Learning Stack repository. Download and copy these files into: .. code-block:: console @@ -184,7 +185,7 @@ Results You need to parse the logs of the Kubernetes pod to get the performance numbers. The pods will still be around post completion and will be in ‘Completed’ state. You can get the logs from any of the pods to inspect the -benchmark results. +benchmark results. More information about `Kubernetes logging`_ is available from the Kubernetes community. .. To-Dos @@ -209,3 +210,7 @@ benchmark results. .. _release notes for the Clear Linux Deep Learning Stack: https://github.com/clearlinux/dockerfiles/tree/master/stacks/dlaas .. _Clear Linux Docker Hub page: https://hub.docker.com/u/clearlinux/ + +.. _jsonnet template files: https://github.com/clearlinux/dockerfiles/tree/master/stacks/dlaas/kubeflow/dlaas-tfjob/dlaas-bench/prototypes + +.. _Kubernetes logging: https://kubernetes.io/docs/concepts/cluster-administration/logging/ From af3e84e2923fe902a1e14659cf96c9d6ba3cd6b4 Mon Sep 17 00:00:00 2001 From: Beth Dean Date: Wed, 5 Dec 2018 10:33:04 -0800 Subject: [PATCH 16/26] renaming file --- source/clear-linux/tutorials/{dlaas-benchmarks.rst => dlaas.rst} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename source/clear-linux/tutorials/{dlaas-benchmarks.rst => dlaas.rst} (100%) diff --git a/source/clear-linux/tutorials/dlaas-benchmarks.rst b/source/clear-linux/tutorials/dlaas.rst similarity index 100% rename from source/clear-linux/tutorials/dlaas-benchmarks.rst rename to source/clear-linux/tutorials/dlaas.rst From 1faf329bed6157cc1dbfca3883381718f522925e Mon Sep 17 00:00:00 2001 From: Beth Dean Date: Wed, 5 Dec 2018 13:49:01 -0800 Subject: [PATCH 17/26] changing from Clear Linux DLS to Intel DLS --- source/clear-linux/tutorials/dlaas.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source/clear-linux/tutorials/dlaas.rst b/source/clear-linux/tutorials/dlaas.rst index 28e4f3ab..d75c23a4 100644 --- a/source/clear-linux/tutorials/dlaas.rst +++ b/source/clear-linux/tutorials/dlaas.rst @@ -4,12 +4,12 @@ Deep Learning as a Service ########################## This tutorial explains how to run benchmarking workloads in |CL-ATTR| using -TensorFlow* and Kubeflow with the Clear Linux* Deep Learning Stack. +TensorFlow* and Kubeflow with the Intel® Deep Learning Stack. Release notes ============= -View current `release notes for the Clear Linux Deep Learning Stack`_. +View current `release notes`_ for the Intel® Deep Learning Stack. Prerequisites ============= @@ -42,7 +42,7 @@ We have validated these steps against the following software package versions * Kubernetes 1.11.3 * Go 1.11.12 -The |CL| Deep Learning Stack is available in two versions. First, a version that includes TensorFlow* optimized for Intel Architecture, the `Eigen`_ version, and a version that includes the TensorFlow* framework optimized using Intel® Math Kernel Library for Deep Neural Networks (Intel® MKL-DNN) primitives, the `Intel MKL`_ version. +The Intel® Deep Learning Stack is available in two versions. First, a version that includes TensorFlow* optimized for Intel Architecture, the `Eigen`_ version, and a version that includes the TensorFlow* framework optimized using Intel® Math Kernel Library for Deep Neural Networks (Intel® MKL-DNN) primitives, the `Intel MKL`_ version. TensorFlow* Single and Multi Node Benchmarks ============================================ @@ -96,7 +96,7 @@ Images ****** We need to add `launcher.py` to our docker image to -include the |CL| Deep Learning Stack, and put the benchmarks repo in the +include the Intel® Deep Learning Stack, and put the benchmarks repo in the right location. From the docker image, run the following: .. code-block:: bash @@ -161,7 +161,7 @@ This creates the CustomResourceDefinition(CRD) endpoint to launch a TFJob. Running the Deep Learning as a Service TFJob ============================================ -The `jsonnet template files`_ for ResNet50 and Alexnet are available in the |CL| +The `jsonnet template files`_ for ResNet50 and Alexnet are available in the Intel® Deep Learning Stack repository. Download and copy these files into: .. code-block:: console @@ -207,7 +207,7 @@ benchmark results. More information about `Kubernetes logging`_ is available fro .. _Eigen: https://hub.docker.com/r/clearlinux/stacks-dlaas-oss/ .. _Intel MKL-DNN: https://hub.docker.com/r/clearlinux/stacks-dlaas-mkl/ -.. _release notes for the Clear Linux Deep Learning Stack: https://github.com/clearlinux/dockerfiles/tree/master/stacks/dlaas +.. _release notes: https://github.com/clearlinux/dockerfiles/tree/master/stacks/dlaas .. _Clear Linux Docker Hub page: https://hub.docker.com/u/clearlinux/ From 09ee3d9b0f6d372247425c6421d625244bcc02e3 Mon Sep 17 00:00:00 2001 From: Michael Vincerra Date: Wed, 5 Dec 2018 17:07:34 -0800 Subject: [PATCH 18/26] Revise for narrative flow to explain use cases: - Revises mention of container-basic requirement - Adds TODOs for follow up Signed-off-by: Michael Vincerra --- source/clear-linux/tutorials/dlaas.rst | 30 ++++++++++++++++++++------ 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/source/clear-linux/tutorials/dlaas.rst b/source/clear-linux/tutorials/dlaas.rst index d75c23a4..5d889c95 100644 --- a/source/clear-linux/tutorials/dlaas.rst +++ b/source/clear-linux/tutorials/dlaas.rst @@ -16,7 +16,7 @@ Prerequisites * |CL| is installed on host system. If not, :ref:`bare-metal-install` * `containers-basic` bundle is installed -* `cloud-native-basic` bundle is installed (includes kubernetes) +* `cloud-native-basic` bundle is installed In |CL|, `containers-basic` provides Docker*, which is required for TensorFlow benchmarking. Use the :command:`swupd` utility to check if @@ -30,7 +30,9 @@ If you need to install the `containers-basic` or `cloud-native-basic`, enter: .. code-block:: bash - sudo swupd bundle-add containers-basic + sudo swupd bundle-add containers-basic cloud-native-basic + +.. TODO: Resolve issue: Are we installing kubernetes in the bare metal or in the Virtual environment. F-up with DnPlas, bd-dean To ensure that kubernetes is correctly installed and configured, :ref:`kubernetes`. @@ -42,14 +44,23 @@ We have validated these steps against the following software package versions * Kubernetes 1.11.3 * Go 1.11.12 -The Intel® Deep Learning Stack is available in two versions. First, a version that includes TensorFlow* optimized for Intel Architecture, the `Eigen`_ version, and a version that includes the TensorFlow* framework optimized using Intel® Math Kernel Library for Deep Neural Networks (Intel® MKL-DNN) primitives, the `Intel MKL`_ version. +The Intel® Deep Learning Stack is available in two versions. First, a +version that includes TensorFlow* optimized for Intel Architecture, the +`Eigen`_ version. Second, there is a version that includes the TensorFlow* +framework optimized using Intel® Math Kernel Library for Deep Neural +Networks (Intel® MKL-DNN) primitives, the `Intel MKL`_ version. TensorFlow* Single and Multi Node Benchmarks ============================================ -This section describes running the `TensorFlow benchmarks`_ in single node. For multi node testing replicate these steps for each node. These steps provide a template to run other benchmarks, providing they can invoke TensorFlow. +This section describes running the `TensorFlow benchmarks`_ in single node. +For multi node testing replicate these steps for each node. These steps +provide a template to run other benchmarks, providing they can invoke +TensorFlow. -Download and run either the `Eigen`_ or the `Intel MKL-DNN`_ docker image from hub.docker.com. The next commands will take place in the running container. Replace with the name of the image. +Download and run either the `Eigen`_ or the `Intel MKL-DNN`_ docker image +from hub.docker.com. The next commands will take place in the running +container. Replace with the name of the image. .. note:: @@ -76,13 +87,18 @@ Download and run either the `Eigen`_ or the `Intel MKL-DNN`_ docker image from Kubeflow Multinode benchmarks ============================= -The benchmark workload will run in a Kubernetes container. We will use Kubeflow and deploy three nodes for this tutorial to show resource management and get sufficient output data for evaluation. +The benchmark workload will run in a Kubernetes container. We will use +Kubeflow and deploy three nodes for this tutorial to show resource +management and get sufficient output data for evaluation. Kubernetes setup **************** Follow the instructions in the :ref:`kubernetes` tutorial to get set up on -|CL|. The kubernetes community also has `instructions for creating a cluster`_. +|CL|. The kubernetes community also has +`instructions for creating a cluster`_. + +.. TODO: Confirm by review of DnPlas answer to thread of email. Kubernetes networking ********************* From 5ae7faa7e3940ce56213913ba289d5d399387a36 Mon Sep 17 00:00:00 2001 From: Michael Vincerra Date: Thu, 6 Dec 2018 11:32:08 -0800 Subject: [PATCH 19/26] Organizational and line-edits include: - Moved and revised summary para. of 2 versions to intro - Added internal TOC for user nav - Simplified Prerequisites - Revise para. as numbered steps in TensorFlow single and multi-node - Revised for consistent use of multi-node - Added URIs for TensorFlow and KubeFlow Signed-off-by: Michael Vincerra --- source/clear-linux/tutorials/dlaas.rst | 81 ++++++++++++++------------ 1 file changed, 44 insertions(+), 37 deletions(-) diff --git a/source/clear-linux/tutorials/dlaas.rst b/source/clear-linux/tutorials/dlaas.rst index 5d889c95..3f4cf4e5 100644 --- a/source/clear-linux/tutorials/dlaas.rst +++ b/source/clear-linux/tutorials/dlaas.rst @@ -3,22 +3,35 @@ Deep Learning as a Service ########################## -This tutorial explains how to run benchmarking workloads in |CL-ATTR| using -TensorFlow* and Kubeflow with the Intel® Deep Learning Stack. +This tutorial shows you how to run benchmarking workloads in |CL-ATTR| using +TensorFlow\* and Kubeflow with the Intel® Deep Learning Stack. + +The Intel® Deep Learning Stack is available in two versions. The first is +`Eigen`_, which includes `TensorFlow`_ optimized for Intel® architecture. The +second is `Intel MKL`_, which includes the TensorFlow framework optimized +using Intel® Math Kernel Library for Deep Neural Networks (Intel® MKL-DNN) +primitives. + +.. contents:: :local: + :depth: 1 Release notes ============= View current `release notes`_ for the Intel® Deep Learning Stack. +.. note:: + + Performance test numbers in the Intel® Deep Learning Stack were obtained using `runc` as the runtime. + Prerequisites ============= -* |CL| is installed on host system. If not, :ref:`bare-metal-install` -* `containers-basic` bundle is installed -* `cloud-native-basic` bundle is installed +* |CL| installed on host system. If not installed, :ref:`bare-metal-install` +* `containers-basic` bundle +* `cloud-native-basic` bundle -In |CL|, `containers-basic` provides Docker*, which is required for +In |CL|, `containers-basic` provides Docker\*, which is required for TensorFlow benchmarking. Use the :command:`swupd` utility to check if `containers-basic` and `cloud-native-basic` are present: @@ -32,48 +45,41 @@ If you need to install the `containers-basic` or `cloud-native-basic`, enter: sudo swupd bundle-add containers-basic cloud-native-basic -.. TODO: Resolve issue: Are we installing kubernetes in the bare metal or in the Virtual environment. F-up with DnPlas, bd-dean - To ensure that kubernetes is correctly installed and configured, :ref:`kubernetes`. -We have validated these steps against the following software package versions +We have validated these steps against the following software package +versions: * |CL| 26240--lowest version permissible. * Docker 18.06.1 * Kubernetes 1.11.3 * Go 1.11.12 -The Intel® Deep Learning Stack is available in two versions. First, a -version that includes TensorFlow* optimized for Intel Architecture, the -`Eigen`_ version. Second, there is a version that includes the TensorFlow* -framework optimized using Intel® Math Kernel Library for Deep Neural -Networks (Intel® MKL-DNN) primitives, the `Intel MKL`_ version. - -TensorFlow* Single and Multi Node Benchmarks +TensorFlow single and multi-node benchmarks ============================================ This section describes running the `TensorFlow benchmarks`_ in single node. -For multi node testing replicate these steps for each node. These steps -provide a template to run other benchmarks, providing they can invoke +For multi-node testing, replicate these steps for each node. These steps +provide a template to run other benchmarks, provided that they can invoke TensorFlow. -Download and run either the `Eigen`_ or the `Intel MKL-DNN`_ docker image -from hub.docker.com. The next commands will take place in the running -container. Replace with the name of the image. +#. Download and run either the `Eigen`_ or the `Intel MKL-DNN`_ docker image + from `Docker Hub`_. + .. note:: -.. note:: + You will enter the following commands in the running container. - Replace with the name of the image. + Replace with the name of the image. -#. First, clone the benchmark repository: +#. Clone the benchmark repository: .. code-block:: bash docker exec -t bash -c ‘git clone http://github.com/tensorflow/benchmarks -b cnn_tf_v1.11_compatible’ -#. Next, execute the benchmark script to run the benchmark +#. Next, execute the benchmark script to run the benchmark. .. code-block:: bash @@ -84,11 +90,11 @@ container. Replace with the name of the image. You can replace the model with one of your choice supported by the TensorFlow benchmarks. -Kubeflow Multinode benchmarks +Kubeflow multi-node benchmarks ============================= The benchmark workload will run in a Kubernetes container. We will use -Kubeflow and deploy three nodes for this tutorial to show resource +`Kubeflow`_ and deploy three nodes for this tutorial to show resource management and get sufficient output data for evaluation. Kubernetes setup @@ -103,7 +109,7 @@ Follow the instructions in the :ref:`kubernetes` tutorial to get set up on Kubernetes networking ********************* -We have used `flannel`_ as the network provider for these tests. If you are +We used `flannel`_ as the network provider for these tests. If you are comfortable with another network layer, refer to the Kubernetes `networking documentation`_ for setup. @@ -111,9 +117,9 @@ comfortable with another network layer, refer to the Kubernetes Images ****** -We need to add `launcher.py` to our docker image to -include the Intel® Deep Learning Stack, and put the benchmarks repo in the -right location. From the docker image, run the following: +We need to add `launcher.py` to our docker image to include the Intel® Deep +Learning Stack and put the benchmarks repo in the correct location. From the +docker image, run the following: .. code-block:: bash @@ -125,12 +131,12 @@ right location. From the docker image, run the following: Your entry point now becomes "/opt/launcher.py". This will build an image which can be consumed directly by TFJob from -kubeflow. We are working to create these images as part of our release +kubeflow. We are working to create these images as part of our release cycle. -ksonnet* -******** +ksonnet\* +********* Kubeflow uses ksonnet* to manage deployments, so we need to install that before setting up Kubeflow. On |CL|, follow these steps: @@ -149,7 +155,7 @@ accessible across the environment. Kubeflow ******** -Once you have Kubernetes running on your nodes, you can setup Kubeflow by following these instructions from their `quick start guide`_. +Once you have Kubernetes running on your nodes, you can setup `Kubeflow`_ by following these instructions from their `quick start guide`_. .. code-block:: bash @@ -212,8 +218,9 @@ benchmark results. More information about `Kubernetes logging`_ is available fro .. The downstream dockerfile will generate another image with benchmarks repo and launcher.py file in the right locations. .. Dynamic generation of ksonnet template files for a matrix of batch_size, model and replicas. - - +.. TensorFlow: https://www.tensorflow.org/ +.. _Kubeflow: https://www.kubeflow.org/ +.. _Docker Hub: https://hub.docker.com/ .. _TensorFlow benchmarks: https://www.tensorflow.org/guide/performance/benchmarks .. _instructions for creating a cluster: https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/ .. _flannel: https://github.com/coreos/flannel From 61cfc256a556024eaac5a66b3cc2fa30dfb58939 Mon Sep 17 00:00:00 2001 From: Michael Vincerra Date: Thu, 6 Dec 2018 14:35:35 -0800 Subject: [PATCH 20/26] Revisions include: - Updates section on Kubeflow per DnPlas comments - Fixes broken URLs - Fixes formatting for rendering Signed-off-by: Michael Vincerra --- source/clear-linux/tutorials/dlaas.rst | 53 ++++++++++---------------- 1 file changed, 21 insertions(+), 32 deletions(-) diff --git a/source/clear-linux/tutorials/dlaas.rst b/source/clear-linux/tutorials/dlaas.rst index 3f4cf4e5..2069a288 100644 --- a/source/clear-linux/tutorials/dlaas.rst +++ b/source/clear-linux/tutorials/dlaas.rst @@ -8,7 +8,7 @@ TensorFlow\* and Kubeflow with the Intel® Deep Learning Stack. The Intel® Deep Learning Stack is available in two versions. The first is `Eigen`_, which includes `TensorFlow`_ optimized for Intel® architecture. The -second is `Intel MKL`_, which includes the TensorFlow framework optimized +second is `Intel MKL-DNN`_, which includes the TensorFlow framework optimized using Intel® Math Kernel Library for Deep Neural Networks (Intel® MKL-DNN) primitives. @@ -91,7 +91,7 @@ TensorFlow. TensorFlow benchmarks. Kubeflow multi-node benchmarks -============================= +============================== The benchmark workload will run in a Kubernetes container. We will use `Kubeflow`_ and deploy three nodes for this tutorial to show resource @@ -104,8 +104,6 @@ Follow the instructions in the :ref:`kubernetes` tutorial to get set up on |CL|. The kubernetes community also has `instructions for creating a cluster`_. -.. TODO: Confirm by review of DnPlas answer to thread of email. - Kubernetes networking ********************* @@ -113,7 +111,6 @@ We used `flannel`_ as the network provider for these tests. If you are comfortable with another network layer, refer to the Kubernetes `networking documentation`_ for setup. - Images ****** @@ -134,7 +131,6 @@ This will build an image which can be consumed directly by TFJob from kubeflow. We are working to create these images as part of our release cycle. - ksonnet\* ********* @@ -159,32 +155,35 @@ Once you have Kubernetes running on your nodes, you can setup `Kubeflow`_ by fol .. code-block:: bash - export KUBEFLOW_SRC=$HOME/kflow - export KUBEFLOW_TAG=”v0.3.2” - export KFAPP=”kflow_app” - export K8S_NAMESPACE=”kubeflow” - mkdir ${KUBEFLOW_SRC} - cd ${KUBEFLOW_SRC} - curl https://raw.githubusercontent.com/kubeflow/kubeflow/${KUBEFLOW_TAG}/scripts/download.sh | bash - ${KUBEFLOW_SRC}/scripts/kfctl.sh init ${KFAPP} --platform none - cd ${KFAPP} - ${KUBEFLOW_SRC}/scripts/kfctl.sh generate k8s + export KUBEFLOW_SRC=$HOME/kflow + export KUBEFLOW_TAG=”v0.3.2” + export KFAPP=”kflow_app” + export K8S_NAMESPACE=”kubeflow” + mkdir ${KUBEFLOW_SRC} + cd ${KUBEFLOW_SRC} + curl https://raw.githubusercontent.com/kubeflow/kubeflow/${KUBEFLOW_TAG}/scripts/download.sh | bash + ${KUBEFLOW_SRC}/scripts/kfctl.sh init ${KFAPP} --platform none + cd ${KFAPP} + ${KUBEFLOW_SRC}/scripts/kfctl.sh generate k8s Now you have all the required kubeflow packages, and you can deploy the primary one for our purposes: tf-job-operator. .. code-block:: bash - kubectl create namespace ${K8S_NAMESPACE} - ks env add default --namespace "${K8S_NAMESPACE}" - ks apply default -c tf-job-operator + ks env rm default + kubectl create namespace ${K8S_NAMESPACE} + ks env add default --namespace "${K8S_NAMESPACE}" + ks generate tf-job-operator tf-job-operator + ks apply default -c tf-job-operator This creates the CustomResourceDefinition(CRD) endpoint to launch a TFJob. Running the Deep Learning as a Service TFJob ============================================ -The `jsonnet template files`_ for ResNet50 and Alexnet are available in the Intel® -Deep Learning Stack repository. Download and copy these files into: +The `jsonnet template files`_ for ResNet50 and Alexnet are available in +the Intel® Deep Learning Stack repository. Download and copy these files +into: .. code-block:: console @@ -201,7 +200,6 @@ Next, generate Kubernetes manifests for the workloads and apply them to create a This will replicate and deploy three test setups in your Kubernetes cluster. - Results ======= You need to parse the logs of the Kubernetes pod to get the performance @@ -209,16 +207,7 @@ numbers. The pods will still be around post completion and will be in ‘Completed’ state. You can get the logs from any of the pods to inspect the benchmark results. More information about `Kubernetes logging`_ is available from the Kubernetes community. -.. To-Dos - -.. Make kubeflow docker images along with release images. -.. Another set of jsonnet files for MKL. -.. Trim down the base DLaaS image to contain tensorflow bundle and nothing else. -.. CI will throw benchmarks into the repo and be able to test it. -.. The downstream dockerfile will generate another image with benchmarks repo and launcher.py file in the right locations. -.. Dynamic generation of ksonnet template files for a matrix of batch_size, model and replicas. - -.. TensorFlow: https://www.tensorflow.org/ +.. _TensorFlow: https://www.tensorflow.org/ .. _Kubeflow: https://www.kubeflow.org/ .. _Docker Hub: https://hub.docker.com/ .. _TensorFlow benchmarks: https://www.tensorflow.org/guide/performance/benchmarks From 62cdbe1439f1009cf6a2cfbce7a8d52422874907 Mon Sep 17 00:00:00 2001 From: Michael Vincerra Date: Thu, 6 Dec 2018 15:22:38 -0800 Subject: [PATCH 21/26] Revisions applied: - KubeFlow section per feedback from DnPls - TFJob section added numbered steps and added new URL link Signed-off-by: Michael Vincerra --- source/clear-linux/tutorials/dlaas.rst | 43 ++++++++++++++++---------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/source/clear-linux/tutorials/dlaas.rst b/source/clear-linux/tutorials/dlaas.rst index 2069a288..1a112a4a 100644 --- a/source/clear-linux/tutorials/dlaas.rst +++ b/source/clear-linux/tutorials/dlaas.rst @@ -151,7 +151,8 @@ accessible across the environment. Kubeflow ******** -Once you have Kubernetes running on your nodes, you can setup `Kubeflow`_ by following these instructions from their `quick start guide`_. +Once you have Kubernetes running on your nodes, you can setup `Kubeflow`_ by +following these instructions from their `quick start guide`_. .. code-block:: bash @@ -159,12 +160,13 @@ Once you have Kubernetes running on your nodes, you can setup `Kubeflow`_ by fol export KUBEFLOW_TAG=”v0.3.2” export KFAPP=”kflow_app” export K8S_NAMESPACE=”kubeflow” + mkdir ${KUBEFLOW_SRC} cd ${KUBEFLOW_SRC} - curl https://raw.githubusercontent.com/kubeflow/kubeflow/${KUBEFLOW_TAG}/scripts/download.sh | bash - ${KUBEFLOW_SRC}/scripts/kfctl.sh init ${KFAPP} --platform none + ks init ${KFAPP} cd ${KFAPP} - ${KUBEFLOW_SRC}/scripts/kfctl.sh generate k8s + ks registry add kubeflow github.com/kubeflow/kubeflow/tree/${KUBEFLOW_TAG}/kubeflow + ks pkg install kubeflow/core Now you have all the required kubeflow packages, and you can deploy the primary one for our purposes: tf-job-operator. @@ -181,22 +183,31 @@ This creates the CustomResourceDefinition(CRD) endpoint to launch a TFJob. Running the Deep Learning as a Service TFJob ============================================ -The `jsonnet template files`_ for ResNet50 and Alexnet are available in -the Intel® Deep Learning Stack repository. Download and copy these files -into: +#. Select this link for the `DLaaS ksonnet registries for deploying TFJobs`_. -.. code-block:: console + #. Install DLaaS TFJob componets as follows: - ${KUBEFLOW_SRC}/${KFAPP}/vendor/kubeflow/examples/prototypes/ + .. code-block:: bash -Next, generate Kubernetes manifests for the workloads and apply them to create and run them using these commands + ks registry add dlaas-tfjob github.com/clearlinux/dockerfiles/tree/master/stacks/dlaas/kubeflow/dlaas-tfjob -.. code-block:: bash + ks pkg install dlaas-tfjob/dlaas-bench - ks generate dlaas-resnet50 dlaasresnet50 --name=dlaasresnet50 - ks generate dlaas-alexnet dlaasalexnet --name=dlaasalexnet - ks apply default -c dlaasresnet50 - ks apply default -c dlaasalexnet +#. Download and copy these files into: + + .. code-block:: console + + ${KUBEFLOW_SRC}/${KFAPP}/vendor/kubeflow/examples/prototypes/ + +#. Next, generate Kubernetes manifests for the workloads and apply them to + create and run them using these commands + + .. code-block:: bash + + ks generate dlaas-resnet50 dlaasresnet50 --name=dlaasresnet50 + ks generate dlaas-alexnet dlaasalexnet --name=dlaasalexnet + ks apply default -c dlaasresnet50 + ks apply default -c dlaasalexnet This will replicate and deploy three test setups in your Kubernetes cluster. @@ -223,6 +234,6 @@ benchmark results. More information about `Kubernetes logging`_ is available fro .. _Clear Linux Docker Hub page: https://hub.docker.com/u/clearlinux/ -.. _jsonnet template files: https://github.com/clearlinux/dockerfiles/tree/master/stacks/dlaas/kubeflow/dlaas-tfjob/dlaas-bench/prototypes +.. _DLaaS ksonnet registries for deploying TFJobs: https://github.com/clearlinux/dockerfiles/tree/master/stacks/dlaas/kubeflow/dlaas-tfjob .. _Kubernetes logging: https://kubernetes.io/docs/concepts/cluster-administration/logging/ From 5a2114019480304227dfaaa566d67d7bdc159ef6 Mon Sep 17 00:00:00 2001 From: Michael Vincerra Date: Thu, 6 Dec 2018 18:28:29 -0800 Subject: [PATCH 22/26] Applies product name change per tvb. Signed-off-by: Michael Vincerra --- source/clear-linux/tutorials/dlaas.rst | 27 +++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/source/clear-linux/tutorials/dlaas.rst b/source/clear-linux/tutorials/dlaas.rst index 1a112a4a..4cd36e88 100644 --- a/source/clear-linux/tutorials/dlaas.rst +++ b/source/clear-linux/tutorials/dlaas.rst @@ -1,16 +1,16 @@ .. _dlaas: -Deep Learning as a Service -########################## +Intel® Deep Learning as a Service Stack +####################################### This tutorial shows you how to run benchmarking workloads in |CL-ATTR| using -TensorFlow\* and Kubeflow with the Intel® Deep Learning Stack. +TensorFlow\* and Kubeflow with the Intel® Deep Learning as a Service Stack. -The Intel® Deep Learning Stack is available in two versions. The first is -`Eigen`_, which includes `TensorFlow`_ optimized for Intel® architecture. The -second is `Intel MKL-DNN`_, which includes the TensorFlow framework optimized -using Intel® Math Kernel Library for Deep Neural Networks (Intel® MKL-DNN) -primitives. +The Intel® Deep Learning as a Service Stack is available in two versions. +The first is `Eigen`_, which includes `TensorFlow`_ optimized for Intel® +architecture. The second is `Intel MKL-DNN`_, which includes the TensorFlow +framework optimized using Intel® Math Kernel Library for Deep Neural +Networks (Intel® MKL-DNN) primitives. .. contents:: :local: :depth: 1 @@ -18,11 +18,12 @@ primitives. Release notes ============= -View current `release notes`_ for the Intel® Deep Learning Stack. +View current `release notes`_ for the Intel® Deep Learning as a Service +Stack. .. note:: - Performance test numbers in the Intel® Deep Learning Stack were obtained using `runc` as the runtime. + Performance test numbers in the Intel® Deep Learning as a Service Stack were obtained using `runc` as the runtime. Prerequisites ============= @@ -151,7 +152,7 @@ accessible across the environment. Kubeflow ******** -Once you have Kubernetes running on your nodes, you can setup `Kubeflow`_ by +Once you have Kubernetes running on your nodes, you can setup `Kubeflow`_ by following these instructions from their `quick start guide`_. .. code-block:: bash @@ -180,8 +181,8 @@ Now you have all the required kubeflow packages, and you can deploy the primary This creates the CustomResourceDefinition(CRD) endpoint to launch a TFJob. -Running the Deep Learning as a Service TFJob -============================================ +Running an Intel Deep Learning as a Service Stack TFJob +======================================================= #. Select this link for the `DLaaS ksonnet registries for deploying TFJobs`_. From 239ecb2cffeadcb6f5c6c0ac327b625bcf9a9ffa Mon Sep 17 00:00:00 2001 From: Michael Vincerra Date: Fri, 7 Dec 2018 14:07:57 -0800 Subject: [PATCH 23/26] Revisions for new name include: - Filename revised to dlrs.rst - Revised Deep Learning as a Service to Deep Learning Reference Stack - Applies revisions per DnPlas--editorial - Removes lines 197-201, per DnPls, deleting step. Signed-off-by: Michael Vincerra --- source/clear-linux/tutorials/dlrs.rst | 232 ++++++++++++++++++++++++++ 1 file changed, 232 insertions(+) create mode 100644 source/clear-linux/tutorials/dlrs.rst diff --git a/source/clear-linux/tutorials/dlrs.rst b/source/clear-linux/tutorials/dlrs.rst new file mode 100644 index 00000000..fd7885cd --- /dev/null +++ b/source/clear-linux/tutorials/dlrs.rst @@ -0,0 +1,232 @@ +.. _dlrs: + +Deep Learning Reference Stack +############################# + +This tutorial shows you how to run benchmarking workloads in |CL-ATTR| using +TensorFlow\* and Kubeflow with the Deep Learning Reference Stack. + +The Deep Learning Reference Stack is available in two versions. +The first is `Eigen`_, which includes `TensorFlow`_ optimized for Intel® +architecture. The second is `Intel MKL-DNN`_, which includes the TensorFlow +framework optimized using Intel® Math Kernel Library for Deep Neural +Networks (Intel® MKL-DNN) primitives. + +.. contents:: :local: + :depth: 1 + +Release notes +============= + +View current `release notes`_ for the Deep Learning Reference Stack. + +.. note:: + + Performance test numbers in the Deep Learning Reference Stack were obtained using `runc` as the runtime. + +Prerequisites +============= + +* |CL| installed on host system. If not installed, :ref:`bare-metal-install` +* `containers-basic` bundle +* `cloud-native-basic` bundle + +In |CL|, `containers-basic` provides Docker\*, which is required for +TensorFlow benchmarking. Use the :command:`swupd` utility to check if +`containers-basic` and `cloud-native-basic` are present: + +.. code-block:: bash + + sudo swupd bundle-list + +If you need to install the `containers-basic` or `cloud-native-basic`, enter: + +.. code-block:: bash + + sudo swupd bundle-add containers-basic cloud-native-basic + +To ensure that kubernetes is correctly installed and configured, +:ref:`kubernetes`. + +We have validated these steps against the following software package +versions: + +* |CL| 26240--lowest version permissible. +* Docker 18.06.1 +* Kubernetes 1.11.3 +* Go 1.11.12 + +TensorFlow single and multi-node benchmarks +============================================ + +This section describes running the `TensorFlow benchmarks`_ in single node. +For multi-node testing, replicate these steps for each node. These steps +provide a template to run other benchmarks, provided that they can invoke +TensorFlow. + +#. Download and run either the `Eigen`_ or the `Intel MKL-DNN`_ docker image + from `Docker Hub`_. + + .. note:: + + You will enter the following commands in the running container. + + Replace with the name of the image. + +#. Clone the benchmark repository: + + .. code-block:: bash + + docker exec -t bash -c ‘git clone http://github.com/tensorflow/benchmarks -b cnn_tf_v1.11_compatible’ + +#. Next, execute the benchmark script to run the benchmark. + + .. code-block:: bash + + docker exec -i bash -c ‘python benchmarks/scripts/tf_cnn_benchmarks/tf_cnn_benchmarks.py --device=cpu --model=resnet50 --data_format=NWHC ’. + + .. note:: + + You can replace the model with one of your choice supported by the + TensorFlow benchmarks. + +Kubeflow multi-node benchmarks +============================== + +The benchmark workload will run in a Kubernetes cluster. We will use +`Kubeflow`_ for the Machine Learning workload deployment on three nodes. + +Kubernetes setup +**************** + +Follow the instructions in the :ref:`kubernetes` tutorial to get set up on +|CL|. The kubernetes community also has +`instructions for creating a cluster`_. + +Kubernetes networking +********************* + +We used `flannel`_ as the network provider for these tests. If you are +comfortable with another network layer, refer to the Kubernetes +`networking documentation`_ for setup. + +Images +****** + +We need to add `launcher.py` to our docker image to include the Deep +Learning Reference Stack and put the benchmarks repo in the correct +location. From the docker image, run the following: + +.. code-block:: bash + + mkdir -p /opt + git clone https://github.com/tensorflow/benchmarks.git /opt/tf-benchmarks + cp launcher.py /opt + chmod u+x /opt/* + +Your entry point now becomes "/opt/launcher.py". + +This will build an image which can be consumed directly by TFJob from +kubeflow. We are working to create these images as part of our release +cycle. + +ksonnet\* +********* + +Kubeflow uses ksonnet* to manage deployments, so we need to install that before setting up Kubeflow. On |CL|, follow these steps: + +.. code-block:: bash + + swupd bundle-add go-basic-dev + export GOPATH=$HOME/go + export PATH=$PATH:$GOPATH/bin + go get github.com/ksonnet/ksonnet + cd $GOPATH/src/github.com/ksonnet/ksonnet + make install + +After the ksonnet installation is complete, ensure that binary `ks` is +accessible across the environment. + +Kubeflow +******** + +Once you have Kubernetes running on your nodes, you can setup `Kubeflow`_ by +following these instructions from their `quick start guide`_. + +.. code-block:: bash + + export KUBEFLOW_SRC=$HOME/kflow + export KUBEFLOW_TAG=”v0.3.2” + export KFAPP=”kflow_app” + export K8S_NAMESPACE=”kubeflow” + + mkdir ${KUBEFLOW_SRC} + cd ${KUBEFLOW_SRC} + ks init ${KFAPP} + cd ${KFAPP} + ks registry add kubeflow github.com/kubeflow/kubeflow/tree/${KUBEFLOW_TAG}/kubeflow + ks pkg install kubeflow/core + +Now you have all the required kubeflow packages, and you can deploy the primary one for our purposes: tf-job-operator. + +.. code-block:: bash + + ks env rm default + kubectl create namespace ${K8S_NAMESPACE} + ks env add default --namespace "${K8S_NAMESPACE}" + ks generate tf-job-operator tf-job-operator + ks apply default -c tf-job-operator + +This creates the CustomResourceDefinition(CRD) endpoint to launch a TFJob. + +Run a TFJob +=========== + +#. Select this link for the `ksonnet registries for deploying TFJobs`_. + + #. Install the TFJob componets as follows: + + .. code-block:: bash + + ks registry add dlaas-tfjob github.com/clearlinux/dockerfiles/tree/master/stacks/dlaas/kubeflow/dlaas-tfjob + + ks pkg install dlaas-tfjob/dlaas-bench + +#. Next, generate Kubernetes manifests for the workloads and apply them to + create and run them using these commands + + .. code-block:: bash + + ks generate dlaas-resnet50 dlaasresnet50 --name=dlaasresnet50 + ks generate dlaas-alexnet dlaasalexnet --name=dlaasalexnet + ks apply default -c dlaasresnet50 + ks apply default -c dlaasalexnet + +This will replicate and deploy three test setups in your Kubernetes cluster. + +Results +======= +You need to parse the logs of the Kubernetes pod to get the performance +numbers. The pods will still be around post completion and will be in +‘Completed’ state. You can get the logs from any of the pods to inspect the +benchmark results. More information about `Kubernetes logging`_ is available from the Kubernetes community. + +.. _TensorFlow: https://www.tensorflow.org/ +.. _Kubeflow: https://www.kubeflow.org/ +.. _Docker Hub: https://hub.docker.com/ +.. _TensorFlow benchmarks: https://www.tensorflow.org/guide/performance/benchmarks +.. _instructions for creating a cluster: https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/ +.. _flannel: https://github.com/coreos/flannel +.. _networking documentation: https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/#pod-network +.. _quick start guide: https://www.kubeflow.org/docs/started/getting-started/ + +.. _Eigen: https://hub.docker.com/r/clearlinux/stacks-dlaas-oss/ +.. _Intel MKL-DNN: https://hub.docker.com/r/clearlinux/stacks-dlaas-mkl/ + +.. _release notes: https://github.com/clearlinux/dockerfiles/tree/master/stacks/dlaas + +.. _Clear Linux Docker Hub page: https://hub.docker.com/u/clearlinux/ + +.. _ksonnet registries for deploying TFJobs: https://github.com/clearlinux/dockerfiles/tree/master/stacks/dlaas/kubeflow/dlaas-tfjob + +.. _Kubernetes logging: https://kubernetes.io/docs/concepts/cluster-administration/logging/ From ae1261daf316b85fea9438bccddd3e01e7ff5376 Mon Sep 17 00:00:00 2001 From: Michael Vincerra Date: Fri, 7 Dec 2018 14:10:23 -0800 Subject: [PATCH 24/26] Renames file from dlaas.rst to dlrs.rst. Signed-off-by: Michael Vincerra --- source/clear-linux/tutorials/dlaas.rst | 240 ------------------------- 1 file changed, 240 deletions(-) delete mode 100644 source/clear-linux/tutorials/dlaas.rst diff --git a/source/clear-linux/tutorials/dlaas.rst b/source/clear-linux/tutorials/dlaas.rst deleted file mode 100644 index 4cd36e88..00000000 --- a/source/clear-linux/tutorials/dlaas.rst +++ /dev/null @@ -1,240 +0,0 @@ -.. _dlaas: - -Intel® Deep Learning as a Service Stack -####################################### - -This tutorial shows you how to run benchmarking workloads in |CL-ATTR| using -TensorFlow\* and Kubeflow with the Intel® Deep Learning as a Service Stack. - -The Intel® Deep Learning as a Service Stack is available in two versions. -The first is `Eigen`_, which includes `TensorFlow`_ optimized for Intel® -architecture. The second is `Intel MKL-DNN`_, which includes the TensorFlow -framework optimized using Intel® Math Kernel Library for Deep Neural -Networks (Intel® MKL-DNN) primitives. - -.. contents:: :local: - :depth: 1 - -Release notes -============= - -View current `release notes`_ for the Intel® Deep Learning as a Service -Stack. - -.. note:: - - Performance test numbers in the Intel® Deep Learning as a Service Stack were obtained using `runc` as the runtime. - -Prerequisites -============= - -* |CL| installed on host system. If not installed, :ref:`bare-metal-install` -* `containers-basic` bundle -* `cloud-native-basic` bundle - -In |CL|, `containers-basic` provides Docker\*, which is required for -TensorFlow benchmarking. Use the :command:`swupd` utility to check if -`containers-basic` and `cloud-native-basic` are present: - -.. code-block:: bash - - sudo swupd bundle-list - -If you need to install the `containers-basic` or `cloud-native-basic`, enter: - -.. code-block:: bash - - sudo swupd bundle-add containers-basic cloud-native-basic - -To ensure that kubernetes is correctly installed and configured, -:ref:`kubernetes`. - -We have validated these steps against the following software package -versions: - -* |CL| 26240--lowest version permissible. -* Docker 18.06.1 -* Kubernetes 1.11.3 -* Go 1.11.12 - -TensorFlow single and multi-node benchmarks -============================================ - -This section describes running the `TensorFlow benchmarks`_ in single node. -For multi-node testing, replicate these steps for each node. These steps -provide a template to run other benchmarks, provided that they can invoke -TensorFlow. - -#. Download and run either the `Eigen`_ or the `Intel MKL-DNN`_ docker image - from `Docker Hub`_. - - .. note:: - - You will enter the following commands in the running container. - - Replace with the name of the image. - -#. Clone the benchmark repository: - - .. code-block:: bash - - docker exec -t bash -c ‘git clone http://github.com/tensorflow/benchmarks -b cnn_tf_v1.11_compatible’ - -#. Next, execute the benchmark script to run the benchmark. - - .. code-block:: bash - - docker exec -i bash -c ‘python benchmarks/scripts/tf_cnn_benchmarks/tf_cnn_benchmarks.py --device=cpu --model=resnet50 --data_format=NWHC ’. - - .. note:: - - You can replace the model with one of your choice supported by the - TensorFlow benchmarks. - -Kubeflow multi-node benchmarks -============================== - -The benchmark workload will run in a Kubernetes container. We will use -`Kubeflow`_ and deploy three nodes for this tutorial to show resource -management and get sufficient output data for evaluation. - -Kubernetes setup -**************** - -Follow the instructions in the :ref:`kubernetes` tutorial to get set up on -|CL|. The kubernetes community also has -`instructions for creating a cluster`_. - -Kubernetes networking -********************* - -We used `flannel`_ as the network provider for these tests. If you are -comfortable with another network layer, refer to the Kubernetes -`networking documentation`_ for setup. - -Images -****** - -We need to add `launcher.py` to our docker image to include the Intel® Deep -Learning Stack and put the benchmarks repo in the correct location. From the -docker image, run the following: - -.. code-block:: bash - - mkdir -p /opt - git clone https://github.com/tensorflow/benchmarks.git /opt/tf-benchmarks - cp launcher.py /opt - chmod u+x /opt/* - -Your entry point now becomes "/opt/launcher.py". - -This will build an image which can be consumed directly by TFJob from -kubeflow. We are working to create these images as part of our release -cycle. - -ksonnet\* -********* - -Kubeflow uses ksonnet* to manage deployments, so we need to install that before setting up Kubeflow. On |CL|, follow these steps: - -.. code-block:: bash - - swupd bundle-add go-basic-dev - export GOPATH=$HOME/go - export PATH=$PATH:$GOPATH/bin - go get github.com/ksonnet/ksonnet - cd $GOPATH/src/github.com/ksonnet/ksonnet - make install - -After the ksonnet installation is complete, ensure that binary `ks` is -accessible across the environment. - -Kubeflow -******** - -Once you have Kubernetes running on your nodes, you can setup `Kubeflow`_ by -following these instructions from their `quick start guide`_. - -.. code-block:: bash - - export KUBEFLOW_SRC=$HOME/kflow - export KUBEFLOW_TAG=”v0.3.2” - export KFAPP=”kflow_app” - export K8S_NAMESPACE=”kubeflow” - - mkdir ${KUBEFLOW_SRC} - cd ${KUBEFLOW_SRC} - ks init ${KFAPP} - cd ${KFAPP} - ks registry add kubeflow github.com/kubeflow/kubeflow/tree/${KUBEFLOW_TAG}/kubeflow - ks pkg install kubeflow/core - -Now you have all the required kubeflow packages, and you can deploy the primary one for our purposes: tf-job-operator. - -.. code-block:: bash - - ks env rm default - kubectl create namespace ${K8S_NAMESPACE} - ks env add default --namespace "${K8S_NAMESPACE}" - ks generate tf-job-operator tf-job-operator - ks apply default -c tf-job-operator - -This creates the CustomResourceDefinition(CRD) endpoint to launch a TFJob. - -Running an Intel Deep Learning as a Service Stack TFJob -======================================================= - -#. Select this link for the `DLaaS ksonnet registries for deploying TFJobs`_. - - #. Install DLaaS TFJob componets as follows: - - .. code-block:: bash - - ks registry add dlaas-tfjob github.com/clearlinux/dockerfiles/tree/master/stacks/dlaas/kubeflow/dlaas-tfjob - - ks pkg install dlaas-tfjob/dlaas-bench - -#. Download and copy these files into: - - .. code-block:: console - - ${KUBEFLOW_SRC}/${KFAPP}/vendor/kubeflow/examples/prototypes/ - -#. Next, generate Kubernetes manifests for the workloads and apply them to - create and run them using these commands - - .. code-block:: bash - - ks generate dlaas-resnet50 dlaasresnet50 --name=dlaasresnet50 - ks generate dlaas-alexnet dlaasalexnet --name=dlaasalexnet - ks apply default -c dlaasresnet50 - ks apply default -c dlaasalexnet - -This will replicate and deploy three test setups in your Kubernetes cluster. - -Results -======= -You need to parse the logs of the Kubernetes pod to get the performance -numbers. The pods will still be around post completion and will be in -‘Completed’ state. You can get the logs from any of the pods to inspect the -benchmark results. More information about `Kubernetes logging`_ is available from the Kubernetes community. - -.. _TensorFlow: https://www.tensorflow.org/ -.. _Kubeflow: https://www.kubeflow.org/ -.. _Docker Hub: https://hub.docker.com/ -.. _TensorFlow benchmarks: https://www.tensorflow.org/guide/performance/benchmarks -.. _instructions for creating a cluster: https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/ -.. _flannel: https://github.com/coreos/flannel -.. _networking documentation: https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/#pod-network -.. _quick start guide: https://www.kubeflow.org/docs/started/getting-started/ - -.. _Eigen: https://hub.docker.com/r/clearlinux/stacks-dlaas-oss/ -.. _Intel MKL-DNN: https://hub.docker.com/r/clearlinux/stacks-dlaas-mkl/ - -.. _release notes: https://github.com/clearlinux/dockerfiles/tree/master/stacks/dlaas - -.. _Clear Linux Docker Hub page: https://hub.docker.com/u/clearlinux/ - -.. _DLaaS ksonnet registries for deploying TFJobs: https://github.com/clearlinux/dockerfiles/tree/master/stacks/dlaas/kubeflow/dlaas-tfjob - -.. _Kubernetes logging: https://kubernetes.io/docs/concepts/cluster-administration/logging/ From ad00e9cac96ef5cf367544a4de40205c65a12344 Mon Sep 17 00:00:00 2001 From: Michael Vincerra Date: Fri, 7 Dec 2018 14:11:07 -0800 Subject: [PATCH 25/26] Adds link to parent file tutorials.rst to show new dlrs.rst. Signed-off-by: Michael Vincerra --- source/clear-linux/tutorials/tutorials.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/source/clear-linux/tutorials/tutorials.rst b/source/clear-linux/tutorials/tutorials.rst index e5d51254..24f3a3d7 100644 --- a/source/clear-linux/tutorials/tutorials.rst +++ b/source/clear-linux/tutorials/tutorials.rst @@ -31,3 +31,4 @@ Explore our tutorials to discover what you can do with |CL|! kata_migration kubernetes greengrass + dlrs From c213d7e6bcf06d212ad5edfe8eeab7fd9d5718e6 Mon Sep 17 00:00:00 2001 From: Michael Vincerra Date: Fri, 7 Dec 2018 16:58:34 -0800 Subject: [PATCH 26/26] Applies requested edits from @unrahul. Signed-off-by: Michael Vincerra --- source/clear-linux/tutorials/dlrs.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/clear-linux/tutorials/dlrs.rst b/source/clear-linux/tutorials/dlrs.rst index fd7885cd..de2b16f4 100644 --- a/source/clear-linux/tutorials/dlrs.rst +++ b/source/clear-linux/tutorials/dlrs.rst @@ -77,16 +77,17 @@ TensorFlow. .. code-block:: bash - docker exec -t bash -c ‘git clone http://github.com/tensorflow/benchmarks -b cnn_tf_v1.11_compatible’ + docker exec -t bash -c ‘git clone http://github.com/tensorflow/benchmarks -b cnn_tf_v1.12_compatible’ #. Next, execute the benchmark script to run the benchmark. .. code-block:: bash - docker exec -i bash -c ‘python benchmarks/scripts/tf_cnn_benchmarks/tf_cnn_benchmarks.py --device=cpu --model=resnet50 --data_format=NWHC ’. + docker exec -i bash -c ‘python benchmarks/scripts/tf_cnn_benchmarks/tf_cnn_benchmarks.py --device=cpu --model=resnet50 --data_format=NHWC ’. .. note:: + You may also use: `--data_format=NCHW` You can replace the model with one of your choice supported by the TensorFlow benchmarks.