{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Packaging and Deploying our ML model to our edge devices - Using IoT jobs\n", "\n", "In this exercise, we will:\n", "\n", " - Invoke SageMaker NEO to compile the trained model \n", " - Create a deployment package with a signed model + the runtime used by SageMaker Edge Agent to load and invoke the optimized model\n", " - Deploy the package using IoT Jobs" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import sagemaker\n", "import time\n", "import boto3\n", "import json\n", "import uuid\n", "\n", "s3_client = boto3.client('s3')\n", "sm_client = boto3.client('sagemaker')\n", "\n", "sagemaker_session = sagemaker.Session()\n", "\n", "role = sagemaker.get_execution_role()\n", "bucket_name = 'sagemaker-wind-turbine-farm-%s' % project_id\n", "\n", "prefix='wind_turbine_anomaly'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Compiling our ML model" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Invoking SageMaker NEO to compile the trained model" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "compilation_job_name = 'wind-turbine-anomaly-%d' % int(time.time()*1000)\n", "sm_client.create_compilation_job(\n", " CompilationJobName=compilation_job_name,\n", " RoleArn=role,\n", " InputConfig={\n", " 'S3Uri': '%s%s/output/model.tar.gz' % (estimator_output_path, training_job_name),\n", " 'DataInputConfig': '{\"input0\":[1,%d,10,10]}' % n_features,\n", " 'Framework': 'PYTORCH'\n", " },\n", " OutputConfig={\n", " 'S3OutputLocation': 's3://%s/wind_turbine/optimized/' % sagemaker_session.default_bucket(), \n", " 'TargetPlatform': { 'Os': 'LINUX', 'Arch': 'X86_64' }\n", " },\n", " StoppingCondition={ 'MaxRuntimeInSeconds': 900 }\n", ")\n", "while True:\n", " resp = sm_client.describe_compilation_job(CompilationJobName=compilation_job_name) \n", " if resp['CompilationJobStatus'] in ['STARTING', 'INPROGRESS']:\n", " print('Running...')\n", " else:\n", " print(resp['CompilationJobStatus'], compilation_job_name)\n", " break\n", " time.sleep(5)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Building the Deployment Package SageMaker Edge Manager\n", "It will sign the model and create a deployment package with:\n", " - The optimized model\n", " - Model Metadata\n", " - SageMaker NEO runtime (dlr)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "model_version = '1.0'\n", "model_name = 'WindTurbineAnomalyDetection'\n", "edge_packaging_job_name='wind-turbine-anomaly-%d' % int(time.time()*1000)\n", "\n", "resp = sm_client.create_edge_packaging_job(\n", " EdgePackagingJobName=edge_packaging_job_name,\n", " CompilationJobName=compilation_job_name,\n", " ModelName=model_name,\n", " ModelVersion=model_version,\n", " RoleArn=role,\n", " OutputConfig={\n", " 'S3OutputLocation': 's3://%s/%s/model/' % (bucket_name, prefix)\n", " }\n", ")\n", "while True:\n", " resp = sm_client.describe_edge_packaging_job(EdgePackagingJobName=edge_packaging_job_name) \n", " if resp['EdgePackagingJobStatus'] in ['STARTING', 'INPROGRESS']:\n", " print('Running...')\n", " else:\n", " print(resp['EdgePackagingJobStatus'], compilation_job_name)\n", " break\n", " time.sleep(5)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Deploy the package\n", "Using IoT Jobs, we will notify the Python application in the edge devices. The application will:\n", " - download the deployment package\n", " - unpack it\n", " - load the new mode (unload previous versions if any)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "iot_client = boto3.client('iot')\n", "sts_client = boto3.client('sts')\n", "\n", "region_name = sagemaker_session.boto_session.region_name\n", "account_id = sts_client.get_caller_identity()[\"Account\"]\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "resp = iot_client.create_job(\n", " jobId=str(uuid.uuid4()),\n", " targets=[\n", " 'arn:aws:iot:%s:%s:thinggroup/WindTurbineFarm-%s' % (region_name, account_id, project_id), \n", " ],\n", " document=json.dumps({\n", " 'type': 'new_model',\n", " 'model_version': model_version,\n", " 'model_name': model_name,\n", " 'model_package_bucket': bucket_name,\n", " 'model_package_key': \"%s/model/%s-%s.tar.gz\" % (prefix, model_name, model_version) \n", " }),\n", " targetSelection='SNAPSHOT'\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First, let us restore variables stored in the previous exercise" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%store -r project_id\n", "%store -r estimator_output_path\n", "%store -r training_job_name\n", "%store -r n_features" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Alright! Now, the deployment process will start on the connected edge devices! \n", "You can start the Exercise #4: Run a simulated fleet of wind turbines and edge devices. Predict anomalies\n", " \n", " > [Exercise 04](../../04-Run-Fleet/greengrass-v2/04-run-fleet-iot-jobs.ipynb)\n" ] } ], "metadata": { "instance_type": "ml.t3.medium", "kernelspec": { "display_name": "Python 3 (Data Science)", "language": "python", "name": "python3__SAGEMAKER_INTERNAL__arn:aws:sagemaker:eu-central-1:936697816551:image/datascience-1.0" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.10" } }, "nbformat": 4, "nbformat_minor": 4 }