)]\n"
]
}
],
"source": [
"from sagemaker.feature_store.feature_definition import FeatureDefinition\n",
"from sagemaker.feature_store.feature_definition import FeatureTypeEnum\n",
"\n",
"default_feature_type = FeatureTypeEnum.STRING\n",
"column_to_feature_type_mapping = {\n",
" \"float\": FeatureTypeEnum.FRACTIONAL,\n",
" \"long\": FeatureTypeEnum.INTEGRAL\n",
"}\n",
"\n",
"feature_definitions = [\n",
" FeatureDefinition(\n",
" feature_name=column_schema['name'], \n",
" feature_type=column_to_feature_type_mapping.get(column_schema['type'], default_feature_type)\n",
" ) for column_schema in column_schemas\n",
"]\n",
"logger.info(f'feature definitions: {feature_definitions}')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Configure Feature Group\n",
"\n",
" 💡 Configurable Settings \n",
"\n",
"1. feature_group_name: name of the feature group.\n",
"1. feature_store_offline_s3_uri: SageMaker FeatureStore writes the data in the OfflineStore of a FeatureGroup to a S3 location owned by you.\n",
"1. enable_online_store: controls if online store is enabled. Enabling the online store allows quick access to the latest value for a Record via the GetRecord API.\n",
"1. iam_role: IAM role for executing the processing job.\n",
"1. table_format: Amazon SageMaker Feature Store supports the AWS Glue and Apache Iceberg table formats for the offline store. \n",
"
"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"# Calculate current_timestamp to create unique entries\n",
"current_timestamp = strftime('%m-%d-%H-%M-%S', gmtime())"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Feature Group Name: fscw-orders-03-30-19-21-40\n"
]
}
],
"source": [
"# flow name and an unique ID for this export (used later as the processing job name for the export)\n",
"flow_name = \"orders\"\n",
"flow_export_name = f'DWF-Orders'\n",
"\n",
"# feature group name, with flow_name and an unique id. You can give it a customized name\n",
"feature_group_name = f\"{fs_champions_workshop_prefix}-{flow_name}-{current_timestamp}\"\n",
"logger.info(f'Feature Group Name: {feature_group_name}')\n",
"\n",
"# SageMaker FeatureStore writes the data in the OfflineStore of a FeatureGroup to a \n",
"# S3 location owned by you.\n",
"feature_store_offline_s3_uri = 's3://' + bucket\n",
"\n",
"# controls if online store is enabled. Enabling the online store allows quick access to \n",
"# the latest value for a Record via the GetRecord API.\n",
"enable_online_store = True"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Initialize Feature Group"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"# Initialize Boto3 session that is required to create feature group\n",
"import boto3\n",
"from sagemaker.session import Session\n",
"\n",
"region = boto3.Session().region_name\n",
"boto_session = boto3.Session(region_name=region)\n",
"\n",
"sagemaker_client = boto_session.client(service_name='sagemaker', region_name=region)\n",
"featurestore_runtime = boto_session.client(service_name='sagemaker-featurestore-runtime', region_name=region)\n",
"\n",
"feature_store_session = Session(\n",
" boto_session=boto_session,\n",
" sagemaker_client=sagemaker_client,\n",
" sagemaker_featurestore_runtime_client=featurestore_runtime\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Feature Group Name: fscw-orders-03-30-17-02\n",
"Create Feature Group: False\n"
]
}
],
"source": [
"#Check if we use the persisted feature store name or create a new one\n",
"if orders_feature_group_name is None:\n",
" create_new_feature_group = True\n",
"elif create_new_feature_group is False:\n",
" feature_group_name = orders_feature_group_name \n",
"\n",
"logger.info(f'Feature Group Name: {feature_group_name}')\n",
"logger.info(f'Create Feature Group: {create_new_feature_group}')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Feature group is initialized and created below"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"from sagemaker.feature_store.feature_group import FeatureGroup\n",
"from sagemaker.feature_store.inputs import TableFormatEnum\n",
"\n",
"if create_new_feature_group is True:\n",
" feature_group = FeatureGroup(\n",
" name=feature_group_name, sagemaker_session=feature_store_session, feature_definitions=feature_definitions)\n",
"\n",
" feature_group.create(\n",
" s3_uri=feature_store_offline_s3_uri,\n",
" record_identifier_name=record_identifier_feature_name,\n",
" event_time_feature_name=event_time_feature_name,\n",
" role_arn=iam_role,\n",
" enable_online_store=enable_online_store,\n",
" table_format=TableFormatEnum.ICEBERG # or GLUE\n",
" )"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Invoke the Feature Store API to create the feature group and wait until it is ready"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"import time\n",
"def wait_for_feature_group_creation_complete(feature_group):\n",
" \"\"\"Helper function to wait for the completions of creating a feature group\"\"\"\n",
" status = feature_group.describe().get(\"FeatureGroupStatus\")\n",
" while status == \"Creating\":\n",
" print(\"Waiting for Feature Group Creation\")\n",
" time.sleep(5)\n",
" status = feature_group.describe().get(\"FeatureGroupStatus\")\n",
" if status != \"Created\":\n",
" raise SystemExit(f\"Failed to create feature group {feature_group.name}: {status}\")\n",
" print(f\"FeatureGroup {feature_group.name} successfully created.\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Create Feature Group"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"if create_new_feature_group is True:\n",
" wait_for_feature_group_creation_complete(feature_group=feature_group)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now that the feature group is created, You will use a processing job to process your \n",
" data at scale and ingest the transformed data into this feature group."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Verify created or existing feature group"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'FeatureGroupArn': 'arn:aws:sagemaker:us-west-2:227246955871:feature-group/fscw-orders-03-30-17-02', 'FeatureGroupName': 'fscw-orders-03-30-17-02', 'RecordIdentifierFeatureName': 'order_id', 'EventTimeFeatureName': 'event_time', 'FeatureDefinitions': [{'FeatureName': 'order_id', 'FeatureType': 'String'}, {'FeatureName': 'customer_id', 'FeatureType': 'String'}, {'FeatureName': 'product_id', 'FeatureType': 'String'}, {'FeatureName': 'purchase_amount', 'FeatureType': 'Fractional'}, {'FeatureName': 'is_reordered', 'FeatureType': 'Integral'}, {'FeatureName': 'event_time', 'FeatureType': 'String'}, {'FeatureName': 'n_days_since_last_purchase', 'FeatureType': 'Fractional'}], 'CreationTime': datetime.datetime(2023, 3, 30, 17, 2, 46, 972000, tzinfo=tzlocal()), 'OnlineStoreConfig': {'EnableOnlineStore': True}, 'OfflineStoreConfig': {'S3StorageConfig': {'S3Uri': 's3://sagemaker-us-west-2-227246955871/sagemaker-feature-store', 'ResolvedOutputS3Uri': 's3://sagemaker-us-west-2-227246955871/sagemaker-feature-store/227246955871/sagemaker/us-west-2/offline-store/fscw-orders-03-30-17-02-1680195766/data'}, 'DisableGlueTableCreation': False, 'DataCatalogConfig': {'TableName': 'fscw_orders_03_30_17_02_1680195766', 'Catalog': 'AwsDataCatalog', 'Database': 'SageMaker_FeatureStore'}, 'TableFormat': 'Iceberg'}, 'RoleArn': 'arn:aws:iam::227246955871:role/service-role/AmazonSageMaker-ExecutionRole-20220810T165739', 'FeatureGroupStatus': 'Created', 'OfflineStoreStatus': {'Status': 'Active'}, 'OnlineStoreTotalSizeBytes': 0, 'ResponseMetadata': {'RequestId': 'c71bea09-f8f8-40c0-98a0-2447935aa952', 'HTTPStatusCode': 200, 'HTTPHeaders': {'x-amzn-requestid': 'c71bea09-f8f8-40c0-98a0-2447935aa952', 'content-type': 'application/x-amz-json-1.1', 'content-length': '1862', 'date': 'Thu, 30 Mar 2023 19:21:56 GMT'}, 'RetryAttempts': 0}}\n"
]
}
],
"source": [
"# Use Describe command to get the details of the feature group\n",
"response = sagemaker_client.describe_feature_group(FeatureGroupName = feature_group_name)\n",
"print(response)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Creating a workflow using Data Wrangler (OPTIONAL)\n",
"[SKIP this section](#Inputs-and-Outputs)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### ** BEGIN **\n",
"\n",
"##### Follow the below steps to create the dwf-orders.flow using Data Wrangler (DW)\n",
"\n",
" #### 1. Please follow these steps for Opening DW \n",
""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
" #### 2. Please follow these steps to open S3 as your source. \n",
""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
" #### 3. Please follow these steps to navigate to the desired S3 bucket/folder path to import the dataset from your source. \n",
" "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
" #### 4. Please follow these steps to add a 'Transform' to your imported dataset. \n",
"\n",
" "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
" #### 5. Please follow these steps to navigate to the desired transform to apply to a source column. \n",
" \n",
" "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
" #### 6. Please follow these steps to 'Export' the created workflow to create a notebook that would ingest the data in to a feature store.. \n",
"\n",
" "
]
},
{
"attachments": {
"image.png": {
"image/png": "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"
}
},
"cell_type": "markdown",
"metadata": {},
"source": [
" #### A notebook is generated as shown below \n",
"\n",
" "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
" #### 7. Please follow these steps to copy the value from the Output name variable (as shown below) that is auto-generated from the selected node's ID from the flowfile. \n",
"\n",
" "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
" #### 8. Please follow these steps to navigate to 'Save As' option to rename the Workflow file to 'orders.flow' \n",
" \n",
" \n",
" "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## ** END ** Creating a workflow using Data Wrangler (OPTIONAL)\n",
"\n",
"\n",
"\n",
"\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Inputs and Outputs\n",
"\n",
"The below settings configure the inputs and outputs for the flow export.\n",
"\n",
" 💡 Configurable Settings \n",
"\n",
"In Input - Source you can configure the data sources that will be used as input by Data Wrangler\n",
"\n",
"1. For S3 sources, configure the source attribute that points to the input S3 prefixes\n",
"2. For all other sources, configure attributes like query_string, database in the source's \n",
"DatasetDefinition object.\n",
"\n",
"If you modify the inputs the provided data must have the same schema and format as the data used in the Flow. \n",
"You should also re-execute the cells in this section if you have modified the settings in any data sources.\n",
"
"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from sagemaker.processing import ProcessingInput, ProcessingOutput\n",
"from sagemaker.dataset_definition.inputs import AthenaDatasetDefinition, DatasetDefinition, RedshiftDatasetDefinition\n",
"\n",
"data_sources = []"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Input: S3 Source: orders.csv"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"ordersfilename='orders.csv'\n",
"# You can override this to point to other dataset on S3\n",
"orders_datasource = f'{bucketlocation}{ordersfilename}'\n",
"%store orders_datasource\n",
"print(f\"Data source: {orders_datasource}\")\n",
"\n",
"data_sources.append(ProcessingInput(\n",
" source=orders_datasource, \n",
" destination=f'/opt/ml/processing/{ordersfilename}',\n",
" input_name=ordersfilename,\n",
" s3_data_type=\"S3Prefix\",\n",
" s3_input_mode=\"File\",\n",
" s3_data_distribution_type=\"FullyReplicated\"\n",
"))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Output: Feature Store \n",
"\n",
"##### Use the link below if you want to go back and create a Data Wrangler flow\n",
"[Create Data Wrangler Workflow](#Creating-a-workflow-using-Data-Wrangler-(OPTIONAL))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Below are the inputs required by the SageMaker Python SDK to launch a processing job with feature store as an output."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"
Warning!!!
\n",
"
The output_name variable shown below should be configured only if you created you own flow file using Data Wrangler and have overwritten the original file.
\n",
"
Use the value copied from Step-7 of the process used to create the DW flow.
\n",
"
"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Output name is auto-generated from the select node's ID + output name from the flow file.\n",
"output_name = None #Use the Node ID from the provided DW flow file.\n",
"if output_name is None: \n",
" output_name = \"739f8413-3a63-42c3-99a0-fa678a68c2d6.default\"\n",
"logger.info(f'output_name = {output_name}')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from sagemaker.processing import FeatureStoreOutput\n",
"\n",
"processing_job_output = ProcessingOutput(\n",
" output_name=output_name,\n",
" app_managed=True,\n",
" feature_store_output=FeatureStoreOutput(feature_group_name=feature_group_name),\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Upload Flow to S3\n",
"\n",
"To use the Data Wrangler as an input to the processing job, first upload your flow file to Amazon S3."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"import json\n",
"import boto3\n",
"\n",
"# name of the flow file which should exist in the current notebook working directory\n",
"flow_file_name = f'{flow_name}.flow'\n",
"\n",
"# Load .flow file from current notebook working directory \n",
"!echo \"Loading flow file from current notebook working directory: $PWD\"\n",
"\n",
"#Read file from current notebook working directory\n",
"with open(flow_file_name) as f:\n",
" flow = json.load(f)\n",
"\n",
"# Upload flow to S3\n",
"s3_client = boto3.client(\"s3\")\n",
"orders_flow_file=f'{workshopfolder}data_wrangler_flows/{flow_export_name}.flow'\n",
"s3_client.upload_file(flow_file_name, bucket, orders_flow_file)\n",
"flow_s3_uri = f's3://{bucket}/{orders_flow_file}'\n",
"print(f\"Data Wrangler flow {flow_file_name} uploaded to {flow_s3_uri}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The Data Wrangler Flow is also provided to the Processing Job as an input source which we configure below."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"## Input - Flow: DWF-Orders.flow\n",
"flow_input = ProcessingInput(\n",
" source=flow_s3_uri,\n",
" destination=\"/opt/ml/processing/flow\",\n",
" input_name=\"flow\",\n",
" s3_data_type=\"S3Prefix\",\n",
" s3_input_mode=\"File\",\n",
" s3_data_distribution_type=\"FullyReplicated\"\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Run Processing Job \n",
"## Job Configurations\n",
"\n",
" 💡 Configurable Settings \n",
"\n",
"You can configure the following settings for Processing Jobs. If you change any configurations you will \n",
"need to re-execute this and all cells below it by selecting the Run menu above and click \n",
"Run Selected Cells and All Below\n",
"\n",
"1. IAM role for executing the processing job. \n",
"2. A unique name of the processing job. Give a unique name every time you re-execute processing jobs\n",
"3. Data Wrangler Container URL.\n",
"4. Instance count, instance type and storage volume size in GB.\n",
"5. Content type for each output. Data Wrangler supports CSV as default and Parquet.\n",
"6. Network Isolation settings\n",
"
"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import uuid\n",
"\n",
"# IAM role for executing the processing job.\n",
"iam_role = sagemaker.get_execution_role()\n",
"\n",
"# Unique processing job name. Give a unique name every time you re-execute processing jobs\n",
"flow_export_id = f\"{strftime('%d-%H-%M-%S', gmtime())}-{str(uuid.uuid4())[:8]}\"\n",
"processing_job_name = f\"data-wrangler-flow-processing-{flow_export_id}\"\n",
"print(f\"Processing job name: {processing_job_name}\")\n",
"%store processing_job_name\n",
"\n",
"# Data Wrangler Container URL.\n",
"container_id = get_container(region)\n",
"print(f\"container_id: {container_id}\")\n",
"container_uri = f'{container_id}.dkr.ecr.{region}.amazonaws.com/sagemaker-data-wrangler-container:1.x'\n",
"print(f\"container_uri: {container_uri}\")\n",
"\n",
"# Processing Job Instance count and instance type.\n",
"instance_count = 2\n",
"instance_type = \"ml.m5.4xlarge\"\n",
"\n",
"# Size in GB of the EBS volume to use for storing data during processing\n",
"volume_size_in_gb = 30\n",
"\n",
"# Content type for each output. Data Wrangler supports CSV as default and Parquet.\n",
"output_content_type = \"CSV\"\n",
"\n",
"# Network Isolation mode; default is off\n",
"enable_network_isolation = False\n",
"\n",
"# Output configuration used as processing job container arguments \n",
"output_config = {\n",
" output_name: {\n",
" \"content_type\": output_content_type\n",
" }\n",
"}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Create and Execute Processing Job\n",
"\n",
"To launch a Processing Job, you will use the SageMaker Python SDK to create a Processor function."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from sagemaker.processing import Processor\n",
"from sagemaker.network import NetworkConfig\n",
"\n",
"processor = Processor(\n",
" role=iam_role,\n",
" image_uri=container_uri,\n",
" instance_count=instance_count,\n",
" instance_type=instance_type,\n",
" volume_size_in_gb=volume_size_in_gb,\n",
" network_config=NetworkConfig(enable_network_isolation=enable_network_isolation),\n",
" sagemaker_session=sess\n",
")\n",
"\n",
"# Start Job\n",
"processor.run(\n",
" inputs=[flow_input] + data_sources, \n",
" outputs=[processing_job_output],\n",
" arguments=[f\"--output-config '{json.dumps(output_config)}'\"],\n",
" wait=False,\n",
" logs=False,\n",
" job_name=processing_job_name\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Job Status\n",
"\n",
"Below you wait for processing job to finish. If it finishes successfully, your feature group should be populated \n",
"with transformed feature values. In addition the raw parameters used by the Processing Job will be printed."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"job_result = sess.wait_for_processing_job(processing_job_name)\n",
"logger.info(f'Job result={job_result}') "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can check the status of your processing job as shown below. In case of errors, the log can be very helpful to debug.\n",
"\n",
""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Verify Processing Job Results"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import random\n",
"\n",
"order_id = f'O{random.randint(1, 5000)}'\n",
"logger.info(f\"order_id={order_id}\") \n",
"\n",
"featurestore_runtime_client = sess.boto_session.client('sagemaker-featurestore-runtime', region_name=region)\n",
"# Verify Processing Job Results by querying Feature Store\n",
"feature_record = featurestore_runtime_client.get_record(FeatureGroupName=feature_group_name, RecordIdentifierValueAsString=order_id)\n",
"logger.info(f\"Feature Record={feature_record}\") "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Storing Variable Values"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Storing the values of the Orders Feature Groupname and DW outputname\n",
"%store output_name\n",
"%store feature_group_name\n",
"processing_job = sagemaker.processing.ProcessingJob.from_processing_name(sess, processing_job_name)\n",
"processing_job_description = processing_job.describe()\n",
"%store processing_job_description\n",
"# These variables will be used by Module-6 & Module-8"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can view newly created feature group in Studio, refer to [Use Amazon SageMaker Feature Store with Amazon SageMaker Studio](https://docs.aws.amazon.com/sagemaker/latest/dg/feature-store-use-with-studio.html)\n",
"for detailed guide. [Learn more about SageMaker Feature Store](https://github.com/aws/amazon-sagemaker-examples/tree/master/sagemaker-featurestore)"
]
}
],
"metadata": {
"availableInstances": [
{
"_defaultOrder": 0,
"_isFastLaunch": true,
"category": "General purpose",
"gpuNum": 0,
"hideHardwareSpecs": false,
"memoryGiB": 4,
"name": "ml.t3.medium",
"vcpuNum": 2
},
{
"_defaultOrder": 1,
"_isFastLaunch": false,
"category": "General purpose",
"gpuNum": 0,
"hideHardwareSpecs": false,
"memoryGiB": 8,
"name": "ml.t3.large",
"vcpuNum": 2
},
{
"_defaultOrder": 2,
"_isFastLaunch": false,
"category": "General purpose",
"gpuNum": 0,
"hideHardwareSpecs": false,
"memoryGiB": 16,
"name": "ml.t3.xlarge",
"vcpuNum": 4
},
{
"_defaultOrder": 3,
"_isFastLaunch": false,
"category": "General purpose",
"gpuNum": 0,
"hideHardwareSpecs": false,
"memoryGiB": 32,
"name": "ml.t3.2xlarge",
"vcpuNum": 8
},
{
"_defaultOrder": 4,
"_isFastLaunch": true,
"category": "General purpose",
"gpuNum": 0,
"hideHardwareSpecs": false,
"memoryGiB": 8,
"name": "ml.m5.large",
"vcpuNum": 2
},
{
"_defaultOrder": 5,
"_isFastLaunch": false,
"category": "General purpose",
"gpuNum": 0,
"hideHardwareSpecs": false,
"memoryGiB": 16,
"name": "ml.m5.xlarge",
"vcpuNum": 4
},
{
"_defaultOrder": 6,
"_isFastLaunch": false,
"category": "General purpose",
"gpuNum": 0,
"hideHardwareSpecs": false,
"memoryGiB": 32,
"name": "ml.m5.2xlarge",
"vcpuNum": 8
},
{
"_defaultOrder": 7,
"_isFastLaunch": false,
"category": "General purpose",
"gpuNum": 0,
"hideHardwareSpecs": false,
"memoryGiB": 64,
"name": "ml.m5.4xlarge",
"vcpuNum": 16
},
{
"_defaultOrder": 8,
"_isFastLaunch": false,
"category": "General purpose",
"gpuNum": 0,
"hideHardwareSpecs": false,
"memoryGiB": 128,
"name": "ml.m5.8xlarge",
"vcpuNum": 32
},
{
"_defaultOrder": 9,
"_isFastLaunch": false,
"category": "General purpose",
"gpuNum": 0,
"hideHardwareSpecs": false,
"memoryGiB": 192,
"name": "ml.m5.12xlarge",
"vcpuNum": 48
},
{
"_defaultOrder": 10,
"_isFastLaunch": false,
"category": "General purpose",
"gpuNum": 0,
"hideHardwareSpecs": false,
"memoryGiB": 256,
"name": "ml.m5.16xlarge",
"vcpuNum": 64
},
{
"_defaultOrder": 11,
"_isFastLaunch": false,
"category": "General purpose",
"gpuNum": 0,
"hideHardwareSpecs": false,
"memoryGiB": 384,
"name": "ml.m5.24xlarge",
"vcpuNum": 96
},
{
"_defaultOrder": 12,
"_isFastLaunch": false,
"category": "General purpose",
"gpuNum": 0,
"hideHardwareSpecs": false,
"memoryGiB": 8,
"name": "ml.m5d.large",
"vcpuNum": 2
},
{
"_defaultOrder": 13,
"_isFastLaunch": false,
"category": "General purpose",
"gpuNum": 0,
"hideHardwareSpecs": false,
"memoryGiB": 16,
"name": "ml.m5d.xlarge",
"vcpuNum": 4
},
{
"_defaultOrder": 14,
"_isFastLaunch": false,
"category": "General purpose",
"gpuNum": 0,
"hideHardwareSpecs": false,
"memoryGiB": 32,
"name": "ml.m5d.2xlarge",
"vcpuNum": 8
},
{
"_defaultOrder": 15,
"_isFastLaunch": false,
"category": "General purpose",
"gpuNum": 0,
"hideHardwareSpecs": false,
"memoryGiB": 64,
"name": "ml.m5d.4xlarge",
"vcpuNum": 16
},
{
"_defaultOrder": 16,
"_isFastLaunch": false,
"category": "General purpose",
"gpuNum": 0,
"hideHardwareSpecs": false,
"memoryGiB": 128,
"name": "ml.m5d.8xlarge",
"vcpuNum": 32
},
{
"_defaultOrder": 17,
"_isFastLaunch": false,
"category": "General purpose",
"gpuNum": 0,
"hideHardwareSpecs": false,
"memoryGiB": 192,
"name": "ml.m5d.12xlarge",
"vcpuNum": 48
},
{
"_defaultOrder": 18,
"_isFastLaunch": false,
"category": "General purpose",
"gpuNum": 0,
"hideHardwareSpecs": false,
"memoryGiB": 256,
"name": "ml.m5d.16xlarge",
"vcpuNum": 64
},
{
"_defaultOrder": 19,
"_isFastLaunch": false,
"category": "General purpose",
"gpuNum": 0,
"hideHardwareSpecs": false,
"memoryGiB": 384,
"name": "ml.m5d.24xlarge",
"vcpuNum": 96
},
{
"_defaultOrder": 20,
"_isFastLaunch": false,
"category": "General purpose",
"gpuNum": 0,
"hideHardwareSpecs": true,
"memoryGiB": 0,
"name": "ml.geospatial.interactive",
"supportedImageNames": [
"sagemaker-geospatial-v1-0"
],
"vcpuNum": 0
},
{
"_defaultOrder": 21,
"_isFastLaunch": true,
"category": "Compute optimized",
"gpuNum": 0,
"hideHardwareSpecs": false,
"memoryGiB": 4,
"name": "ml.c5.large",
"vcpuNum": 2
},
{
"_defaultOrder": 22,
"_isFastLaunch": false,
"category": "Compute optimized",
"gpuNum": 0,
"hideHardwareSpecs": false,
"memoryGiB": 8,
"name": "ml.c5.xlarge",
"vcpuNum": 4
},
{
"_defaultOrder": 23,
"_isFastLaunch": false,
"category": "Compute optimized",
"gpuNum": 0,
"hideHardwareSpecs": false,
"memoryGiB": 16,
"name": "ml.c5.2xlarge",
"vcpuNum": 8
},
{
"_defaultOrder": 24,
"_isFastLaunch": false,
"category": "Compute optimized",
"gpuNum": 0,
"hideHardwareSpecs": false,
"memoryGiB": 32,
"name": "ml.c5.4xlarge",
"vcpuNum": 16
},
{
"_defaultOrder": 25,
"_isFastLaunch": false,
"category": "Compute optimized",
"gpuNum": 0,
"hideHardwareSpecs": false,
"memoryGiB": 72,
"name": "ml.c5.9xlarge",
"vcpuNum": 36
},
{
"_defaultOrder": 26,
"_isFastLaunch": false,
"category": "Compute optimized",
"gpuNum": 0,
"hideHardwareSpecs": false,
"memoryGiB": 96,
"name": "ml.c5.12xlarge",
"vcpuNum": 48
},
{
"_defaultOrder": 27,
"_isFastLaunch": false,
"category": "Compute optimized",
"gpuNum": 0,
"hideHardwareSpecs": false,
"memoryGiB": 144,
"name": "ml.c5.18xlarge",
"vcpuNum": 72
},
{
"_defaultOrder": 28,
"_isFastLaunch": false,
"category": "Compute optimized",
"gpuNum": 0,
"hideHardwareSpecs": false,
"memoryGiB": 192,
"name": "ml.c5.24xlarge",
"vcpuNum": 96
},
{
"_defaultOrder": 29,
"_isFastLaunch": true,
"category": "Accelerated computing",
"gpuNum": 1,
"hideHardwareSpecs": false,
"memoryGiB": 16,
"name": "ml.g4dn.xlarge",
"vcpuNum": 4
},
{
"_defaultOrder": 30,
"_isFastLaunch": false,
"category": "Accelerated computing",
"gpuNum": 1,
"hideHardwareSpecs": false,
"memoryGiB": 32,
"name": "ml.g4dn.2xlarge",
"vcpuNum": 8
},
{
"_defaultOrder": 31,
"_isFastLaunch": false,
"category": "Accelerated computing",
"gpuNum": 1,
"hideHardwareSpecs": false,
"memoryGiB": 64,
"name": "ml.g4dn.4xlarge",
"vcpuNum": 16
},
{
"_defaultOrder": 32,
"_isFastLaunch": false,
"category": "Accelerated computing",
"gpuNum": 1,
"hideHardwareSpecs": false,
"memoryGiB": 128,
"name": "ml.g4dn.8xlarge",
"vcpuNum": 32
},
{
"_defaultOrder": 33,
"_isFastLaunch": false,
"category": "Accelerated computing",
"gpuNum": 4,
"hideHardwareSpecs": false,
"memoryGiB": 192,
"name": "ml.g4dn.12xlarge",
"vcpuNum": 48
},
{
"_defaultOrder": 34,
"_isFastLaunch": false,
"category": "Accelerated computing",
"gpuNum": 1,
"hideHardwareSpecs": false,
"memoryGiB": 256,
"name": "ml.g4dn.16xlarge",
"vcpuNum": 64
},
{
"_defaultOrder": 35,
"_isFastLaunch": false,
"category": "Accelerated computing",
"gpuNum": 1,
"hideHardwareSpecs": false,
"memoryGiB": 61,
"name": "ml.p3.2xlarge",
"vcpuNum": 8
},
{
"_defaultOrder": 36,
"_isFastLaunch": false,
"category": "Accelerated computing",
"gpuNum": 4,
"hideHardwareSpecs": false,
"memoryGiB": 244,
"name": "ml.p3.8xlarge",
"vcpuNum": 32
},
{
"_defaultOrder": 37,
"_isFastLaunch": false,
"category": "Accelerated computing",
"gpuNum": 8,
"hideHardwareSpecs": false,
"memoryGiB": 488,
"name": "ml.p3.16xlarge",
"vcpuNum": 64
},
{
"_defaultOrder": 38,
"_isFastLaunch": false,
"category": "Accelerated computing",
"gpuNum": 8,
"hideHardwareSpecs": false,
"memoryGiB": 768,
"name": "ml.p3dn.24xlarge",
"vcpuNum": 96
},
{
"_defaultOrder": 39,
"_isFastLaunch": false,
"category": "Memory Optimized",
"gpuNum": 0,
"hideHardwareSpecs": false,
"memoryGiB": 16,
"name": "ml.r5.large",
"vcpuNum": 2
},
{
"_defaultOrder": 40,
"_isFastLaunch": false,
"category": "Memory Optimized",
"gpuNum": 0,
"hideHardwareSpecs": false,
"memoryGiB": 32,
"name": "ml.r5.xlarge",
"vcpuNum": 4
},
{
"_defaultOrder": 41,
"_isFastLaunch": false,
"category": "Memory Optimized",
"gpuNum": 0,
"hideHardwareSpecs": false,
"memoryGiB": 64,
"name": "ml.r5.2xlarge",
"vcpuNum": 8
},
{
"_defaultOrder": 42,
"_isFastLaunch": false,
"category": "Memory Optimized",
"gpuNum": 0,
"hideHardwareSpecs": false,
"memoryGiB": 128,
"name": "ml.r5.4xlarge",
"vcpuNum": 16
},
{
"_defaultOrder": 43,
"_isFastLaunch": false,
"category": "Memory Optimized",
"gpuNum": 0,
"hideHardwareSpecs": false,
"memoryGiB": 256,
"name": "ml.r5.8xlarge",
"vcpuNum": 32
},
{
"_defaultOrder": 44,
"_isFastLaunch": false,
"category": "Memory Optimized",
"gpuNum": 0,
"hideHardwareSpecs": false,
"memoryGiB": 384,
"name": "ml.r5.12xlarge",
"vcpuNum": 48
},
{
"_defaultOrder": 45,
"_isFastLaunch": false,
"category": "Memory Optimized",
"gpuNum": 0,
"hideHardwareSpecs": false,
"memoryGiB": 512,
"name": "ml.r5.16xlarge",
"vcpuNum": 64
},
{
"_defaultOrder": 46,
"_isFastLaunch": false,
"category": "Memory Optimized",
"gpuNum": 0,
"hideHardwareSpecs": false,
"memoryGiB": 768,
"name": "ml.r5.24xlarge",
"vcpuNum": 96
},
{
"_defaultOrder": 47,
"_isFastLaunch": false,
"category": "Accelerated computing",
"gpuNum": 1,
"hideHardwareSpecs": false,
"memoryGiB": 16,
"name": "ml.g5.xlarge",
"vcpuNum": 4
},
{
"_defaultOrder": 48,
"_isFastLaunch": false,
"category": "Accelerated computing",
"gpuNum": 1,
"hideHardwareSpecs": false,
"memoryGiB": 32,
"name": "ml.g5.2xlarge",
"vcpuNum": 8
},
{
"_defaultOrder": 49,
"_isFastLaunch": false,
"category": "Accelerated computing",
"gpuNum": 1,
"hideHardwareSpecs": false,
"memoryGiB": 64,
"name": "ml.g5.4xlarge",
"vcpuNum": 16
},
{
"_defaultOrder": 50,
"_isFastLaunch": false,
"category": "Accelerated computing",
"gpuNum": 1,
"hideHardwareSpecs": false,
"memoryGiB": 128,
"name": "ml.g5.8xlarge",
"vcpuNum": 32
},
{
"_defaultOrder": 51,
"_isFastLaunch": false,
"category": "Accelerated computing",
"gpuNum": 1,
"hideHardwareSpecs": false,
"memoryGiB": 256,
"name": "ml.g5.16xlarge",
"vcpuNum": 64
},
{
"_defaultOrder": 52,
"_isFastLaunch": false,
"category": "Accelerated computing",
"gpuNum": 4,
"hideHardwareSpecs": false,
"memoryGiB": 192,
"name": "ml.g5.12xlarge",
"vcpuNum": 48
},
{
"_defaultOrder": 53,
"_isFastLaunch": false,
"category": "Accelerated computing",
"gpuNum": 4,
"hideHardwareSpecs": false,
"memoryGiB": 384,
"name": "ml.g5.24xlarge",
"vcpuNum": 96
},
{
"_defaultOrder": 54,
"_isFastLaunch": false,
"category": "Accelerated computing",
"gpuNum": 8,
"hideHardwareSpecs": false,
"memoryGiB": 768,
"name": "ml.g5.48xlarge",
"vcpuNum": 192
}
],
"instance_type": "ml.t3.medium",
"kernelspec": {
"display_name": "Python 3 (Data Science)",
"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
}