From a563d2fef96851677596d7de1d7f57cbd7e6702c Mon Sep 17 00:00:00 2001 From: Paolo Di Francesco Date: Fri, 27 Feb 2026 15:17:58 +0000 Subject: [PATCH] Upgrade sagemake sdk from v2 to v3 upgrade pytorch container to 2.x --- .../sm-hyperparameter_tuning_pytorch.ipynb | 2177 +++-------------- 1 file changed, 281 insertions(+), 1896 deletions(-) diff --git a/ build_and_train_models/sm-hyperparameter_tuning_pytorch/sm-hyperparameter_tuning_pytorch.ipynb b/ build_and_train_models/sm-hyperparameter_tuning_pytorch/sm-hyperparameter_tuning_pytorch.ipynb index 5c683cfb9e..0ffa11feb8 100644 --- a/ build_and_train_models/sm-hyperparameter_tuning_pytorch/sm-hyperparameter_tuning_pytorch.ipynb +++ b/ build_and_train_models/sm-hyperparameter_tuning_pytorch/sm-hyperparameter_tuning_pytorch.ipynb @@ -1,71 +1,51 @@ { "cells": [ { - "attachments": {}, "cell_type": "markdown", - "id": "a56c1578", - "metadata": { - "papermill": { - "duration": 0.011109, - "end_time": "2021-06-04T00:19:08.757271", - "exception": false, - "start_time": "2021-06-04T00:19:08.746162", - "status": "completed" - }, - "tags": [] - }, + "id": "984a252c", + "metadata": {}, "source": [ - "# Hyperparameter Tuning using SageMaker PyTorch Container\n" + "# Hyperparameter Tuning using SageMaker PyTorch Container\n", + "\n", + "This notebook demonstrates how to use [SageMaker Automatic Model Tuning](https://docs.aws.amazon.com/sagemaker/latest/dg/automatic-model-tuning.html) (hyperparameter optimization) to find the best hyperparameters for training a PyTorch MNIST model.\n", + "\n", + "### SageMaker Python SDK V3 APIs used\n", + "\n", + "| Package | Class / Utility | Purpose |\n", + "|---------|----------------|----------|\n", + "| `sagemaker-train` | `ModelTrainer` | Unified training interface (replaces V2 `PyTorch` Estimator) |\n", + "| `sagemaker-train` | `HyperparameterTuner` | Automatic hyperparameter optimization |\n", + "| `sagemaker-train` | `SourceCode`, `InputData`, `Compute` | Structured training configuration |\n", + "| `sagemaker-core` | `Model`, `EndpointConfig`, `Endpoint` | Low-level resource management for deployment |\n", + "| `sagemaker-core` | `repack_model()` | Inject inference code into model artifacts |\n", + "| `sagemaker-core` | `image_uris.retrieve()` | Retrieve SageMaker Deep Learning Container URIs |\n", + "| `sagemaker-core` | `Session`, `get_execution_role` | Session management and IAM role resolution |" ] }, { - "attachments": {}, "cell_type": "markdown", - "id": "56bdb206", + "id": "1d71a8c4", "metadata": {}, "source": [ - "---\n", - "\n", - "This notebook's CI test result for us-west-2 is as follows. CI test results in other regions can be found at the end of the notebook. \n", - "\n", - "![This us-west-2 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://prod.us-west-2.tcx-beacon.docs.aws.dev/sagemaker-nb/us-west-2/build_and_train_models|sm-hyperparameter_tuning_pytorch|sm-hyperparameter_tuning_pytorch.ipynb)\n", - "\n", - "---" + "
\n", + "\u26a0\ufe0f Compatibility Notice: This notebook has been tested using SageMaker Distribution Image 3.7.0 and the SageMaker Python SDK version 3.4.0.\n", + "
" ] }, { - "attachments": {}, - "cell_type": "markdown", - "id": "ed79612a", - "metadata": { - "papermill": { - "duration": 0.011109, - "end_time": "2021-06-04T00:19:08.757271", - "exception": false, - "start_time": "2021-06-04T00:19:08.746162", - "status": "completed" - }, - "tags": [] - }, + "cell_type": "code", + "execution_count": null, + "id": "56249c52", + "metadata": {}, + "outputs": [], "source": [ - "\n", - "Kernel `Python 3 (PyTorch CPU (or GPU) Optimized)` works well with this notebook." + "!pip install -q -U \"sagemaker==3.4.0\"" ] }, { - "attachments": {}, "cell_type": "markdown", - "id": "d5f1cd63", - "metadata": { - "papermill": { - "duration": 0.011085, - "end_time": "2021-06-04T00:19:08.779349", - "exception": false, - "start_time": "2021-06-04T00:19:08.768264", - "status": "completed" - }, - "tags": [] - }, + "id": "855e6656", + "metadata": {}, "source": [ "## Contents\n", "\n", @@ -79,53 +59,32 @@ "\n", "## Background\n", "\n", - "MNIST is a widely used dataset for handwritten digit classification. It consists of 70,000 labeled 28x28 pixel grayscale images of hand-written digits. The dataset is split into 60,000 training images and 10,000 test images. There are 10 classes (one for each of the 10 digits). This tutorial will show how to train and test an MNIST model on SageMaker using PyTorch. It also shows how to use SageMaker Automatic Model Tuning to select appropriate hyperparameters in order to get the best model. \n", - "\n", - "For more information about the PyTorch in SageMaker, please visit [sagemaker-pytorch-containers](https://github.com/aws/sagemaker-pytorch-containers) and [sagemaker-python-sdk](https://github.com/aws/sagemaker-python-sdk) github repositories.\n", + "MNIST is a widely used dataset for handwritten digit classification. It consists of 70,000 labeled 28x28 pixel grayscale images of hand-written digits. The dataset is split into 60,000 training images and 10,000 test images. There are 10 classes (one for each of the 10 digits). This tutorial shows how to train and test an MNIST model on SageMaker using PyTorch, and how to use SageMaker Automatic Model Tuning to find the best hyperparameters.\n", "\n", "---\n", "\n", "## Setup\n", "\n", - "_This notebook was created and tested on an ml.m4.xlarge notebook instance._\n", + "We start by creating a `Session` (from `sagemaker.core`) and resolving the IAM execution role. The session manages interactions with S3 and the SageMaker service.\n", "\n", - "Let's start by creating a SageMaker session and specifying:\n", - "\n", - "- The S3 bucket and prefix that you want to use for training and model data. This should be within the same region as the Notebook Instance, training, and hosting.\n", - "- The IAM role arn used to give training and hosting access to your data. See the documentation for how to create these. Note, if more than one role is required for notebook instances, training, and/or hosting, please replace the `sagemaker.get_execution_role()` with a the appropriate full IAM role arn string(s).\n" + "- `Session()` \u2014 initializes the SageMaker session with default bucket and region\n", + "- `get_execution_role()` \u2014 retrieves the IAM role ARN for training and hosting" ] }, { "cell_type": "code", "execution_count": null, - "id": "84cd0297", - "metadata": { - "execution": { - "iopub.execute_input": "2021-06-04T00:19:08.805684Z", - "iopub.status.busy": "2021-06-04T00:19:08.805175Z", - "iopub.status.idle": "2021-06-04T00:19:10.039920Z", - "shell.execute_reply": "2021-06-04T00:19:10.040332Z" - }, - "papermill": { - "duration": 1.250042, - "end_time": "2021-06-04T00:19:10.040468", - "exception": false, - "start_time": "2021-06-04T00:19:08.790426", - "status": "completed" - }, - "tags": [] - }, + "id": "551453b6", + "metadata": {}, "outputs": [], "source": [ - "import sagemaker\n", - "from sagemaker.tuner import (\n", - " IntegerParameter,\n", - " CategoricalParameter,\n", - " ContinuousParameter,\n", - " HyperparameterTuner,\n", - ")\n", + "from importlib.metadata import version as pkg_version\n", + "print(f\"SageMaker SDK version: {pkg_version('sagemaker')}\")\n", "\n", - "sagemaker_session = sagemaker.Session()\n", + "from sagemaker.core.helper.session_helper import Session, get_execution_role\n", + "from sagemaker.core import image_uris\n", + "\n", + "sagemaker_session = Session()\n", "region = sagemaker_session.boto_region_name\n", "\n", "bucket = sagemaker_session.default_bucket()\n", @@ -136,107 +95,66 @@ "if default_bucket_prefix:\n", " prefix = f\"{default_bucket_prefix}/{prefix}\"\n", "\n", - "role = sagemaker.get_execution_role()" + "role = get_execution_role()" ] }, { - "attachments": {}, "cell_type": "markdown", - "id": "ae9b8102", - "metadata": { - "papermill": { - "duration": 0.011414, - "end_time": "2021-06-04T00:19:10.063501", - "exception": false, - "start_time": "2021-06-04T00:19:10.052087", - "status": "completed" - }, - "tags": [] - }, + "id": "17ee7278", + "metadata": {}, "source": [ "## Data\n", - "### Getting the data\n", - "\n" + "### Getting the data" ] }, { "cell_type": "code", "execution_count": null, - "id": "2cb31093", - "metadata": { - "execution": { - "iopub.execute_input": "2021-06-04T00:19:10.091514Z", - "iopub.status.busy": "2021-06-04T00:19:10.091028Z", - "iopub.status.idle": "2021-06-04T00:24:59.422064Z", - "shell.execute_reply": "2021-06-04T00:24:59.422432Z" - }, - "papermill": { - "duration": 349.34758, - "end_time": "2021-06-04T00:24:59.422559", - "exception": false, - "start_time": "2021-06-04T00:19:10.074979", - "status": "completed" - }, - "tags": [] - }, + "id": "0bb3ecfa", + "metadata": {}, "outputs": [], "source": [ - "from torchvision.datasets import MNIST\n", - "from torchvision import transforms\n", - "\n", + "import os\n", + "import gzip\n", + "import urllib.request\n", "\n", "local_dir = \"data\"\n", - "MNIST.mirrors = [\n", - " f\"https://sagemaker-example-files-prod-{region}.s3.amazonaws.com/datasets/image/MNIST/\"\n", + "base_url = f\"https://sagemaker-example-files-prod-{region}.s3.amazonaws.com/datasets/image/MNIST/\"\n", + "files = [\n", + " \"t10k-images-idx3-ubyte.gz\",\n", + " \"t10k-labels-idx1-ubyte.gz\",\n", + " \"train-images-idx3-ubyte.gz\",\n", + " \"train-labels-idx1-ubyte.gz\",\n", "]\n", - "MNIST(\n", - " local_dir,\n", - " download=True,\n", - " transform=transforms.Compose(\n", - " [transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,))]\n", - " ),\n", - ")" + "os.makedirs(\"data/MNIST/raw\", exist_ok=True)\n", + "for f in files:\n", + " gz_path = f\"data/MNIST/raw/{f}\"\n", + " raw_path = gz_path.replace(\".gz\", \"\")\n", + " if not os.path.exists(gz_path):\n", + " print(f\"Downloading {f}...\")\n", + " urllib.request.urlretrieve(base_url + f, gz_path)\n", + " # Extract .gz files (torchvision in the container expects uncompressed files)\n", + " if not os.path.exists(raw_path):\n", + " with gzip.open(gz_path, \"rb\") as f_in:\n", + " with open(raw_path, \"wb\") as f_out:\n", + " f_out.write(f_in.read())\n", + "print(\"MNIST data ready.\")" ] }, { - "attachments": {}, "cell_type": "markdown", - "id": "0f7857bf", - "metadata": { - "papermill": { - "duration": 0.014222, - "end_time": "2021-06-04T00:24:59.452075", - "exception": false, - "start_time": "2021-06-04T00:24:59.437853", - "status": "completed" - }, - "tags": [] - }, + "id": "fa198623", + "metadata": {}, "source": [ "### Uploading the data to S3\n", - "We are going to use the `sagemaker.Session.upload_data` function to upload our datasets to an S3 location. The return value inputs identifies the location -- we will use later when we start the training job.\n" + "We use `Session.upload_data()` to upload the dataset to S3. The returned S3 URI is passed as an `InputData` source to the training job." ] }, { "cell_type": "code", "execution_count": null, - "id": "55da9b97", - "metadata": { - "execution": { - "iopub.execute_input": "2021-06-04T00:24:59.484304Z", - "iopub.status.busy": "2021-06-04T00:24:59.483818Z", - "iopub.status.idle": "2021-06-04T00:25:01.707958Z", - "shell.execute_reply": "2021-06-04T00:25:01.708340Z" - }, - "papermill": { - "duration": 2.242278, - "end_time": "2021-06-04T00:25:01.708498", - "exception": false, - "start_time": "2021-06-04T00:24:59.466220", - "status": "completed" - }, - "tags": [] - }, + "id": "5fff1bed", + "metadata": {}, "outputs": [], "source": [ "inputs = sagemaker_session.upload_data(path=\"data\", bucket=bucket, key_prefix=prefix)\n", @@ -244,202 +162,128 @@ ] }, { - "attachments": {}, "cell_type": "markdown", - "id": "5963b4a4", - "metadata": { - "papermill": { - "duration": 0.014491, - "end_time": "2021-06-04T00:25:01.737669", - "exception": false, - "start_time": "2021-06-04T00:25:01.723178", - "status": "completed" - }, - "tags": [] - }, + "id": "fef347fc", + "metadata": {}, "source": [ "## Train\n", "### Training script\n", "The `mnist.py` script provides all the code we need for training and hosting a SageMaker model (`model_fn` function to load a model).\n", "The training script is very similar to a training script you might run outside of SageMaker, but you can access useful properties about the training environment through various environment variables, such as:\n", "\n", - "* `SM_MODEL_DIR`: A string representing the path to the directory to write model artifacts to.\n", - " These artifacts are uploaded to S3 for model hosting.\n", - "* `SM_NUM_GPUS`: The number of gpus available in the current container.\n", - "* `SM_CURRENT_HOST`: The name of the current container on the container network.\n", - "* `SM_HOSTS`: JSON encoded list containing all the hosts .\n", - "\n", - "Supposing one input channel, 'training', was used in the call to the `fit()` method, the following will be set, following the format `SM_CHANNEL_[channel_name]`:\n", - "\n", + "* `SM_MODEL_DIR`: A string representing the path to the directory to write model artifacts to. These artifacts are uploaded to S3 for model hosting.\n", + "* `SM_NUM_GPUS`: The number of GPUs available in the current container.\n", "* `SM_CHANNEL_TRAINING`: A string representing the path to the directory containing data in the 'training' channel.\n", "\n", - "For more information about training environment variables, please visit [SageMaker Containers](https://github.com/aws/sagemaker-containers).\n", - "\n", - "A typical training script loads data from the input channels, configures training with hyperparameters, trains a model, and saves a model to `model_dir` so that it can be hosted later. Hyperparameters are passed to your script as arguments and can be retrieved with an `argparse.ArgumentParser` instance.\n", - "\n", - "Because the SageMaker imports the training script, you should put your training code in a main guard (``if __name__=='__main__':``) if you are using the same script to host your model as we do in this example, so that SageMaker does not inadvertently run your training code at the wrong point in execution.\n", - "\n", - "For example, the script run by this notebook:" + "For more information about training environment variables, please visit [SageMaker Containers](https://github.com/aws/sagemaker-containers)." ] }, { "cell_type": "code", "execution_count": null, - "id": "1bb764d0", - "metadata": { - "execution": { - "iopub.execute_input": "2021-06-04T00:25:01.771052Z", - "iopub.status.busy": "2021-06-04T00:25:01.770235Z", - "iopub.status.idle": "2021-06-04T00:25:02.581475Z", - "shell.execute_reply": "2021-06-04T00:25:02.581887Z" - }, - "papermill": { - "duration": 0.829854, - "end_time": "2021-06-04T00:25:02.582021", - "exception": false, - "start_time": "2021-06-04T00:25:01.752167", - "status": "completed" - }, - "tags": [] - }, + "id": "e1fa69c7", + "metadata": {}, "outputs": [], "source": [ "!pygmentize mnist.py" ] }, { - "attachments": {}, "cell_type": "markdown", - "id": "8d3d0dc9", - "metadata": { - "papermill": { - "duration": 0.01517, - "end_time": "2021-06-04T00:25:02.612636", - "exception": false, - "start_time": "2021-06-04T00:25:02.597466", - "status": "completed" - }, - "tags": [] - }, + "id": "aa77980f", + "metadata": {}, "source": [ "### Set up hyperparameter tuning job\n", "*Note, with the default setting below, the hyperparameter tuning job can take about 20 minutes to complete.*\n", "\n", - "Now that we have prepared the dataset and the script, we are ready to train models. Before we do that, one thing to note is there are many hyperparameters that can dramtically affect the performance of the trained models. For example, learning rate, batch size, number of epochs, etc. Since which hyperparameter setting can lead to the best result depends on the dataset as well, it is almost impossible to pick the best hyperparameter setting without searching for it. Using SageMaker Automatic Model Tuning, we can create a hyperparameter tuning job to search for the best hyperparameter setting in an automated and effective way.\n", + "We use the V3 `HyperparameterTuner` (from `sagemaker.train.tuner`) together with `ModelTrainer` to run automatic model tuning. The steps are:\n", "\n", - "In this example, we are using SageMaker Python SDK to set up and manage a hyperparameter tuning job. Specifically, we specify a range, or a list of possible values in the case of categorical hyperparameters, for each of the hyperparameter that we plan to tune. The hyperparameter tuning job will automatically launch multiple training jobs with different hyperparameter settings, evaluate results of those training jobs based on a predefined \"objective metric\", and select the hyperparameter settings for future attempts based on previous results. For each hyperparameter tuning job, we will give it a budget (max number of training jobs) and it will complete once that many training jobs have been executed.\n", - "\n", - "Now we will set up the hyperparameter tuning job using SageMaker Python SDK, following below steps:\n", - "* Create an estimator to set up the PyTorch training job\n", - "* Define the ranges of hyperparameters we plan to tune, in this example, we are tuning learning_rate and batch size\n", - "* Define the objective metric for the tuning job to optimize\n", - "* Create a hyperparameter tuner with above setting, as well as tuning resource configurations " + "1. Create a `ModelTrainer` with `SourceCode`, `Compute`, and the training image URI\n", + "2. Define hyperparameter ranges using `ContinuousParameter`, `CategoricalParameter`, or `IntegerParameter` (from `sagemaker.core.parameter`)\n", + "3. Define the objective metric and its regex pattern\n", + "4. Create a `HyperparameterTuner` with the trainer, ranges, metric, and resource budget" ] }, { - "attachments": {}, "cell_type": "markdown", - "id": "562cad5e", - "metadata": { - "papermill": { - "duration": 0.01515, - "end_time": "2021-06-04T00:25:02.642851", - "exception": false, - "start_time": "2021-06-04T00:25:02.627701", - "status": "completed" - }, - "tags": [] - }, + "id": "ec6214cd", + "metadata": {}, "source": [ - "Similar to training a single PyTorch job in SageMaker, we define our PyTorch estimator passing in the PyTorch script, IAM role, and (per job) hardware configuration. " + "We define a `ModelTrainer` (from `sagemaker.train`) passing in:\n", + "- `training_image` \u2014 the container URI retrieved via `image_uris.retrieve()`\n", + "- `source_code` \u2014 a `SourceCode` config pointing to the local directory and entry script\n", + "- `compute` \u2014 a `Compute` config specifying instance type and count\n", + "- `role` \u2014 the IAM execution role\n", + "- `hyperparameters` \u2014 static hyperparameters (not tuned)" ] }, { "cell_type": "code", "execution_count": null, - "id": "7568768e", - "metadata": { - "execution": { - "iopub.execute_input": "2021-06-04T00:25:02.677309Z", - "iopub.status.busy": "2021-06-04T00:25:02.676798Z", - "iopub.status.idle": "2021-06-04T00:25:02.795228Z", - "shell.execute_reply": "2021-06-04T00:25:02.794340Z" - }, - "papermill": { - "duration": 0.137601, - "end_time": "2021-06-04T00:25:02.795452", - "exception": true, - "start_time": "2021-06-04T00:25:02.657851", - "status": "failed" - }, - "tags": [] - }, + "id": "7c3cc905", + "metadata": {}, "outputs": [], "source": [ - "from sagemaker.pytorch import PyTorch\n", + "from sagemaker.train import ModelTrainer\n", + "from sagemaker.train.configs import SourceCode, InputData, Compute\n", + "\n", + "training_image = image_uris.retrieve(\n", + " framework=\"pytorch\",\n", + " region=region,\n", + " version=\"2.0.1\",\n", + " py_version=\"py310\",\n", + " instance_type=\"ml.c5.2xlarge\",\n", + " image_scope=\"training\",\n", + ")\n", "\n", - "estimator = PyTorch(\n", - " entry_point=\"mnist.py\",\n", + "trainer = ModelTrainer(\n", + " training_image=training_image,\n", + " source_code=SourceCode(source_dir=\".\", entry_script=\"mnist.py\"),\n", + " compute=Compute(instance_type=\"ml.c5.2xlarge\", instance_count=1),\n", " role=role,\n", - " py_version=\"py3\",\n", - " framework_version=\"1.8.0\",\n", - " instance_count=1,\n", - " instance_type=\"ml.c5.2xlarge\",\n", - " hyperparameters={\"epochs\": 1, \"backend\": \"gloo\"},\n", + " hyperparameters={\"epochs\": \"1\", \"backend\": \"gloo\"},\n", + " base_job_name=\"pytorch-mnist-hpo\",\n", ")" ] }, { "cell_type": "code", "execution_count": null, - "id": "7783dd43", + "id": "41063779", "metadata": {}, "outputs": [], "source": [ "# test training job\n", "\n", - "estimator.fit({\"training\": inputs})" + "trainer.train(\n", + " input_data_config=[InputData(channel_name=\"training\", data_source=inputs)],\n", + " wait=True,\n", + " logs=True,\n", + ")" ] }, { - "attachments": {}, "cell_type": "markdown", - "id": "eb13623a", - "metadata": { - "papermill": { - "duration": null, - "end_time": null, - "exception": null, - "start_time": null, - "status": "pending" - }, - "tags": [] - }, + "id": "65fd8508", + "metadata": {}, "source": [ - "Once we've defined our estimator we can specify the hyperparameters we'd like to tune and their possible values. We have three different types of hyperparameters.\n", - "- Categorical parameters need to take one value from a discrete set. We define this by passing the list of possible values to `CategoricalParameter(list)`\n", + "Once we've defined our `ModelTrainer` we can specify the hyperparameters we'd like to tune and their possible values. We have three different types of hyperparameters.\n", + "- Categorical parameters need to take one value from a discrete set. We define this by passing the list of possible values to `CategoricalParameter(list)`\n", "- Continuous parameters can take any real number value between the minimum and maximum value, defined by `ContinuousParameter(min, max)`\n", "- Integer parameters can take any integer value between the minimum and maximum value, defined by `IntegerParameter(min, max)`\n", "\n", - "*Note, if possible, it's almost always best to specify a value as the least restrictive type. For example, tuning learning rate as a continuous value between 0.01 and 0.2 is likely to yield a better result than tuning as a categorical parameter with values 0.01, 0.1, 0.15, or 0.2. We did specify batch size as categorical parameter here since it is generally recommended to be the power of 2.*" + "*Note, if possible, it's almost always best to specify a value as the least restrictive type. For example, tuning learning rate as a continuous value between 0.01 and 0.2 is likely to yield a better result than tuning as a categorical parameter with values 0.01, 0.1, 0.15, or 0.2.*" ] }, { "cell_type": "code", "execution_count": null, - "id": "232d7fc6", - "metadata": { - "papermill": { - "duration": null, - "end_time": null, - "exception": null, - "start_time": null, - "status": "pending" - }, - "tags": [] - }, + "id": "60b03a1b", + "metadata": {}, "outputs": [], "source": [ + "from sagemaker.core.parameter import ContinuousParameter, CategoricalParameter\n", + "\n", "hyperparameter_ranges = {\n", " \"lr\": ContinuousParameter(0.001, 0.1),\n", " \"batch-size\": CategoricalParameter([32, 64, 128, 256, 512]),\n", @@ -447,37 +291,18 @@ ] }, { - "attachments": {}, "cell_type": "markdown", - "id": "d1d151cd", - "metadata": { - "papermill": { - "duration": null, - "end_time": null, - "exception": null, - "start_time": null, - "status": "pending" - }, - "tags": [] - }, + "id": "62d8dc06", + "metadata": {}, "source": [ - "Next we'll specify the objective metric that we'd like to tune and its definition, which includes the regular expression (Regex) needed to extract that metric from the CloudWatch logs of the training job. In this particular case, our script emits average loss value and we will use it as the objective metric, we also set the objective_type to be 'minimize', so that hyperparameter tuning seeks to minize the objective metric when searching for the best hyperparameter setting. By default, objective_type is set to 'maximize'." + "Next we specify the objective metric that we'd like to tune and its definition, which includes the regular expression (Regex) needed to extract that metric from the CloudWatch logs of the training job. In this case, our script emits average loss value and we will use it as the objective metric. We set `objective_type` to `'Minimize'`, so that hyperparameter tuning seeks to minimize the objective metric when searching for the best hyperparameter setting." ] }, { "cell_type": "code", "execution_count": null, - "id": "10f8c041", - "metadata": { - "papermill": { - "duration": null, - "end_time": null, - "exception": null, - "start_time": null, - "status": "pending" - }, - "tags": [] - }, + "id": "eea9e415", + "metadata": {}, "outputs": [], "source": [ "objective_metric_name = \"average test loss\"\n", @@ -486,45 +311,38 @@ ] }, { - "attachments": {}, "cell_type": "markdown", - "id": "681d6722", - "metadata": { - "papermill": { - "duration": null, - "end_time": null, - "exception": null, - "start_time": null, - "status": "pending" - }, - "tags": [] - }, + "id": "23596e57", + "metadata": {}, "source": [ - "Now, we'll create a `HyperparameterTuner` object, to which we pass:\n", - "- The PyTorch estimator we created above\n", - "- Our hyperparameter ranges\n", + "Now, we create a `HyperparameterTuner` (from `sagemaker.train.tuner`), passing in:\n", + "- The `ModelTrainer` instance\n", + "- Hyperparameter ranges\n", "- Objective metric name and definition\n", - "- Tuning resource configurations such as Number of training jobs to run in total and how many training jobs can be run in parallel." + "- Tuning resource configurations: `max_jobs` (total training jobs) and `max_parallel_jobs` (concurrent jobs)" ] }, { "cell_type": "code", "execution_count": null, - "id": "cdeb8b7a", - "metadata": { - "papermill": { - "duration": null, - "end_time": null, - "exception": null, - "start_time": null, - "status": "pending" - }, - "tags": [] - }, + "id": "8974d656", + "metadata": {}, "outputs": [], "source": [ + "from sagemaker.train.tuner import HyperparameterTuner\n", + "\n", + "# Create a fresh ModelTrainer for the tuner\n", + "tuner_trainer = ModelTrainer(\n", + " training_image=training_image,\n", + " source_code=SourceCode(source_dir=\".\", entry_script=\"mnist.py\"),\n", + " compute=Compute(instance_type=\"ml.c5.2xlarge\", instance_count=1),\n", + " role=role,\n", + " hyperparameters={\"epochs\": \"1\", \"backend\": \"gloo\"},\n", + " base_job_name=\"pytorch-mnist-hpo\",\n", + ")\n", + "\n", "tuner = HyperparameterTuner(\n", - " estimator,\n", + " tuner_trainer,\n", " objective_metric_name,\n", " hyperparameter_ranges,\n", " metric_definitions,\n", @@ -535,162 +353,177 @@ ] }, { - "attachments": {}, "cell_type": "markdown", - "id": "e72a285a", - "metadata": { - "papermill": { - "duration": null, - "end_time": null, - "exception": null, - "start_time": null, - "status": "pending" - }, - "tags": [] - }, + "id": "2361157e", + "metadata": {}, "source": [ "### Launch hyperparameter tuning job\n", - "And finally, we can start our hyperprameter tuning job by calling `.fit()` and passing in the S3 path to our train and test dataset.\n", + "We start the tuning job by calling `tuner.tune()` with an `InputData` config pointing to our S3 training data. Setting `wait=True` blocks until all training jobs complete.\n", "\n", - "After the hyperprameter tuning job is created, you should be able to describe the tuning job to see its progress in the next step, and you can go to SageMaker console->Jobs to check out the progress of the progress of the hyperparameter tuning job." + "You can monitor progress in the SageMaker console under **Hyperparameter tuning jobs**." ] }, { "cell_type": "code", "execution_count": null, - "id": "74d2876b", - "metadata": { - "papermill": { - "duration": null, - "end_time": null, - "exception": null, - "start_time": null, - "status": "pending" - }, - "tags": [] - }, + "id": "381f8cf8", + "metadata": {}, "outputs": [], "source": [ - "tuner.fit({\"training\": inputs})" + "tuner.tune(\n", + " inputs=[InputData(channel_name=\"training\", data_source=inputs)],\n", + " wait=True,\n", + ")" ] }, { - "attachments": {}, "cell_type": "markdown", - "id": "a8872720", - "metadata": { - "papermill": { - "duration": null, - "end_time": null, - "exception": null, - "start_time": null, - "status": "pending" - }, - "tags": [] - }, + "id": "e3ea8a8e", + "metadata": {}, "source": [ "## Host\n", "### Create endpoint\n", - "After training, we use the tuner object to build and deploy a `PyTorchPredictor`. This creates a Sagemaker Endpoint -- a hosted prediction service that we can use to perform inference, based on the best model in the tuner. Remember in previous steps, the tuner launched multiple training jobs during tuning and the resulting model with the best objective metric is defined as the best model. \n", + "After tuning completes, we deploy the best model to a real-time endpoint. The steps are:\n", "\n", - "As mentioned above we have implementation of `model_fn` in the `mnist.py` script that is required. We are going to use default implementations of `input_fn`, `predict_fn`, `output_fn` and `transform_fm` defined in [sagemaker-pytorch-containers](https://github.com/aws/sagemaker-pytorch-containers).\n", + "1. **Get best training job** \u2014 `tuner.best_training_job()` returns the name of the job with the best objective metric\n", + "2. **Retrieve model artifacts** \u2014 `TrainingJob.get()` fetches the job metadata, including the S3 URI of `model.tar.gz`\n", + "3. **Repack model** \u2014 `repack_model()` (from `sagemaker.core.utils`) injects the inference script into the model archive. The PyTorch serving container expects a `code/` directory inside `model.tar.gz` containing the entry point script\n", + "4. **Create resources** \u2014 Use `sagemaker-core` resource classes (`Model.create()`, `EndpointConfig.create()`, `Endpoint`) to deploy\n", "\n", - "The arguments to the deploy function allow us to set the number and type of instances that will be used for the Endpoint. These do not need to be the same as the values we used for the training job. For example, you can train a model on a set of GPU-based instances, and then deploy the Endpoint to a fleet of CPU-based instances, but you need to make sure that you return or save your model as a cpu model similar to what we did in `mnist.py`. Here we will deploy the model to a single ```ml.m4.xlarge``` instance." + "The `repack_model()` utility handles the full download \u2192 extract \u2192 inject \u2192 re-tar \u2192 upload workflow in a single call, replacing what would otherwise be ~15 lines of manual S3/tarfile code." ] }, { "cell_type": "code", "execution_count": null, - "id": "4e6f51e1", - "metadata": { - "papermill": { - "duration": null, - "end_time": null, - "exception": null, - "start_time": null, - "status": "pending" - }, - "tags": [] - }, + "id": "16a97bff", + "metadata": {}, "outputs": [], "source": [ - "predictor = tuner.deploy(initial_instance_count=1, instance_type=\"ml.m4.xlarge\")" + "import time\n", + "import boto3\n", + "from sagemaker.core.resources import TrainingJob, Model, EndpointConfig, Endpoint\n", + "from sagemaker.core.shapes import ContainerDefinition, ProductionVariant\n", + "from sagemaker.core.utils import repack_model\n", + "\n", + "sm_client = boto3.client(\"sagemaker\")\n", + "sm_runtime = boto3.client(\"sagemaker-runtime\")\n", + "\n", + "# Get best training job\n", + "best_job_name = tuner.best_training_job()\n", + "print(f\"Best training job: {best_job_name}\")\n", + "\n", + "best_training_job = TrainingJob.get(training_job_name=best_job_name)\n", + "model_data = best_training_job.model_artifacts.s3_model_artifacts\n", + "print(f\"Best model artifacts: {model_data}\")\n", + "\n", + "inference_image = image_uris.retrieve(\n", + " framework=\"pytorch\", region=region, version=\"2.0.1\",\n", + " py_version=\"py310\", instance_type=\"ml.m5.xlarge\", image_scope=\"inference\",\n", + ")\n", + "\n", + "# Repack model with inference code using V3 repack_model utility\n", + "repackaged_s3 = f\"s3://{bucket}/{prefix}/repackaged-model/model.tar.gz\"\n", + "repack_model(\n", + " inference_script=\"mnist.py\",\n", + " source_directory=\".\",\n", + " dependencies=[],\n", + " model_uri=model_data,\n", + " repacked_model_uri=repackaged_s3,\n", + " sagemaker_session=sagemaker_session,\n", + ")\n", + "print(f\"Repacked model: {repackaged_s3}\")\n", + "\n", + "timestamp = time.strftime(\"%Y%m%d-%H%M%S\")\n", + "model_name = f\"pytorch-mnist-hpo-model-{timestamp}\"\n", + "endpoint_config_name = f\"pytorch-mnist-hpo-epc-{timestamp}\"\n", + "endpoint_name = f\"pytorch-mnist-hpo-ep-{timestamp}\"\n", + "\n", + "sm_model = Model.create(\n", + " model_name=model_name,\n", + " primary_container=ContainerDefinition(\n", + " image=inference_image,\n", + " model_data_url=repackaged_s3,\n", + " environment={\"SAGEMAKER_PROGRAM\": \"mnist.py\"},\n", + " ),\n", + " execution_role_arn=role,\n", + ")\n", + "print(f\"Model created: {model_name}\")\n", + "\n", + "endpoint_config = EndpointConfig.create(\n", + " endpoint_config_name=endpoint_config_name,\n", + " production_variants=[\n", + " ProductionVariant(\n", + " variant_name=\"AllTraffic\",\n", + " model_name=model_name,\n", + " instance_type=\"ml.m5.xlarge\",\n", + " initial_instance_count=1,\n", + " )\n", + " ],\n", + ")\n", + "print(f\"EndpointConfig created: {endpoint_config_name}\")\n", + "\n", + "sm_client.create_endpoint(EndpointName=endpoint_name, EndpointConfigName=endpoint_config_name)\n", + "print(f\"Creating endpoint: {endpoint_name} ...\")\n", + "waiter = sm_client.get_waiter(\"endpoint_in_service\")\n", + "waiter.wait(EndpointName=endpoint_name, WaiterConfig={\"Delay\": 30, \"MaxAttempts\": 60})\n", + "print(\"Endpoint in service!\")" ] }, { - "attachments": {}, "cell_type": "markdown", - "id": "35c535d9", - "metadata": { - "papermill": { - "duration": null, - "end_time": null, - "exception": null, - "start_time": null, - "status": "pending" - }, - "tags": [] - }, + "id": "2b61890e", + "metadata": {}, "source": [ "### Evaluate\n", - "We can now use this predictor to classify hand-written digits. \n", - "\n", - "You will see an empty image box once you've executed cell below. Then you can draw a number in it and pixel data will be loaded into a `data` variable in this notebook, which we can then pass to the `predictor`." + "We can now use this endpoint to classify hand-written digits. We load test images, serialize them with `NumpySerializer` (from `sagemaker.core.serializers`), and invoke the endpoint via `boto3 invoke_endpoint()`." ] }, { "cell_type": "code", "execution_count": null, - "id": "4cda6848", - "metadata": { - "papermill": { - "duration": null, - "end_time": null, - "exception": null, - "start_time": null, - "status": "pending" - }, - "scrolled": true, - "tags": [] - }, + "id": "0e39140a", + "metadata": {}, "outputs": [], "source": [ - "import gzip\n", "import numpy as np\n", "import random\n", - "import os\n", + "import io\n", "\n", "data_dir = \"data/MNIST/raw\"\n", "with gzip.open(os.path.join(data_dir, \"t10k-images-idx3-ubyte.gz\"), \"rb\") as f:\n", " images = np.frombuffer(f.read(), np.uint8, offset=16).reshape(-1, 28, 28).astype(np.float32)\n", "\n", "mask = random.sample(range(len(images)), 16) # randomly select some of the test images\n", - "mask = np.array(mask, dtype=np.int)\n", + "mask = np.array(mask, dtype=np.intp)\n", "data = images[mask]" ] }, { "cell_type": "code", "execution_count": null, - "id": "2de2dcfe", - "metadata": { - "papermill": { - "duration": null, - "end_time": null, - "exception": null, - "start_time": null, - "status": "pending" - }, - "tags": [] - }, + "id": "e7f78bab", + "metadata": {}, "outputs": [], "source": [ - "response = predictor.predict(np.expand_dims(data, axis=1))\n", + "from sagemaker.core.serializers import NumpySerializer\n", + "\n", + "serializer = NumpySerializer()\n", + "payload = serializer.serialize(np.expand_dims(data, axis=1))\n", + "\n", + "response = sm_runtime.invoke_endpoint(\n", + " EndpointName=endpoint_name,\n", + " ContentType=\"application/x-npy\",\n", + " Accept=\"application/x-npy\",\n", + " Body=payload,\n", + ")\n", + "result = np.load(io.BytesIO(response[\"Body\"].read()), allow_pickle=True)\n", + "\n", "print(\"Raw prediction result:\")\n", - "print(response)\n", + "print(result)\n", "print()\n", "\n", - "labeled_predictions = list(zip(range(10), response[0]))\n", + "labeled_predictions = list(zip(range(10), result[0]))\n", "print(\"Labeled predictions: \")\n", "print(labeled_predictions)\n", "print()\n", @@ -700,91 +533,34 @@ ] }, { - "attachments": {}, "cell_type": "markdown", - "id": "75d6cc80", - "metadata": { - "papermill": { - "duration": null, - "end_time": null, - "exception": null, - "start_time": null, - "status": "pending" - }, - "tags": [] - }, + "id": "8de4e951", + "metadata": {}, "source": [ "### Cleanup\n", "\n", - "After you have finished with this example, remember to delete the prediction endpoint to release the instance(s) associated with it" + "Delete the endpoint, endpoint configuration, and model to release resources and stop incurring charges." ] }, { "cell_type": "code", "execution_count": null, - "id": "a1d14c22", - "metadata": { - "papermill": { - "duration": null, - "end_time": null, - "exception": null, - "start_time": null, - "status": "pending" - }, - "tags": [] - }, + "id": "5b9a9c56", + "metadata": {}, "outputs": [], "source": [ - "tuner.delete_endpoint()" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "6d70a854", - "metadata": {}, - "source": [ - "## Notebook CI Test Results\n", - "\n", - "This notebook was tested in multiple regions. The test results are as follows, except for us-west-2 which is shown at the top of the notebook.\n", - "\n", - "![This us-east-1 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://prod.us-west-2.tcx-beacon.docs.aws.dev/sagemaker-nb/us-east-1/build_and_train_models|sm-hyperparameter_tuning_pytorch|sm-hyperparameter_tuning_pytorch.ipynb)\n", - "\n", - "![This us-east-2 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://prod.us-west-2.tcx-beacon.docs.aws.dev/sagemaker-nb/us-east-2/build_and_train_models|sm-hyperparameter_tuning_pytorch|sm-hyperparameter_tuning_pytorch.ipynb)\n", - "\n", - "![This us-west-1 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://prod.us-west-2.tcx-beacon.docs.aws.dev/sagemaker-nb/us-west-1/build_and_train_models|sm-hyperparameter_tuning_pytorch|sm-hyperparameter_tuning_pytorch.ipynb)\n", - "\n", - "![This ca-central-1 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://prod.us-west-2.tcx-beacon.docs.aws.dev/sagemaker-nb/ca-central-1/build_and_train_models|sm-hyperparameter_tuning_pytorch|sm-hyperparameter_tuning_pytorch.ipynb)\n", - "\n", - "![This sa-east-1 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://prod.us-west-2.tcx-beacon.docs.aws.dev/sagemaker-nb/sa-east-1/build_and_train_models|sm-hyperparameter_tuning_pytorch|sm-hyperparameter_tuning_pytorch.ipynb)\n", - "\n", - "![This eu-west-1 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://prod.us-west-2.tcx-beacon.docs.aws.dev/sagemaker-nb/eu-west-1/build_and_train_models|sm-hyperparameter_tuning_pytorch|sm-hyperparameter_tuning_pytorch.ipynb)\n", - "\n", - "![This eu-west-2 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://prod.us-west-2.tcx-beacon.docs.aws.dev/sagemaker-nb/eu-west-2/build_and_train_models|sm-hyperparameter_tuning_pytorch|sm-hyperparameter_tuning_pytorch.ipynb)\n", - "\n", - "![This eu-west-3 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://prod.us-west-2.tcx-beacon.docs.aws.dev/sagemaker-nb/eu-west-3/build_and_train_models|sm-hyperparameter_tuning_pytorch|sm-hyperparameter_tuning_pytorch.ipynb)\n", - "\n", - "![This eu-central-1 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://prod.us-west-2.tcx-beacon.docs.aws.dev/sagemaker-nb/eu-central-1/build_and_train_models|sm-hyperparameter_tuning_pytorch|sm-hyperparameter_tuning_pytorch.ipynb)\n", - "\n", - "![This eu-north-1 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://prod.us-west-2.tcx-beacon.docs.aws.dev/sagemaker-nb/eu-north-1/build_and_train_models|sm-hyperparameter_tuning_pytorch|sm-hyperparameter_tuning_pytorch.ipynb)\n", - "\n", - "![This ap-southeast-1 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://prod.us-west-2.tcx-beacon.docs.aws.dev/sagemaker-nb/ap-southeast-1/build_and_train_models|sm-hyperparameter_tuning_pytorch|sm-hyperparameter_tuning_pytorch.ipynb)\n", - "\n", - "![This ap-southeast-2 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://prod.us-west-2.tcx-beacon.docs.aws.dev/sagemaker-nb/ap-southeast-2/build_and_train_models|sm-hyperparameter_tuning_pytorch|sm-hyperparameter_tuning_pytorch.ipynb)\n", - "\n", - "![This ap-northeast-1 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://prod.us-west-2.tcx-beacon.docs.aws.dev/sagemaker-nb/ap-northeast-1/build_and_train_models|sm-hyperparameter_tuning_pytorch|sm-hyperparameter_tuning_pytorch.ipynb)\n", - "\n", - "![This ap-northeast-2 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://prod.us-west-2.tcx-beacon.docs.aws.dev/sagemaker-nb/ap-northeast-2/build_and_train_models|sm-hyperparameter_tuning_pytorch|sm-hyperparameter_tuning_pytorch.ipynb)\n", - "\n", - "![This ap-south-1 badge failed to load. Check your device's internet connectivity, otherwise the service is currently unavailable](https://prod.us-west-2.tcx-beacon.docs.aws.dev/sagemaker-nb/ap-south-1/build_and_train_models|sm-hyperparameter_tuning_pytorch|sm-hyperparameter_tuning_pytorch.ipynb)\n" + "sm_client.delete_endpoint(EndpointName=endpoint_name)\n", + "sm_client.delete_endpoint_config(EndpointConfigName=endpoint_config_name)\n", + "sm_client.delete_model(ModelName=model_name)\n", + "print(\"Cleanup complete.\")" ] } ], "metadata": { "kernelspec": { - "display_name": "Python 3 (PyTorch 1.10 Python 3.8 CPU Optimized)", + "display_name": "Python 3 (ipykernel)", "language": "python", - "name": "python3__SAGEMAKER_INTERNAL__arn:aws:sagemaker:us-west-2:236514542706:image/pytorch-1.10-cpu-py38" + "name": "python3" }, "language_info": { "codemirror_mode": { @@ -796,1400 +572,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.10" - }, - "notice": "Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. Licensed under the Apache License, Version 2.0 (the \"License\"). You may not use this file except in compliance with the License. A copy of the License is located at http://aws.amazon.com/apache2.0/ or in the \"license\" file accompanying this file. This file is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.", - "papermill": { - "default_parameters": {}, - "duration": 356.115593, - "end_time": "2021-06-04T00:25:04.018784", - "environment_variables": {}, - "exception": true, - "input_path": "hpo_pytorch_mnist.ipynb", - "output_path": "/opt/ml/processing/output/hpo_pytorch_mnist-2021-06-04-00-14-50.ipynb", - "parameters": { - "kms_key": "arn:aws:kms:us-west-2:521695447989:key/6e9984db-50cf-4c7e-926c-877ec47a8b25" - }, - "start_time": "2021-06-04T00:19:07.903191", - "version": "2.3.3" - }, - "widgets": { - "application/vnd.jupyter.widget-state+json": { - "state": { - "0a48ed59718d42cdbf66279c3b41030b": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "ProgressStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "ProgressStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "bar_color": null, - "description_width": "" - } - }, - "0d57feffe72948d6b9c975eca0d2b838": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HTMLModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_4b222c272327496e8cde87d1d93a26fb", - "placeholder": "​", - "style": "IPY_MODEL_c0a3b9718eb648fc9e16cc13e80b93f2", - "value": " 0%" - } - }, - "0db9457cd797437db3cc243533420906": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HTMLModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_7ccdc5f1e1a94eaf915449774862890a", - "placeholder": "​", - "style": "IPY_MODEL_825cb8ee0f4e4bbe9b4f722ea8b878ea", - "value": " 0%" - } - }, - "1be264ebf6cd4860936262eeea65aa18": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "FloatProgressModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "FloatProgressModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "ProgressView", - "bar_style": "info", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_4a0abffa504a400287b7b69eb687412b", - "max": 1, - "min": 0, - "orientation": "horizontal", - "style": "IPY_MODEL_df1c6338167146c48ccc8bfaae340f1d", - "value": 0 - } - }, - "28074c81b8ff45208c259ade3870d4d6": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "DescriptionStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - }, - "280e555e9f894fbd92be0bbf53e322f7": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HBoxModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HBoxModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HBoxView", - "box_style": "", - "children": [ - "IPY_MODEL_0db9457cd797437db3cc243533420906", - "IPY_MODEL_bef16c8945ec49aca94e42c2b06a971f", - "IPY_MODEL_8ef481987fe84d18abef6a99edbfde55" - ], - "layout": "IPY_MODEL_bf95ef1dd2414eec964b25b7a02ab8c6" - } - }, - "28aa2f2dd3054c7a9ee83cd6273b6874": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "2a44bca0af914383bbf9f8ae22940e62": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "DescriptionStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - }, - "3cad2fbcd54e450e864dc7ff0269acdb": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "3fb49f4bc95f4fa6b603f1048a66d126": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HTMLModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_7822236a79584d908311bfa13f6233b3", - "placeholder": "​", - "style": "IPY_MODEL_59e159be53fc4937954de036d950d06b", - "value": " 0/28881 [00:00<?, ?it/s]" - } - }, - "45b54aa0db84424dbb79c93a2cca4500": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": "20px" - } - }, - "4a0abffa504a400287b7b69eb687412b": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": "20px" - } - }, - "4b222c272327496e8cde87d1d93a26fb": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "52db93f9ebba42879ec5dc71b83f3456": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "FloatProgressModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "FloatProgressModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "ProgressView", - "bar_style": "info", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_e5ea4e0518c54f1f997efe10cc22e684", - "max": 1, - "min": 0, - "orientation": "horizontal", - "style": "IPY_MODEL_efb95f9a99cf4260b10a73b29057564e", - "value": 1 - } - }, - "59e159be53fc4937954de036d950d06b": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "DescriptionStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - }, - "601d94f21fe84f479d785a01a7010a63": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "614ba06d3ff343e9a79ab87c68245cdf": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "DescriptionStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - }, - "642c7b3c500b450bb1a4320fdc032af0": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "ProgressStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "ProgressStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "bar_color": null, - "description_width": "" - } - }, - "742f833508aa40ae832072f796f4dd83": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "7656e8023a8d46f58bef491201e20e86": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "7822236a79584d908311bfa13f6233b3": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "7b4283cba0b149bd957e36fde60bb6da": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HBoxModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HBoxModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HBoxView", - "box_style": "", - "children": [ - "IPY_MODEL_c4626ec8099b4e04a88f4c276e8a44ee", - "IPY_MODEL_fd60d2bcc4fb40ea84de3cfe9ab3e82b", - "IPY_MODEL_ae683b2e1439420ba286132a9edb716d" - ], - "layout": "IPY_MODEL_742f833508aa40ae832072f796f4dd83" - } - }, - "7ccdc5f1e1a94eaf915449774862890a": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "7f9a8650418b4f69a85f7aef4a0eee1b": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "825cb8ee0f4e4bbe9b4f722ea8b878ea": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "DescriptionStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - }, - "82a9c91fc7964b70b8b36e938569cebf": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HTMLModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_8687dd8a35eb4ac68665a34cef665c27", - "placeholder": "​", - "style": "IPY_MODEL_28074c81b8ff45208c259ade3870d4d6", - "value": " 9920512/? [05:10<00:00, 34025.71it/s]" - } - }, - "8687dd8a35eb4ac68665a34cef665c27": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "8ef481987fe84d18abef6a99edbfde55": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HTMLModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_d26ee95a5d914f25aafeed66fcde6df0", - "placeholder": "​", - "style": "IPY_MODEL_cd54721fa4a54664a0bfafac7b92d21a", - "value": " 0/4542 [00:00<?, ?it/s]" - } - }, - "929449d0f85240b9b4090cfa3e7d1d76": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HTMLModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_3cad2fbcd54e450e864dc7ff0269acdb", - "placeholder": "​", - "style": "IPY_MODEL_2a44bca0af914383bbf9f8ae22940e62", - "value": "" - } - }, - "a5b36f51a50b4f39acb61409905a8e4e": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "DescriptionStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - }, - "ac3cd11248254c9b9a436ef179adbe4e": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HBoxModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HBoxModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HBoxView", - "box_style": "", - "children": [ - "IPY_MODEL_929449d0f85240b9b4090cfa3e7d1d76", - "IPY_MODEL_52db93f9ebba42879ec5dc71b83f3456", - "IPY_MODEL_82a9c91fc7964b70b8b36e938569cebf" - ], - "layout": "IPY_MODEL_28aa2f2dd3054c7a9ee83cd6273b6874" - } - }, - "ae683b2e1439420ba286132a9edb716d": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HTMLModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_7656e8023a8d46f58bef491201e20e86", - "placeholder": "​", - "style": "IPY_MODEL_a5b36f51a50b4f39acb61409905a8e4e", - "value": " 1654784/? [00:50<00:00, 29498.13it/s]" - } - }, - "bc2f39803a9a424bae2935e4790eb572": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HBoxModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HBoxModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HBoxView", - "box_style": "", - "children": [ - "IPY_MODEL_0d57feffe72948d6b9c975eca0d2b838", - "IPY_MODEL_1be264ebf6cd4860936262eeea65aa18", - "IPY_MODEL_3fb49f4bc95f4fa6b603f1048a66d126" - ], - "layout": "IPY_MODEL_7f9a8650418b4f69a85f7aef4a0eee1b" - } - }, - "bef16c8945ec49aca94e42c2b06a971f": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "FloatProgressModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "FloatProgressModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "ProgressView", - "bar_style": "info", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_d6e69d7419fb4e6d9c42c40a9717bfbc", - "max": 1, - "min": 0, - "orientation": "horizontal", - "style": "IPY_MODEL_642c7b3c500b450bb1a4320fdc032af0", - "value": 0 - } - }, - "bf95ef1dd2414eec964b25b7a02ab8c6": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "c0a3b9718eb648fc9e16cc13e80b93f2": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "DescriptionStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - }, - "c4626ec8099b4e04a88f4c276e8a44ee": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "HTMLModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "HTMLModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "HTMLView", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_601d94f21fe84f479d785a01a7010a63", - "placeholder": "​", - "style": "IPY_MODEL_614ba06d3ff343e9a79ab87c68245cdf", - "value": "" - } - }, - "cd54721fa4a54664a0bfafac7b92d21a": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "DescriptionStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "DescriptionStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "description_width": "" - } - }, - "d26ee95a5d914f25aafeed66fcde6df0": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "d6e69d7419fb4e6d9c42c40a9717bfbc": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": "20px" - } - }, - "df1c6338167146c48ccc8bfaae340f1d": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "ProgressStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "ProgressStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "bar_color": null, - "description_width": "" - } - }, - "e5ea4e0518c54f1f997efe10cc22e684": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "1.2.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "1.2.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "overflow_x": null, - "overflow_y": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": "20px" - } - }, - "efb95f9a99cf4260b10a73b29057564e": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "ProgressStyleModel", - "state": { - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "ProgressStyleModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "1.2.0", - "_view_name": "StyleView", - "bar_color": null, - "description_width": "" - } - }, - "fd60d2bcc4fb40ea84de3cfe9ab3e82b": { - "model_module": "@jupyter-widgets/controls", - "model_module_version": "1.5.0", - "model_name": "FloatProgressModel", - "state": { - "_dom_classes": [], - "_model_module": "@jupyter-widgets/controls", - "_model_module_version": "1.5.0", - "_model_name": "FloatProgressModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/controls", - "_view_module_version": "1.5.0", - "_view_name": "ProgressView", - "bar_style": "info", - "description": "", - "description_tooltip": null, - "layout": "IPY_MODEL_45b54aa0db84424dbb79c93a2cca4500", - "max": 1, - "min": 0, - "orientation": "horizontal", - "style": "IPY_MODEL_0a48ed59718d42cdbf66279c3b41030b", - "value": 1 - } - } - }, - "version_major": 2, - "version_minor": 0 - } + "version": "3.12.9" } }, "nbformat": 4, "nbformat_minor": 5 -} +} \ No newline at end of file