blob: b1ffc4d7ac68ad914874ab495545d345b40f44ed [file] [log] [blame] [view]
---
title: Quickstart
---
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
This document gives you a quick view on the basic usage of Submarine platform. You can finish each step of ML model lifecycle on the platform without messing up with the troublesome environment problems.
## Installation
### Prepare a Kubernetes cluster
1. Prerequisite
- Check [dependency page](../devDocs/Dependencies.md) for the compatible version
- [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/)
- [helm](https://helm.sh/docs/intro/install/) (Helm v3 is minimum requirement.)
- [minikube](https://minikube.sigs.k8s.io/docs/start/).
2. Start minikube cluster
```
minikube start --vm-driver=docker --cpus 8 --memory 4096 --kubernetes-version v1.21.2
```
### Launch submarine in the cluster
1. Clone the project
```
git clone https://github.com/apache/submarine.git
```
2. Install the submarine operator and dependencies by helm chart
```
cd submarine
helm install submarine ./helm-charts/submarine
```
3. Create a Submarine custom resource and the operator will create the submarine server, database, etc. for us.
```
kubectl apply -f submarine-cloud-v2/artifacts/examples/example-submarine.yaml
```
### Ensure submarine is ready
1. Use kubectl to query the status of pods
```
kubectl get pods
```
2. Make sure each pod is `Running`
```
NAME READY STATUS RESTARTS AGE
notebook-controller-deployment-5d4f5f874c-mnbc8 1/1 Running 0 61m
pytorch-operator-844c866d54-xm8nl 1/1 Running 2 61m
submarine-database-85bd68dbc5-qggtm 1/1 Running 0 11m
submarine-minio-76465444f6-hdgdp 1/1 Running 0 11m
submarine-mlflow-75f86d8f4d-rj2z7 1/1 Running 0 11m
submarine-operator-5dd79cdf86-gpm2p 1/1 Running 0 61m
submarine-server-68985b767-vjdvx 1/1 Running 0 11m
submarine-tensorboard-5df8499fd4-vnklf 1/1 Running 0 11m
submarine-traefik-7cbcfd4bd9-wbf8b 1/1 Running 0 61m
tf-job-operator-6bb69fd44-zmlmr 1/1 Running 1 61m
```
### Connect to workbench
1. Exposing service
```
# Method 1 -- use minikube ip
minikube ip # you'll get the IP address of minikube, ex: 192.168.49.2
# Method 2 -- use port-forwarding
kubectl port-forward --address 0.0.0.0 service/submarine-traefik 32080:80
```
2. View workbench
If you use method 1, go to `http://{minikube ip}:32080`. For example, `http://192.168.49.2:32080`. If you use method 2, go to `http://0.0.0.0:32080`.
![](/img/quickstart-worbench.png)
## Example: Submit a mnist distributed example
We put the code of this example [here](https://github.com/apache/submarine/tree/master/dev-support/examples/quickstart). `train.py` is our training script, and `build.sh` is the script to build a docker image.
### 1. Write a python script for distributed training
Take a simple mnist tensorflow script as an example. We choose `MultiWorkerMirroredStrategy` as our distributed strategy.
```python
"""
./dev-support/examples/quickstart/train.py
Reference: https://github.com/kubeflow/tf-operator/blob/master/examples/v1/distribution_strategy/keras-API/multi_worker_strategy-with-keras.py
"""
import tensorflow_datasets as tfds
import tensorflow as tf
from tensorflow.keras import layers, models
import submarine
def make_datasets_unbatched():
BUFFER_SIZE = 10000
# Scaling MNIST data from (0, 255] to (0., 1.]
def scale(image, label):
image = tf.cast(image, tf.float32)
image /= 255
return image, label
datasets, _ = tfds.load(name='mnist', with_info=True, as_supervised=True)
return datasets['train'].map(scale).cache().shuffle(BUFFER_SIZE)
def build_and_compile_cnn_model():
model = models.Sequential()
model.add(
layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.Flatten())
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(10, activation='softmax'))
model.summary()
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
return model
def main():
strategy = tf.distribute.experimental.MultiWorkerMirroredStrategy(
communication=tf.distribute.experimental.CollectiveCommunication.AUTO)
BATCH_SIZE_PER_REPLICA = 4
BATCH_SIZE = BATCH_SIZE_PER_REPLICA * strategy.num_replicas_in_sync
with strategy.scope():
ds_train = make_datasets_unbatched().batch(BATCH_SIZE).repeat()
options = tf.data.Options()
options.experimental_distribute.auto_shard_policy = \
tf.data.experimental.AutoShardPolicy.DATA
ds_train = ds_train.with_options(options)
# Model building/compiling need to be within `strategy.scope()`.
multi_worker_model = build_and_compile_cnn_model()
class MyCallback(tf.keras.callbacks.Callback):
def on_epoch_end(self, epoch, logs=None):
# monitor the loss and accuracy
print(logs)
submarine.log_metrics({"loss": logs["loss"], "accuracy": logs["accuracy"]}, epoch)
multi_worker_model.fit(ds_train, epochs=10, steps_per_epoch=70, callbacks=[MyCallback()])
if __name__ == '__main__':
main()
```
### 2. Prepare an environment compatible with the training
Build a docker image equipped with the requirement of the environment.
```bash
eval $(minikube docker-env)
./dev-support/examples/quickstart/build.sh
```
### 3. Submit the experiment
1. Open submarine workbench and click `+ New Experiment`
2. Choose `Define your experiment`
3. Fill the form accordingly. Here we set 3 workers.
1. Step 1
![](/img/quickstart-submit-1-0-7-0.png)
2. Step 2
![](/img/quickstart-submit-2-0-7-0.png)
3. Step 3
![](/img/quickstart-submit-3-0-7-0.png)
4. The experiment is successfully submitted
![](/img/quickstart-submit-4-0-7-0.png)
### 4. Monitor the process
1. In our code, we use `submarine` from `submarine-sdk` to record the metrics. To see the result, click corresponding experiment with name `mnist-example` in the workbench.
2. To see the metrics of each worker, you can select a worker from the left top list.
![](/img/quickstart-ui-0-7-0.png)
### 5. Serve the model (In development)