In [1]:
# Copyright 2019 Google Inc. All Rights Reserved.
#
# Licensed 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.

In [9]:
# Install Pipeline SDK - This only needs to be ran once in the enviroment. 
!python3 -m pip install 'kfp>=0.1.31' --quiet
!pip3 install tensorflow==1.14 --upgrade


Requirement already up-to-date: kfp in /opt/conda/lib/python3.6/site-packages (0.1.30)
Requirement already satisfied, skipping upgrade: kfp-server-api<=0.1.25,>=0.1.18 in /opt/conda/lib/python3.6/site-packages (from kfp) (0.1.18.3)
Requirement already satisfied, skipping upgrade: tabulate==0.8.3 in /opt/conda/lib/python3.6/site-packages (from kfp) (0.8.3)
Requirement already satisfied, skipping upgrade: cloudpickle in /opt/conda/lib/python3.6/site-packages (from kfp) (0.8.1)
Requirement already satisfied, skipping upgrade: six>=1.10 in /opt/conda/lib/python3.6/site-packages (from kfp) (1.12.0)
Requirement already satisfied, skipping upgrade: cryptography>=2.4.2 in /opt/conda/lib/python3.6/site-packages (from kfp) (2.6.1)
Requirement already satisfied, skipping upgrade: PyYAML in /opt/conda/lib/python3.6/site-packages (from kfp) (3.13)
Requirement already satisfied, skipping upgrade: python-dateutil in /opt/conda/lib/python3.6/site-packages (from kfp) (2.8.0)
Requirement already satisfied, skipping upgrade: google-auth>=1.6.1 in /opt/conda/lib/python3.6/site-packages (from kfp) (1.6.3)
Requirement already satisfied, skipping upgrade: PyJWT>=1.6.4 in /opt/conda/lib/python3.6/site-packages (from kfp) (1.7.1)
Requirement already satisfied, skipping upgrade: requests-toolbelt>=0.8.0 in /opt/conda/lib/python3.6/site-packages (from kfp) (0.9.1)
Requirement already satisfied, skipping upgrade: argo-models==2.2.1a in /opt/conda/lib/python3.6/site-packages (from kfp) (2.2.1a0)
Requirement already satisfied, skipping upgrade: Deprecated in /opt/conda/lib/python3.6/site-packages (from kfp) (1.2.6)
Requirement already satisfied, skipping upgrade: kubernetes<=9.0.0,>=8.0.0 in /opt/conda/lib/python3.6/site-packages (from kfp) (9.0.0)
Requirement already satisfied, skipping upgrade: urllib3<1.25,>=1.15 in /opt/conda/lib/python3.6/site-packages (from kfp) (1.24.1)
Requirement already satisfied, skipping upgrade: jsonschema>=3.0.1 in /opt/conda/lib/python3.6/site-packages (from kfp) (3.0.1)
Requirement already satisfied, skipping upgrade: click==7.0 in /opt/conda/lib/python3.6/site-packages (from kfp) (7.0)
Requirement already satisfied, skipping upgrade: certifi in /opt/conda/lib/python3.6/site-packages (from kfp) (2019.3.9)
Requirement already satisfied, skipping upgrade: google-cloud-storage>=1.13.0 in /opt/conda/lib/python3.6/site-packages (from kfp) (1.18.0)
Requirement already satisfied, skipping upgrade: asn1crypto>=0.21.0 in /opt/conda/lib/python3.6/site-packages (from cryptography>=2.4.2->kfp) (0.24.0)
Requirement already satisfied, skipping upgrade: cffi!=1.11.3,>=1.8 in /opt/conda/lib/python3.6/site-packages (from cryptography>=2.4.2->kfp) (1.12.2)
Requirement already satisfied, skipping upgrade: cachetools>=2.0.0 in /opt/conda/lib/python3.6/site-packages (from google-auth>=1.6.1->kfp) (3.1.0)
Requirement already satisfied, skipping upgrade: rsa>=3.1.4 in /opt/conda/lib/python3.6/site-packages (from google-auth>=1.6.1->kfp) (4.0)
Requirement already satisfied, skipping upgrade: pyasn1-modules>=0.2.1 in /opt/conda/lib/python3.6/site-packages (from google-auth>=1.6.1->kfp) (0.2.4)
Requirement already satisfied, skipping upgrade: requests<3.0.0,>=2.0.1 in /opt/conda/lib/python3.6/site-packages (from requests-toolbelt>=0.8.0->kfp) (2.21.0)
Requirement already satisfied, skipping upgrade: wrapt<2,>=1.10 in /opt/conda/lib/python3.6/site-packages (from Deprecated->kfp) (1.11.2)
Requirement already satisfied, skipping upgrade: setuptools>=21.0.0 in /opt/conda/lib/python3.6/site-packages (from kubernetes<=9.0.0,>=8.0.0->kfp) (40.9.0)
Requirement already satisfied, skipping upgrade: requests-oauthlib in /opt/conda/lib/python3.6/site-packages (from kubernetes<=9.0.0,>=8.0.0->kfp) (1.2.0)
Requirement already satisfied, skipping upgrade: websocket-client!=0.40.0,!=0.41.*,!=0.42.*,>=0.32.0 in /opt/conda/lib/python3.6/site-packages (from kubernetes<=9.0.0,>=8.0.0->kfp) (0.56.0)
Requirement already satisfied, skipping upgrade: attrs>=17.4.0 in /opt/conda/lib/python3.6/site-packages (from jsonschema>=3.0.1->kfp) (19.1.0)
Requirement already satisfied, skipping upgrade: pyrsistent>=0.14.0 in /opt/conda/lib/python3.6/site-packages (from jsonschema>=3.0.1->kfp) (0.14.11)
Requirement already satisfied, skipping upgrade: google-resumable-media>=0.3.1 in /opt/conda/lib/python3.6/site-packages (from google-cloud-storage>=1.13.0->kfp) (0.3.2)
Requirement already satisfied, skipping upgrade: google-cloud-core<2.0dev,>=1.0.0 in /opt/conda/lib/python3.6/site-packages (from google-cloud-storage>=1.13.0->kfp) (1.0.3)
Requirement already satisfied, skipping upgrade: pycparser in /opt/conda/lib/python3.6/site-packages (from cffi!=1.11.3,>=1.8->cryptography>=2.4.2->kfp) (2.19)
Requirement already satisfied, skipping upgrade: pyasn1>=0.1.3 in /opt/conda/lib/python3.6/site-packages (from rsa>=3.1.4->google-auth>=1.6.1->kfp) (0.4.5)
Requirement already satisfied, skipping upgrade: chardet<3.1.0,>=3.0.2 in /opt/conda/lib/python3.6/site-packages (from requests<3.0.0,>=2.0.1->requests-toolbelt>=0.8.0->kfp) (3.0.4)
Requirement already satisfied, skipping upgrade: idna<2.9,>=2.5 in /opt/conda/lib/python3.6/site-packages (from requests<3.0.0,>=2.0.1->requests-toolbelt>=0.8.0->kfp) (2.8)
Requirement already satisfied, skipping upgrade: oauthlib>=3.0.0 in /opt/conda/lib/python3.6/site-packages (from requests-oauthlib->kubernetes<=9.0.0,>=8.0.0->kfp) (3.0.1)
Requirement already satisfied, skipping upgrade: google-api-core<2.0.0dev,>=1.14.0 in /opt/conda/lib/python3.6/site-packages (from google-cloud-core<2.0dev,>=1.0.0->google-cloud-storage>=1.13.0->kfp) (1.14.2)
Requirement already satisfied, skipping upgrade: pytz in /opt/conda/lib/python3.6/site-packages (from google-api-core<2.0.0dev,>=1.14.0->google-cloud-core<2.0dev,>=1.0.0->google-cloud-storage>=1.13.0->kfp) (2018.9)
Requirement already satisfied, skipping upgrade: protobuf>=3.4.0 in /opt/conda/lib/python3.6/site-packages (from google-api-core<2.0.0dev,>=1.14.0->google-cloud-core<2.0dev,>=1.0.0->google-cloud-storage>=1.13.0->kfp) (3.7.1)
Requirement already satisfied, skipping upgrade: googleapis-common-protos<2.0dev,>=1.6.0 in /opt/conda/lib/python3.6/site-packages (from google-api-core<2.0.0dev,>=1.14.0->google-cloud-core<2.0dev,>=1.0.0->google-cloud-storage>=1.13.0->kfp) (1.6.0)
You are using pip version 19.0.1, however version 19.2.3 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
Collecting tensorflow==1.14
  Downloading https://files.pythonhosted.org/packages/de/f0/96fb2e0412ae9692dbf400e5b04432885f677ad6241c088ccc5fe7724d69/tensorflow-1.14.0-cp36-cp36m-manylinux1_x86_64.whl (109.2MB)
    100% |████████████████████████████████| 109.2MB 279kB/s eta 0:00:01
