[PYTHON] Deploy functions with Cloud Pak for Data

It is possible to deploy Python functions with Cloud Pak for Data (CP4D). The purpose is mainly before and after model execution, and error handling of try & except can be incorporated, and above all, it is possible to call (use properly) multiple models.

Excerpt from CP4D v2.5 product manual https://www.ibm.com/support/knowledgecenter/ja/SSQNUZ_2.5.0/wsj/analyze-data/ml-deploy-functions_local.html

Python functions can be deployed to Watson Machine Learning in the same way as deploying a model. Your tools and applications can use the Watson Machine Learning Python client or REST API to send data to deployed functions in the same way that they send data to a deployed model. You can deploy functions to hide details (such as credentials), preprocess data before passing it to the model, perform error handling, and incorporate calls into multiple models. All of these features are built into the deployed function, not the application.

Deploying functions in WML has preceding article, but it is the method in Watson Studio of IBM Cloud service, and the method is slightly different in CP4D. I'm addicted to it, so I'll leave an example of how it worked. This is the result of creating a simple function, deploying it as an Online type, and checking the operation.

Configuration image

Models and functions created in Notebook are stored in the deployment space, and each is deployed as an Online type. By setting the function to call the model deployment, the configuration is as follows: call the function deployment → call the model deployment. At the end of the Notebook, score the function deployment to see it in action. image.png

Actually make it with Notebook

Log in to CP4D, open your analytics project and launch a new Notebook. The confirmed CP4D version is v3.0 LA.

Preparation: Model creation and deployment

Create and deploy the model first. You will use this deployment ID later to call it in a function.

(1) Create a model

Create a model of a random forest using Iris data.

#Load Iris sample data
import pandas as pd
from sklearn.datasets import load_iris
iris = load_iris()
df = pd.DataFrame(iris.data, columns=iris.feature_names)
df['iris_type'] = iris.target_names[iris.target]

#Create a model in a random forest
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier

X = df.drop('iris_type', axis=1)
y = df['iris_type']
X_train, X_test, y_train, y_test = train_test_split(X,y,random_state=0)

clf = RandomForestClassifier(max_depth=2, random_state=0, n_estimators=10)
model = clf.fit(X_train, y_train)

#Check the accuracy of the model
from sklearn.metrics import confusion_matrix, accuracy_score
y_test_predicted = model.predict(X_test)    
print("confusion_matrix:")
print(confusion_matrix(y_test,y_test_predicted))
print("accuracy:", accuracy_score(y_test,y_test_predicted))

The above `` `model``` is a trained model.

(2) Save and deploy the model

Save the model in the deployment space and create an Online deployment. The operation uses the WML client. (Reference article)

python


#WML client initialization and authentication
from watson_machine_learning_client import WatsonMachineLearningAPIClient
import os
token = os.environ['USER_ACCESS_TOKEN']
url = "https://cp4d.host.name.com"
wml_credentials = {
    "token" : token,
    "instance_id" : "openshift",
    "url": url,
    "version": "3.0.0"
}
client = WatsonMachineLearningAPIClient(wml_credentials)

#Display deployment space ID list
# client.repository.list_spaces()

#Switch to deployment space(ID is the above list_spaces()Find out in)
space_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
client.set.default_space(space_id)

#Describe model meta information
model_name = "sample_iris_model"
meta_props={
    client.repository.ModelMetaNames.NAME: model_name,
    client.repository.ModelMetaNames.RUNTIME_UID: "scikit-learn_0.22-py3.6",
    client.repository.ModelMetaNames.TYPE: "scikit-learn_0.22",
    client.repository.ModelMetaNames.INPUT_DATA_SCHEMA:{
        "id":"iris model",
        "fields":[
            {'name': 'sepal length (cm)', 'type': 'double'},
            {'name': 'sepal width (cm)', 'type': 'double'},
            {'name': 'petal length (cm)', 'type': 'double'},
            {'name': 'petal width (cm)', 'type': 'double'}
        ]
    },
    client.repository.ModelMetaNames.OUTPUT_DATA_SCHEMA: {
        "id":"iris model",
        "fields": [
            {'name': 'iris_type', 'type': 'string','metadata': {'modeling_role': 'prediction'}}
        ]
    }
}

#Save model
model_artifact = client.repository.store_model(model, meta_props=meta_props, training_data=X, training_target=y)
model_id = model_artifact['metadata']['guid']

#Create a deployment with Online type
dep_name = "sample_iris_online"
meta_props = {
    client.deployments.ConfigurationMetaNames.NAME: dep_name,
    client.deployments.ConfigurationMetaNames.ONLINE: {}
}
deployment_details = client.deployments.create(model_id, meta_props=meta_props)
dep_id = deployment_details['metadata']['guid']

(3) Model operation check

Make sure that the model (deployment) you created works properly. You can check the operation using WML client.

#Generate sample data and convert to JSON
scoring_x = pd.DataFrame(
    data = [[5.1,3.5,1.4,0.2]],
    columns=['sepal length (cm)','sepal width (cm)','petal length (cm)','petal width (cm)']
)
values = scoring_x.values.tolist()
fields = scoring_x.columns.values.tolist()
scoring_payload = {client.deployments.ScoringMetaNames.INPUT_DATA: [{'fields': fields, 'values': values}]}

#Scoring execution
prediction = client.deployments.score(dep_id, scoring_payload)
prediction

