{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Amazon SageMaker PreProcessing, Inferencing & PostProcessing with Your custom Machine Learning Code\n", "\n", "This Notebook demonstrates how to rapidly migrate your local custom Machine Learning code to AWS Cloud. \n", "With this example we illustrate how a custom`preprocess.py`, custom`predict.py`and custom`postprocess.py`scripts can be migrated to AWS without any changes to your code-base. With this approach you can rapidly embed your ML code into AWS ecosystem and take advantage of agility and scale offered by AWS SageMaker.\n", "\n", "*Please choose Python 3 (Data Science) kernel to proceed.*" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Setup\n", "To build Docker images inside SageMaker Studio we'll need *sm-docker* library which is part of **sagemaker_studio-image_build**. Let's get that package into our Notebook instance." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true, "tags": [] }, "outputs": [], "source": [ "#Install sagemaker_studio_image_build utility\n", "import sys\n", "\n", "!{sys.executable} -m pip install sagemaker_studio_image_build" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Review Dockerfile\n", "Docker is a program that performs operating system-level virtualization for installing, distributing, and managing software. It packages applications and their dependencies into virtual containers that provide isolation, portability, and security. With Docker, you can ship code faster, standardize application operations, seamlessly move code, and economize by improving resource utilization.\n", "\n", "For demonstration of this example **Dockerfile**, we will use python-slim base containers. We add the code that implements our specific inference code to the container and set up the right environment to run under using **requirements.txt**." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "!cd InferenceContainer\n", "!cat Dockerfile" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Perform Docker image build using **sm-docker** abstraction layer.\n", "\n", "The **sm-docker** command workflow contains the following steps:\n", "\n", "1. The CLI automatically zips the directory containing your Dockerfile, generates the buildspec for AWS CodeBuild, and adds the .zip package the final .zip file. By default, the final .zip package is put in the Amazon SageMaker default session S3 bucket. Alternatively, you can specify a custom bucket using the --bucket argument.\n", "2. After packaging your files for build, the CLI creates an ECR repository if one doesn’t exist. By default, the ECR repository created has the naming convention of sagemaker-studio-. The final step performed by the CLI is to create a temporary build project in CodeBuild and start the build, which builds your container image, tags it, and pushes it to the ECR repository.\n", " \n", "The great part about the CLI is you no longer have to set any of this up or worry about the underlying activities to easily build your container images from Amazon SageMaker Studio." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true, "tags": [] }, "outputs": [], "source": [ "%%sh\n", "\n", "sm-docker build . --repository legacycode:latest" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Initialize parameters used for SageMaker API calls\n", "\n", "Here we are capturing various parameters that will be later used by different Sagemaker API calls" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "import sagemaker\n", "import boto3\n", "\n", "session = sagemaker.Session()\n", "\n", "# Set a default S3 bucket\n", "default_bucket = session.default_bucket()\n", "\n", "# Get the region\n", "region = boto3.Session().region_name\n", "\n", "# Get the account\n", "account = session.boto_session.client('sts').get_caller_identity()['Account']\n", "\n", "# Get the SageMaker Execution Role\n", "role = sagemaker.get_execution_role()\n", "\n", "# Upload the input data and scripts into S3 bucket\n", "S3_prefix= \"legacycode2\"\n", "\n", "preprocessing_scripts_file= \"../preprocessing/preprocess.py\"\n", "scripts_location = session.upload_data(preprocessing_scripts_file, \n", " key_prefix=S3_prefix+\"/scripts\")\n", "\n", "postprocessing_scripts_file= \"../postprocessing/postprocess.py\"\n", "scripts_location = session.upload_data(postprocessing_scripts_file, \n", " key_prefix=S3_prefix+\"/scripts\")\n", "\n", "data_directory= \"../data\"\n", "input_location = session.upload_data(data_directory, \n", " key_prefix=S3_prefix+\"/data/preproc/input\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Pull the Amazon SageMaker *sklearn* pre-built docker image for processing job" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "from sagemaker import image_uris\n", "sklearn_image_uri=image_uris.retrieve(framework='sklearn',region=region,version='0.23-1',image_scope='training')\n", "print(sklearn_image_uri)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Configure SageMaker Processing Job for Data Pre-Processing Step\n", "\n", "Here is a sample configuration of Processing job. We are setting up the required arguments to trigger a SageMaker Processing Job. You will need to change the Input location based on your use-case to point to your specific input dataset. Here you'll notice we are using `preprocess.py` as our container entrypoint. This python script fill will have the data preprocessing logic." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "## Create pre-processing job in script mode job using the pre-built sci-kit learn container\n", "import os\n", "import json\n", "import boto3\n", "import time\n", "\n", "sm = boto3.client('sagemaker')\n", "\n", "# Define parameters\n", "instance_type = \"ml.m5.xlarge\"\n", "volume_size = 20\n", "max_runtime = 3600 # Default: 1h\n", "\n", "\n", "timestamp = time.strftime('%Y%m%d-%H%M%S')\n", "job_name = f'SM-Pre-Processing-Job-{timestamp}' \n", "\n", "\n", "#s3://sagemaker-us-west-2-123456789/legacycode1/scripts/data/preproc/input\n", "\n", "# Define inputs/outputs\n", "\n", "create_preprocessing_params = {\n", " \"ProcessingInputs\": [\n", " {\n", " 'InputName': 'input_data',\n", " 'S3Input': {\n", " 'S3Uri': \"s3://{}/{}/data/preproc/input\".format(default_bucket, S3_prefix),\n", " 'LocalPath': '/opt/ml/processing/input/data/',\n", " 'S3DataType': 'S3Prefix',\n", " 'S3InputMode': 'File'\n", " }\n", " },\n", " {\n", " 'InputName': 'scripts',\n", " 'S3Input': {\n", " 'S3Uri': \"s3://{}/{}/scripts\".format(default_bucket,S3_prefix),\n", " 'LocalPath': '/opt/ml/processing/input/scripts/',\n", " 'S3DataType': 'S3Prefix',\n", " 'S3InputMode': 'File'\n", " }\n", " }\n", " ],\n", " \"ProcessingOutputConfig\": {\n", " 'Outputs': [\n", " {\n", " 'OutputName': 'output_data',\n", " 'S3Output': {\n", " 'S3Uri': \"s3://{}/{}/data/predict/input\".format(default_bucket,S3_prefix),\n", " 'LocalPath': '/opt/ml/processing/output',\n", " 'S3UploadMode': 'EndOfJob'\n", " }\n", " }\n", " ]\n", " },\n", " \"ProcessingJobName\": job_name,\n", " \"ProcessingResources\": {\n", " 'ClusterConfig': {\n", " 'InstanceCount': 1,\n", " 'InstanceType': instance_type,\n", " 'VolumeSizeInGB': volume_size\n", " }\n", " },\n", " \"StoppingCondition\": {\n", " 'MaxRuntimeInSeconds': max_runtime\n", " },\n", " \"AppSpecification\": {\n", " 'ImageUri': sklearn_image_uri,\n", " 'ContainerEntrypoint': ['python',\"/opt/ml/processing/input/scripts/preprocess.py\"]\n", " },\n", " \"RoleArn\": role\n", "}\n", "# Create processing job and return job ARN\n", "sm.create_processing_job(**create_preprocessing_params)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Let's wait and monitor the processing Job to complete before proceeding to next steps\n", "The 3 steps (PreProcess, Inference & PostProcess) in this Notebook has inter-dependencies, so let's wait until each steps finishes." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "# confirm that the processing job has started & Wait before proceeding to next cells\n", "status = sm.describe_processing_job(ProcessingJobName=job_name)[\"ProcessingJobStatus\"]\n", "print(\"Processing Job {} current status: {}\".format(job_name, status))\n", "\n", "try:\n", " # wait for the job to finish and report the ending status\n", " sm.get_waiter(\"processing_job_completed_or_stopped\").wait(ProcessingJobName=job_name)\n", " processing_info = sm.describe_processing_job(ProcessingJobName=job_name)\n", " status = processing_info[\"ProcessingJobStatus\"]\n", " print(\"Processing Job {} ended with status: {} \".format(job_name, status))\n", "except:\n", " print(\"Processing Job {} failed to start\".format(job_name))\n", " # if exception is raised, that means it has failed\n", " message = sm.describe_processing_job(ProcessingJobName=job_name)[\"FailureReason\"]\n", " print(\"Processing failed with the following error: {}\".format(message))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Configure SageMaker Processing Job for Inference Step using the custom image\n", "\n", "Here is a sample configuration of Processing job used for inferencing. We are setting up the required arguments to trigger a SageMaker Processing Job. Here we are using the custom image that we build at the start of this notebook. You'll need to change the input dataset location to point to your batch input payload. The entrypoint script `predict.py` is the inference script that will read your input payload and run inference against your trained model." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "## Create processing job using the customer container built in the above cell\n", "import os\n", "import json\n", "import boto3\n", "import time\n", "from sagemaker import get_execution_role\n", "\n", "sm = boto3.client('sagemaker')\n", "\n", "\n", "# Get parameters\n", "image_uri = '{}.dkr.ecr.{}.amazonaws.com/legacycode:latest'.format(account, region)\n", "instance_type = \"ml.m5.xlarge\"\n", "volume_size = 20\n", "max_runtime = 3600 # Default: 1h\n", "entrypoint = \"/opt/ml/code/predict.py\"\n", "\n", "timestamp = time.strftime('%Y%m%d-%H%M%S')\n", "job_name = f'SM-Inference-Process-Job-{timestamp}' \n", "\n", "# Define inputs/outputs\n", "\n", "create_processing_params = {\n", " \"ProcessingInputs\": [\n", " {\n", " 'InputName': 'input_data',\n", " 'S3Input': {\n", " 'S3Uri': \"s3://{}/{}/data/predict/input\".format(default_bucket, S3_prefix),\n", " 'LocalPath': '/opt/ml/processing/input',\n", " 'S3DataType': 'S3Prefix',\n", " 'S3InputMode': 'File'\n", " }\n", " }\n", " ],\n", " \"ProcessingOutputConfig\": {\n", " 'Outputs': [\n", " {\n", " 'OutputName': 'output_data',\n", " 'S3Output': {\n", " 'S3Uri': \"s3://{}/{}/data/postproc/input\".format(default_bucket, S3_prefix),\n", " 'LocalPath': '/opt/ml/processing/output',\n", " 'S3UploadMode': 'EndOfJob'\n", " }\n", " }\n", " ]\n", " },\n", " \"ProcessingJobName\": job_name,\n", " \"ProcessingResources\": {\n", " 'ClusterConfig': {\n", " 'InstanceCount': 1,\n", " 'InstanceType': instance_type,\n", " 'VolumeSizeInGB': volume_size\n", " }\n", " },\n", " \"StoppingCondition\": {\n", " 'MaxRuntimeInSeconds': max_runtime\n", " },\n", " \"AppSpecification\": {\n", " 'ImageUri': image_uri,\n", " 'ContainerEntrypoint': ['python', entrypoint]\n", " },\n", " \"RoleArn\": role\n", "}\n", "# Create processing job and return job ARN\n", "sm.create_processing_job(**create_processing_params)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Let's wait and monitor the Inference Job to complete before proceeding to next steps\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "# confirm that the processing job has started & Wait before proceeding to next cells\n", "status = sm.describe_processing_job(ProcessingJobName=job_name)[\"ProcessingJobStatus\"]\n", "print(\"Processing Job {} current status: {}\".format(job_name, status))\n", "\n", "try:\n", " # wait for the job to finish and report the ending status\n", " sm.get_waiter(\"processing_job_completed_or_stopped\").wait(ProcessingJobName=job_name)\n", " processing_info = sm.describe_processing_job(ProcessingJobName=job_name)\n", " status = processing_info[\"ProcessingJobStatus\"]\n", " print(\"Processing Job {} ended with status: {} \".format(job_name, status))\n", "except:\n", " print(\"Processing Job {} failed to start\".format(job_name))\n", " # if exception is raised, that means it has failed\n", " message = sm.describe_processing_job(ProcessingJobName=job_name)[\"FailureReason\"]\n", " print(\"Processing failed with the following error: {}\".format(message))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Configure SageMaker Processing Job for post Processing Step\n", "\n", "Here is a sample configuration of Post-Processing job. We are setting up the required arguments to trigger a SageMaker Processing Job. You will need to change the Input location based on your use-case to point to your specific input dataset. Here you'll notice we are using `preprocess.py` as our container entrypoint. This python script fill will have the data post-processing logic." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "## Create post-processing job in script mode job using the pre-built sci-kit learn container\n", "import os\n", "import json\n", "import boto3\n", "import time\n", "from sagemaker import get_execution_role\n", "\n", "sm = boto3.client('sagemaker')\n", "\n", "# Define parameters\n", "instance_type = \"ml.m5.xlarge\"\n", "volume_size = 20\n", "max_runtime = 3600 # Default: 1h\n", "\n", "timestamp = time.strftime('%Y%m%d-%H%M%S')\n", "job_name = f'SM-Post-Processing-Job-{timestamp}' \n", "\n", "# Define inputs/outputs\n", "\n", "create_postprocessing_params = {\n", " \"ProcessingInputs\": [\n", " {\n", " 'InputName': 'input_data',\n", " 'S3Input': {\n", " 'S3Uri': \"s3://{}/{}/data/postproc/input\".format(default_bucket, S3_prefix),\n", " 'LocalPath': '/opt/ml/processing/input/data/',\n", " 'S3DataType': 'S3Prefix',\n", " 'S3InputMode': 'File'\n", " }\n", " },\n", " {\n", " 'InputName': 'scripts',\n", " 'S3Input': {\n", " 'S3Uri': \"s3://{}/{}/scripts\".format(default_bucket,S3_prefix),\n", " 'LocalPath': '/opt/ml/processing/input/scripts/',\n", " 'S3DataType': 'S3Prefix',\n", " 'S3InputMode': 'File'\n", " }\n", " }\n", " ],\n", " \"ProcessingOutputConfig\": {\n", " 'Outputs': [\n", " {\n", " 'OutputName': 'output_data',\n", " 'S3Output': {\n", " 'S3Uri': \"s3://{}/{}/data/postproc/output\".format(default_bucket, S3_prefix),\n", " 'LocalPath': '/opt/ml/processing/output',\n", " 'S3UploadMode': 'EndOfJob'\n", " }\n", " }\n", " ]\n", " },\n", " \"ProcessingJobName\": job_name,\n", " \"ProcessingResources\": {\n", " 'ClusterConfig': {\n", " 'InstanceCount': 1,\n", " 'InstanceType': instance_type,\n", " 'VolumeSizeInGB': volume_size\n", " }\n", " },\n", " \"StoppingCondition\": {\n", " 'MaxRuntimeInSeconds': max_runtime\n", " },\n", " \"AppSpecification\": {\n", " 'ImageUri': sklearn_image_uri,\n", " 'ContainerEntrypoint': ['python'],\n", " \"ContainerArguments\": [\n", " \"/opt/ml/processing/input/scripts/postprocess.py\"\n", " ]\n", " },\n", " \"RoleArn\": role\n", "}\n", "# Create processing job and return job ARN\n", "sm.create_processing_job(**create_postprocessing_params)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Let's wait and monitor the PostProcessing Job to complete before proceeding to next steps\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "# confirm that the processing job has started & Wait before proceeding to next cells\n", "status = sm.describe_processing_job(ProcessingJobName=job_name)[\"ProcessingJobStatus\"]\n", "print(\"Processing Job {} current status: {}\".format(job_name, status))\n", "\n", "try:\n", " # wait for the job to finish and report the ending status\n", " sm.get_waiter(\"processing_job_completed_or_stopped\").wait(ProcessingJobName=job_name)\n", " processing_info = sm.describe_processing_job(ProcessingJobName=job_name)\n", " status = processing_info[\"ProcessingJobStatus\"]\n", " print(\"Processing Job {} ended with status: {} \".format(job_name, status))\n", "except:\n", " print(\"Processing Job {} failed to start\".format(job_name))\n", " # if exception is raised, that means it has failed\n", " message = sm.describe_processing_job(ProcessingJobName=job_name)[\"FailureReason\"]\n", " print(\"Processing failed with the following error: {}\".format(message))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Here we show how to test your custom script locally on this Jupyter Notebook (Optional)\n", "\n", "First let's get the required packages needed to run our custom ML Script." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true, "tags": [] }, "outputs": [], "source": [ "#Install requirements locally\n", "!{sys.executable} -m pip install -r src/requirements.txt" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Once you have all the libraries in your Notebook environment, its as easy as calling `python` to run your script with local argument" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "#Test preprocess script locally\n", "!python ../preprocessing/preprocess.py local ../data/" ] } ], "metadata": { "availableInstances": [ { "_defaultOrder": 0, "_isFastLaunch": true, "category": "General purpose", "gpuNum": 0, "memoryGiB": 4, "name": "ml.t3.medium", "vcpuNum": 2 }, { "_defaultOrder": 1, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "memoryGiB": 8, "name": "ml.t3.large", "vcpuNum": 2 }, { "_defaultOrder": 2, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "memoryGiB": 16, "name": "ml.t3.xlarge", "vcpuNum": 4 }, { "_defaultOrder": 3, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "memoryGiB": 32, "name": "ml.t3.2xlarge", "vcpuNum": 8 }, { "_defaultOrder": 4, "_isFastLaunch": true, "category": "General purpose", "gpuNum": 0, "memoryGiB": 8, "name": "ml.m5.large", "vcpuNum": 2 }, { "_defaultOrder": 5, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "memoryGiB": 16, "name": "ml.m5.xlarge", "vcpuNum": 4 }, { "_defaultOrder": 6, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "memoryGiB": 32, "name": "ml.m5.2xlarge", "vcpuNum": 8 }, { "_defaultOrder": 7, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "memoryGiB": 64, "name": "ml.m5.4xlarge", "vcpuNum": 16 }, { "_defaultOrder": 8, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "memoryGiB": 128, "name": "ml.m5.8xlarge", "vcpuNum": 32 }, { "_defaultOrder": 9, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "memoryGiB": 192, "name": "ml.m5.12xlarge", "vcpuNum": 48 }, { "_defaultOrder": 10, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "memoryGiB": 256, "name": "ml.m5.16xlarge", "vcpuNum": 64 }, { "_defaultOrder": 11, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "memoryGiB": 384, "name": "ml.m5.24xlarge", "vcpuNum": 96 }, { "_defaultOrder": 12, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "memoryGiB": 8, "name": "ml.m5d.large", "vcpuNum": 2 }, { "_defaultOrder": 13, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "memoryGiB": 16, "name": "ml.m5d.xlarge", "vcpuNum": 4 }, { "_defaultOrder": 14, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "memoryGiB": 32, "name": "ml.m5d.2xlarge", "vcpuNum": 8 }, { "_defaultOrder": 15, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "memoryGiB": 64, "name": "ml.m5d.4xlarge", "vcpuNum": 16 }, { "_defaultOrder": 16, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "memoryGiB": 128, "name": "ml.m5d.8xlarge", "vcpuNum": 32 }, { "_defaultOrder": 17, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "memoryGiB": 192, "name": "ml.m5d.12xlarge", "vcpuNum": 48 }, { "_defaultOrder": 18, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "memoryGiB": 256, "name": "ml.m5d.16xlarge", "vcpuNum": 64 }, { "_defaultOrder": 19, "_isFastLaunch": false, "category": "General purpose", "gpuNum": 0, "memoryGiB": 384, "name": "ml.m5d.24xlarge", "vcpuNum": 96 }, { "_defaultOrder": 20, "_isFastLaunch": true, "category": "Compute optimized", "gpuNum": 0, "memoryGiB": 4, "name": "ml.c5.large", "vcpuNum": 2 }, { "_defaultOrder": 21, "_isFastLaunch": false, "category": "Compute optimized", "gpuNum": 0, "memoryGiB": 8, "name": "ml.c5.xlarge", "vcpuNum": 4 }, { "_defaultOrder": 22, "_isFastLaunch": false, "category": "Compute optimized", "gpuNum": 0, "memoryGiB": 16, "name": "ml.c5.2xlarge", "vcpuNum": 8 }, { "_defaultOrder": 23, "_isFastLaunch": false, "category": "Compute optimized", "gpuNum": 0, "memoryGiB": 32, "name": "ml.c5.4xlarge", "vcpuNum": 16 }, { "_defaultOrder": 24, "_isFastLaunch": false, "category": "Compute optimized", "gpuNum": 0, "memoryGiB": 72, "name": "ml.c5.9xlarge", "vcpuNum": 36 }, { "_defaultOrder": 25, "_isFastLaunch": false, "category": "Compute optimized", "gpuNum": 0, "memoryGiB": 96, "name": "ml.c5.12xlarge", "vcpuNum": 48 }, { "_defaultOrder": 26, "_isFastLaunch": false, "category": "Compute optimized", "gpuNum": 0, "memoryGiB": 144, "name": "ml.c5.18xlarge", "vcpuNum": 72 }, { "_defaultOrder": 27, "_isFastLaunch": false, "category": "Compute optimized", "gpuNum": 0, "memoryGiB": 192, "name": "ml.c5.24xlarge", "vcpuNum": 96 }, { "_defaultOrder": 28, "_isFastLaunch": true, "category": "Accelerated computing", "gpuNum": 1, "memoryGiB": 16, "name": "ml.g4dn.xlarge", "vcpuNum": 4 }, { "_defaultOrder": 29, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "memoryGiB": 32, "name": "ml.g4dn.2xlarge", "vcpuNum": 8 }, { "_defaultOrder": 30, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "memoryGiB": 64, "name": "ml.g4dn.4xlarge", "vcpuNum": 16 }, { "_defaultOrder": 31, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "memoryGiB": 128, "name": "ml.g4dn.8xlarge", "vcpuNum": 32 }, { "_defaultOrder": 32, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 4, "memoryGiB": 192, "name": "ml.g4dn.12xlarge", "vcpuNum": 48 }, { "_defaultOrder": 33, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "memoryGiB": 256, "name": "ml.g4dn.16xlarge", "vcpuNum": 64 }, { "_defaultOrder": 34, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "memoryGiB": 61, "name": "ml.p3.2xlarge", "vcpuNum": 8 }, { "_defaultOrder": 35, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 4, "memoryGiB": 244, "name": "ml.p3.8xlarge", "vcpuNum": 32 }, { "_defaultOrder": 36, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 8, "memoryGiB": 488, "name": "ml.p3.16xlarge", "vcpuNum": 64 }, { "_defaultOrder": 37, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 8, "memoryGiB": 768, "name": "ml.p3dn.24xlarge", "vcpuNum": 96 }, { "_defaultOrder": 38, "_isFastLaunch": false, "category": "Memory Optimized", "gpuNum": 0, "memoryGiB": 16, "name": "ml.r5.large", "vcpuNum": 2 }, { "_defaultOrder": 39, "_isFastLaunch": false, "category": "Memory Optimized", "gpuNum": 0, "memoryGiB": 32, "name": "ml.r5.xlarge", "vcpuNum": 4 }, { "_defaultOrder": 40, "_isFastLaunch": false, "category": "Memory Optimized", "gpuNum": 0, "memoryGiB": 64, "name": "ml.r5.2xlarge", "vcpuNum": 8 }, { "_defaultOrder": 41, "_isFastLaunch": false, "category": "Memory Optimized", "gpuNum": 0, "memoryGiB": 128, "name": "ml.r5.4xlarge", "vcpuNum": 16 }, { "_defaultOrder": 42, "_isFastLaunch": false, "category": "Memory Optimized", "gpuNum": 0, "memoryGiB": 256, "name": "ml.r5.8xlarge", "vcpuNum": 32 }, { "_defaultOrder": 43, "_isFastLaunch": false, "category": "Memory Optimized", "gpuNum": 0, "memoryGiB": 384, "name": "ml.r5.12xlarge", "vcpuNum": 48 }, { "_defaultOrder": 44, "_isFastLaunch": false, "category": "Memory Optimized", "gpuNum": 0, "memoryGiB": 512, "name": "ml.r5.16xlarge", "vcpuNum": 64 }, { "_defaultOrder": 45, "_isFastLaunch": false, "category": "Memory Optimized", "gpuNum": 0, "memoryGiB": 768, "name": "ml.r5.24xlarge", "vcpuNum": 96 }, { "_defaultOrder": 46, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "memoryGiB": 16, "name": "ml.g5.xlarge", "vcpuNum": 4 }, { "_defaultOrder": 47, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "memoryGiB": 32, "name": "ml.g5.2xlarge", "vcpuNum": 8 }, { "_defaultOrder": 48, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "memoryGiB": 64, "name": "ml.g5.4xlarge", "vcpuNum": 16 }, { "_defaultOrder": 49, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "memoryGiB": 128, "name": "ml.g5.8xlarge", "vcpuNum": 32 }, { "_defaultOrder": 50, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 1, "memoryGiB": 256, "name": "ml.g5.16xlarge", "vcpuNum": 64 }, { "_defaultOrder": 51, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 4, "memoryGiB": 192, "name": "ml.g5.12xlarge", "vcpuNum": 48 }, { "_defaultOrder": 52, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 4, "memoryGiB": 384, "name": "ml.g5.24xlarge", "vcpuNum": 96 }, { "_defaultOrder": 53, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 8, "memoryGiB": 768, "name": "ml.g5.48xlarge", "vcpuNum": 192 } ], "instance_type": "ml.t3.medium", "kernelspec": { "display_name": "Python 3 (Data Science)", "language": "python", "name": "python3__SAGEMAKER_INTERNAL__arn:aws:sagemaker:us-east-1:081325390199: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 }