XGBoostModel

Overview

The XGBoostModel class in ADS is designed to allow you to rapidly get a XGBoost model into production. The .prepare() method creates the model artifacts that are needed to deploy a functioning model without you having to configure it or write code. However, you can customize the required score.py file.

The .verify() method simulates a model deployment by calling the load_model() and predict() methods in the score.py file. With the .verify() method, you can debug your score.py file without deploying any models. The .save() method deploys a model artifact to the model catalog. The .deploy() method deploys a model to a REST endpoint.

The following steps take your trained XGBoost model and deploy it into production with a few lines of code.

The XGBoostModel module in ADS supports serialization for models generated from both the Learning API using xgboost.train() and the Scikit-Learn API using xgboost.XGBClassifier(). Both of these interfaces are defined by XGBoost.

Create Learning API and Scikit-Learn Wrapper XGBoost Models

In the following several code snippets you will prepare the data and train XGBoost models. In the first snippet, the data will be prepared. This will involved loading a dataset, splitting it into dependent and independent variables and into test and training sets. The data will be encoded and a preprocessing pipeline will be defined. In the second snippet, the XGBoost Learning API will be used to train the model. In the third and final code snippet, the Scikit-Learn Wrapper interface is used to create another XGBoost model.

import pandas as pd
import os
import tempfile
import xgboost as xgb

from ads.model.framework.xgboost_model import XGBoostModel
from sklearn.compose import ColumnTransformer
from sklearn.impute import SimpleImputer
from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import LabelEncoder, OrdinalEncoder

df_path = os.path.join("/", "opt", "notebooks", "ads-examples", "oracle_data", "orcl_attrition.csv")
df = pd.read_csv(df_path)
y = df["Attrition"]
X = df.drop(columns=["Attrition", "name"])

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.1, random_state=42)


# Label encode the y values
le = LabelEncoder()
y_train_transformed = le.fit_transform(y_train)
y_test_transformed = le.transform(y_test)

# Extract numerical columns and categorical columns
categorical_cols = []
numerical_cols = []
for i, col in X.iteritems():
    if col.dtypes == "object":
        categorical_cols.append(col.name)
    else:
        numerical_cols.append(col.name)

categorical_transformer = Pipeline(
    steps=[('encoder', OrdinalEncoder())]
)

# Build a pipeline
preprocessor = ColumnTransformer(
    transformers=[('cat', categorical_transformer, categorical_cols)]
)

preprocessor_pipeline = Pipeline(steps=[('preprocessor', preprocessor)])
preprocessor_pipeline.fit(X_train)

X_train_transformed = preprocessor_pipeline.transform(X_train)
X_test_transformed = preprocessor_pipeline.transform(X_test)

Create an XGBoost model using the Learning API.

dtrain = xgb.DMatrix(X_train_transformed, y_train_transformed)
dtest = xgb.DMatrix(X_test_transformed, y_test_transformed)

model_learn = xgb.train(
    params = {"learning_rate": 0.01, "max_depth": 3},
    dtrain = dtrain,
)

Create an XGBoost model using the Scikit-Learn Wrapper interface.

model = xgb.XGBClassifier(
    n_estimators=100, max_depth=3, learning_rate=0.01, random_state=42,
    use_label_encoder=False
)
model.fit(
    X_train_transformed,
    y_train_transformed,
)

Initialize

Instantiate a XGBoostModel() object with an XGBoost model. Each instance accepts the following parameters:

  • artifact_dir: str: Artifact directory to store the files needed for deployment.

  • auth: (Dict, optional): Defaults to None. The default authentication is set using the ads.set_auth API. To override the default, use ads.common.auth.api_keys() or ads.common.auth.resource_principal() and create the appropriate authentication signer and the **kwargs required to instantiate the IdentityClient object.

  • estimator: (Callable): Trained XGBoost model either using the Learning API or the Scikit-Learn Wrapper interface.

  • properties: (ModelProperties, optional): Defaults to None. The ModelProperties object required to save and deploy a model.

The properties is an instance of the ModelProperties class and has the following predefined fields:

  • compartment_id (str):

  • deployment_access_log_id (str):

  • deployment_bandwidth_mbps (int):

  • deployment_instance_count (int):

  • deployment_instance_shape (str):

  • deployment_log_group_id (str):

  • deployment_predict_log_id (str):

  • inference_conda_env (str):

  • inference_python_version (str):

  • model_version_set_id (str):

  • project_id (str):

  • training_conda_env (str):

  • training_id (str):

  • training_python_version (str):

  • training_resource_id (str):

  • training_script_path (str):

  • version_label (str):