If the following result is returned, the operation check is complete.

output


{'predictions': [{'fields': ['prediction', 'probability'],
   'values': [[0, [0.8131726303900102, 0.18682736960998966]]]}]}

Creating a function

There are various ways to create a function.

Here is the function I actually made. Please refer to Reference article for how to perform deployment using WML client.

Creating a function


# variables for function
func_variables = {
    "url" : url,
    "space_id" : space_id,
    "dep_id" : dep_id,
    "token"  : token
}

# Function for scoring model only
def iris_scoring(func_vars=func_variables):
    from watson_machine_learning_client import WatsonMachineLearningAPIClient
    #Note: wml_credentials are defined here
    wml_credentials = {
                   "token" : func_vars['token'],
                   "instance_id": "openshift",
                   "url": func_vars['url'],
                   "version" : "3.0.0"
                  }
    client = WatsonMachineLearningAPIClient(wml_credentials)

    def score(scoring_payload):
        try:
            client.set.default_space(func_vars['space_id'])
            prediction = client.deployments.score(func_vars['dep_id'], scoring_payload)
            return prediction

        except Exception as e:
            return {'error': repr(e)}

    return score

Variables used inside the function are defined outside the function and passed to the function. url is the URL of the CP4D (up to the FQDN, without the last slash), space_id is the ID of the deployment space where you deployed the model you just created, and dep_id is the deployment ID of that model. The content of the function is simply to call the Online deployment.

As I wrote in the comment, the point is to initialize the *** WML client with an outer function ***, and to define *** wml_credentials used there *** in the outer function. If you try to receive wml_credentials defined outside the function as an argument, it will not work. This seems to be different from Watson Studio on IBM Cloud, and I was very addicted to it.

Check the operation of the created function. Continue to run the following in your Notebook to see if the function calls the deployment successfully. Input data scoring_payload uses the sample data created earlier.

Function check


#Execute function(Scoring to inner function_Pass payload)
iris_scoring()(scoring_payload)

It is OK if the following result is returned.

output


{'predictions': [{'fields': ['prediction', 'probability'],
   'values': [['setosa', [0.9939393939393939, 0.006060606060606061, 0.0]]]}]}

Save function

Save the function in the deployment space.

#Create meta information
meta_props = {
    client.repository.FunctionMetaNames.NAME: 'iris_scoring_func',
    client.repository.FunctionMetaNames.RUNTIME_UID: "ai-function_0.1-py3.6",
    client.repository.FunctionMetaNames.SPACE_UID: space_id
}

#Save function
function_details = client.repository.store_function(meta_props=meta_props, function=iris_scoring)
function_id = function_details['metadata']['guid']

In the deployment space, you can see that it is registered in the section called "Functions" under the asset. image.png

Deploy function

Deploy the function saved in the deployment space with the Online type.

#Create meta information
meta_props = {
    client.deployments.ConfigurationMetaNames.NAME: "iris_scoring_online",
    client.deployments.ConfigurationMetaNames.ONLINE: {}
}

#Create a deployment
function_deployment_details = client.deployments.create(function_id, meta_props=meta_props)
func_dep_id = function_deployment_details['metadata']['guid']

You have now deployed the function. Ready to run.

Function check

I will check the operation at once. Make a scoring call to your deployment using the WML client.

prediction = client.deployments.score(func_dep_id, scoring_payload)
prediction

If you get the same result as before, you are successful.

output


{'predictions': [{'fields': ['prediction', 'probability'],
   'values': [['setosa', [0.9939393939393939, 0.006060606060606061, 0.0]]]}]}

Now you have a simple way to make a model call using a function. I will post more applied multi-model calling patterns later.

Recommended Posts

Deploy functions with Cloud Pak for Data
Output log file with Job (Notebook) of Cloud Pak for Data
[GCP] [Python] Deploy API serverless with Google Cloud Functions!
Clean up the Cloud pak for Data deployment space
Execute API of Cloud Pak for Data analysis project Job with environment variables
Test python models and functions deployed online with Cloud Pack for Data with form-formatted input data
Save pandas data in Excel format to data assets with Cloud Pak for Data (Watson Studio)
Best practices for messing with data with pandas
[GCP] Procedure for creating a web application with Cloud Functions (Python + Flask)
Eliminate garbled Japanese characters in matplotlib graphs in Cloud Pak for Data Notebook
Cloud Pak for Data object operation example in Python (WML client, project_lib)
Serverless LINE bot made with IBM Cloud Functions
Data analysis for improving POG 1 ~ Web scraping with Python ~
Run Google Cloud Functions locally with Cloud Native Build packs
Delete DynamoDB data after 5 minutes with AWS Step Functions
Data analysis with python 2
How to change python version of Notebook in Watson Studio (or Cloud Pak for Data)
Visualize data with Streamlit
Reading data with TensorFlow
Data visualization with pandas
Data manipulation with Pandas!
Point Cloud with Pepper
Shuffle data with pandas
Data Augmentation with openCV
Normarize data with Scipy
Data analysis with Python
LOAD DATA with PyMysql
Cloud Functions to resize images using OpenCV with Cloud Storage triggers
Stylish technique for pasting CSV data into Excel with Python
Deploy the strongest front-end Streamlit for data scientists on Azure!
Get data from analytics API with Google API Client for python
This and that for using Step Functions with CDK + Python