Collecting tensorboard<1.15.0,>=1.14.0 (from tensorflow==1.14)
  Downloading https://files.pythonhosted.org/packages/91/2d/2ed263449a078cd9c8a9ba50ebd50123adf1f8cfbea1492f9084169b89d9/tensorboard-1.14.0-py3-none-any.whl (3.1MB)
    100% |████████████████████████████████| 3.2MB 7.2MB/s eta 0:00:01
Requirement already satisfied, skipping upgrade: keras-applications>=1.0.6 in /opt/conda/lib/python3.6/site-packages (from tensorflow==1.14) (1.0.7)
Requirement already satisfied, skipping upgrade: numpy<2.0,>=1.14.5 in /opt/conda/lib/python3.6/site-packages (from tensorflow==1.14) (1.16.2)
Requirement already satisfied, skipping upgrade: absl-py>=0.7.0 in /opt/conda/lib/python3.6/site-packages (from tensorflow==1.14) (0.7.1)
Requirement already satisfied, skipping upgrade: grpcio>=1.8.6 in /opt/conda/lib/python3.6/site-packages (from tensorflow==1.14) (1.19.0)
Collecting google-pasta>=0.1.6 (from tensorflow==1.14)
  Downloading https://files.pythonhosted.org/packages/d0/33/376510eb8d6246f3c30545f416b2263eee461e40940c2a4413c711bdf62d/google_pasta-0.1.7-py3-none-any.whl (52kB)
    100% |████████████████████████████████| 61kB 25.5MB/s ta 0:00:01