By default, properties is populated from the appropriate environment variables if it’s not specified. For example, in a notebook session, the environment variables for project id and compartment id are preset and stored in PROJECT_OCID and NB_SESSION_COMPARTMENT_OCID by default. So properties populates these variables from the environment variables and uses the values in methods such as .save() and .deploy(). However, you can explicitly pass in values to overwrite the defaults. When you use a method that includes an instance of properties, then properties records the values that you pass in. For example, when you pass inference_conda_env into the .prepare() method, then properties records this value. To reuse the properties file in different places, you can export the properties file using the .to_yaml() method and reload it into a different machine using the .from_yaml() method.

Summary Status

You can call the .summary_status() method after a model serialization instance such as AutoMLModel, GenericModel, SklearnModel, TensorFlowModel, or PyTorchModel is created. The .summary_status() method returns a Pandas dataframe that guides you through the entire workflow. It shows which methods are available to call and which ones aren’t. Plus it outlines what each method does. If extra actions are required, it also shows those actions.

The following image displays an example summary status table created after a user initiates a model instance. The table’s Step column displays a Status of Done for the initiate step. And the Details column explains what the initiate step did such as generating a score.py file. The Step column also displays the prepare(), verify(), save(), deploy(), and predict() methods for the model. The Status column displays which method is available next. After the initiate step, the prepare() method is available. The next step is to call the prepare() method.

../../_images/summary_status.png

Model Deployment

Prepare

The prepare step is performed by the .prepare() method. It creates several customized files used to run the model after it is deployed. These files include:

  • input_schema.json: A JSON file that defines the nature of the features of the X_sample data. It includes metadata such as the data type, name, constraints, summary statistics, feature type, and more.

  • model.json: This is the default filename of the serialized model. It can be changed with the model_file_name attribute. By default, the model is stored in a JSON file. You can use the as_onnx parameter to save in ONNX format, and the model name defaults to model.onnx.

  • output_schema.json: A JSON file that defines the nature of the dependent variable in the y_sample data. It includes metadata such as the data type, name, constraints, summary statistics, feature type, and more.

  • runtime.yaml: This file contains information needed to set up the runtime environment on the deployment server. It has information about what conda environment was used to train the model and what environment to use to deploy the model. The file also specifies what version of Python should be used.

  • score.py: This script contains the load_model() and predict() functions. The load_model() function understands the format the model file was saved in and loads it into memory. The .predict() method is used to make inferences in a deployed model. There are also hooks that allow you to perform operations before and after inference. You can modify this script to fit your specific needs.

To create the model artifacts you use the .prepare() method. There are a number of parameters that allow you to store model provenance information.

To serialize the model to ONNX format, set the as_onnx parameter to True. You can provide the initial_types parameter, which is a Python list describing the variable names and types. Alternatively, the service tries to infer this information from the data in the X_sample parameter. X_sample supports List, Numpy array or Pandas dataframe. DMatrix class is not supported because this format can’t convert into a JSON serializable format, see the ONNX docs.

