Deploy a custom model with Pulumi¶
This notebook outlines how to use Pulumi to deploy a Scikit-learn classifier. Before proceeding, download the necessary assets to execute the tasks in this notebook.
Initialize the environment¶
Start the environment and import the DataRobot library.
import os
import datarobot as dr
os.environ['PULUMI_CONFIG_PASSPHRASE'] = 'default'
assert 'DATAROBOT_API_TOKEN' in os.environ, 'Please set the DATAROBOT_API_TOKEN environment variable'
assert 'DATAROBOT_ENDPOINT' in os.environ, 'Please set the DATAROBOT_ENDPOINT environment variable'
dr.Client()
Set up a project¶
Set up functions to create and build or destroy your Pulumi stack.
from pulumi import automation as auto
def stack_up(project_name: str, stack_name: str, program: callable) -> auto.Stack:
# create (or select if one already exists) a stack that uses our inline program
stack = auto.create_or_select_stack(
stack_name=stack_name, project_name=project_name, program=program
)
stack.refresh(on_output=print)
stack.up(on_output=print)
return stack
def destroy_project(stack: auto.Stack):
"""Destroy pulumi project"""
stack_name = stack.name
stack.destroy(on_output=print)
stack.workspace.remove_stack(stack_name)
print(f"stack {stack_name} in project removed")
Create a declarative custom model deployment¶
Use this cell to create a custom model deployment. Add your source code to DataRobot, register the model, and then initialize the deployment. The make_custom_deployment
function below shows how to declaratively do this. You'll see some variant of this across all application templates.
import pulumi_datarobot as datarobot
import pulumi
def make_custom_inference_deployment():
"""
Deploy a trained model onto DataRobot's prediction environment.
Upload source code to create a custom model version.
Then create a registered model and deploy it to a prediction environment.
"""
# ID for Python 3.9 Scikit learn drop in environment
base_environment_id = "5e8c889607389fe0f466c72d"
# ID for the default prediction server
default_prediction_server_id = "5dd7fa2274a35f003102f60d"
custom_model_name = "App Template Minis - Readmitted Custom Model"
registered_model_name = "App Template Minis - Readmitted Registered Model"
deployment_name = "App Template Minis - Readmitted Deployed Model"
deployment_files = [
("./model_package/requirements.txt", "requirements.txt"),
("./model_package/custom.py", "custom.py"),
("./model_package/model.pkl", "model.pkl"),
]
custom_model = datarobot.CustomModel(
resource_name=custom_model_name,
files=deployment_files,
base_environment_id=base_environment_id,
language="python",
target_type="Binary",
target_name="readmitted",
)
registered_model = datarobot.RegisteredModel(
resource_name=registered_model_name,
custom_model_version_id=custom_model.version_id,
)
deployment = datarobot.Deployment(
resource_name=deployment_name,
label=deployment_name,
registered_model_version_id=registered_model.version_id,
prediction_environment_id=default_prediction_server_id,
)
pulumi.export("custom_model_id", custom_model.id)
pulumi.export("registered_model_id", registered_model.id)
pulumi.export("deployment_id", deployment.id)
Run the Pulumi stack¶
You can now run the Pulumi stack. Doing so takes the files in the model_package
directory from the downloaded assets, puts them into DataRobot as a custom model, registers that model, and deploys the result.
project_name = "AppTemplateMinis-CustomInferenceModels"
stack_name = "MarshallsCustomReadmissionsPredictor"
stack = stack_up(project_name, stack_name, program=make_custom_inference_deployment)
Interact with outputs¶
from datarobot_predict.deployment import predict
import pandas as pd
df = pd.read_csv(
"https://s3.amazonaws.com/datarobot_public_datasets/10k_diabetes.csv"
).tail(100)
deployment_id = stack.outputs().get("deployment_id").value
deployment = dr.Deployment.get(deployment_id)
predict(deployment, data_frame=df).dataframe.head(10).iloc[:, :2]
Clear your work¶
You may not be interested in keeping the custom model. Use this cell to shut down the stack, deleting any assets created in DataRobot.
destroy_project(stack)
Appendix¶
How does scoring code work?¶
The code below shows what you upload so that DataRobot knows how to interact with the custom model. Since you are deploying a custom inference model with minimal transformations, it only defines two hooks to interact with the model, but you could add others too. Since the example model is a standard Scikit-learn binary classifier, DataRobot can figure out how to interact with it without you defining any hooks. Since most model artifacts require some custom scoring logic, the example includes a custom.py
file anyway.
from IPython.display import Code
Code(filename="./model_package/custom.py", language="python")
What did I deploy?¶
If you're curious how you got the fitted model in the first place, fit_custom_model.py
shows the dataset and model fitting code. This example trains a random forest binary classifier using the 10K diabetes dataset. The code below is used to train and pickle the model. It's not important for running the template.
from IPython.display import Code
Code(filename="./fit_custom_model.py", language="python")