{ "cells": [ { "cell_type": "markdown", "id": "601993bd-1607-4def-8217-8a405dca9bcb", "metadata": { "jp-MarkdownHeadingCollapsed": true, "tags": [] }, "source": [ "### Direct Marketing in Banking - Propensity Modelling with Tabular Data\n", "\n", "# Part 2: AutoGluon-Tabular Ensemble Models\n", "\n", "> *This notebook works well with the `Python 3 (Data Science 3.0)` kernel on SageMaker Studio*\n", "\n", "This workshop explores a tabular, [binary classification](https://en.wikipedia.org/wiki/Binary_classification) use-case with significant **class imbalance**: predicting which of a bank's customers are likely to respond to a targeted marketing campaign.\n", "\n", "In this optional second notebook, you'll explore [AutoGluon-Tabular](https://docs.aws.amazon.com/sagemaker/latest/dg/autogluon-tabular.html) - another advanced, built-in algorithm from SageMaker that automatically ensembles different model types together for high accuracy.\n", "\n", "> ⚠️ **You must** have run [Notebook 1 Autopilot and XGBoost.ipynb](1%20Autopilot%20and%20XGBoost.ipynb) before this notebook (at least to the point of having queried a data snapshot from SageMaker Feature Store)\n", "\n", "\n", "## Contents\n", "\n", "> ℹ️ **Tip:** You can use the Table of Contents panel in the left sidebar on JupyterLab / SageMaker Studio, to view and navigate sections\n", "\n", "1. **[Prepare our environment](#Prepare-our-environment)**\n", "1. **[Algorithms, AutoML, and AutoGluon](#intro)**\n", "1. **[Understand the algorithm requirements](#Understand-the-algorithm-requirements)**\n", "1. **[Prepare training and test data](#Prepare-training-and-test-data)**\n", "1. **[Train a model](#Train-a-model)**\n", "1. **[Batch inference](#Batch-inference)**\n", "1. **[Hyperparameter Optimization (HPO)](#Hyperparameter-Optimization-(HPO))**\n", "1. **[Deploy and test the optimized model](#Deploy-and-test-the-optimized-model)**\n", "1. **[Conclusions](#Conclusions)**" ] }, { "cell_type": "markdown", "id": "c2b71f36-4f16-4d1e-99ef-3bfd168b502e", "metadata": {}, "source": [ "## Prepare our environment\n", "\n", "As in the previous notebook, we'll start by importing libraries and configuring AWS/Sagemaker service connections:" ] }, { "cell_type": "code", "execution_count": null, "id": "bcecf6b9-d086-4d2f-b5b3-5af0678dc6a5", "metadata": {}, "outputs": [], "source": [ "%load_ext autoreload\n", "%autoreload 2\n", "\n", "# Python Built-Ins:\n", "import json\n", "import time\n", "\n", "# External Dependencies:\n", "import boto3 # General-purpose AWS SDK for Python\n", "import numpy as np # For matrix operations and numerical processing\n", "import pandas as pd # Tabular data utilities\n", "import sagemaker # High-level SDK specifically for Amazon SageMaker\n", "\n", "# Local Helper Functions:\n", "import util\n", "\n", "# Setting up SageMaker parameters\n", "sgmk_session = sagemaker.Session() # Connect to SageMaker APIs\n", "bucket_name = sgmk_session.default_bucket() # Select an Amazon S3 bucket\n", "bucket = boto3.resource(\"s3\").Bucket(bucket_name)\n", "bucket_prefix = \"sm101/direct-marketing\" # Location in the bucket to store our files\n", "sgmk_role = sagemaker.get_execution_role() # IAM Execution Role to use for permissions\n", "\n", "print(f\"s3://{bucket_name}/{bucket_prefix}\")\n", "print(sgmk_role)" ] }, { "cell_type": "markdown", "id": "b764dfba-9602-4c84-9897-c47906f5cb0a", "metadata": {}, "source": [ "## Algorithms, AutoML, and AutoGluon\n", "\n", "Another useful tool to build highly-accurate models quickly is the open-source [AutoGluon framework](https://auto.gluon.ai/stable/index.html) and the SageMaker built-in [AutoGluon-Tabular algorithm](https://docs.aws.amazon.com/sagemaker/latest/dg/autogluon-tabular.html).\n", "\n", "As outlined in the [2020 paper by Erickson, Mueller et al](https://arxiv.org/abs/2003.06505), AutoGluon-Tabular is an advanced model stacking ensembling framework that beat 99% of participating data scientists in benchmark Kaggle contests with just 4hrs of model training.\n", "\n", "In fact at the time of writing, SageMaker Autopilot makes use of AutoGluon under the hood when running in ensembling mode: But you can also use AutoGluon directly as shown here for more customized experiments." ] }, { "cell_type": "markdown", "id": "7210a33d-5394-4962-8dec-92f4075d2768", "metadata": {}, "source": [ "## Understand the algorithm requirements\n", "\n", "As described in the [how to use](https://docs.aws.amazon.com/sagemaker/latest/dg/autogluon-tabular.html#autogluon-tabular-modes) section of the AutoGluon-Tabular doc page, [SageMaker JumpStart-based](https://sagemaker.readthedocs.io/en/stable/overview.html#use-built-in-algorithms-with-pre-trained-models-in-sagemaker-python-sdk) algorithms like AutoGluon-Tabular need a `script_uri` and `model_uri` in addition to the container `image_uri` as we configured for XGBoost.\n", "\n", "These resources are all pre-built, and we can look them up by the `retrieve()` functions in the SageMaker Python SDK as shown below.\n", "\n", "The default [hyperparameters](https://docs.aws.amazon.com/sagemaker/latest/dg/autogluon-tabular-hyperparameters.html) for the algorithm can also be loaded through the SDK, and below we make some minor customizations ready for inference." ] }, { "cell_type": "code", "execution_count": null, "id": "efb076fd-0268-45b5-811c-30f4d3d1b604", "metadata": {}, "outputs": [], "source": [ "from sagemaker import image_uris, script_uris, model_uris\n", "from sagemaker.hyperparameters import retrieve_default as retrieve_default_hyperparams\n", "\n", "ag_model_id, ag_model_version, train_scope = (\n", " \"autogluon-classification-ensemble\",\n", " \"*\",\n", " \"training\",\n", ")\n", "training_instance_type = \"ml.p3.2xlarge\"\n", "\n", "# Retrieve the docker image\n", "train_image_uri = image_uris.retrieve(\n", " region=None,\n", " framework=None,\n", " model_id=ag_model_id,\n", " model_version=ag_model_version,\n", " image_scope=train_scope,\n", " instance_type=training_instance_type,\n", ")\n", "print(train_image_uri)\n", "# Retrieve the training script\n", "train_source_uri = script_uris.retrieve(\n", " model_id=ag_model_id, model_version=ag_model_version, script_scope=train_scope\n", ")\n", "print(train_source_uri)\n", "# Retrieve the pre-trained model tarball to further fine-tune. In tabular case, however, the pre-trained model tarball is dummy and fine-tune means training from scratch.\n", "train_model_uri = model_uris.retrieve(\n", " model_id=ag_model_id, model_version=ag_model_version, model_scope=train_scope\n", ")\n", "print(train_model_uri)\n", "\n", "# Retrieve the default hyper-parameters for training the model\n", "hyperparameters = retrieve_default_hyperparams(\n", " model_id=ag_model_id, model_version=ag_model_version\n", ")\n", "\n", "# [Optional] Override default hyperparameters with custom values\n", "hyperparameters[\"auto_stack\"] = \"True\"\n", "hyperparameters[\"save_space\"] = \"True\"\n", "print(\"\\n\", hyperparameters)" ] }, { "cell_type": "markdown", "id": "10aba13d-367c-447c-bc4b-b88dccf8901b", "metadata": {}, "source": [ "## Prepare training and test data\n", "\n", "We'll **re-use the snapshot** queried from SageMaker Feature Store in the previous notebook, reading all CSVs under the S3 prefix into a combined dataframe.\n", "\n", "▶️ **Check** the `data_extract_s3uri` here matches your `data_extract_s3uri` from notebook 1" ] }, { "cell_type": "code", "execution_count": null, "id": "cf456b1a-5980-4789-88cb-4aa21a8fc5ca", "metadata": {}, "outputs": [], "source": [ "data_extract_s3uri = f\"s3://{bucket_name}/{bucket_prefix}/data-extract\"\n", "data_extract_prefix = data_extract_s3uri[len(\"s3://\"):].partition(\"/\")[2]\n", "\n", "full_df = pd.concat(\n", " [\n", " pd.read_csv(f\"s3://{s3obj.bucket_name}/{s3obj.key}\")\n", " for s3obj in bucket.objects.filter(Prefix=data_extract_prefix)\n", " if s3obj.key.lower().endswith(\".csv\")\n", " ],\n", " axis=0,\n", ")\n", "full_df" ] }, { "cell_type": "markdown", "id": "59e5e999-4475-4f78-8c55-af18cc078d17", "metadata": {}, "source": [ "From the [Input and Output Interface section](https://docs.aws.amazon.com/sagemaker/latest/dg/autogluon-tabular.html#InputOutput-AutoGluon-Tabular) of the algorithm doc, we know that AutoGluon-Tabular expects **CSV data in a particular structure**: `train/` and `validation/` folders each containing a single `data.csv`, with **no headers**, and the **target column first** in the files.\n", "\n", "Unlike XGBoost, string categorical fields can be left as-is. Below we'll split the raw data snapshot as done previously - and upload to S3 in the required format:" ] }, { "cell_type": "code", "execution_count": null, "id": "dc03b27f-96b2-48ca-b4e4-80b3545e7b05", "metadata": {}, "outputs": [], "source": [ "df_model_data = full_df.drop(\n", " columns=[\n", " # Drop Feature Store metadata fields that aren't relevant to the model:\n", " \"customer_id\", \"event_time\", \"write_time\", \"api_invocation_time\", \"is_deleted\", \"row_number\"\n", " ],\n", " errors=\"ignore\", # Your DF may not have 'row_number' if you did a simple 'select * from' query\n", ")\n", "df_model_data\n", "\n", "# Shuffle and split dataset\n", "train_data, validation_data, test_data = np.split(\n", " df_model_data.sample(frac=1, random_state=1729),\n", " [int(0.7 * len(df_model_data)), int(0.9 * len(df_model_data))],\n", ")\n", "\n", "# Create CSV files for Train / Validation / Test\n", "train_data.to_csv(\"data/train.csv\", index=False, header=False)\n", "validation_data.to_csv(\"data/validation.csv\", index=False, header=False)\n", "test_data.to_csv(\"data/test.csv\", index=False, header=False)\n", "\n", "df_model_data" ] }, { "cell_type": "code", "execution_count": null, "id": "2d587ef5-4c4d-4fa5-a877-e93b85bdb6ad", "metadata": {}, "outputs": [], "source": [ "model_data_s3uri = f\"s3://{bucket_name}/{bucket_prefix}/model-data-ag\"\n", "\n", "# Upload data to Amazon S3:\n", "train_data_s3uri = model_data_s3uri + \"/train/data.csv\"\n", "train_data.to_csv(train_data_s3uri, index=False, header=False)\n", "validation_data_s3uri = model_data_s3uri + \"/validation/data.csv\"\n", "validation_data.to_csv(validation_data_s3uri, index=False, header=False)\n", "test_data_s3uri = model_data_s3uri + \"/test/data.csv\"\n", "test_data.to_csv(test_data_s3uri, index=False, header=False)" ] }, { "cell_type": "markdown", "id": "9f9e6833-1a31-464c-a27f-7b533eba1074", "metadata": {}, "source": [ "## Train a model\n", "\n", "With the parameters collected and data prepared in a compatible format, we're ready to train an AutoGluon model.\n", "\n", "Like in the previous XGBoost example, this process uses the [Estimator](https://sagemaker.readthedocs.io/en/stable/api/training/estimators.html#sagemaker.estimator.Estimator) SDK class to define and run the training job.\n", "\n", "Unlike the XGBoost example:\n", "\n", "- The AutoGluon algorithm uses a single `training` data channel, with subfolders in S3 defining the separate splits of data.\n", "- Additional parameters are needed (`source_dir`, `model_uri`, `entry_point`) to reference the separate (but pre-built) input artifacts that need to be bundled into the job." ] }, { "cell_type": "code", "execution_count": null, "id": "dbf4f5ed-b223-4045-92fa-f63282ce5dc3", "metadata": { "scrolled": true, "tags": [] }, "outputs": [], "source": [ "%%time\n", "\n", "ag_estimator = sagemaker.estimator.Estimator(\n", " base_job_name=\"autogluon\",\n", " role=sgmk_role, # IAM role for job permissions\n", " output_path=f\"s3://{bucket_name}/{bucket_prefix}/train-output\", # Optional artifact output loc\n", "\n", " image_uri=train_image_uri, # AutoGluon-Tabular algorithm container\n", " source_dir=train_source_uri, # AutoGluon-Tabular script bundle (pre-built)\n", " model_uri=train_model_uri, # AutoGluon-Tabular pre-trained artifacts\n", " entry_point=\"transfer_learning.py\", # Training script in the source_dir\n", "\n", " hyperparameters=hyperparameters,\n", "\n", " instance_type=training_instance_type, # Type of compute instance\n", " instance_count=1,\n", " max_run=25 * 60, # Limit job to 25 minutes\n", ")\n", "\n", "# Launch a SageMaker Training job by passing the S3 path of the datasets:\n", "ag_estimator.fit({\"training\": model_data_s3uri})" ] }, { "cell_type": "markdown", "id": "26877f11-054c-4fd8-87a2-52ccdab688ff", "metadata": {}, "source": [ "## Deploy the model\n", "\n", "When the training job is completed successfully, your model is ready to use for inference either in batch or real-time.\n", "\n", "For this particular algorithm, the **container URI and script are different** for inference than training, so we need to look up the inference artifacts similarly to training above:" ] }, { "cell_type": "code", "execution_count": null, "id": "e2901f70-b7ad-424b-867f-d1bf67b7469e", "metadata": {}, "outputs": [], "source": [ "inference_instance_type = \"ml.m5.large\"\n", "\n", "inference_image_uri = image_uris.retrieve(\n", " region=None,\n", " framework=None,\n", " model_id=ag_model_id,\n", " model_version=ag_model_version,\n", " image_scope=\"inference\",\n", " instance_type=inference_instance_type,\n", ")\n", "print(inference_image_uri)\n", "\n", "inference_src_uri = script_uris.retrieve(\n", " model_id=ag_model_id, model_version=ag_model_version, script_scope=\"inference\"\n", ")\n", "print(inference_src_uri)" ] }, { "cell_type": "markdown", "id": "a40196fb-f1e4-4f6a-8dfa-a20be48c6b0d", "metadata": {}, "source": [ "Although you could deploy in **one line** with `ag_predictor = ag_estimator.deploy(...)`, this encapsulates [multiple steps](https://docs.aws.amazon.com/sagemaker/latest/dg/realtime-endpoints-deployment.html) of generating a Model, Endpoint Configuration, and Endpoint.\n", "\n", "We'll explicitly separate out the model step here, which will be helpful for storing model metadata later:" ] }, { "cell_type": "code", "execution_count": null, "id": "d671eeb1-07bd-4354-9389-48a6e2589b19", "metadata": {}, "outputs": [], "source": [ "ag_model = ag_estimator.create_model(\n", " image_uri=inference_image_uri,\n", " source_dir=inference_src_uri,\n", " entry_point=\"inference.py\",\n", ")" ] }, { "cell_type": "markdown", "id": "2e4789ba-158e-4d7b-ba31-359dacced853", "metadata": {}, "source": [ "Whether from a Model or direct from an Estimator, setting up a real-time endpoint for the trained model is just one `.deploy(...)` function call as shown below.\n", "\n", "> ⏰ This deployment might take **up to 5-10 minutes**, and by default the code will wait for the deployment to complete.\n", "\n", "If you like, you can instead:\n", "\n", "- Un-comment the `wait=False` parameter (or if you already ran the cell, press the ⏹ \"stop\" button in the toolbar above)\n", "- Use the [Endpoints page of the SageMaker Console](https://console.aws.amazon.com/sagemaker/home?#/endpoints) to check the status of the deployment" ] }, { "cell_type": "code", "execution_count": null, "id": "199539a0-a518-4074-8edf-8197a792aaaa", "metadata": {}, "outputs": [], "source": [ "%%time\n", "ag_predictor = ag_model.deploy(\n", " initial_instance_count=1,\n", " instance_type=inference_instance_type,\n", " \n", " # wait=False, # Remember, predictor.predict() won't work until deployment finishes!\n", "\n", " # We will also turn on data capture here, in case you want to experiment with monitoring later:\n", " data_capture_config=sagemaker.model_monitor.DataCaptureConfig(\n", " enable_capture=True,\n", " sampling_percentage=100,\n", " destination_s3_uri=f\"s3://{bucket_name}/{bucket_prefix}/data-capture\",\n", " ),\n", ")" ] }, { "cell_type": "markdown", "id": "4a9e0a0f-a4d0-4db3-bc13-d76b9ad65636", "metadata": {}, "source": [ "## Use the endpoint\n", "\n", "As in the previous notebook, we can use the high-level SageMaker Python SDK [Predictor](https://sagemaker.readthedocs.io/en/stable/api/inference/predictors.html) class to interact with our deployed model.\n", "\n", "Again, when using a pre-built algorithm, refer to the [algorithm docs](https://docs.aws.amazon.com/sagemaker/latest/dg/autogluon-tabular.html#InputOutput-AutoGluon-Tabular) to see what input and output formats are supported at inference time.\n", "\n", "When using `application/json` with the `verbose` flag, AutoGluon-Tabular can return **both** the predicted class labels and the class probabilities, which we'll use below:" ] }, { "cell_type": "code", "execution_count": null, "id": "88553a5a-2f41-4863-9f55-b9ae35489109", "metadata": {}, "outputs": [], "source": [ "ag_predictor.serializer = sagemaker.serializers.CSVSerializer()\n", "ag_predictor.deserializer = sagemaker.deserializers.JSONDeserializer(\n", " accept=\"application/json;verbose\"\n", ")\n", "\n", "X_test_numpy = test_data.drop([\"y\"], axis=1).values\n", "\n", "model_response = ag_predictor.predict(X_test_numpy)\n", "\n", "print(\"Response keys:\", model_response.keys())\n", "\n", "# probabilities is (N, 2) with probs for both classes, so convert to 1D probability of cls '1':\n", "probabilities = np.array(model_response[\"probabilities\"], dtype=float)[:, 1].squeeze()\n", "probabilities" ] }, { "cell_type": "markdown", "id": "6183111b-30e0-4460-83f5-5848f227801a", "metadata": {}, "source": [ "We can use both the probabilities and the assigned class labels in downstream processing - depending whether we want to use the model's own inferred threshold or override it. As a reminder for this bank marketing tasks, the class labels are:\n", "\n", "- 0: The person **will not** enroll\n", "- 1: The person **will** enroll (making them a good candidate for direct marketing)" ] }, { "cell_type": "code", "execution_count": null, "id": "9ff5a640-4aa7-45e0-b4fa-7ddbadc38999", "metadata": {}, "outputs": [], "source": [ "test_results = pd.concat(\n", " [\n", " pd.Series(probabilities, name=\"y_prob\", index=test_data.index),\n", " pd.Series(model_response[\"predicted_label\"], name=\"y_pred\", index=test_data.index),\n", " test_data,\n", " ],\n", " axis=1,\n", ")\n", "test_results.head()" ] }, { "cell_type": "markdown", "id": "86b7e0c2-4e11-4d97-ba86-a72e9816b686", "metadata": {}, "source": [ "From this joined data we can calculate standard quality metrics to measure the performance of the classifier. Run the below to produce a model quality report similar to the previous notebook.\n", "\n", "Note that here we're using the model's own labels, rather than automatically inferring the F1-score-maximising probability threshold:" ] }, { "cell_type": "code", "execution_count": null, "id": "9daf15b1-4253-4b6f-984d-9336692cc826", "metadata": {}, "outputs": [], "source": [ "report = util.reporting.generate_binary_classification_report(\n", " y_real=test_data[\"y\"].values,\n", " y_predict_proba=probabilities,\n", " # Since this model already outputs both labels and probabilities, we can use both:\n", " y_predict_label=test_results[\"y_pred\"].values,\n", " # No need for an arbitrary decision threshold:\n", " # decision_threshold=0.5,\n", " class_names_list=[\"Did not enroll\", \"Enrolled\"],\n", " title=\"AutoGluon model\",\n", ")\n", "\n", "# Store the model quality report locally and on Amazon S3:\n", "with open(\"data/report-autogluon.json\", \"w\") as f:\n", " json.dump(report, f, indent=2)\n", "model_quality_s3uri = f\"s3://{bucket_name}/{bucket_prefix}/{ag_model.name}/model-quality.json\"\n", "!aws s3 cp data/report-autogluon.json {model_quality_s3uri}" ] }, { "cell_type": "markdown", "id": "f26498f0-45a3-4195-9669-8a2974b3f034", "metadata": { "tags": [] }, "source": [ "### Register and share the model\n", "\n", "As with XGBoost, we can add this model candidate to SageMaker Model Registry - and from there compare its performance to other candidates." ] }, { "cell_type": "code", "execution_count": null, "id": "2199e4e7-7f86-4076-b974-3c0bacc6c9f5", "metadata": { "tags": [] }, "outputs": [], "source": [ "ag_model.register(\n", " content_types=[\"text/csv\"],\n", " response_types=[\"application/json\", \"application/json;verbose\"],\n", " model_package_group_name=\"sm101-dm\",\n", " description=\"AutoGluon-Tabular model\",\n", " model_metrics=sagemaker.model_metrics.ModelMetrics(\n", " model_statistics=sagemaker.model_metrics.MetricsSource(\n", " content_type=\"application/json\",\n", " s3_uri=model_quality_s3uri,\n", " ),\n", " ),\n", " domain=\"MACHINE_LEARNING\",\n", " task=\"CLASSIFICATION\",\n", " sample_payload_url=test_data_s3uri,\n", ")" ] }, { "cell_type": "markdown", "id": "a93dc079-d8c8-45c6-9312-0c4f786af381", "metadata": {}, "source": [ "You can compare the model charts and statistics side-by-side in SageMaker Studio's Model Registry UI to assess their performance - as shown in the screenshot below:\n", "\n", "![](img/model-registry-compare.png \"Screenshot of side-by-side comparison in SageMaker Studio Model Registry UI\")\n", "\n", "Note that:\n", "\n", "- F1-related comparisons may not be entirely fair: Our XGBoost models' metrics automatically inferred the F1-maximising threshold and used it to drive decisions, whereas AutoGluon-Tabular used its own threshold selection algorithm to assign labels.\n", "- This model package group can contain versions with different I/O contracts (Our XGBoost models expect one-hot encoded inputs, and our AutoGluon model produces JSON output instead of CSV). You could consider also attaching [data quality reports](https://docs.aws.amazon.com/sagemaker/latest/dg/model-monitor-data-quality.html) to fully specify the expected distribution of model inputs and outputs from training, and attaching additional lineage metadata." ] }, { "cell_type": "markdown", "id": "d85c24ff-cf6d-49ac-811d-d2974a734d3a", "metadata": {}, "source": [ "## Conclusions\n", "\n", "In this example we used an alternative built-in algorithm for tabular data on SageMaker, [AutoGluon-Tabular **built-in algorithm**](https://docs.aws.amazon.com/sagemaker/latest/dg/autogluon-tabular.html), which automatically ensembles different modelling approaches to deliver high accuracy. In fact, this uses similar techniques to [SageMaker Autopilot](https://docs.aws.amazon.com/sagemaker/latest/dg/autopilot-automate-model-development.html) runs in `Ensembling` mode. It's well worth checking this algorithm out (and the open-source [AutoGluon library](https://auto.gluon.ai/)), if you're mainly using single-algorithm approaches like XGBoost or LightGBM today.\n", "\n", "Some key things to remember:\n", "\n", "- In the case of SageMaker Autopilot, you don't even need to write code to get started: Just upload your data to Amazon S3 and work through the `Create experiment` UI flow.\n", "- When using built-in algorithms, **refer to the [algorithm's doc pages](https://docs.aws.amazon.com/sagemaker/latest/dg/algos.html)** for important usage info like data formats, and whether multi-instance training parallelism is supported.\n", "\n", "Check out the other workshops in this repository to dive deeper on custom ML with bring-your-own-script training jobs." ] }, { "cell_type": "markdown", "id": "8aa7c449-4c89-4307-b952-e34cc1a40f16", "metadata": {}, "source": [ "## Releasing cloud resources\n", "\n", "As mentioned in the previous notebook, you should shut down any created inference endpoints when finished experimenting. You may also choose to clear out your Amazon S3 storage, in which case do remember to delete your SageMaker Feature Store Feature Group and Model Registry Model Group first.\n", "\n", "You can un-comment the below code to delete the inference endpoint created by this notebook:" ] }, { "cell_type": "code", "execution_count": null, "id": "1c64a6ee-4bef-49fb-bd0c-fc1861c709d9", "metadata": {}, "outputs": [], "source": [ "# ag_predictor.delete_endpoint(delete_endpoint_config=True)" ] } ], "metadata": { "availableInstances": [ { "_defaultOrder": 0, "_isFastLaunch": true, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 4, "name": "ml.t3.medium", "vcpuNum": 2 }, { "_defaultOrder": 1, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 8, "name": "ml.t3.large", "vcpuNum": 2 }, { "_defaultOrder": 2, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 16, "name": "ml.t3.xlarge", "vcpuNum": 4 }, { "_defaultOrder": 3, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 32, "name": "ml.t3.2xlarge", "vcpuNum": 8 }, { "_defaultOrder": 4, "_isFastLaunch": true, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 8, "name": "ml.m5.large", "vcpuNum": 2 }, { "_defaultOrder": 5, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 16, "name": "ml.m5.xlarge", "vcpuNum": 4 }, { "_defaultOrder": 6, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 32, "name": "ml.m5.2xlarge", "vcpuNum": 8 }, { "_defaultOrder": 7, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 64, "name": "ml.m5.4xlarge", "vcpuNum": 16 }, { "_defaultOrder": 8, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 128, "name": "ml.m5.8xlarge", "vcpuNum": 32 }, { "_defaultOrder": 9, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 192, "name": "ml.m5.12xlarge", "vcpuNum": 48 }, { "_defaultOrder": 10, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 256, "name": "ml.m5.16xlarge", "vcpuNum": 64 }, { "_defaultOrder": 11, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 384, "name": "ml.m5.24xlarge", "vcpuNum": 96 }, { "_defaultOrder": 12, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 8, "name": "ml.m5d.large", "vcpuNum": 2 }, { "_defaultOrder": 13, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 16, "name": "ml.m5d.xlarge", "vcpuNum": 4 }, { "_defaultOrder": 14, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 32, "name": "ml.m5d.2xlarge", "vcpuNum": 8 }, { "_defaultOrder": 15, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 64, "name": "ml.m5d.4xlarge", "vcpuNum": 16 }, { "_defaultOrder": 16, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 128, "name": "ml.m5d.8xlarge", "vcpuNum": 32 }, { "_defaultOrder": 17, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 192, "name": "ml.m5d.12xlarge", "vcpuNum": 48 }, { "_defaultOrder": 18, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 256, "name": "ml.m5d.16xlarge", "vcpuNum": 64 }, { "_defaultOrder": 19, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 384, "name": "ml.m5d.24xlarge", "vcpuNum": 96 }, { "_defaultOrder": 20, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "hideHardwareSpecs": true, "memoryGiB": 0, "name": "ml.geospatial.interactive", "supportedImageNames": [ "sagemaker-geospatial-v1-0" ], "vcpuNum": 0 }, { "_defaultOrder": 21, "_isFastLaunch": true, "category": "Compute optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 4, "name": "ml.c5.large", "vcpuNum": 2 }, { "_defaultOrder": 22, "_isFastLaunch": false, "category": "Compute optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 8, "name": "ml.c5.xlarge", "vcpuNum": 4 }, { "_defaultOrder": 23, "_isFastLaunch": false, "category": "Compute optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 16, "name": "ml.c5.2xlarge", "vcpuNum": 8 }, { "_defaultOrder": 24, "_isFastLaunch": false, "category": "Compute optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 32, "name": "ml.c5.4xlarge", "vcpuNum": 16 }, { "_defaultOrder": 25, "_isFastLaunch": false, "category": "Compute optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 72, "name": "ml.c5.9xlarge", "vcpuNum": 36 }, { "_defaultOrder": 26, "_isFastLaunch": false, "category": "Compute optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 96, "name": "ml.c5.12xlarge", "vcpuNum": 48 }, { "_defaultOrder": 27, "_isFastLaunch": false, "category": "Compute optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 144, "name": "ml.c5.18xlarge", "vcpuNum": 72 }, { "_defaultOrder": 28, "_isFastLaunch": false, "category": "Compute optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 192, "name": "ml.c5.24xlarge", "vcpuNum": 96 }, { "_defaultOrder": 29, "_isFastLaunch": true, "category": "Accelerated computing", "gpuNum": 1, "hideHardwareSpecs": false, "memoryGiB": 16, "name": "ml.g4dn.xlarge", "vcpuNum": 4 }, { "_defaultOrder": 30, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "hideHardwareSpecs": false, "memoryGiB": 32, "name": "ml.g4dn.2xlarge", "vcpuNum": 8 }, { "_defaultOrder": 31, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "hideHardwareSpecs": false, "memoryGiB": 64, "name": "ml.g4dn.4xlarge", "vcpuNum": 16 }, { "_defaultOrder": 32, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "hideHardwareSpecs": false, "memoryGiB": 128, "name": "ml.g4dn.8xlarge", "vcpuNum": 32 }, { "_defaultOrder": 33, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 4, "hideHardwareSpecs": false, "memoryGiB": 192, "name": "ml.g4dn.12xlarge", "vcpuNum": 48 }, { "_defaultOrder": 34, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "hideHardwareSpecs": false, "memoryGiB": 256, "name": "ml.g4dn.16xlarge", "vcpuNum": 64 }, { "_defaultOrder": 35, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "hideHardwareSpecs": false, "memoryGiB": 61, "name": "ml.p3.2xlarge", "vcpuNum": 8 }, { "_defaultOrder": 36, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 4, "hideHardwareSpecs": false, "memoryGiB": 244, "name": "ml.p3.8xlarge", "vcpuNum": 32 }, { "_defaultOrder": 37, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 8, "hideHardwareSpecs": false, "memoryGiB": 488, "name": "ml.p3.16xlarge", "vcpuNum": 64 }, { "_defaultOrder": 38, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 8, "hideHardwareSpecs": false, "memoryGiB": 768, "name": "ml.p3dn.24xlarge", "vcpuNum": 96 }, { "_defaultOrder": 39, "_isFastLaunch": false, "category": "Memory Optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 16, "name": "ml.r5.large", "vcpuNum": 2 }, { "_defaultOrder": 40, "_isFastLaunch": false, "category": "Memory Optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 32, "name": "ml.r5.xlarge", "vcpuNum": 4 }, { "_defaultOrder": 41, "_isFastLaunch": false, "category": "Memory Optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 64, "name": "ml.r5.2xlarge", "vcpuNum": 8 }, { "_defaultOrder": 42, "_isFastLaunch": false, "category": "Memory Optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 128, "name": "ml.r5.4xlarge", "vcpuNum": 16 }, { "_defaultOrder": 43, "_isFastLaunch": false, "category": "Memory Optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 256, "name": "ml.r5.8xlarge", "vcpuNum": 32 }, { "_defaultOrder": 44, "_isFastLaunch": false, "category": "Memory Optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 384, "name": "ml.r5.12xlarge", "vcpuNum": 48 }, { "_defaultOrder": 45, "_isFastLaunch": false, "category": "Memory Optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 512, "name": "ml.r5.16xlarge", "vcpuNum": 64 }, { "_defaultOrder": 46, "_isFastLaunch": false, "category": "Memory Optimized", "gpuNum": 0, "hideHardwareSpecs": false, "memoryGiB": 768, "name": "ml.r5.24xlarge", "vcpuNum": 96 }, { "_defaultOrder": 47, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "hideHardwareSpecs": false, "memoryGiB": 16, "name": "ml.g5.xlarge", "vcpuNum": 4 }, { "_defaultOrder": 48, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "hideHardwareSpecs": false, "memoryGiB": 32, "name": "ml.g5.2xlarge", "vcpuNum": 8 }, { "_defaultOrder": 49, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "hideHardwareSpecs": false, "memoryGiB": 64, "name": "ml.g5.4xlarge", "vcpuNum": 16 }, { "_defaultOrder": 50, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "hideHardwareSpecs": false, "memoryGiB": 128, "name": "ml.g5.8xlarge", "vcpuNum": 32 }, { "_defaultOrder": 51, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "hideHardwareSpecs": false, "memoryGiB": 256, "name": "ml.g5.16xlarge", "vcpuNum": 64 }, { "_defaultOrder": 52, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 4, "hideHardwareSpecs": false, "memoryGiB": 192, "name": "ml.g5.12xlarge", "vcpuNum": 48 }, { "_defaultOrder": 53, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 4, "hideHardwareSpecs": false, "memoryGiB": 384, "name": "ml.g5.24xlarge", "vcpuNum": 96 }, { "_defaultOrder": 54, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 8, "hideHardwareSpecs": false, "memoryGiB": 768, "name": "ml.g5.48xlarge", "vcpuNum": 192 } ], "instance_type": "ml.t3.medium", "kernelspec": { "display_name": "Python 3 (Data Science 3.0)", "language": "python", "name": "python3__SAGEMAKER_INTERNAL__arn:aws:sagemaker:us-east-1:081325390199:image/sagemaker-data-science-310-v1" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.6" } }, "nbformat": 4, "nbformat_minor": 5 }