The .prepare() method serializes the model and prepares and saves the score.py and runtime.yaml files using the following parameters:

  • as_onnx (bool, optional): Defaults to False. If True, it will serialize as an ONNX model.

  • force_overwrite (bool, optional): Defaults to False. If True, it will overwrite existing files.

  • ignore_pending_changes (bool): Defaults to False. If False, it will ignore the pending changes in Git.

  • inference_conda_env (str, optional): Defaults to None. Can be either slug or the Object Storage path of the conda environment. You can only pass in slugs if the conda environment is a Data Science service environment.

  • inference_python_version (str, optional): Defaults to None. The version of Python to use in the model deployment.

  • max_col_num (int, optional): Defaults to utils.DATA_SCHEMA_MAX_COL_NUM. Do not automatically generate the input schema if the input data has more than this number of features.

  • model_file_name (str): Name of the serialized model.

  • namespace (str, optional): Namespace of the OCI region. This is used for identifying which region the service environment is from when you provide a slug to the inference_conda_env or training_conda_env parameters.

  • training_conda_env (str, optional): Defaults to None. Can be either slug or object storage path of the conda environment that was used to train the model. You can only pass in a slug if the conda environment is a Data Science service environment.

  • training_id (str, optional): Defaults to value from environment variables. The training OCID for the model. Can be a notebook session or job OCID.

  • training_python_version (str, optional): Defaults to None. The version of Python used to train the model.

  • training_script_path (str): Defaults to None. The training script path.

  • use_case_type (str): The use case type of the model. Use it with the UserCaseType class or the string provided in UseCaseType. For example, use_case_type=UseCaseType.BINARY_CLASSIFICATION or use_case_type="binary_classification", see the UseCaseType class to see all supported types.

  • X_sample (Union[list, tuple, pd.Series, np.ndarray, pd.DataFrame]): Defaults to None. A sample of the input data. It is used to generate the input schema.

  • y_sample (Union[list, tuple, pd.Series, np.ndarray, pd.DataFrame]): Defaults to None. A sample of output data. It is used to generate the output schema.

  • **kwarg:
    • impute_values (dict, optional): The dictionary where the key is the column index (or names is accepted for Pandas dataframe), and the value is the imputed value for the corresponding column.

New in version 2.6.3.

If you run the code using a service conda pack in a notebook session, you do not need to pass inference_conda_env. The .prepare() method automatically tries to detect the conda environment.

When using the Scikit-Learn Wrapper interface, the .prepare() method accepts any parameter that skl2onnx.convert_sklearn accepts. When using the Learning API, the .prepare() method accepts any parameter that onnxmltools.convert_xgboost accepts.

Verify

If you update the score.py file included in a model artifact, you can verify your changes, without deploying the model. With the .verify() method, you can debug your code without having to save the model to the model catalog and then deploying it. The .verify() method takes a set of test parameters and performs the prediction by calling the predict() function in score.py. It also runs the load_model() function to load the model.

The verify() method tests whether the .predict() API works in the local environment and it takes the following parameter:

  • data: Any: Data used to test if deployment works in a local environment.

Save

After you are satisfied with the performance of your model and have verified that the score.py file is working, use the .save() method to save the model to the model catalog. The .save() method bundles up the model artifacts, stores them in the model catalog, and returns the model OCID.

The .save() method stores the model artifacts in the model catalog. It takes the following parameters:

  • defined_tags (Dict(str, dict(str, object)), optional): Defaults to None. Defined tags for the model.

  • description (str, optional): Defaults to None. The description of the model.

  • display_name (str, optional): Defaults to None. The name of the model.

  • freeform_tags Dict(str, str): Defaults to None. Free form tags for the model.

  • ignore_introspection (bool, optional): Defaults to None. Determines whether to ignore the result of model introspection or not. If set to True, then .save() ignores all model introspection errors.

  • **kwargs:
    • compartment_id (str, optional): Compartment OCID. If not specified, the value is taken either from the environment variables or model properties.

    • model_version_set_id (str, optional): Model Version Set OCID.

    • project_id (str, optional): Project OCID. If not specified, the value is taken either from the environment variables or model properties.

    • timeout (int, optional): Defaults to 10 seconds. The connection timeout in seconds for the client.

    • version_label (str, optional): The version label to be associated with the model when the model is part of a model version set.

The .save() method reloads score.py and runtime.yaml files from disk. This will pick up any changes that have been made to those files. If ignore_introspection=False then it conducts an introspection test to determine if the model deployment might have issues. If potential problems are detected, it will suggest possible remedies. Lastly, it uploads the artifacts to the model catalog, and returns the model OCID. You can also call .instrospect() to conduct the test any time after you call .prepare().

Deploy

You can use the .deploy() method to deploy a model. You must first save the model to the model catalog, and then deploy it.