Collecting tensorflow-estimator<1.15.0rc0,>=1.14.0rc0 (from tensorflow==1.14)
  Downloading https://files.pythonhosted.org/packages/3c/d5/21860a5b11caf0678fbc8319341b0ae21a07156911132e0e71bffed0510d/tensorflow_estimator-1.14.0-py2.py3-none-any.whl (488kB)
    100% |████████████████████████████████| 491kB 25.5MB/s ta 0:00:01
Requirement already satisfied, skipping upgrade: keras-preprocessing>=1.0.5 in /opt/conda/lib/python3.6/site-packages (from tensorflow==1.14) (1.0.9)
Requirement already satisfied, skipping upgrade: six>=1.10.0 in /opt/conda/lib/python3.6/site-packages (from tensorflow==1.14) (1.12.0)
Requirement already satisfied, skipping upgrade: gast>=0.2.0 in /opt/conda/lib/python3.6/site-packages (from tensorflow==1.14) (0.2.2)
Requirement already satisfied, skipping upgrade: protobuf>=3.6.1 in /opt/conda/lib/python3.6/site-packages (from tensorflow==1.14) (3.7.1)
Requirement already satisfied, skipping upgrade: wrapt>=1.11.1 in /opt/conda/lib/python3.6/site-packages (from tensorflow==1.14) (1.11.2)
Requirement already satisfied, skipping upgrade: termcolor>=1.1.0 in /opt/conda/lib/python3.6/site-packages (from tensorflow==1.14) (1.1.0)
Requirement already satisfied, skipping upgrade: wheel>=0.26 in /opt/conda/lib/python3.6/site-packages (from tensorflow==1.14) (0.33.1)
Requirement already satisfied, skipping upgrade: astor>=0.6.0 in /opt/conda/lib/python3.6/site-packages (from tensorflow==1.14) (0.7.1)
Collecting setuptools>=41.0.0 (from tensorboard<1.15.0,>=1.14.0->tensorflow==1.14)
  Downloading https://files.pythonhosted.org/packages/b2/86/095d2f7829badc207c893dd4ac767e871f6cd547145df797ea26baea4e2e/setuptools-41.2.0-py2.py3-none-any.whl (576kB)
    100% |████████████████████████████████| 583kB 23.7MB/s ta 0:00:01
