{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# SageMaker Inference Recommender for a NLP transformer model\n", "\n", "## Contents\n", "[1. Introduction](#1.-Introduction) \n", "[2. Download HuggingFace Pretrained Model](#2.-Download-HuggingFace-Pretrained-Model) \n", "[3. Deploy HuggingFace model](#3.-Deploy-HuggingFace-model) \n", "[4. Register Model Version/Package](#4.-Register-Model-Version/Package) \n", "[5. Create a SageMaker Inference Recommender Default Job](#5:-Create-a-SageMaker-Inference-Recommender-Default-Job) \n", "[6. Instance Recommendation Results](#6.-Instance-Recommendation-Results) \n", "[7. Create a SageMaker Inference Recommender Advanced Job](#7.-Custom-Load-Test) \n", "[8. Describe result of an Advanced Job](#8.-Custom-Load-Test-Results) " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 1. Introduction\n", "\n", "Deploying and scaling NLP models in a production set up can be a hard engineering problem\n", "1. NLP models are very large in size, often contain millions of model parameters\n", "2. Requires accelerated compute infrastructure(GPUs) to speed up huge and complex calculations during inference\n", "3. Scaling requirements to satisfy concurreny,latency and throughput of ML applications\n", "4. Finding best instance type and configurations can be expensive and time consuming\n", "\n", "SageMaker Inference Recommender is a new capability of SageMaker that reduces the time required to get machine learning (ML) models in production by automating performance benchmarking and load testing models across SageMaker ML instances. You can use Inference Recommender to deploy your model to a real-time inference endpoint that delivers the best performance at the lowest cost.Inference Recommender helps you select the best instance type and configuration (such as instance count, container parameters, and model optimizations) for your ML models and workloads.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Installs and Set Up\n", "To begin, let's update the required packages i.e. SageMaker Python SDK, `boto3`, `botocore` and `awscli`" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "/opt/conda/bin/python: No module named pip3\n", "/opt/conda/lib/python3.7/site-packages/secretstorage/dhcrypto.py:16: CryptographyDeprecationWarning: int_from_bytes is deprecated, use int.from_bytes instead\n", " from cryptography.utils import int_from_bytes\n", "/opt/conda/lib/python3.7/site-packages/secretstorage/util.py:25: CryptographyDeprecationWarning: int_from_bytes is deprecated, use int.from_bytes instead\n", " from cryptography.utils import int_from_bytes\n", "\u001b[33mWARNING: Ignoring invalid distribution -wscli (/opt/conda/lib/python3.7/site-packages)\u001b[0m\u001b[33m\n", "\u001b[0m\u001b[33mWARNING: Ignoring invalid distribution -wscli (/opt/conda/lib/python3.7/site-packages)\u001b[0m\u001b[33m\n", "\u001b[0mRequirement already satisfied: sagemaker in /opt/conda/lib/python3.7/site-packages (2.87.0)\n", "Collecting sagemaker\n", " Downloading sagemaker-2.88.0.tar.gz (527 kB)\n", "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m527.7/527.7 KB\u001b[0m \u001b[31m4.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m00:01\u001b[0m\n", "\u001b[?25h Preparing metadata (setup.py) ... \u001b[?25ldone\n", "\u001b[?25hRequirement already satisfied: attrs==20.3.0 in /opt/conda/lib/python3.7/site-packages (from sagemaker) (20.3.0)\n", "Requirement already satisfied: boto3>=1.20.21 in /opt/conda/lib/python3.7/site-packages (from sagemaker) (1.21.46)\n", "Requirement already satisfied: google-pasta in /opt/conda/lib/python3.7/site-packages (from sagemaker) (0.2.0)\n", "Requirement already satisfied: numpy>=1.9.0 in /opt/conda/lib/python3.7/site-packages (from sagemaker) (1.20.3)\n", "Requirement already satisfied: protobuf>=3.1 in /opt/conda/lib/python3.7/site-packages (from sagemaker) (3.19.1)\n", "Requirement already satisfied: protobuf3-to-dict>=0.1.5 in /opt/conda/lib/python3.7/site-packages (from sagemaker) (0.1.5)\n", "Requirement already satisfied: smdebug_rulesconfig==1.0.1 in /opt/conda/lib/python3.7/site-packages (from sagemaker) (1.0.1)\n", "Requirement already satisfied: importlib-metadata>=1.4.0 in /opt/conda/lib/python3.7/site-packages (from sagemaker) (4.11.3)\n", "Requirement already satisfied: packaging>=20.0 in /opt/conda/lib/python3.7/site-packages (from sagemaker) (21.3)\n", "Requirement already satisfied: pandas in /opt/conda/lib/python3.7/site-packages (from sagemaker) (1.0.1)\n", "Requirement already satisfied: pathos in /opt/conda/lib/python3.7/site-packages (from sagemaker) (0.2.8)\n", "Requirement already satisfied: botocore<1.25.0,>=1.24.46 in /opt/conda/lib/python3.7/site-packages (from boto3>=1.20.21->sagemaker) (1.24.46)\n", "Requirement already satisfied: jmespath<2.0.0,>=0.7.1 in /opt/conda/lib/python3.7/site-packages (from boto3>=1.20.21->sagemaker) (0.10.0)\n", "Requirement already satisfied: s3transfer<0.6.0,>=0.5.0 in /opt/conda/lib/python3.7/site-packages (from boto3>=1.20.21->sagemaker) (0.5.0)\n", "Requirement already satisfied: zipp>=0.5 in /opt/conda/lib/python3.7/site-packages (from importlib-metadata>=1.4.0->sagemaker) (2.2.0)\n", "Requirement already satisfied: typing-extensions>=3.6.4 in /opt/conda/lib/python3.7/site-packages (from importlib-metadata>=1.4.0->sagemaker) (4.0.1)\n", "Requirement already satisfied: pyparsing!=3.0.5,>=2.0.2 in /opt/conda/lib/python3.7/site-packages (from packaging>=20.0->sagemaker) (2.4.6)\n", "Requirement already satisfied: six in /opt/conda/lib/python3.7/site-packages (from protobuf3-to-dict>=0.1.5->sagemaker) (1.14.0)\n", "Requirement already satisfied: pytz>=2017.2 in /opt/conda/lib/python3.7/site-packages (from pandas->sagemaker) (2019.3)\n", "Requirement already satisfied: python-dateutil>=2.6.1 in /opt/conda/lib/python3.7/site-packages (from pandas->sagemaker) (2.8.1)\n", "Requirement already satisfied: pox>=0.3.0 in /opt/conda/lib/python3.7/site-packages (from pathos->sagemaker) (0.3.0)\n", "Requirement already satisfied: ppft>=1.6.6.4 in /opt/conda/lib/python3.7/site-packages (from pathos->sagemaker) (1.6.6.4)\n", "Requirement already satisfied: multiprocess>=0.70.12 in /opt/conda/lib/python3.7/site-packages (from pathos->sagemaker) (0.70.12.2)\n", "Requirement already satisfied: dill>=0.3.4 in /opt/conda/lib/python3.7/site-packages (from pathos->sagemaker) (0.3.4)\n", "Requirement already satisfied: urllib3<1.27,>=1.25.4 in /opt/conda/lib/python3.7/site-packages (from botocore<1.25.0,>=1.24.46->boto3>=1.20.21->sagemaker) (1.26.7)\n", "Building wheels for collected packages: sagemaker\n", " Building wheel for sagemaker (setup.py) ... \u001b[?25ldone\n", "\u001b[?25h Created wheel for sagemaker: filename=sagemaker-2.88.0-py2.py3-none-any.whl size=728465 sha256=7c77ec4d7cdb8129513f1667c0a85777df9e37204ea689dabc9b0366536b25a1\n", " Stored in directory: /root/.cache/pip/wheels/e8/55/f3/cd171fc1fe2c8a6a0d0969ee3d88c1bc68bdff86cc31154722\n", "Successfully built sagemaker\n", "\u001b[33mWARNING: Ignoring invalid distribution -wscli (/opt/conda/lib/python3.7/site-packages)\u001b[0m\u001b[33m\n", "\u001b[0mInstalling collected packages: sagemaker\n", " Attempting uninstall: sagemaker\n", "\u001b[33m WARNING: Ignoring invalid distribution -wscli (/opt/conda/lib/python3.7/site-packages)\u001b[0m\u001b[33m\n", "\u001b[0m Found existing installation: sagemaker 2.87.0\n", " Uninstalling sagemaker-2.87.0:\n", " Successfully uninstalled sagemaker-2.87.0\n", "\u001b[33mWARNING: Ignoring invalid distribution -wscli (/opt/conda/lib/python3.7/site-packages)\u001b[0m\u001b[33m\n", "\u001b[0mSuccessfully installed sagemaker-2.88.0\n", "\u001b[33mWARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv\u001b[0m\u001b[33m\n", "\u001b[0m\u001b[33mWARNING: Ignoring invalid distribution -wscli (/opt/conda/lib/python3.7/site-packages)\u001b[0m\u001b[33m\n", "\u001b[0m\u001b[33mWARNING: Ignoring invalid distribution -wscli (/opt/conda/lib/python3.7/site-packages)\u001b[0m\u001b[33m\n", "\u001b[0m/opt/conda/lib/python3.7/site-packages/secretstorage/dhcrypto.py:16: CryptographyDeprecationWarning: int_from_bytes is deprecated, use int.from_bytes instead\n", " from cryptography.utils import int_from_bytes\n", "/opt/conda/lib/python3.7/site-packages/secretstorage/util.py:25: CryptographyDeprecationWarning: int_from_bytes is deprecated, use int.from_bytes instead\n", " from cryptography.utils import int_from_bytes\n", "\u001b[33mWARNING: Ignoring invalid distribution -wscli (/opt/conda/lib/python3.7/site-packages)\u001b[0m\u001b[33m\n", "\u001b[0m\u001b[33mWARNING: Ignoring invalid distribution -wscli (/opt/conda/lib/python3.7/site-packages)\u001b[0m\u001b[33m\n", "\u001b[0mKilled\n", "/opt/conda/lib/python3.7/site-packages/secretstorage/dhcrypto.py:16: CryptographyDeprecationWarning: int_from_bytes is deprecated, use int.from_bytes instead\n", " from cryptography.utils import int_from_bytes\n", "/opt/conda/lib/python3.7/site-packages/secretstorage/util.py:25: CryptographyDeprecationWarning: int_from_bytes is deprecated, use int.from_bytes instead\n", " from cryptography.utils import int_from_bytes\n", "\u001b[33mWARNING: Ignoring invalid distribution -wscli (/opt/conda/lib/python3.7/site-packages)\u001b[0m\u001b[33m\n", "\u001b[0m\u001b[33mWARNING: Ignoring invalid distribution -wscli (/opt/conda/lib/python3.7/site-packages)\u001b[0m\u001b[33m\n", "\u001b[0mRequirement already satisfied: transformers in /opt/conda/lib/python3.7/site-packages (4.18.0)\n", "Requirement already satisfied: tqdm>=4.27 in /opt/conda/lib/python3.7/site-packages (from transformers) (4.42.1)\n", "Requirement already satisfied: huggingface-hub<1.0,>=0.1.0 in /opt/conda/lib/python3.7/site-packages (from transformers) (0.5.1)\n", "Requirement already satisfied: requests in /opt/conda/lib/python3.7/site-packages (from transformers) (2.26.0)\n", "Requirement already satisfied: pyyaml>=5.1 in /opt/conda/lib/python3.7/site-packages (from transformers) (5.4.1)\n", "Requirement already satisfied: sacremoses in /opt/conda/lib/python3.7/site-packages (from transformers) (0.0.49)\n", "Requirement already satisfied: packaging>=20.0 in /opt/conda/lib/python3.7/site-packages (from transformers) (21.3)\n", "Requirement already satisfied: filelock in /opt/conda/lib/python3.7/site-packages (from transformers) (3.0.12)\n", "Requirement already satisfied: numpy>=1.17 in /opt/conda/lib/python3.7/site-packages (from transformers) (1.20.3)\n", "Requirement already satisfied: regex!=2019.12.17 in /opt/conda/lib/python3.7/site-packages (from transformers) (2022.3.15)\n", "Requirement already satisfied: importlib-metadata in /opt/conda/lib/python3.7/site-packages (from transformers) (4.11.3)\n", "Requirement already satisfied: tokenizers!=0.11.3,<0.13,>=0.11.1 in /opt/conda/lib/python3.7/site-packages (from transformers) (0.12.1)\n", "Requirement already satisfied: typing-extensions>=3.7.4.3 in /opt/conda/lib/python3.7/site-packages (from huggingface-hub<1.0,>=0.1.0->transformers) (4.0.1)\n", "Requirement already satisfied: pyparsing!=3.0.5,>=2.0.2 in /opt/conda/lib/python3.7/site-packages (from packaging>=20.0->transformers) (2.4.6)\n", "Requirement already satisfied: zipp>=0.5 in /opt/conda/lib/python3.7/site-packages (from importlib-metadata->transformers) (2.2.0)\n", "Requirement already satisfied: idna<4,>=2.5 in /opt/conda/lib/python3.7/site-packages (from requests->transformers) (2.8)\n", "Requirement already satisfied: certifi>=2017.4.17 in /opt/conda/lib/python3.7/site-packages (from requests->transformers) (2021.10.8)\n", "Requirement already satisfied: urllib3<1.27,>=1.21.1 in /opt/conda/lib/python3.7/site-packages (from requests->transformers) (1.26.7)\n", "Requirement already satisfied: charset-normalizer~=2.0.0 in /opt/conda/lib/python3.7/site-packages (from requests->transformers) (2.0.4)\n", "Requirement already satisfied: six in /opt/conda/lib/python3.7/site-packages (from sacremoses->transformers) (1.14.0)\n", "Requirement already satisfied: joblib in /opt/conda/lib/python3.7/site-packages (from sacremoses->transformers) (0.14.1)\n", "Requirement already satisfied: click in /opt/conda/lib/python3.7/site-packages (from sacremoses->transformers) (7.0)\n", "\u001b[33mWARNING: Ignoring invalid distribution -wscli (/opt/conda/lib/python3.7/site-packages)\u001b[0m\u001b[33m\n", "\u001b[0m\u001b[33mWARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv\u001b[0m\u001b[33m\n", "\u001b[0m\u001b[33mWARNING: Ignoring invalid distribution -wscli (/opt/conda/lib/python3.7/site-packages)\u001b[0m\u001b[33m\n", "\u001b[0m\u001b[33mWARNING: Ignoring invalid distribution -wscli (/opt/conda/lib/python3.7/site-packages)\u001b[0m\u001b[33m\n", "\u001b[0m" ] } ], "source": [ "import sys\n", "\n", "!{sys.executable} -m pip3 install botocore boto3 awscli ipywidgets seaborn --upgrade -q\n", "!pip3 install sagemaker --upgrade\n", "!pip3 install torch -q\n", "!pip3 install transformers" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### **Note: Restart the notebook after installing the above packages.**" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "from IPython.display import display_html\n", "def restartkernel() :\n", " display_html(\"\",raw=True)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "restartkernel()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Imports" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "/opt/conda/lib/python3.7/site-packages/secretstorage/dhcrypto.py:16: CryptographyDeprecationWarning: int_from_bytes is deprecated, use int.from_bytes instead\n", " from cryptography.utils import int_from_bytes\n", "/opt/conda/lib/python3.7/site-packages/secretstorage/util.py:25: CryptographyDeprecationWarning: int_from_bytes is deprecated, use int.from_bytes instead\n", " from cryptography.utils import int_from_bytes\n", "\u001b[33mWARNING: Ignoring invalid distribution -wscli (/opt/conda/lib/python3.7/site-packages)\u001b[0m\u001b[33m\n", "\u001b[0m\u001b[33mWARNING: Ignoring invalid distribution -wscli (/opt/conda/lib/python3.7/site-packages)\u001b[0m\u001b[33m\n", "\u001b[0m \u001b[1;31merror\u001b[0m: \u001b[1msubprocess-exited-with-error\u001b[0m\n", " \n", " \u001b[31m×\u001b[0m \u001b[32mpython setup.py bdist_wheel\u001b[0m did not run successfully.\n", " \u001b[31m│\u001b[0m exit code: \u001b[1;36m1\u001b[0m\n", " \u001b[31m╰─>\u001b[0m \u001b[31m[6 lines of output]\u001b[0m\n", " \u001b[31m \u001b[0m Traceback (most recent call last):\n", " \u001b[31m \u001b[0m File \"\", line 36, in \n", " \u001b[31m \u001b[0m File \"\", line 34, in \n", " \u001b[31m \u001b[0m File \"/tmp/pip-install-ytt7myck/pytorch_b94c4d8025ee40a6afc9ca4b1872a361/setup.py\", line 15, in \n", " \u001b[31m \u001b[0m raise Exception(message)\n", " \u001b[31m \u001b[0m Exception: You tried to install \"pytorch\". The package named for PyTorch is \"torch\"\n", " \u001b[31m \u001b[0m \u001b[31m[end of output]\u001b[0m\n", " \n", " \u001b[1;35mnote\u001b[0m: This error originates from a subprocess, and is likely not a problem with pip.\n", "\u001b[31m ERROR: Failed building wheel for pytorch\u001b[0m\u001b[31m\n", "\u001b[0m\u001b[33mWARNING: Ignoring invalid distribution -wscli (/opt/conda/lib/python3.7/site-packages)\u001b[0m\u001b[33m\n", "\u001b[0m \u001b[1;31merror\u001b[0m: \u001b[1msubprocess-exited-with-error\u001b[0m\n", " \n", " \u001b[31m×\u001b[0m \u001b[32mRunning setup.py install for pytorch\u001b[0m did not run successfully.\n", " \u001b[31m│\u001b[0m exit code: \u001b[1;36m1\u001b[0m\n", " \u001b[31m╰─>\u001b[0m \u001b[31m[6 lines of output]\u001b[0m\n", " \u001b[31m \u001b[0m Traceback (most recent call last):\n", " \u001b[31m \u001b[0m File \"\", line 36, in \n", " \u001b[31m \u001b[0m File \"\", line 34, in \n", " \u001b[31m \u001b[0m File \"/tmp/pip-install-ytt7myck/pytorch_b94c4d8025ee40a6afc9ca4b1872a361/setup.py\", line 11, in \n", " \u001b[31m \u001b[0m raise Exception(message)\n", " \u001b[31m \u001b[0m Exception: You tried to install \"pytorch\". The package named for PyTorch is \"torch\"\n", " \u001b[31m \u001b[0m \u001b[31m[end of output]\u001b[0m\n", " \n", " \u001b[1;35mnote\u001b[0m: This error originates from a subprocess, and is likely not a problem with pip.\n", "\u001b[1;31merror\u001b[0m: \u001b[1mlegacy-install-failure\u001b[0m\n", "\n", "\u001b[31m×\u001b[0m Encountered error while trying to install package.\n", "\u001b[31m╰─>\u001b[0m pytorch\n", "\n", "\u001b[1;35mnote\u001b[0m: This is an issue with the package mentioned above, not pip.\n", "\u001b[1;36mhint\u001b[0m: See above for output from the failure.\n", "\u001b[33mWARNING: Ignoring invalid distribution -wscli (/opt/conda/lib/python3.7/site-packages)\u001b[0m\u001b[33m\n", "\u001b[0m\u001b[33mWARNING: Ignoring invalid distribution -wscli (/opt/conda/lib/python3.7/site-packages)\u001b[0m\u001b[33m\n", "\u001b[0m" ] } ], "source": [ "#generic packages\n", "import sys\n", "from time import gmtime, strftime\n", "import datetime\n", "import boto3\n", "import pprint\n", "import pandas as pd\n", "import time\n", "\n", "#sagemaker\n", "import sagemaker\n", "from sagemaker.s3 import S3Uploader,s3_path_join\n", "from sagemaker.huggingface import HuggingFaceModel\n", "from sagemaker import get_execution_role\n", "import sagemaker\n", "from sagemaker.s3 import S3Uploader,s3_path_join\n", "\n", "#visualization\n", "import matplotlib\n", "import matplotlib.pyplot as plt\n", "import seaborn as sns\n", "\n", "#hugging face transformers\n", "from transformers import AutoModelForSequenceClassification, AutoTokenizer\n", "\n", "!pip install pytorch --quiet" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Variables" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "#sagemaker\n", "sess = sagemaker.Session()\n", "role = 'arn:aws:iam::156991241640:role/service-role/AmazonSageMaker-ExecutionRole-20210302T095973' #sagemaker.get_execution_role()\n", "sagemaker_session_bucket = sess.default_bucket()\n", "prefix = \"inference-receommender\"\n", "client = boto3.client(\"sagemaker\")\n", "\n", "current_timestamp = strftime('%m-%d-%H-%M', gmtime())\n", "endpoint_name=f\"nlp-benchmark-bert-base-uncased-{current_timestamp}\"\n", "MODEL = \"bert-base-uncased\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2. Download HuggingFace Pretrained Model\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In this notebook, we will download pre-trained `bert-base-uncased` model from HuggingFace package and use it for Sequence classification task. We will use `AutoModelForSequenceClassification`, a generic sequence classification model class to load pre-trained model weights and `AutoTokenizer`, a generic tokenizer classes to instantiate a tokenizer from a pre-trained model vocabulary. Once you instantiate model and tokenizer, we will save them to `model_artifacts` directory locally." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "!mkdir model_artifacts" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "ename": "ImportError", "evalue": "\nAutoModelForSequenceClassification requires the PyTorch library but it was not found in your environment. Checkout the instructions on the\ninstallation page: https://pytorch.org/get-started/locally/ and follow the ones that match your environment.\n", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mImportError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mmodel\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mAutoModelForSequenceClassification\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfrom_pretrained\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mMODEL\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0mtokenizer\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mAutoTokenizer\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfrom_pretrained\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mMODEL\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0mmodel\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msave_pretrained\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'model_artifacts'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0mtokenizer\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msave_pretrained\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'model_artifacts'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m/opt/conda/lib/python3.7/site-packages/transformers/utils/import_utils.py\u001b[0m in \u001b[0;36m__getattr__\u001b[0;34m(cls, key)\u001b[0m\n\u001b[1;32m 771\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mkey\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mstartswith\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"_\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 772\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0msuper\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__getattr__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcls\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 773\u001b[0;31m \u001b[0mrequires_backends\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcls\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcls\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_backends\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 774\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 775\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m/opt/conda/lib/python3.7/site-packages/transformers/utils/import_utils.py\u001b[0m in \u001b[0;36mrequires_backends\u001b[0;34m(obj, backends)\u001b[0m\n\u001b[1;32m 759\u001b[0m \u001b[0mfailed\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mmsg\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mname\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mavailable\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmsg\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mchecks\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mavailable\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 760\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mfailed\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 761\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mImportError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"\"\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mjoin\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfailed\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 762\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 763\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mImportError\u001b[0m: \nAutoModelForSequenceClassification requires the PyTorch library but it was not found in your environment. Checkout the instructions on the\ninstallation page: https://pytorch.org/get-started/locally/ and follow the ones that match your environment.\n" ] } ], "source": [ "model = AutoModelForSequenceClassification.from_pretrained(MODEL)\n", "tokenizer = AutoTokenizer.from_pretrained(MODEL)\n", "model.save_pretrained('model_artifacts')\n", "tokenizer.save_pretrained('model_artifacts')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Package the saved model to tar.gz format\n", "\n", "Once the model is downloaded, we need to package (tokenizer and model weights) it to `.tar.gz` format as expected by Amazon SageMaker. " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "!cd model_artifacts && tar zcvf bert_model.tar.gz * \n", "!mv model_artifacts/bert_model.tar.gz ./bert_model.tar.gz" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Upload Pre-trained Model to S3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We are going to use the `sagemaker.s3.S3Uploader` api to upload our model to an S3 location. We will provide this s3 path to the `HuggingFaceModel` class during deployment." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# uploads a given file to S3.\n", "upload_path = s3_path_join(\"s3://\",sagemaker_session_bucket,prefix)\n", "print(f\"Uploading Model to {upload_path}\")\n", "model_uri = S3Uploader.upload('bert_model.tar.gz',upload_path)\n", "print(f\"Uploaded model to {model_uri}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 3. Deploy HuggingFace model\n", "\n", "We will deploy our pre-trained model which we packaged and uploaded to s3 in the previous steps, using the model_data argument to specify the s3 location of your tokenizer and model weights.\n", "\n", "#### Parameters for `HuggingFaceModel` class\n", "We will use following parameters in this lab for deploying the model. \n", "* `model_data (str)` – The Amazon S3 location of a SageMaker model data .tar.gz file.\n", "\n", "* `role (str)` – An AWS IAM role specified with either the name or full ARN. The Amazon SageMaker training jobs and APIs that create Amazon SageMaker endpoints use this role to access training data and model artifacts. After the endpoint is created, the inference code might use the IAM role, if it needs to access an AWS resource.\n", "\n", "* `transformers_version (str)` – Transformers version you want to use for executing your model training code. Defaults to None. Required unless image_uri is provided.\n", "\n", "* `pytorch_version (str)` – PyTorch version you want to use for executing your inference code. Defaults to None. Required unless tensorflow_version is provided. List of supported versions: https://github.com/aws/sagemaker-python-sdk#huggingface-sagemaker-estimators.\n", "\n", "* `py_version (str)` – Python version you want to use for executing your model training code. Defaults to None. Required unless image_uri is provided.\n", "\n", "For details about other paramets, please click [here](#https://sagemaker.readthedocs.io/en/stable/frameworks/huggingface/sagemaker.huggingface.html?highlight=huggingfacemodel#sagemaker.huggingface.model.HuggingFaceModel)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# create Hugging Face Model Class\n", "huggingface_model = HuggingFaceModel(\n", " model_data=model_uri, # path to your trained sagemaker model\n", " role=role, # iam role with permissions to create an Endpoint\n", " transformers_version=\"4.6\", # transformers version used\n", " pytorch_version=\"1.7\", # pytorch version used\n", " py_version=\"py36\", # python version of the DLC\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We created a HuggingFace model class in the above step. Now, we will deploy the model to a SageMaker real time endpoint. We are deploying the model to a GPU accelerated instance type. \n", "Note: For the inference recommender we will retrieve the image_uri based on this endpoint, if you wish to run inference recommender on CPU based instance, change deploy step with CPU based instance type and run inference recommender. " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# deploy model to SageMaker Inference\n", "predictor = huggingface_model.deploy(\n", " initial_instance_count=1,\n", " instance_type=\"ml.g4dn.xlarge\",\n", " endpoint_name=endpoint_name\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Sample Inference\n", "\n", "We use below sample inference payload, pass it to the predictor to get inference results. " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "data = {\n", " \"inputs\": \"This is really exciting! The new Hugging Face SageMaker DLC makes it super easy to deploy large NLP models in production.\"\n", "}\n", "\n", "# request\n", "predictor.predict(data)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Tar the payload and upload to S3\n", "We need to create an archive that contains individual files that Inference Recommender can send to your SageMaker Endpoints. Inference Recommender will randomly sample files from this archive so make sure it contains a similar distribution of payloads you'd expect in production. Note that your inference code must be able to read in the file formats from the sample payload.\n", "\n", "We now have a model archive ready. We need to upload it to S3 before we can use it with Inference Recommender, so we will use the SageMaker Python SDK to handle the upload." ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "ename": "NameError", "evalue": "name 'data' is not defined", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mjson\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;32mwith\u001b[0m \u001b[0mopen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'payload.json'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'w'\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mfp\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mjson\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdump\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfp\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mNameError\u001b[0m: name 'data' is not defined" ] } ], "source": [ "import json\n", "with open('payload.json', 'w') as fp:\n", " json.dump(data, fp)" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a payload.json\n", "upload: ./payload.tar.gz to s3://sagemaker-us-east-2-156991241640/inference-receommender/payload.tar.gz\n" ] }, { "data": { "text/plain": [ "'s3://sagemaker-us-east-2-156991241640/inference-receommender/payload.tar.gz'" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "!tar -cvzf payload.tar.gz payload.json\n", "!aws s3 cp payload.tar.gz s3://{sagemaker_session_bucket}/{prefix}/\n", " \n", "sample_payload_url= f\"s3://{sagemaker_session_bucket}/{prefix}/payload.tar.gz\"\n", "sample_payload_url" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Container Images and Model URL\n", "\n", "Now that we deployed the model, we will retrieve model artifacts and Inference container image and use it in SageMaker inference recommender." ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "763104351884.dkr.ecr.us-east-2.amazonaws.com/huggingface-pytorch-inference:1.7-transformers4.6-gpu-py36-cu110-ubuntu18.04\n", "s3://sagemaker-us-east-2-156991241640/inference-receommender/bert_model.tar.gz\n", "Endpoint creation completed\n", "CPU times: user 31.7 ms, sys: 10.3 ms, total: 42 ms\n", "Wall time: 587 ms\n" ] } ], "source": [ "%%time\n", "\n", "ended = False\n", "while not ended:\n", " endpoint_response = client.describe_endpoint(EndpointName=endpoint_name)\n", " if endpoint_response[\"EndpointStatus\"] in [\"InService\", \"Failed\"]:\n", " ended = True\n", " else:\n", " print(\"Endpoint Creation in progress\")\n", " time.sleep(300)\n", "\n", "if endpoint_response[\"EndpointStatus\"] == \"Failed\":\n", " print(\"Endpoint creation failed \")\n", " print(\"Failed Reason: {}\".endpoint_response[\"FailureReason\"])\n", "else:\n", " endpoint_config_name = endpoint_response[\"EndpointConfigName\"]\n", " image_uri = endpoint_response[\"ProductionVariants\"][0][\"DeployedImages\"][0][\"SpecifiedImage\"]\n", " endpoint_config_response = client.describe_endpoint_config(EndpointConfigName=endpoint_config_name)\n", " model_name = endpoint_config_response[\"ProductionVariants\"][0][\"ModelName\"]\n", " endpoint_model_response = client.describe_model(ModelName=model_name)\n", " model_url = endpoint_model_response[\"PrimaryContainer\"][\"ModelDataUrl\"]\n", " print(image_uri)\n", " print(model_url)\n", " print(\"Endpoint creation completed\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 4. Register Model Version/Package\n", "\n", "Inference Recommender expects the model to be packaged in the model registry. Here, we are creating a model package group and a model package version. The model package version which takes container, model `URL` etc. will now allow you to pass additional information about the model like `Domain`, `Task`, `Framework`, `FrameworkVersion`, `NearestModelName`, `SamplePayloadUrl`\n", "You specify a list of the instance types that are used to generate inferences in real-time in`SupportedRealtimeInferenceInstanceTypes` parameter.\n", "\n", "For Inference on NLP data, e.g. HuggingFace Models you want to use accelerated GPU based computing instances. Here, we have used ml.p2, ml.p3, ml.g4dn type instances in `SupportedRealtimeInferenceInstanceTypes` parameter\n", "\n", "\n", "\n", "As `SamplePayloadUrl` and `SupportedContentTypes` parameters are essential for benchmarking the endpoint, we also highly recommend that you specify `Domain`, `Task`, `Framework`, `FrameworkVersion`, `NearestModelName` for better inference recommendation.\n" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [], "source": [ "ml_domain = \"NATURAL_LANGUAGE_PROCESSING\" \n", "ml_task = \"FILL_MASK\"\n", "framework = \"PYTORCH\"\n", "framework_version = \"1.7\"\n", "\n", "#sagemaker model registry\n", "model_package_group_name = f\"nlp-bert-mg-{current_timestamp}\"\n", "model_package_group_description = \"model benchmark use case\"\n", "nearest_model_name = \"bert-base-uncased\" #The name of the ML model as standardized by common model zoos\n", "input_content_type=\"application/json\" #MIME types for input\n", "response_content_type=\"application/json\" #MIME types for input\n", "model_package_description = \"model bert-base-uncased benchmark\"\n", "default_job = f\"nlp-basic-inference-recommender-job-{current_timestamp}\"\n", "advanced_job = f\"nlp-advanced-inference-recommender-job-{current_timestamp}\"" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [], "source": [ "model_package_group_input_dict = {\n", " \"ModelPackageGroupName\" : model_package_group_name,\n", " \"ModelPackageGroupDescription\" : model_package_group_description,\n", "}\n", "\n", "model_package_group_response = client.create_model_package_group(**model_package_group_input_dict)" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "ModelPackage Version ARN : arn:aws:sagemaker:us-east-2:156991241640:model-package/nlp-bert-mg-01-04-16-33/1\n" ] } ], "source": [ "model_package_input_dict = {\n", " \"ModelPackageGroupName\" :model_package_group_name,\n", " \"Domain\": ml_domain,\n", " \"Task\": ml_task,\n", " \"SamplePayloadUrl\": sample_payload_url,\n", " \"ModelPackageDescription\" : model_package_group_description,\n", " \"InferenceSpecification\": {\n", " \"Containers\": [\n", " {\n", " \"Image\": image_uri,\n", " \"ModelDataUrl\": model_url,\n", " \"Framework\": framework.upper(), \n", " \"FrameworkVersion\": framework_version,\n", " \"NearestModelName\": nearest_model_name\n", " }\n", " ],\n", " \"SupportedContentTypes\": [input_content_type],\n", " \"SupportedResponseMIMETypes\": [response_content_type],\n", " \"SupportedRealtimeInferenceInstanceTypes\": ['ml.p3.8xlarge','ml.p3.2xlarge','ml.p3.16xlarge','ml.p2.16xlarge',\n", " 'ml.g4dn.xlarge','ml.g4dn.8xlarge','ml.g4dn.4xlarge','ml.g4dn.2xlarge',\n", " 'ml.g4dn.16xlarge','ml.g4dn.12xlarge']\n", " }\n", " }\n", "\n", "model_package_response = client.create_model_package(**model_package_input_dict)\n", "model_package_arn = model_package_response[\"ModelPackageArn\"]\n", "print('ModelPackage Version ARN : {}'.format(model_package_arn))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 5: Create a SageMaker Inference Recommender Default Job\n", "\n", "Now with your model in Model Registry, you can kick off a 'Default' job to get instance recommendations. This only requires your `ModelPackageVersionArn` and comes back with recommendations within an hour. \n", "\n", "The output is a list of instance type recommendations with associated environment variables, cost, throughput and latency metrics." ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'JobArn': 'arn:aws:sagemaker:us-east-2:156991241640:inference-recommendations-job/nlp-basic-inference-recommender-job-01-04-16-33', 'ResponseMetadata': {'RequestId': '07f4fd6d-4a69-4035-93d8-0ac5fcde675c', 'HTTPStatusCode': 200, 'HTTPHeaders': {'x-amzn-requestid': '07f4fd6d-4a69-4035-93d8-0ac5fcde675c', 'content-type': 'application/x-amz-json-1.1', 'content-length': '131', 'date': 'Tue, 04 Jan 2022 17:11:30 GMT'}, 'RetryAttempts': 0}}\n" ] } ], "source": [ "default_response = client.create_inference_recommendations_job(\n", " JobName=str(default_job),\n", " JobDescription=\"NLP Inference Basic Recommender Job\",\n", " JobType=\"Default\",\n", " RoleArn=role,\n", " InputConfig={\"ModelPackageVersionArn\": model_package_response[\"ModelPackageArn\"]},\n", ")\n", "\n", "print(default_response)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 6. Instance Recommendation Results\n", "\n", "The inference recommender job provides multiple endpoint recommendations in its result. The recommendation includes `InstanceType`, `InitialInstanceCount`, `EnvironmentParameters` which includes tuned parameters for better performance. We also include the benchmarking results like `MaxInvocations`, `ModelLatency`, `CostPerHour` and `CostPerInference` for deeper analysis. The information provided will help you narrow down to a specific endpoint configuration that suits your use case.\n", "\n", "Example: \n", "\n", "If your motivation is overall price-performance, then you should focus on `CostPerInference` metrics \n", "If your motivation is latency/throughput, then you should focus on `ModelLatency` / `MaxInvocations` metrics" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Running the Inference recommender job will take ~35 minutes." ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Inference recommender job in progress\n", "Inference recommender job in progress\n", "Inference recommender job in progress\n", "Inference recommender job in progress\n", "Inference recommender job in progress\n", "Inference recommender job in progress\n", "Inference recommender job completed\n", "CPU times: user 298 ms, sys: 60.6 ms, total: 358 ms\n", "Wall time: 30min 5s\n" ] } ], "source": [ "%%time\n", "\n", "ended = False\n", "while not ended:\n", " inference_recommender_job = client.describe_inference_recommendations_job(\n", " JobName=str(default_job)\n", " )\n", " if inference_recommender_job[\"Status\"] in [\"COMPLETED\", \"STOPPED\", \"FAILED\"]:\n", " ended = True\n", " else:\n", " print(\"Inference recommender job in progress\")\n", " time.sleep(300)\n", "\n", "if inference_recommender_job[\"Status\"] == \"FAILED\":\n", " print(\"Inference recommender job failed \")\n", " print(\"Failed Reason: {}\".format(inference_recommender_job[\"FailedReason\"]))\n", "else:\n", " print(\"Inference recommender job completed\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Detailing out the result" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [], "source": [ "data = [\n", " {**x[\"EndpointConfiguration\"], **x[\"ModelConfiguration\"], **x[\"Metrics\"]}\n", " for x in inference_recommender_job[\"InferenceRecommendations\"]\n", "]\n", "df = pd.DataFrame(data)\n", "df.drop(\"VariantName\", inplace=True, axis=1)\n", "pd.set_option(\"max_colwidth\", 400)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "By `MaxInvocations` - The maximum number of requests per minute expected for the endpoint." ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
EndpointNameInstanceTypeInitialInstanceCountEnvironmentParametersCostPerHourCostPerInferenceMaxInvocationsModelLatency
2sm-epc-d95508cc-794c-482c-bc1a-03078559c8b3ml.p2.16xlarge1[]16.5599990.0000083340325
0sm-epc-9c4282ab-8928-4740-94e1-dff3c32ea1ceml.g4dn.xlarge1[]0.7360000.000003482275
1sm-epc-6a316092-2388-474c-9f73-d20efa2c659cml.p3.2xlarge1[]3.8250000.0000213026129
\n", "
" ], "text/plain": [ " EndpointName InstanceType \\\n", "2 sm-epc-d95508cc-794c-482c-bc1a-03078559c8b3 ml.p2.16xlarge \n", "0 sm-epc-9c4282ab-8928-4740-94e1-dff3c32ea1ce ml.g4dn.xlarge \n", "1 sm-epc-6a316092-2388-474c-9f73-d20efa2c659c ml.p3.2xlarge \n", "\n", " InitialInstanceCount EnvironmentParameters CostPerHour CostPerInference \\\n", "2 1 [] 16.559999 0.000008 \n", "0 1 [] 0.736000 0.000003 \n", "1 1 [] 3.825000 0.000021 \n", "\n", " MaxInvocations ModelLatency \n", "2 33403 25 \n", "0 4822 75 \n", "1 3026 129 " ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.sort_values(by=[\"MaxInvocations\"], ascending=False)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "By `ModelLatencyThresholds` - The interval of time taken by a model to respond as viewed from SageMaker. The interval includes the local communication time taken to send the request and to fetch the response from the container of a model and the time taken to complete the inference in the container." ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
EndpointNameInstanceTypeInitialInstanceCountEnvironmentParametersCostPerHourCostPerInferenceMaxInvocationsModelLatency
2sm-epc-d95508cc-794c-482c-bc1a-03078559c8b3ml.p2.16xlarge1[]16.5599990.0000083340325
0sm-epc-9c4282ab-8928-4740-94e1-dff3c32ea1ceml.g4dn.xlarge1[]0.7360000.000003482275
1sm-epc-6a316092-2388-474c-9f73-d20efa2c659cml.p3.2xlarge1[]3.8250000.0000213026129
\n", "
" ], "text/plain": [ " EndpointName InstanceType \\\n", "2 sm-epc-d95508cc-794c-482c-bc1a-03078559c8b3 ml.p2.16xlarge \n", "0 sm-epc-9c4282ab-8928-4740-94e1-dff3c32ea1ce ml.g4dn.xlarge \n", "1 sm-epc-6a316092-2388-474c-9f73-d20efa2c659c ml.p3.2xlarge \n", "\n", " InitialInstanceCount EnvironmentParameters CostPerHour CostPerInference \\\n", "2 1 [] 16.559999 0.000008 \n", "0 1 [] 0.736000 0.000003 \n", "1 1 [] 3.825000 0.000021 \n", "\n", " MaxInvocations ModelLatency \n", "2 33403 25 \n", "0 4822 75 \n", "1 3026 129 " ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.sort_values(by=[\"ModelLatency\"])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Visualization\n", "\n", "Let's plot the results to visualize the trade-off in terms cost of inference and maximum invocations for different GPU based instance types" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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HcflbrPonSGd1Co8wOxYAABRXAAAAAB6Z+0hxX3/syTptT+117VNQ80NBABworgAAABAjbZ421FN+2qPJOnJ/i11e7twkxMBAH6P4gIAAAA11rr9KZr0yXZJ0sgekfrzdVeZnAgA8EcUFwAAAKiRdv6aqVH/3qJih6Hb2oXriVtamh0JAHAeFBcAAACocY6k52nY+5uUW2hX9FUhevWetrJaLWbHAgCch0vFxdatW7Vjxw7n888//1wDBgzQ448/rsLCwnILBwAAAJS39NxCxc5NUGpOgVqE+emfQzvJ081mdiwAwAW4VFz85S9/0b59+yRJhw4d0uDBg+Xj46NPPvlEkydPLteAAAAAQHk5XWjXyHmbdCg1V/UDvTVvRFf5e7mbHQsAcBEuFRf79u1T+/btJUmffPKJevbsqfnz5ysuLk6fffZZeeYDAAAAykWx3aGx87dqW1KGArzdNW9EF9X19zI7FgDgElwqLgzDkMPhkCR98803uuWWWyRJERERSk1NLb90AAAAQDkwDENPfb5Tq/aclKebVf+K7aymdfzMjgUAuAwuFRedO3fWCy+8oH//+99as2aN+vfvL0k6fPiw6tatW64BAQAAgLKauWq/Pko4IqtFeuPeDurcONjsSACAy+RScTFjxgxt3bpVY8eO1RNPPKGmTZtKkj799FNde+215RoQAAAAKIuPEpI045v9kqTn72itmFZhJicCAJSGmysvatu2bYm7ipz1yiuvyGZjR2YAAABUDqt+OqEnFp/5vXVs76Z64JpGJicCAJSWS8XFWYWFhTp58qRzv4uzGjZsWKZQAAAAQFltTTqlMfO3ymFI93RqoL/2vdrsSAAAF7hUXOzbt08jR47U999/X+K4YRiyWCyy2+3lEg4AAABwxcGUHI2M26T8Iod6Na+tv9/VRhaLxexYAAAXuFRcDB8+XG5ublq6dKnq1avHDwEAAABUGiez8hU7N0Gn8orUtkGAZt/XUe42l7Z2AwCUQnFxsebPn6+YmJhyvXGHS9/BExMT9c9//lP9+vVT+/bt1a5duxIPAAAAwAzZ+UUa9v4mHT11Wo1DfDR3WBf5epZpdTQAVBtr167VbbfdpvDwcFksFi1ZsqTEecMw9PTTT6tevXry9vZWnz59tH///sue383NTaNGjVJ+fn655napuIiKilJqamq5BgEAAADKorDYodH/2ardx7MUWstD80Z0VWgtT7NjAUClkZubq3bt2mn27NnnPT99+nS98cYbmjNnjjZu3ChfX1/FxMSUqojo2rWrEhMTyynxGS7Vzy+//LImT56sv//972rTpo3c3d1LnPf39y+XcAAAAMDlcDgMTf70R60/kCofD5vmDuuiRiG+ZscCgEqlX79+6tev33nPGYahGTNm6Mknn9Qdd9whSfrggw9Ut25dLVmyRIMHD76s93j44Yc1ceJEHTlyRJ06dZKvb8nvxW3bti11bpeKiz59+kiSbrzxxhLH2ZwTAAAAZnh5xR4tSTwmN6tFb93fUW0bBJodCQAqTHZ2trKyspzPPT095elZuivODh8+rOTkZOe/9yUpICBA3bp1U3x8/GUXF2fHjR8/3nnMYrGUqS9waanId999p++++07ffvtticfZY5dr2rRp6tKli/z8/FSnTh0NGDBAe/fuLTEmPz9fY8aMUUhIiGrVqqWBAwfqxIkTJcYkJSWpf//+8vHxUZ06dTRp0iQVFxeXGLN69Wp17NhRnp6eatq0qeLi4s7JM3v2bDVu3FheXl7q1q2bEhISLv+LAgAAAFO8v+Gw/rnmkCTppYFt1at5HZMTAUDFioqKUkBAgPMxbdq0Us+RnJwsSedsqlm3bl3nuctx+PDhcx6HDh1y/tcVLl1xcf3117v0Zn+0Zs0ajRkzRl26dFFxcbEef/xx9e3bV7t373ZeTjJhwgQtW7ZMn3zyiQICAjR27Fjddddd2rBhgyTJbrerf//+CgsL0/fff6/jx49r6NChcnd319///ndJZ75w/fv316hRo/Thhx9q1apV+vOf/6x69eopJiZGkrRgwQJNnDhRc+bMUbdu3TRjxgzFxMRo7969qlOHH34AAACV0dLtx/T80t2SpEkxzXV3pwYmJwKAird7927Vr1/f+by0V1uUp0aNGpX7nBbDMAxXXpiRkaF//etf+umnnyRJrVq10ogRIxQQEOBymJSUFNWpU0dr1qxRz549lZmZqdq1a2v+/Pm6++67JUl79uxRy5YtFR8fr2uuuUZfffWVbr31Vh07dszZDM2ZM0dTpkxRSkqKPDw8NGXKFC1btkw7d+50vtfgwYOVkZGh5cuXS5K6deumLl26aNasWZIkh8OhiIgIjRs3To899tg5WQsKClRQUOB8/uuvvyoqKkpHjhxRgwb8wAQAALjSfjiUpqH/SlCh3aEh1zTS83e0ksViMTuWJKn7m93NjgCgjDaM22B2hEs6evSoIiIiXPp3qMVi0eLFizVgwABJ0qFDh9SkSRNt27ZN7du3d467/vrr1b59e82cOfOy5v3ggw8uen7o0KGlyim5eMXF5s2bFRMTI29vb3Xt2lWS9Prrr+vFF1/U119/rY4dO7oyrTIzMyVJwcHBkqQtW7aoqKioxBqbFi1aqGHDhs7iIj4+Xm3atClxOUtMTIxGjx6tXbt2qUOHDoqPjy8xx9kxjz76qCSpsLBQW7Zs0dSpU53nrVar+vTpo/j4+PNmnTZtmp577jmXPicAAADKZk9ylh78YLMK7Q7d3CpMz95eeUoLAKiKIiMjFRYWplWrVjmLi6ysLG3cuFGjR4++7HkeeeSREs+LioqUl5cnDw8P+fj4uFRcuLTHxYQJE3T77bfr559/1qJFi7Ro0SIdPnxYt956q7MMKC2Hw6FHH31U3bt3V+vWrSWdWWPj4eGhwMDAEmN/v8YmOTn5vGtwzp672JisrCydPn1aqampstvtpVrLM3XqVGVmZjofu3fvdulzAwAAoHSOZZzWsLmblJ1frC6NgzRjcHvZrJQWAHApOTk5SkxMdN6u9PDhw0pMTFRSUpIsFoseffRRvfDCC/riiy+0Y8cODR06VOHh4c6rMi7HqVOnSjxycnK0d+9e9ejRQx999JFLuV2+4uLdd9+Vm9v/Xu7m5qbJkyerc+fOLgUZM2aMdu7cqfXr17v0+or2x11af7+DKwAAAK6MzLwixc5NUHJWvprWqaV3h3aWl7vN7FgAUCVs3rxZvXv3dj6fOHGiJCk2NlZxcXGaPHmycnNz9dBDDykjI0M9evTQ8uXL5eXlVab3bdasmV566SU98MAD2rNnT6lf71Jx4e/vr6SkJLVo0aLE8SNHjsjPz6/U840dO1ZLly7V2rVrS6zLCQsLU2FhoTIyMkpcdXHixAmFhYU5x/zx7h9n7zry+zF/vBPJiRMn5O/vL29vb9lsNtlstvOOOTsHAAAAzJVfZNeDH2zW/pM5CvP30rwRXRXo42F2LACoMnr16qWLbXNpsVj0/PPP6/nnny/393Zzc9OxY8dce60rLxo0aJBGjhypV199Vddee60kacOGDZo0aZLuvffey57HMAyNGzdOixcv1urVqxUZGVnifKdOneTu7q5Vq1Zp4MCBkqS9e/cqKSlJ0dHRkqTo6Gi9+OKLOnnypPPuHytXrpS/v7+ioqKcY7788ssSc69cudI5h4eHhzp16qRVq1Y5L4FxOBxatWqVxo4dW8qvDgAAAMqb3WHo0Y8TlfBzuvw83RQ3oovqB3qbHQsA8AdffPFFieeGYej48eOaNWuWund3beNil4qLV199VRaLRUOHDlVxcbEkyd3dXaNHj9ZLL7102fOMGTNG8+fP1+effy4/Pz/nfhIBAQHy9vZWQECARo4cqYkTJyo4OFj+/v4aN26coqOjdc0110iS+vbtq6ioKA0ZMkTTp09XcnKynnzySY0ZM8a5lGPUqFGaNWuWJk+erBEjRujbb7/VwoULtWzZMmeWiRMnKjY2Vp07d1bXrl01Y8YM5ebmavjw4a58iQAAAFBODMPQc//dpeW7kuVhs+qdoZ3VIszf7FgAgPP4434YFotFtWvX1g033KDXXnvNpTldKi48PDw0c+ZMTZs2TQcPHpQkNWnSRD4+PqWa5+2335Z05nKV33v//fc1bNgwSdI//vEPWa1WDRw4UAUFBYqJidFbb73lHGuz2bR06VKNHj1a0dHR8vX1VWxsbIlLWyIjI7Vs2TJNmDBBM2fOVIMGDfTee+8pJibGOWbQoEFKSUnR008/reTkZLVv317Lly8/Z8NOAAAAVKy31xzUB/G/yGKRXh/UTtFNQsyOBAC4AIfDUe5zWoyLLXDBZSvL/XMBAABwfp9tOaq/fvKjJOnpW6M0okfkJV5ROXR/07XLoQFUHhvGbTA7wiVV9n+Hnq0bynq76su+4uKuu+5SXFyc/P39ddddd1107KJFi8oUCgAAAFi996SmfLZdkvRQz6uqTGkBADXdBx98oFdeeUX79++XJF199dWaNGmShgwZ4tJ8l11cBAQEOFsSf3//MjcmAAAAwIXsOJqphz/cqmKHoQHtw/XYzS0u/SIAgOlef/11PfXUUxo7dqxzM87169dr1KhRSk1N1YQJE0o952UXF++//77zz3FxcaV+IwAAAOBy/JKWq+FxCcortKt70xBNv7udrFb+pxkAVAVvvvmm3n77bQ0dOtR57Pbbb1erVq307LPPulRcWF0JcsMNNygjI+Oc41lZWbrhhhtcmRIAAABQak6BYucmKDWnUFH1/DXngU7ycHPpV1YAgAmOHz+ua6+99pzj1157rY4fP+7SnC79FFi9erUKCwvPOZ6fn69169a5FAQAAAA1W15hsUbGbdLPaXlqEOStuOFd5OflbnYsAEApNG3aVAsXLjzn+IIFC9SsWTOX5izV7VC3b9/u/PPu3buVnJzsfG6327V8+XLVr1/fpSAAAACouYrsDo35cKt+PJqpIB93zRvRVXX8vcyOBQAopeeee06DBg3S2rVrnXtcbNiwQatWrTpvoXE5SlVctG/fXhaLRRaL5bxLQry9vfXmm2+6FAQAAAA1k2EYemLxDn23N0Ve7lb9a1gXNaldy+xYAAAXDBw4UBs3btQ//vEPLVmyRJLUsmVLJSQkqEOHDi7NWari4vDhwzIMQ1dddZUSEhJUu3Zt5zkPDw/VqVNHNpvNpSAAAAComf6xcp8Wbj4qq0V6896O6tgwyOxIAIAy6NSpk/7zn/+U23ylKi4aNWokSXI4HOUWAAAAADXXhxt/0RvfHpAkvXhnG90UVdfkRAAAV2RlZV3WOH9//1LPXari4o92796tpKSkczbqvP3228syLQAAAGqAFbuS9dSSnZKkR25spnu7NjQ5EQDAVYGBgbJYLnzrasMwZLFYZLfbSz23S8XFoUOHdOedd2rHjh2yWCwyDEOSnCFdCQIAAICaY8sv6Rr/0TY5DGlwlwg92se1neYBAJXDd9995/yzYRi65ZZb9N5775XLDTxcKi4eeeQRRUZGatWqVYqMjFRCQoLS0tL017/+Va+++mqZQwEAAKD6OnAyRyPnbVZBsUM3tqijFwa0vuj/pQMAVH7XX399iec2m03XXHONrrrqqjLP7VJxER8fr2+//VahoaGyWq2yWq3q0aOHpk2bpvHjx2vbtm1lDgYAAIDq50RWvmLnJigjr0jtIwL15n0d5Gazmh0LAFCJufRTwm63y8/PT5IUGhqqY8eOSTqzeefevXvLLx0AAACqjaz8IsXOTdCvGacVGeqrf8V2lo9HmbZcAwDUAC79pGjdurV+/PFHRUZGqlu3bpo+fbo8PDz0zjvvlMtlIAAAAKheCortGvXvLdqTnK3QWp76YERXhdTyNDsWAOAKKq9lgC4VF08++aRyc3MlSc8//7xuvfVWXXfddQoJCdGCBQvKJRgAAACqB4fD0P99sl3fH0yTr4dNccO7KCLYx+xYAIBydNddd5V4np+fr1GjRsnX17fE8UWLFpV6bpeKi5iYGOefmzZtqj179ig9PV1BQUFsrAQAAIAS/v7lT/rvj8fkZrVozpBOal0/wOxIAIByFhBQ8nv7Aw88UG5zu1RcZGZmym63Kzg42HksODhY6enpcnNzk7+/f7kFBAAAQNX13rpDem/9YUnSK/e01XXNapucCABwJbz//vtXbG6XNuccPHiwPv7443OOL1y4UIMHDy5zKAAAAFR9X/x4TC8s+0mS9Fi/FrqzQwOTEwEArqSioiK5ublp586d5TqvS8XFxo0b1bt373OO9+rVSxs3bixzKAAAAFRt3x9I1V8XJkqShl3bWH/pyQbuAFDdubu7q2HDhrLb7eU6r0vFRUFBgYqLi885XlRUpNOnT5c5FAAAAKqu3cey9Jd/b1GR3dAtbcL01K1R7IMGADXEE088occff1zp6enlNqdLe1x07dpV77zzjt58880Sx+fMmaNOnTqVSzAAAABUPUdP5WnY+wnKLihW18hgvf6n9rJZKS0AoKaYNWuWDhw4oPDwcDVq1Oicu4ps3bq11HO6VFy88MIL6tOnj3788UfdeOONkqRVq1Zp06ZN+vrrr12ZEgAAAFXcqdxCxc5N0MnsAl1dt5beHdJZXu42s2MBACrQgAEDyn1Ol4qL7t27Kz4+XtOnT9fChQvl7e2ttm3b6l//+peaNWtW3hkBAABQyeUX2fXnDzbrYEqu6gV4ad6IrgrwcTc7FgCggj3zzDPlPqdLxYUktW/fXvPnzy/PLAAAAKiC7A5D4z/api2/nJK/l5vmjeiqegHeZscCAJgkIyNDn376qQ4ePKhJkyYpODhYW7duVd26dVW/fv1Sz+dycWG327VkyRL99NOZW1y1atVKt99+u2w2LgcEAACoKQzD0NOf79TXu0/Iw82q92K76Oq6fmbHAgCYZPv27erTp48CAgL0888/68EHH1RwcLAWLVqkpKQkffDBB6We06W7ihw4cEBRUVEaOnSoFi1apEWLFumBBx5Qq1atdPDgQVemBAAAQBU0+7sD+nBjkiwWaeag9uoaGWx2JACAiSZOnKhhw4Zp//798vLych6/5ZZbtHbtWpfmdKm4GD9+vK666iodOXJEW7du1datW5WUlKTIyEiNHz/epSAAAACoWhZuPqJXv94nSXr2tlbq16aeyYkAAGbbtGmT/vKXv5xzvH79+kpOTnZpTpeWiqxZs0Y//PCDgoP/16iHhITopZdeUvfu3V0KAgAAgKrjuz0nNXXRDknS6F5NFHttY3MDAQAqBU9PT2VlZZ1zfN++fapdu7ZLc7p0xYWnp6eys7PPOZ6TkyMPDw+XggAAAKBq+PFIhh7+cKvsDkN3daivyTHNzY4EAKgkbr/9dj3//PMqKiqSJFksFiUlJWnKlCkaOHCgS3O6VFzceuuteuihh7Rx40YZhiHDMPTDDz9o1KhRuv32210KAgAAgMrv59RcjYjbpNNFdl3XLFQv391WFovF7FgAgEritddeU05OjurUqaPTp0/r+uuvV9OmTeXn56cXX3zRpTldWiryxhtvKDY2VtHR0XJ3P3N/7uLiYt1+++2aOXOmS0EAAABQuaVkF2jo3ASl5RaqdX1/vf1AJ7nbXPr/YACAaiogIEArV67Uhg0b9OOPPyonJ0cdO3ZUnz59XJ7TpeIiMDBQn3/+ufbv3689e/ZIklq2bKmmTZu6HAQAAACVV25BsUbEbVJSep4igr01d1gX1fJ06VdJAEA1tWDBAn3xxRcqLCzUjTfeqIcffrhc5nXpp8369evVo0cPNWvWTM2aNSuXIAAAAKiciuwOjf5wq3b8mqlgXw99MKKb6vh5XfqFAIAa4+2339aYMWPUrFkzeXt7a9GiRTp48KBeeeWVMs/t0rV9N9xwgyIjI/X4449r9+7dZQ4BAACAyskwDE35bLvW7kuRt7tNc4d1UWSor9mxAACVzKxZs/TMM89o7969SkxM1Lx58/TWW2+Vy9wuFRfHjh3TX//6V61Zs0atW7dW+/bt9corr+jo0aPlEgoAAACVwysr9mrR1l9ls1o0+/4Oah8RaHYkAEAldOjQIcXGxjqf33fffSouLtbx48fLPLdLxUVoaKjGjh2rDRs26ODBg7rnnns0b948NW7cWDfccEOZQwEAAMB8H8T/rLdWH5QkTbuzjW5oUdfkRACAyqqgoEC+vv+7Is9qtcrDw0OnT58u89xl3lEpMjJSjz32mNq1a6ennnpKa9asKXMoAAAAmGv5zuN65otdkqSJN12tP3WJMDkRAKCye+qpp+Tj4+N8XlhYqBdffFEBAQHOY6+//nqp5y1TcbFhwwZ9+OGH+vTTT5Wfn6877rhD06ZNK8uUAAAAMFnC4XSN/zhRhiHd27Whxt3AneMAoDqw2+169tln9Z///EfJyckKDw/XsGHD9OSTT8pisZRp7p49e2rv3r0ljl177bU6dOhQmeaVXCwupk6dqo8//ljHjh3TTTfdpJkzZ+qOO+4o0awAAACg6tl/Ilt/nrdJhcUO9WlZV3+7o1WZf5kFAFQOL7/8st5++23NmzdPrVq10ubNmzV8+HAFBARo/PjxZZp79erV5RPyPFza42Lt2rWaNGmSfv31Vy1dulT33nsvpQUAAEAVdzzztGLnJigrv1gdGwbqzXs7yM3m0q+LAIBK6Pvvv9cdd9yh/v37q3Hjxrr77rvVt29fJSQklNt7PP/888rLyzvn+OnTp/X888+7NKdLP4k2bNighx9+WKGhoS69KQAAACqXzNNFGjZ3k45l5uuq2r76V2wXeXvYzI4FALgM2dnZysrKcj4KCgrOO+7aa6/VqlWrtG/fPknSjz/+qPXr16tfv37lluW5555TTk7OOcfz8vL03HPPuTSny3tc7N+/X999951Onjwph8NR4tzTTz/t6rQAAACoYAXFdj30wWbtPZGt2n6emje8q4J8PcyOBQC4TFFRUSWeP/PMM3r22WfPGffYY48pKytLLVq0kM1mk91u14svvqj777+/3LIYhnHeJYY//vijgoODXZrTpeLi3Xff1ejRoxUaGqqwsLASoSwWC8UFAABAFeFwGJq48EdtPJyuWp5uihveRRHBLAEGgKpk9+7dql+/vvO5p6fnecctXLhQH374oebPn69WrVopMTFRjz76qMLDwxUbG1umDEFBQbJYLLJYLLr66qtL9AR2u105OTkaNWqUS3O7VFy88MILevHFFzVlyhSX3hQAAADmMwxDf1u2W8u2H5e7zaJ/DumkVuEBl34hAKBS8fPzk7+//yXHTZo0SY899pgGDx4sSWrTpo1++eUXTZs2rczFxYwZM2QYhkaMGKHnnnuuxC1QPTw81LhxY0VHR7s0t0vFxalTp3TPPfe49IYAAACoHN5dd0jvb/hZkvTqPe3UvSn7lwFAdZaXlyerteRWlzab7ZztH1xxtviIjIxU9+7d5ebm8s4U53Bpc8577rlHX3/9dbmFAAAAQMVasu1X/f3LPZKkJ25pqTva17/EKwAAVd1tt92mF198UcuWLdPPP/+sxYsX6/XXX9edd95Zbu/h5+enn376yfn8888/14ABA/T444+rsLDQpTldqkCaNm2qp556Sj/88IPatGkjd3f3EufLev9XAAAAXDnr96dq0qc/SpJG9ojUgz2vMjkRAKAivPnmm3rqqaf08MMP6+TJkwoPD9df/vKXct2n8i9/+Ysee+wxtWnTRocOHdKgQYN011136ZNPPlFeXp5mzJhR6jkthmEYpX1RZGTkhSe0WHTo0KFSB6nqjh49qoiICB05ckQNGjQwOw4AAMB57fw1U4P+Ga/cQrtubVtPbwzuIKv13N3fUTbd3+xudgQAZbRh3AazI1xSZfx3aEBAgLZu3aomTZro5Zdf1rfffqsVK1Zow4YNGjx4sI4cOVLqOV264uLw4cOuvAwAAAAmOpKep+Fxm5RbaFf0VSF67U/tKC0AAOXKMAznnhnffPONbr31VklSRESEUlNTXZrTpT0uAAAAULWk5xYqdm6CUrIL1CLMT/8c2kmebjazYwEAqpnOnTvrhRde0L///W+tWbNG/fv3l3TmAoi6deu6NGeprriYOHHiZY17/fXXXQoDAACA8ne60K6R8zbpUGqu6gd6K254V/l7uV/6hQAAlNKMGTN0//33a8mSJXriiSfUtGlTSdKnn36qa6+91qU5S1VcbNu27ZJjLBYuNwQAAKgsiu0Ojftoq7YlZSjA213zRnRRWICX2bEAANVU27ZttWPHjnOOv/LKK7LZXLvSr1TFxXfffefSmwAAAKDiGYahpz7fqW9+OilPN6v+FdtZTev4mR0LAFADbNmyxXlb1KioKHXs2NHluVza4yI/P/+C544fP37Z86xdu1a33XabwsPDZbFYtGTJkhLnhw0bJovFUuJx8803lxiTnp6u+++/X/7+/goMDNTIkSOVk5NTYsz27dt13XXXycvLSxEREZo+ffo5WT755BO1aNFCXl5eatOmjb788svL/hwAAACV0cxV+/VRwhFZLdLMwR3UuXGw2ZEAANXcyZMn1bt3b3Xp0kXjx4/X+PHj1blzZ914441KSUlxaU6XiouOHTsqMTHxnOOfffaZ2rZte9nz5Obmql27dpo9e/YFx9x88806fvy48/HRRx+VOH///fdr165dWrlypZYuXaq1a9fqoYcecp7PyspS37591ahRI23ZskWvvPKKnn32Wb3zzjvOMd9//73uvfdejRw5Utu2bdOAAQM0YMAA7dy587I/CwAAQGXycUKSZnyzX5L03B2tdXPrMJMTAQBqgnHjxiknJ0e7du1Senq60tPTtXPnTmVlZWn8+PEuzenS7VB79eqla665Rs8995ymTJmi3NxcjRkzRgsXLtSLL7542fP069dP/fr1u+gYT09PhYWd/wftTz/9pOXLl2vTpk3q3LmzJOnNN9/ULbfcoldffVXh4eH68MMPVVhYqLlz58rDw0OtWrVSYmKiXn/9dWfBMXPmTN18882aNGmSJOlvf/ubVq5cqVmzZmnOnDmX/XkAAAAqg1U/ndATS878D5ixvZtqyDWNTE4EAKgpli9frm+++UYtW7Z0HouKitLs2bPVt29fl+Z06YqLt956S5999plmzJih6667Tu3atVNiYqISEhI0YcIEl4JcyOrVq1WnTh01b95co0ePVlpamvNcfHy8AgMDnaWFJPXp00dWq1UbN250junZs6c8PDycY2JiYrR3716dOnXKOaZPnz4l3jcmJkbx8fEXzFVQUKCsrCznIzs7u1w+LwAAQFlsTTqlMfO3yu4wdHenBvpr36vNjgQAqEEcDofc3c+9c5W7u7scDodLc7pUXEhnrpa46667tGHDBiUlJenll19W69atXZ3uvG6++WZ98MEHWrVqlV5++WWtWbNG/fr1k91ulyQlJyerTp06JV7j5uam4OBgJScnO8f88V6xZ59faszZ8+czbdo0BQQEOB9RUVFl+7AAAABldCglRyPjNim/yKFezWtr2l1tuOMbAKBC3XDDDXrkkUd07Ngx57Fff/1VEyZM0I033ujSnC4VFwcPHlR0dLSWLl2qFStWaPLkybr99ts1efJkFRUVuRTkfAYPHqzbb79dbdq00YABA7R06VJt2rRJq1evLrf3cNXUqVOVmZnpfOzevdvsSAAAoAY7mZ2voXMTdCqvSG0bBGj2fR3lbnP5/1EBAOCSWbNmKSsrS40bN1aTJk3UpEkTRUZGKisrS2+++aZLc7q0x0X79u3Vv39/rVixQoGBgbrpppt0yy23aOjQoVq5cqW2bdvmUphLueqqqxQaGqoDBw7oxhtvVFhYmE6ePFliTHFxsdLT0537YoSFhenEiRMlxpx9fqkxF9pbQzqz94anp6fzeVZWlusfDAAAoAyy84s0/P1NOnrqtBqF+GjusC7y9XTp1zwAAMokIiJCW7du1TfffKM9e/ZIklq2bHnO9gyl4fIeFx9//LECAwOdx6699lpt27atTPdmvZSjR48qLS1N9erVkyRFR0crIyNDW7ZscY759ttv5XA41K1bN+eYtWvXlrgSZOXKlWrevLmCgoKcY1atWlXivVauXKno6Ogr9lkAAADKQ2GxQ6P/s1W7jmUpxNdDH4zoqtBanpd+IQAA5ejbb79VVFSUsrKyZLFYdNNNN2ncuHEaN26cunTpolatWmndunUuze1ScTFkyJDzHvfz89O//vWvy54nJydHiYmJzlurHj58WImJiUpKSlJOTo4mTZqkH374QT///LNWrVqlO+64Q02bNlVMTIykM63NzTffrAcffFAJCQnasGGDxo4dq8GDBys8PFySdN9998nDw0MjR47Url27tGDBAs2cOVMTJ0505njkkUe0fPlyvfbaa9qzZ4+effZZbd68WWPHjnXlywMAAFAhHA5DUz7brvUHUuXjYdP7w7uoUYiv2bEAADXQjBkz9OCDD8rf3/+ccwEBAfrLX/6i119/3aW5y3QN4e7du5WUlKTCwkLnMYvFottuu+2yXr9582b17t3b+fxsmRAbG6u3335b27dv17x585SRkaHw8HD17dtXf/vb30os0fjwww81duxY3XjjjbJarRo4cKDeeOMN5/mAgAB9/fXXGjNmjDp16qTQ0FA9/fTTzluhSmeuFpk/f76efPJJPf7442rWrJmWLFlS7puNAgAAlKeXV+zR4m2/yma16K37O6ptg0CzIwEAaqgff/xRL7/88gXP9+3bV6+++qpLc7tUXBw6dEh33nmnduzYIYvFIsMwJMm5a/XZu35cSq9evZyvPZ8VK1Zcco7g4GDNnz//omPatm17yUtS7rnnHt1zzz2XfD8AAIDK4P0Nh/XPNYckSS/d1Ua9mte5xCsAALhyTpw4cd7boJ7l5uamlJQUl+Z2aanII488osjISJ08eVI+Pj7atWuX1q5dq86dO1eKO34AAABUZ8u2H9fzS8/c0WxSTHPd0znC5EQAgJqufv362rlz5wXPb9++3blfZWm5VFzEx8fr+eefV2hoqKxWq6xWq3r06KFp06Zp/PjxLgUBAADApf1wKE0TFiTKMKQh1zTSw72amB0JAADdcssteuqpp5Sfn3/OudOnT+uZZ57Rrbfe6tLcLi0Vsdvt8vPzkySFhobq2LFjat68uRo1aqS9e/e6FAQAAAAXtyc5Sw9+sFmFdodiWtXVs7e3ci7VBQDATE8+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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "matplotlib.rc_file_defaults()\n", "ax1 = sns.set_style(style=None, rc=None )\n", "\n", "fig, ax1 = plt.subplots(figsize=(12,6))\n", "\n", "ax2 = ax1.twinx()\n", "\n", "sns.barplot(data = df, x='InstanceType', y='MaxInvocations', ax=ax1)\n", "sns.lineplot( x='InstanceType', y='CostPerHour',data= df, ax=ax2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 7. Custom Load Test\n", "\n", "With an 'Advanced' job, you can provide your production requirements, select instance types, tune environment variables and perform more extensive load tests. This typically takes 2 hours depending on your traffic pattern and number of instance types. \n", "\n", "The output is a list of endpoint configuration recommendations (instance type, instance count, environment variables) with associated cost, throughput and latency metrics.\n", "\n", "In the below example, we aim to limit the latency requirement to 50 ms. The goal is to find the best performance in the sense of the maximum number of requests per minute expected for the endpoint for a `ml.m5.2xlarge` instance.\n", "We specify `DurationInSeconds`, how long traffic phase should be, to be 120, and the maximum duration of the job, in seconds `JobDurationInSeconds` to 7200." ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'JobArn': 'arn:aws:sagemaker:us-east-1:917092859813:inference-recommendations-job/nlp-advanced-inference-recommender-job-01-03-20-55', 'ResponseMetadata': {'RequestId': '2a75020d-3d62-486d-9301-da30f5299598', 'HTTPStatusCode': 200, 'HTTPHeaders': {'x-amzn-requestid': '2a75020d-3d62-486d-9301-da30f5299598', 'content-type': 'application/x-amz-json-1.1', 'content-length': '134', 'date': 'Tue, 04 Jan 2022 00:54:10 GMT'}, 'RetryAttempts': 0}}\n" ] } ], "source": [ "advanced_response = client.create_inference_recommendations_job(\n", " JobName=advanced_job,\n", " JobDescription=\"NLP bert Inference Advanced Recommender Job\",\n", " JobType=\"Advanced\",\n", " RoleArn=role,\n", " InputConfig={\n", " \"ModelPackageVersionArn\": model_package_arn,\n", " \"JobDurationInSeconds\": 7200,\n", " \"EndpointConfigurations\": [{'InstanceType': 'ml.p3.8xlarge'},\n", " {'InstanceType': 'ml.p3.2xlarge'},\n", " {'InstanceType': 'ml.p3.16xlarge'},\n", " {'InstanceType': 'ml.p2.16xlarge'},\n", " {'InstanceType': 'ml.g4dn.xlarge'},\n", " {'InstanceType': 'ml.g4dn.8xlarge'},\n", " {'InstanceType': 'ml.g4dn.4xlarge'},\n", " {'InstanceType': 'ml.g4dn.2xlarge'},\n", " {'InstanceType': 'ml.g4dn.16xlarge'},\n", " {'InstanceType': 'ml.g4dn.12xlarge'}],\n", " \"TrafficPattern\": {\n", " \"TrafficType\": \"PHASES\",\n", " \"Phases\": [{\"InitialNumberOfUsers\": 1, \"SpawnRate\": 3, \"DurationInSeconds\": 120}],\n", " },\n", " \"ResourceLimit\": {\n", " \"MaxNumberOfTests\": 10,\n", " \"MaxParallelOfTests\": 2\n", " },\n", " },\n", " StoppingConditions={\n", " \"MaxInvocations\": 60,\n", " \"ModelLatencyThresholds\": [{\"Percentile\": \"P95\", \"ValueInMilliseconds\": 20}],\n", " },\n", ")\n", "\n", "print(advanced_response)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 8. Custom Load Test Results\n", "\n", "Inference recommender runs benchmarks on both of the endpoint configurations. Below is the result.\n", "\n", "Running the Inference recommender job will take ~15 minutes.\n" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Inference recommender job in progress\n", "Inference recommender job in progress\n", "Inference recommender job in progress\n", "Inference recommender job in progress\n", "Inference recommender job in progress\n", "Inference recommender job in progress\n", "Inference recommender job in progress\n", "Inference recommender job in progress\n", "Inference recommender job in progress\n", "Inference recommender job in progress\n", "Inference recommender job in progress\n", "Inference recommender job in progress\n", "Inference recommender job in progress\n", "Inference recommender job in progress\n", "Inference recommender job in progress\n", "Inference recommender job completed\n", "CPU times: user 302 ms, sys: 57.9 ms, total: 360 ms\n", "Wall time: 1h 15min 4s\n" ] } ], "source": [ "%%time\n", "\n", "ended = False\n", "while not ended:\n", " inference_recommender_job = client.describe_inference_recommendations_job(\n", " JobName=str(advanced_job)\n", " )\n", " if inference_recommender_job[\"Status\"] in [\"COMPLETED\", \"STOPPED\", \"FAILED\"]:\n", " ended = True\n", " else:\n", " print(\"Inference recommender job in progress\")\n", " time.sleep(300)\n", "\n", "if inference_recommender_job[\"Status\"] == \"FAILED\":\n", " print(\"Inference recommender job failed \")\n", " print(\"Failed Reason: {}\".inference_recommender_job[\"FailedReason\"])\n", "else:\n", " print(\"Inference recommender job completed\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Detailing out the result\n", "\n", "Analyzing load test result, we can see that to achieve 50 ms latency, we will need two `ml.m5.2xlarge` instances, with `MaxInvocations` (The maximum number of requests per minute expected for the endpoint) of ~736." ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
EndpointNameInstanceTypeInitialInstanceCountEnvironmentParametersCostPerHourCostPerInferenceMaxInvocationsModelLatency
0sm-epc-3ea0cba0-027e-4d81-9d1e-3f0bee142892ml.g4dn.12xlarge1[]4.8900.000047173314
1sm-epc-4fa41173-0e16-45b5-b3fc-246de065b52aml.g4dn.8xlarge1[]2.7200.000027170118
2sm-epc-3b263d89-5a2a-4bc1-94c7-3b6808afd94fml.g4dn.4xlarge1[]1.5050.000014180418
3sm-epc-f712c9fe-200e-46b0-8acc-a06e8b170c58ml.g4dn.2xlarge1[]0.9400.000010163115
4sm-epc-a4ea9afb-cc71-442f-a9ff-f4abc16c8d1fml.g4dn.xlarge1[]0.7360.000011116820
\n", "
" ], "text/plain": [ " EndpointName InstanceType \\\n", "0 sm-epc-3ea0cba0-027e-4d81-9d1e-3f0bee142892 ml.g4dn.12xlarge \n", "1 sm-epc-4fa41173-0e16-45b5-b3fc-246de065b52a ml.g4dn.8xlarge \n", "2 sm-epc-3b263d89-5a2a-4bc1-94c7-3b6808afd94f ml.g4dn.4xlarge \n", "3 sm-epc-f712c9fe-200e-46b0-8acc-a06e8b170c58 ml.g4dn.2xlarge \n", "4 sm-epc-a4ea9afb-cc71-442f-a9ff-f4abc16c8d1f ml.g4dn.xlarge \n", "\n", " InitialInstanceCount EnvironmentParameters CostPerHour CostPerInference \\\n", "0 1 [] 4.890 0.000047 \n", "1 1 [] 2.720 0.000027 \n", "2 1 [] 1.505 0.000014 \n", "3 1 [] 0.940 0.000010 \n", "4 1 [] 0.736 0.000011 \n", "\n", " MaxInvocations ModelLatency \n", "0 1733 14 \n", "1 1701 18 \n", "2 1804 18 \n", "3 1631 15 \n", "4 1168 20 " ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "data = [\n", " {**x[\"EndpointConfiguration\"], **x[\"ModelConfiguration\"], **x[\"Metrics\"]}\n", " for x in inference_recommender_job[\"InferenceRecommendations\"]\n", "]\n", "df = pd.DataFrame(data)\n", "df.drop(\"VariantName\", inplace=True, axis=1)\n", "pd.set_option(\"max_colwidth\", 400)\n", "df.head()" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAABCUAAAINCAYAAAAJJ8XzAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAPYQAAD2EBqD+naQAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjMsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+AADFEAAAgAElEQVR4nOzdeXRU9f3/8dedmewkISFkgxAIixDDEnZEZdGCVEFE61oQi2irYBX9Wm2tX+tPSutW+8XW1kpVUIRaBBUqgqwiYQmL7HsgISSENRtkmZn7+yNkamQLY5I7SZ6Pc+45zL13Pvd1PZ5k8p73/XwM0zRNAQAAAAAA1DGb1QEAAAAAAEDjRFECAAAAAABYgqIEAAAAAACwBEUJAAAAAABgCYoSAAAAAADAEhQlAAAAAACAJShKAAAAAAAAS1CUAAAAAAAAlnBYHaC+cDqd2rRpk2JiYmSzUcsBAAAAANQut9uto0ePKjU1VQ5Hw/zzvWHeVS3YtGmTevfubXUMAAAAAEAjs27dOvXq1cvqGLWCokQ1xcTESKr4nyEuLs7iNAAAAACAhi4nJ0e9e/f2/D3aEFGUqKbKRzbi4uLUsmVLi9MAAAAAABqLhjyFQMO9MwAAAAAA4NMoSgAAAAAAAEtQlAAAAAAAAJagKAEAAAAAACxBUQIAAAAAAFiCogQAAAAAALAERQkAAAAAAGAJihIAAAAAAMASFCUAAAAAAIAlKEoAAAAAAABLUJQAAAAAAACWoCgBAAAAAAAsQVECAAAAAABYgqIEAAAAAACwBEUJAAAAAABgCYoSAAAAAADAEhQlAAAAUKsyjhfryOmzVscAAPggihIAAACoNYdOFOumN1bq1r98o7NlLqvjAAB8DEUJAAAA1Jq3lu9XqdOtY4Wl+uzbbKvjAAB8jMPqAAAat/5T+1sdwed8M/EbqyMAQI3IPn1WczYe9ryennZId/ZMkGEYFqYCAPgSOiUAAABQK/6+Yr/KXaa6JjRVgMOm7UcKtDHztNWxAAA+hKIEAAAAalxeQYlmrc+SJP1q6FUa3jVekjQ97aB1oQAAPoeiBAAAAGrc2ysPqMzpVo/ECPVr20z392stSfrP1hwdKyy1NhwAwGdQlAAAAECNOlFUqg/XZkqSJgxuJ8Mw1LlluLolNFW5y9Ts9ZkWJwQA+AqKEgAAAKhR//wmQ2fLXercIlwDOzT37B/TL1GS9OHaTDldbqviAQB8CEUJAAAA1Jj8M+V6f/UhSf/tkqj0485xigzxV05+ib7amWdVRACAD6EoAQAAgBrz3uqDKip16qqYUP2oU0yVY4F+dt3VK0GSNGPNQQvSAQB8DUUJAAAA1IiiUqf++U2GJOnRwe1ksxnnnXNfn1ayGdI3+05oX15RXUcEAPgYS4sSK1eu1PDhwxUfHy/DMDRv3rwqxw3DuOD2yiuveM5p3br1ecefeeaZKuNkZmZq+PDhCgkJUVRUlB577DGVlZXVyT0CAAA0FjPSDin/bLmSokJ0c+e4C57TMiJYgztWdFB8sOZQXcYDAPggS4sSxcXF6tq1q958880LHs/Jyamy/fOf/5RhGLr99turnPfiiy9WOe+5557zHHO5XLr55ptVXFysVatWadasWZozZ46efPLJWr03AACAxuRsmUvvfH1AkvTIoHayX6BLolLlhJdzNhxWcamzTvIBAHyTw8qLDxs2TMOGDbvo8djY2CqvP/30Uw0aNEhJSUlV9oeGhp53bqVFixZpx44dysrKUnx8vCTptdde09ixYzV58mSFhYX9wLsAAADAzHWZOlFcpoTIIN3aLf6S517bLkptokKUcbxYczdl66d9E+soJQDA19SbOSWOHj2qBQsWaNy4cecd++Mf/6hmzZqpW7dumjx5cpVHM9LS0pSSkuIpSEjS0KFDVVpaqg0bNlz0eqWlpSooKPBshYWFNXtDAAAADURJuUtvr9wvSfrFgHbys1/6I6bNZngKETPSDsk0zVrPCADwTfWmKPH+++8rNDRUo0aNqrL/l7/8pWbNmqVly5ZpwoQJeuONN/TII494jufm5iompurMzxEREfL391dubu5FrzdlyhSFh4d7tuTk5Jq9IQAAgAbi3xsO62hBqeLCA3V7jxbVes8dPVoqyM+u3UcLtS7jZC0nBAD4qnpTlPjnP/+p++67T4GBgVX2P/HEExowYIC6dOmiBx98UH/72980bdo0nThxwnPOd9fHrmSa5gX3V3r22WeVn5/v2Xbs2FFzNwMAANBAlLvcemt5RZfEw9cnKcBhr9b7woP8NDK1opN1OhNeAkCjVS+KEl9//bV2796tBx988LLn9u3bV5K0b98+SRXzUny/I+LUqVMqLy8/r4PiuwICAhQWFubZQkND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vkmRVsex1NCrY9U8NEDHCkv15fZcq+MAAC7Ap4sSw4YN04cffqilS5fqtdde0/r16zV48GCVlpZKknJzc+Xv76+IiKptiTExMcrNzfWcExMTU+V4RESE/P39PedcyJQpUxQeHu7ZkpOTa/juAAAAataJolJ9uPaQJGniDe1lGIbFiazl77Dpnt6tJEkz0g5ZnAYAcCE+XZS46667dPPNNyslJUXDhw/XF198oT179mjBggWXfJ9pmlV+CV/oF/L3z/m+Z599Vvn5+Z5tx44d3t8IAABAHXhnVYZKyt3q0jJc17ePsjqOT7i3dyvZbYbWHTypXbkFVscBAHyPTxclvi8uLk6JiYnau3evJCk2NlZlZWU6depUlfPy8vI83RGxsbHndUScOnVK5eXl53VQfFdAQIDCwsI8W2hoaA3fDQAAQM05faZM01cflCRNGNSu0XdJVIoND9TQqys+802nWwIAfE69KkqcOHFCWVlZiouLkyT16NFDfn5+Wrx4seecnJwcbdu2Tddcc40kqV+/ftq2bZtycnI85yxatEgBAQHq0aNH3d4AAABALXlv9UEVl7nUMTZUN3a6+BcvjdHovq0lSfM2ZaugpNzaMACAKiwtShQVFWnz5s3avHmzJCkjI0ObN29WZmamioqK9NRTTyktLU0HDx7U8uXLNXz4cEVFRem2226TJIWHh2vcuHF68skntWTJEm3atEk//elP1blzZ89qHEOGDFFycrJGjx6tTZs2acmSJXrqqac0fvx4Vt4AAAANQmFJuf65KkOSNGFwO9lsdEl8V9+kSHWIaaIzZS7N2XDY6jgAgO+wtCiRnp6u1NRUpaamSpImTZqk1NRUPf/887Lb7dq6datuvfVWdejQQffff786dOigtLS0Ko9S/OlPf9LIkSN15513qn///goODtbnn38uu90uSbLb7VqwYIECAwPVv39/3XnnnRo5cqReffVVS+4ZAACgps1Yc0gFJU61bR6iYSlxVsfxOYZhaHTfREkVE1663abFiQAAlRxWXnzgwIEyzYv/Uvjyyy8vO0ZgYKCmTp2qqVOnXvScVq1aaf78+V5lBAAA8GVnypx65+uKLolHB7WTnS6JC7qte0v9ceFuHTherG/2H9d17ZtbHQkAoHo2pwQAAACqmrk2UyeLy9QqMlgjusZbHcdnNQlwaFT3FpKY8BIAfAlF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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "matplotlib.rc_file_defaults()\n", "ax1 = sns.set_style(style=None, rc=None )\n", "\n", "fig, ax1 = plt.subplots(figsize=(12,6))\n", "\n", "#sns.lineplot(data = df['max_invocations'], marker='o', sort = False, ax=ax1)\n", "ax2 = ax1.twinx()\n", "\n", "sns.barplot(data = df, x='InstanceType', y='MaxInvocations', ax=ax1)\n", "sns.lineplot( x='InstanceType', y='CostPerHour',data= df, ax=ax2)" ] } ], "metadata": { "instance_type": "ml.t3.medium", "kernelspec": { "display_name": "Python 3 (Data Science)", "language": "python", "name": "python3__SAGEMAKER_INTERNAL__arn:aws:sagemaker:us-west-2:236514542706:image/datascience-1.0" }, "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.7.10" } }, "nbformat": 4, "nbformat_minor": 4 }