The .deploy() method returns a ModelDeployment object. Specify deployment attributes such as display name, instance type, number of instances, maximum router bandwidth, and logging groups. The API takes the following parameters:

  • deployment_access_log_id (str, optional): Defaults to None. The access log OCID for the access logs, see logging.

  • deployment_bandwidth_mbps (int, optional): Defaults to 10. The bandwidth limit on the load balancer in Mbps.

  • deployment_instance_count (int, optional): Defaults to 1. The number of instances used for deployment.

  • deployment_instance_shape (str, optional): Default to VM.Standard2.1. The shape of the instance used for deployment.

  • deployment_log_group_id (str, optional): Defaults to None. The OCI logging group OCID. The access log and predict log share the same log group.

  • deployment_predict_log_id (str, optional): Defaults to None. The predict log OCID for the predict logs, see logging.

  • description (str, optional): Defaults to None. The description of the model.

  • display_name (str, optional): Defaults to None. The name of the model.

  • wait_for_completion (bool, optional): Defaults to True. Set to wait for the deployment to complete before proceeding.

  • **kwargs:
    • compartment_id (str, optional): Compartment OCID. If not specified, the value is taken from the environment variables.

    • max_wait_time (int, optional): Defaults to 1200 seconds. The maximum amount of time to wait in seconds. A negative value implies an infinite wait time.

    • poll_interval (int, optional): Defaults to 60 seconds. Poll interval in seconds.

    • project_id (str, optional): Project OCID. If not specified, the value is taken from the environment variables.

Predict

To get a prediction for your model, after your model deployment is active, call the .predict() method. The .predict() method sends a request to the deployed endpoint, and computes the inference values based on the data that you input in the .predict() method.

The .predict() method returns a prediction of input data that is run against the model deployment endpoint and takes the following parameters:

  • data: Any: JSON serializable data used for making inferences.

The .predict() and .verify() methods take the same data formats. You must ensure that the data passed into and returned by the predict() function in the score.py file is JSON serializable.

Load

You can restore serialization models from model artifacts, from model deployments or from models in the model catalog. This section provides details on how to restore serialization models.

Model Artifact

A model artifact is a collection of files used to create a model deployment. Some example files included in a model artifact are the serialized model, score.py, and runtime.yaml. You can store your model artifact in a local directory, in a ZIP or TAR format. Then use the .from_model_artifact() method to import the model artifact into the serialization model class. The .from_model_artifact() method takes the following parameters:

  • artifact_dir (str): Artifact directory to store the files needed for deployment.

  • auth (Dict, optional): Defaults to None. The default authentication is set using the ads.set_auth API. To override the default, use ads.common.auth.api_keys() or ads.common.auth.resource_principal() and create the appropriate authentication signer and the **kwargs required to instantiate the IdentityClient object.

  • force_overwrite (bool, optional): Defaults to False. If True, it will overwrite existing files.

  • model_file_name (str): The serialized model file name.

  • properties (ModelProperties, optional): Defaults to None. ModelProperties object required to save and deploy the model.

  • uri (str): The path to the folder, ZIP, or TAR file that contains the model artifact. The model artifact must contain the serialized model, the score.py, runtime.yaml and other files needed for deployment. The content of the URI is copied to the artifact_dir folder.

from ads.model.framework.xgboost_model import XGBoostModel

model = XGBoostModel.from_model_artifact(
                uri="/folder_to_your/artifact.zip",
                model_file_name="model.joblib",
                artifact_dir="/folder_store_artifact"
            )

Model Catalog

To populate a serialization model object from a model stored in the model catalog, call the .from_model_catalog() method. This method uses the model OCID to download the model artifacts, write them to the artifact_dir, and update the serialization model object. The .from_model_catalog() method takes the following parameters:

  • artifact_dir (str): Artifact directory to store the files needed for deployment.

  • auth (Dict, optional): Defaults to None. The default authentication is set using the ads.set_auth API. To override the default, use ads.common.auth.api_keys() or ads.common.auth.resource_principal() and create the appropriate authentication signer and the **kwargs required to instantiate the IdentityClient object.

  • force_overwrite (bool, optional): Defaults to False. If True, it will overwrite existing files.

  • model_id (str): The model OCID.

  • model_file_name (str): The serialized model file name.

  • properties (ModelProperties, optional): Defaults to None. Define the properties to save and deploy the model.

  • **kwargs:
    • compartment_id (str, optional): Compartment OCID. If not specified, the value will be taken from the environment variables.

    • timeout (int, optional): Defaults to 10 seconds. The connection timeout in seconds for the client.

from ads.model.framework.xgboost_model import XGBoostModel

model = XGBoostModel.from_model_catalog(model_id="<model_id>",
                                        model_file_name="model.json",
                                        artifact_dir=tempfile.mkdtemp())

Model Deployment

New in version 2.6.2.