Requirement already satisfied, skipping upgrade: markdown>=2.6.8 in /opt/conda/lib/python3.6/site-packages (from tensorboard<1.15.0,>=1.14.0->tensorflow==1.14) (3.1)
Requirement already satisfied, skipping upgrade: werkzeug>=0.11.15 in /opt/conda/lib/python3.6/site-packages (from tensorboard<1.15.0,>=1.14.0->tensorflow==1.14) (0.15.2)
Requirement already satisfied, skipping upgrade: h5py in /opt/conda/lib/python3.6/site-packages (from keras-applications>=1.0.6->tensorflow==1.14) (2.9.0)
fairing 0.5 has requirement oauth2client>=4.0.0, but you'll have oauth2client 3.0.0 which is incompatible.
Installing collected packages: setuptools, tensorboard, google-pasta, tensorflow-estimator, tensorflow
  Found existing installation: setuptools 40.9.0
    Uninstalling setuptools-40.9.0:
      Successfully uninstalled setuptools-40.9.0
  Found existing installation: tensorboard 1.13.1
    Uninstalling tensorboard-1.13.1:
      Successfully uninstalled tensorboard-1.13.1
  Found existing installation: tensorflow-estimator 1.13.0
    Uninstalling tensorflow-estimator-1.13.0:
      Successfully uninstalled tensorflow-estimator-1.13.0
  Found existing installation: tensorflow 1.13.1
    Uninstalling tensorflow-1.13.1:
      Successfully uninstalled tensorflow-1.13.1
Successfully installed google-pasta-0.1.7 setuptools-41.2.0 tensorboard-1.14.0 tensorflow-1.14.0 tensorflow-estimator-1.14.0
You are using pip version 19.0.1, however version 19.2.3 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.

KubeFlow Pipelines Serving Component

In this notebook, we will demo:

  • Saving a Keras model in a format compatible with TF Serving
  • Creating a pipeline to serve a trained model within a KubeFlow cluster

Reference documentation:

Setup


In [28]:
# Set your output and project. !!!Must Do before you can proceed!!!
project =  'Your-Gcp-Project-ID'                          #'Your-GCP-Project-ID'
model_name = 'model-name'                                      # Model name matching TF_serve naming requirements       
import time
ts = int(time.time())
model_version = str(ts)                                            # Here we use timestamp as version to avoid conflict 
output = 'Your-Gcs-Path'     # A GCS bucket for asset outputs
KUBEFLOW_DEPLOYER_IMAGE = 'gcr.io/ml-pipeline/ml-pipeline-kubeflow-deployer:ad9bd5648dd0453005225779f25d8cebebc7ca00'

In [30]:
model_path = '%s/%s' % (output,model_name)               
model_version_path = '%s/%s/%s' % (output,model_name,model_version)

Load a Keras Model

Loading a pretrained Keras model to use as an example.


In [32]:
import tensorflow as tf

In [33]:
model = tf.keras.applications.NASNetMobile(input_shape=None,
                                   include_top=True,
                                   weights='imagenet',
                                   input_tensor=None,
                                   pooling=None,
                                   classes=1000)


Exception ignored in: <bound method _CheckpointRestoreCoordinator.__del__ of <tensorflow.python.training.tracking.util._CheckpointRestoreCoordinator object at 0x7f31dc197f98>>
Traceback (most recent call last):
  File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/training/tracking/util.py", line 244, in __del__
    .format(pretty_printer.node_names[node_id]))
  File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/training/tracking/util.py", line 93, in node_names
    path_to_root[node_id] + (child.local_name,))
  File "/opt/conda/lib/python3.6/site-packages/tensorflow/python/training/tracking/object_identity.py", line 76, in __getitem__
    return self._storage[self._wrap_key(key)]
KeyError: (<tensorflow.python.training.tracking.object_identity._ObjectIdentityWrapper object at 0x7f32aca065f8>,)

Saved the Model for TF-Serve

Save the model using keras export_saved_model function. Note that specifically for TF-Serve the output directory should be structure as model_name/model_version/saved_model.


In [34]:
tf.keras.experimental.export_saved_model(model, model_version_path)

Create a pipeline using KFP TF-Serve component


In [36]:
def kubeflow_deploy_op():
    return dsl.ContainerOp(
        name = 'deploy',
        image = KUBEFLOW_DEPLOYER_IMAGE,
        arguments = [
            '--model-export-path', model_path,
            '--server-name', model_name,
        ]
    )

In [37]:
import kfp
import kfp.dsl as dsl

# The pipeline definition
@dsl.pipeline(
    name='Sample model deployer',
    description='Sample for deploying models using KFP model serving component'
)
def model_server():
    deploy = kubeflow_deploy_op()

Submit pipeline for execution on Kubeflow Pipelines cluster


In [39]:
kfp.Client().create_run_from_pipeline_func(model_server, arguments={})

#vvvvvvvvv This link leads to the run information page. (Note: There is a bug in JupyterLab that modifies the URL and makes the link stop working)


Run link here