{ "cells": [ { "cell_type": "markdown", "id": "5c1c08a9-6046-41da-baf5-9c9ea48f5fdd", "metadata": {}, "source": [ "# Classifying news headlines (Local Version)\n", "\n", "> This notebook works well with the `Python 3 (PyTorch 1.13 Python 3.9 CPU Optimized)` kernel on SageMaker Studio\n", "\n", "In this example, you'll train a news headline classifier model using a custom script and the [Hugging Face Transformers](https://huggingface.co/docs/transformers/index) framework.\n", "\n", "This \"local\" notebook will demonstrate training and testing the model here on the notebook itself, while the companion [\"SageMaker\" notebook](Headline%20Classifier%20SageMaker.ipynb) will repeat the same process using containerized SageMaker training jobs and endpoint deployment.\n", "\n", "If you're new to Hugging Face, you might like to read the [Transformers quick tour](https://huggingface.co/docs/transformers/quicktour) or watch the following (1hr) introductory video:" ] }, { "cell_type": "code", "execution_count": null, "id": "7373d72c-7f09-4a87-851d-dc603412912b", "metadata": { "tags": [] }, "outputs": [], "source": [ "%%html\n", "" ] }, { "cell_type": "markdown", "id": "57514090-30b2-46c3-bee6-cb013b2038cb", "metadata": {}, "source": [ "## Installation and setup\n", "\n", "The PyTorch SageMaker kernel specified above has most of the libraries we need, but not quite everything. First, we'll need to install appropriate versions of HF transformers/datasets, and also IPyWidgets to power our interactive classifier widget later on:\n", "\n", "> âš ī¸ **Note:** So long as you run this cell first, there should be no need to restart your notebook kernel. If you `import`ed anything already though, you'll need to click the circular 'restart the kernel' button in the toolbar above for these installs to take effect.\n", "\n", "You can ignore any *warnings* from pip in the output below, but should not see any *errors*." ] }, { "cell_type": "code", "execution_count": null, "id": "d2cc7de2-59b4-49a7-8823-6953e2531cea", "metadata": { "scrolled": true, "tags": [] }, "outputs": [], "source": [ "%pip install datasets \"ipywidgets<8\" transformers==4.26" ] }, { "cell_type": "markdown", "id": "d83e5d2d-d062-468f-96dc-d51018cc2450", "metadata": {}, "source": [ "With installs complete, we'll load the libraries and Python built-ins to be used in the rest of the notebook.\n", "\n", "The [%autoreload magic](https://ipython.readthedocs.io/en/stable/config/extensions/autoreload.html) is useful when working with local .py files, because re-loading libraries on each cell execution lets you consume locally edited/updated scripts without having to restart your notebook kernel." ] }, { "cell_type": "code", "execution_count": null, "id": "efbe751a-dce5-4dd1-b96c-35738d28fe1e", "metadata": { "tags": [] }, "outputs": [], "source": [ "%load_ext autoreload\n", "%autoreload 2\n", "\n", "# Python Built-Ins:\n", "import os # Operating system utils e.g. file paths\n", "\n", "# External Dependencies:\n", "import datasets # Hugging Face data loading utilities\n", "import ipywidgets as widgets # Interactive prediction widget\n", "import pandas as pd # Utilities for working with data tables (dataframes)\n", "from sklearn.metrics import accuracy_score, precision_recall_fscore_support\n", "import transformers # Hugging Face Transformers framework\n", "\n", "local_dir = \"data\"" ] }, { "cell_type": "markdown", "id": "f05b6e3e-1f50-4337-8339-fc05d71af52f", "metadata": {}, "source": [ "## Prepare the dataset\n", "\n", "This example will download the **FastAi AG News** dataset from the [Registry of Open Data on AWS](https://registry.opendata.aws/fast-ai-nlp/) public repository. This dataset contains a table of news headlines and their corresponding topic classes." ] }, { "cell_type": "code", "execution_count": null, "id": "131a0145-9033-4112-a67f-5e229679229e", "metadata": { "tags": [] }, "outputs": [], "source": [ "%%time\n", "# Download the AG News data from the Registry of Open Data on AWS.\n", "!mkdir -p {local_dir}\n", "!aws s3 cp s3://fast-ai-nlp/ag_news_csv.tgz {local_dir} --no-sign-request\n", "\n", "# Un-tar the AG News data.\n", "!tar zxf {local_dir}/ag_news_csv.tgz -C {local_dir}/ --strip-components=1 --no-same-owner\n", "\n", "# Push data partitions to separate subfolders, which is useful for local script debugging later\n", "os.renames(f\"{local_dir}/test.csv\", f\"{local_dir}/test/test.csv\")\n", "os.renames(f\"{local_dir}/train.csv\", f\"{local_dir}/train/train.csv\")\n", "print(\"Done!\")" ] }, { "cell_type": "markdown", "id": "6dba225c-14bd-4941-8fa0-a68fe7f5fe6f", "metadata": {}, "source": [ "With the data downloaded and extracted, we can explore some of the examples as shown below:" ] }, { "cell_type": "code", "execution_count": null, "id": "5369b9a2-c6f8-46ce-9b98-9451817be488", "metadata": { "tags": [] }, "outputs": [], "source": [ "column_names = [\"CATEGORY\", \"TITLE\", \"CONTENT\"]\n", "# we use the train.csv only\n", "df = pd.read_csv(f\"{local_dir}/train/train.csv\", names=column_names, header=None, delimiter=\",\")\n", "# shuffle the DataFrame rows\n", "df = df.sample(frac=1, random_state=1337)\n", "\n", "# Make the (1-indexed) category classes more readable:\n", "class_names = [\"Other\", \"World\", \"Sports\", \"Business\", \"Sci/Tech\"]\n", "idx2label = {ix: name for ix, name in enumerate(class_names)}\n", "label2idx = {name: ix for ix, name in enumerate(class_names)}\n", "\n", "df = df.replace({\"CATEGORY\": idx2label})\n", "df.head()" ] }, { "cell_type": "markdown", "id": "51f56818-09f1-48fc-bd5b-21530e7ef9c5", "metadata": {}, "source": [ "For this exercise we'll **only use**:\n", "\n", "- The **title** (Headline) of the news story, as our input\n", "- The **category**, as our target variable to predict\n", "\n", "This dataset contains 4 evenly distributed topic classes, as shown below.\n", "\n", "> â„šī¸ **What about 'Other'?:** Since the raw dataset represents categories with a number from 1-4, and our model will expect numbers starting from 0, we've inserted the un-used 'Other' class to keep data preparation simple and avoid introducing an extra, confusing, numeric representation of the classes." ] }, { "cell_type": "code", "execution_count": null, "id": "1a70b377-ee49-4780-8b32-57db4ee149ac", "metadata": { "tags": [] }, "outputs": [], "source": [ "df[\"CATEGORY\"].value_counts()" ] }, { "cell_type": "markdown", "id": "a628acab-0b0b-4b77-9800-8dc154c55249", "metadata": {}, "source": [ "## Define training parameters\n", "\n", "We'll be fine-tuning a (relatively small) pre-trained model from the [Hugging Face Hub](https://huggingface.co/models), and using their high-level [Trainer API](https://huggingface.co/docs/transformers/main_classes/trainer) rather than writing a low-level training loop from scratch.\n", "\n", "Below, we'll set up the basic parameters for the training.\n", "\n", "> đŸŽī¸ For this in-notebook example we'll be using **low-cost, CPU-only compute** by default. Although the model we're training is \"small\" by modern LLM standards, We'll still need to stop the training very early so it can complete in a reasonable time.\n", ">\n", "> The resulting model will be very under-trained, and much less accurate than the same architecture could ultimately get to." ] }, { "cell_type": "code", "execution_count": null, "id": "01c772a2-b9f1-4908-b7e0-07e162933fe1", "metadata": { "tags": [] }, "outputs": [], "source": [ "model_id = \"amazon/bort\" # ID of the pre-trained model to start from\n", "\n", "training_args = transformers.TrainingArguments(\n", " output_dir=f\"{local_dir}/model\", # Where to save trained model snapshots\n", " #logging_dir=f\"{local_dir}/local-logs\", # Optionally, save logs too\n", " max_steps=500, # Maximum number of training steps to run\n", " num_train_epochs=3, # Maximum number of times to loop through the training data\n", " per_device_train_batch_size=16, # Examples per mini-batch for training\n", " per_device_eval_batch_size=32, # Examples per mini-batch for validation\n", " evaluation_strategy=\"steps\", # Run validation every N 'steps' instead of every 'epoch'\n", " eval_steps=100, # Number of training steps between validation runs\n", " save_strategy=\"steps\", # Must be same as evaluation_strategy when load_best_model_at_end=True\n", " load_best_model_at_end=True, # If current model at end is not the best, load the best\n", " metric_for_best_model=\"f1\", # Use F1 score for judging which model is 'best'\n", " learning_rate=5e-5, # Initial learning rate (decays over time by default)\n", " warmup_steps=100, # Number of steps to gradually increase the learning rate from the start\n", ")" ] }, { "cell_type": "markdown", "id": "60a37d97-07f7-4985-8b6a-19aa751d1ab4", "metadata": {}, "source": [ "## Define metrics\n", "\n", "Here, we'll define how we'd like to measure the quality of the trained model by setting up a [callback function](https://huggingface.co/docs/transformers/main_classes/callback) that'll be run every time the model gets validated." ] }, { "cell_type": "code", "execution_count": null, "id": "ca817667-2bb8-4098-9840-466d42a13d76", "metadata": { "tags": [] }, "outputs": [], "source": [ "def compute_metrics(pred):\n", " labels = pred.label_ids\n", " preds = pred.predictions.argmax(-1)\n", " precision, recall, f1, _ = precision_recall_fscore_support(labels, preds, average=\"micro\")\n", " acc = accuracy_score(labels, preds)\n", " return {\"accuracy\": acc, \"f1\": f1, \"precision\": precision, \"recall\": recall}" ] }, { "cell_type": "markdown", "id": "d8a2df25-93e0-4f15-89de-844b291d6862", "metadata": {}, "source": [ "## Train and validate the model\n", "\n", "In this section we'll load up the base model and datasets, and run the actual training and validation process.\n", "\n", "First, we'll need to load the pre-trained model and accompanying [tokenizer](https://huggingface.co/docs/transformers/main_classes/tokenizer) for the given `model_id` - which will be automatically downloaded from the Hugging Face Hub.\n", "\n", "As part of setting up the model, we'll need to specify how many topic classes we'll fine-tune on and set up their human-readable names:" ] }, { "cell_type": "code", "execution_count": null, "id": "f351c2e7-70ee-4d02-8b28-b1792073b8df", "metadata": { "tags": [] }, "outputs": [], "source": [ "tokenizer = transformers.AutoTokenizer.from_pretrained(model_id)\n", "\n", "model = transformers.AutoModelForSequenceClassification.from_pretrained(model_id, num_labels=len(class_names))\n", "model.config.label2id = label2idx\n", "model.config.id2label = idx2label\n", "\n", "data_collator = transformers.DataCollatorWithPadding(tokenizer=tokenizer)" ] }, { "cell_type": "markdown", "id": "fcabbc33-4f7a-4591-82d2-ec0b07bcb1d4", "metadata": { "tags": [] }, "source": [ "We'll use the raw `train.csv` and `test.csv` files already provided in the dataset as inputs for our training, but will need to set up some pre-processing first:\n", "\n", "- Since the CSVs don't have column headers, we'll need to specify their `column_names` manually\n", "- The `tokenizer` will convert raw text to the (numeric) inputs the model expects - including truncating any long headlines to the maximum length supported by the model" ] }, { "cell_type": "code", "execution_count": null, "id": "9610050f-63d8-43d1-9037-39e75d8bcf65", "metadata": { "tags": [] }, "outputs": [], "source": [ "def preprocess(batch):\n", " \"\"\"Tokenize and pre-process raw examples for training/validation\"\"\"\n", " result = tokenizer(batch[\"title\"], truncation=True)\n", " result[\"label\"] = batch[\"category\"]\n", " return result\n", "\n", "\n", "# Load the raw datasets:\n", "raw_train_dataset = datasets.load_dataset(\n", " \"csv\",\n", " data_files=os.path.join(local_dir, \"train\", \"train.csv\"),\n", " column_names=[\"category\", \"title\", \"content\"],\n", " split=datasets.Split.ALL,\n", ")\n", "raw_test_dataset = datasets.load_dataset(\n", " \"csv\",\n", " data_files=os.path.join(local_dir, \"test\", \"test.csv\"),\n", " column_names=[\"category\", \"title\", \"content\"],\n", " split=datasets.Split.ALL,\n", ")\n", "\n", "# Run the tokenization/pre-processing, keeping only the output fields from preprocess()\n", "train_dataset = raw_train_dataset.map(\n", " preprocess, batched=True, batch_size=1000, remove_columns=raw_train_dataset.column_names\n", ")\n", "test_dataset = raw_test_dataset.map(\n", " preprocess, batched=True, batch_size=1000, remove_columns=raw_test_dataset.column_names\n", ")" ] }, { "cell_type": "markdown", "id": "427526e0-6fb6-45a0-94a0-9bb755a9f9e4", "metadata": {}, "source": [ "With the parameters and pre-processed data loaded, we're ready to train and evaluate the model.\n", "\n", "> ⏰ **Note:** On the default `ml.t3.medium` (2 vCPU + 4 GiB RAM) Studio instance type, this process should take about 20 minutes to complete.\n", ">\n", "> While waiting, you can move on to the [SageMaker notebook](Headline%20Classifier%20SageMaker.ipynb) to start exploring how this process would be different when migrated to a SageMaker training job." ] }, { "cell_type": "code", "execution_count": null, "id": "97b077dc-5cb7-4945-885b-cfccd49c25d8", "metadata": { "tags": [] }, "outputs": [], "source": [ "%%time\n", "\n", "# create Trainer instance\n", "trainer = transformers.Trainer(\n", " model=model,\n", " args=training_args,\n", " compute_metrics=compute_metrics,\n", " train_dataset=train_dataset,\n", " eval_dataset=test_dataset,\n", " tokenizer=tokenizer,\n", " data_collator=data_collator,\n", ")\n", "\n", "# train model\n", "trainer.train()\n", "\n", "# evaluate model\n", "eval_result = trainer.evaluate(eval_dataset=test_dataset)" ] }, { "cell_type": "markdown", "id": "575fd733-4aa9-457c-b369-a5cbcde46768", "metadata": {}, "source": [ "As you'll see from the metrics, the model trained here is likely not very accurate and the accuracy will still be rapidly increasing at the point training was terminated." ] }, { "cell_type": "markdown", "id": "887e58b2-f792-46e1-b7a3-7613bb9f3184", "metadata": {}, "source": [ "## Use the model for inference\n", "\n", "Once the model is trained, we're ready to use it for inference on new data.\n", "\n", "Here, the model is already loaded in memory from the training process so we can wrap it with a [Pipeline](https://huggingface.co/docs/transformers/main_classes/pipelines) for easy usage.\n", "\n", "The cell below creates an interactive widget where you can enter your own news headline and have the model classify it in real time:" ] }, { "cell_type": "code", "execution_count": null, "id": "d658acce-6ba1-401c-bf2a-027c227c4db7", "metadata": { "tags": [] }, "outputs": [], "source": [ "pipe = transformers.pipeline(\n", " task=\"text-classification\",\n", " model=model,\n", " tokenizer=tokenizer,\n", ")\n", "\n", "\n", "def classify(text: str) -> dict:\n", " \"\"\"Classify a headline and print the results\"\"\"\n", " print(pipe(text)[0])\n", "\n", "\n", "# Either try out the interactive widget:\n", "interaction = widgets.interact_manual(\n", " classify,\n", " text=widgets.Text(\n", " value=\"The markets were bullish after news of the merger\",\n", " placeholder=\"Type a news headline...\",\n", " description=\"Headline:\",\n", " layout=widgets.Layout(width=\"99%\"),\n", " ),\n", ")\n", "interaction.widget.children[1].description = \"Classify!\"" ] }, { "cell_type": "markdown", "id": "2fe1d76f-4a2e-41ab-b498-e3b8c1611e9d", "metadata": {}, "source": [ "Alternatively, you can call the pipeline direct from code:" ] }, { "cell_type": "code", "execution_count": null, "id": "d11b0acb-f5b9-48b5-b7b3-404ad8158175", "metadata": { "tags": [] }, "outputs": [], "source": [ "classify(\"Retailers are expanding after the recent economic growth\")" ] }, { "cell_type": "markdown", "id": "f8ba7286-50b7-45e7-9a4c-db5d1ba96bcc", "metadata": {}, "source": [ "## Review\n", "\n", "In this notebook, we showed how you might train a text classification model using Hugging Face transformers locally in a plain Jupyter environment.\n", "\n", "Because the default notebook compute infrastructure (`ml.t3.medium`) was quite small, training took a long time and we had to stop it early for a chance to explore the results.\n", "\n", "- You could extend the training epochs/steps cut-offs to train a better model, but then the process would take even longer\n", "- You could toggle your Studio notebook to a higher-resource instance (perhaps even using a GPU), but then that extra resource might be idle in the time you're not actually training the model - such as during data exploration or evaluation.\n", "- We would also need to manually record our experiments to keep track of different parameters we tried in the training process\n", "\n", "Next, head on over to the [SageMaker notebook](Headline%20Classifier%20SageMaker.ipynb) where we'll show how SageMaker training jobs and endpoint deployments can help you take advantage of on-demand compute for faster training and automatic metadata tracking - while only paying for what you need." ] } ], "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 }, { "_defaultOrder": 55, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 8, "hideHardwareSpecs": false, "memoryGiB": 1152, "name": "ml.p4d.24xlarge", "vcpuNum": 96 }, { "_defaultOrder": 56, "_isFastLaunch": false, "category": "Accelerated computing", "gpuNum": 8, "hideHardwareSpecs": false, "memoryGiB": 1152, "name": "ml.p4de.24xlarge", "vcpuNum": 96 } ], "instance_type": "ml.t3.medium", "kernelspec": { "display_name": "Python 3 (PyTorch 1.13 Python 3.9 CPU Optimized)", "language": "python", "name": "python3__SAGEMAKER_INTERNAL__arn:aws:sagemaker:us-east-1:081325390199:image/pytorch-1.13-cpu-py39" }, "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.9.16" } }, "nbformat": 4, "nbformat_minor": 5 }