To populate a serialization model object from a model deployment, call the .from_model_deployment() method. This method accepts a model deployment OCID. It downloads the model artifacts, writes them to the model artifact directory (artifact_dir), and updates the serialization model object. The .from_model_deployment() method takes the following parameters:

  • artifact_dir (str): Artifact directory to store the files needed for deployment.

  • auth (Dict, optional): Defaults to None. The default authentication is set using the ads.set_auth API. To override the default, use ads.common.auth.api_keys() or ads.common.auth.resource_principal(). Supply the appropriate authentication signer and the **kwargs required to instantiate an IdentityClient object.

  • force_overwrite (bool, optional): Defaults to False. If True, it will overwrite existing files in the artifact directory.

  • model_deployment_id (str): The model deployment OCID.

  • model_file_name (str): The serialized model file name.

  • properties (ModelProperties, optional): Defaults to None. Define the properties to save and deploy the model.

  • **kwargs:
    • compartment_id (str, optional): Compartment OCID. If not specified, the value will be taken from the environment variables.

    • timeout (int, optional): Defaults to 10 seconds. The connection timeout in seconds for the client.

from ads.model.generic_model import XGBoostModel

model = XGBoostModel.from_model_deployment(
    model_deployment_id="<model_deployment_id>",
    model_file_name="model.pkl",
    artifact_dir=tempfile.mkdtemp())

Delete a Deployment

Use the .delete_deployment() method on the serialization model object to delete a model deployment. You must delete a model deployment before deleting its associated model from the model catalog.

Each time you call the .deploy() method, it creates a new deployment. Only the most recent deployment is attached to the object.

The .delete_deployment() method deletes the most recent deployment and takes the following optional parameter:

  • wait_for_completion: (bool, optional). Defaults to False and the process runs in the background. If set to True, the method returns when the model deployment is deleted.

Example

import pandas as pd
import os
import tempfile
import xgboost as xgb

from ads.catalog.model import ModelCatalog
from ads.common.model_metadata import UseCaseType
from ads.model.framework.xgboost_model import XGBoostModel
from sklearn.compose import ColumnTransformer
from sklearn.impute import SimpleImputer
from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import LabelEncoder, OrdinalEncoder

df_path = os.path.join("/", "opt", "notebooks", "ads-examples", "oracle_data", "orcl_attrition.csv")
df = pd.read_csv(df_path)
y = df["Attrition"]
X = df.drop(columns=["Attrition", "name"])

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.1, random_state=42)

# Label encode the y values
le = LabelEncoder()
y_train_transformed = le.fit_transform(y_train)
y_test_transformed = le.transform(y_test)

# Extract numerical columns and categorical columns
categorical_cols = []
numerical_cols = []
for i, col in X.iteritems():
    if col.dtypes == "object":
        categorical_cols.append(col.name)
    else:
        numerical_cols.append(col.name)

categorical_transformer = Pipeline(
    steps=[('encoder', OrdinalEncoder())]
)

# Build a pipeline
preprocessor = ColumnTransformer(
    transformers=[('cat', categorical_transformer, categorical_cols)]
)

preprocessor_pipeline = Pipeline(steps=[('preprocessor', preprocessor)])
preprocessor_pipeline.fit(X_train)

X_train_transformed = preprocessor_pipeline.transform(X_train)
X_test_transformed = preprocessor_pipeline.transform(X_test)

# XGBoost Scikit-Learn API
model = xgb.XGBClassifier(
    n_estimators=100, learning_rate=0.01, random_state=42,
    use_label_encoder=False
)
model.fit(X_train_transformed, y_train_transformed)

# Deploy the model, test it and clean up.
artifact_dir = tempfile.mkdtemp()
xgboost_model = XGBoostModel(estimator=model, artifact_dir=artifact_dir)
xgboost_model.prepare(
    inference_conda_env="generalml_p37_cpu_v1",
    training_conda_evn="generalml_p37_cpu_v1",
    use_case_type=UseCaseType.BINARY_CLASSIFICATION,
    X_sample=X_test_transformed,
    y_sample=y_test_transformed,
)
xgboost_model.verify(X_test_transformed[:10])['prediction']
model_id = xgboost_model.save()
xgboost_model.deploy()
xgboost_model.predict(X_test_transformed[:10])['prediction']
xgboost_model.delete_deployment(wait_for_completion=True)
ModelCatalog(compartment_id=os.environ['NB_SESSION_COMPARTMENT_OCID']).delete_model(model_id)