{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Spacy Pre-Trained NER Deployment Example" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[Container Structure](https://sagemaker-workshop.com/custom/containers.html)\n", "- NER\n", " - predictor.py: (Flask app for inference)\n", " - wsgi.py: (Wrapper around predictor)\n", " - nginx.conf: (Config for nginx front-end)\n", " - serve: program for container hosting, launches gunicorn server\n", " - Note that there is no train for pre-trained\n", "- Dockerfile" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Push Docker Image to ECR" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%%sh\n", "\n", "# Name of algo -> ECR\n", "algorithm_name=sm-pretrained-spacy\n", "\n", "cd container\n", "\n", "#make serve executable\n", "chmod +x NER/serve\n", "\n", "account=$(aws sts get-caller-identity --query Account --output text)\n", "\n", "# Region, defaults to us-west-2\n", "region=$(aws configure get region)\n", "region=${region:-us-east-1}\n", "\n", "fullname=\"${account}.dkr.ecr.${region}.amazonaws.com/${algorithm_name}:latest\"\n", "\n", "# If the repository doesn't exist in ECR, create it.\n", "aws ecr describe-repositories --repository-names \"${algorithm_name}\" > /dev/null 2>&1\n", "\n", "if [ $? -ne 0 ]\n", "then\n", " aws ecr create-repository --repository-name \"${algorithm_name}\" > /dev/null\n", "fi\n", "\n", "# Get the login command from ECR and execute it directly\n", "aws ecr get-login-password --region ${region}|docker login --username AWS --password-stdin ${fullname}\n", "\n", "# Build the docker image locally with the image name and then push it to ECR\n", "# with the full name.\n", "\n", "docker build -t ${algorithm_name} .\n", "docker tag ${algorithm_name} ${fullname}\n", "\n", "docker push ${fullname}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# SageMaker Client Setup\n", "\n", "- [SageMaker Client](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sagemaker.html#SageMaker.Client.create_model): Model, Endpoint Config, and Endpoint Creation\n", "- [SageMaker RunTime Client](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sagemaker-runtime.html#SageMakerRuntime.Client.invoke_endpoint): Endpoint Invocation/Testing" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import boto3\n", "from sagemaker import get_execution_role\n", "\n", "sm_client = boto3.client(service_name='sagemaker')\n", "runtime_sm_client = boto3.client(service_name='sagemaker-runtime')\n", "\n", "account_id = boto3.client('sts').get_caller_identity()['Account']\n", "region = boto3.Session().region_name\n", "\n", "#not really used in this use case, use when need to store model artifacts (Ex: MME)\n", "s3_bucket = 'spacy-sagemaker-us-east-1-bucket'\n", "\n", "role = get_execution_role()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Model Creation\n", "[Documentation](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sagemaker.html#SageMaker.Client.create_model)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from time import gmtime, strftime\n", "\n", "model_name = 'spacy-nermodel-' + strftime(\"%Y-%m-%d-%H-%M-%S\", gmtime())\n", "model_url = 's3://{}/spacy/'.format(s3_bucket) ## MODEL S3 URL\n", "container = '{}.dkr.ecr.{}.amazonaws.com/sm-pretrained-spacy:latest'.format(account_id, region)\n", "instance_type = 'ml.c5d.18xlarge'\n", "\n", "print('Model name: ' + model_name)\n", "print('Model data Url: ' + model_url)\n", "print('Container image: ' + container)\n", "\n", "container = {\n", " 'Image': container\n", "}\n", "\n", "create_model_response = sm_client.create_model(\n", " ModelName = model_name,\n", " ExecutionRoleArn = role,\n", " Containers = [container])\n", "\n", "print(\"Model Arn: \" + create_model_response['ModelArn'])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Endpoint Config Creation\n", "\n", "[Documentation](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sagemaker.html#SageMaker.Client.create_endpoint_config)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "endpoint_config_name = 'spacy-ner-config' + strftime(\"%Y-%m-%d-%H-%M-%S\", gmtime())\n", "print('Endpoint config name: ' + endpoint_config_name)\n", "\n", "create_endpoint_config_response = sm_client.create_endpoint_config(\n", " EndpointConfigName = endpoint_config_name,\n", " ProductionVariants=[{\n", " 'InstanceType': instance_type,\n", " 'InitialInstanceCount': 1,\n", " 'InitialVariantWeight': 1,\n", " 'ModelName': model_name,\n", " 'VariantName': 'AllTraffic'}])\n", "\n", "print(\"Endpoint config Arn: \" + create_endpoint_config_response['EndpointConfigArn'])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Endpoint Creation\n", "[Documentation](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sagemaker.html#SageMaker.Client.create_endpoint)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%%time\n", "\n", "import time\n", "\n", "endpoint_name = 'spacy-ner-endpoint' + strftime(\"%Y-%m-%d-%H-%M-%S\", gmtime())\n", "print('Endpoint name: ' + endpoint_name)\n", "\n", "create_endpoint_response = sm_client.create_endpoint(\n", " EndpointName=endpoint_name,\n", " EndpointConfigName=endpoint_config_name)\n", "print('Endpoint Arn: ' + create_endpoint_response['EndpointArn'])\n", "\n", "resp = sm_client.describe_endpoint(EndpointName=endpoint_name)\n", "status = resp['EndpointStatus']\n", "print(\"Endpoint Status: \" + status)\n", "\n", "print('Waiting for {} endpoint to be in service...'.format(endpoint_name))\n", "waiter = sm_client.get_waiter('endpoint_in_service')\n", "waiter.wait(EndpointName=endpoint_name)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Endpoint Invocation\n", "\n", "[Documentation](https://boto3.amazonaws.com/v1/documentation/api/1.9.42/reference/services/sagemaker-runtime.html#SageMakerRuntime.Client.invoke_endpoint)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import json\n", "content_type = \"application/json\"\n", "request_body = {\"input\": \"This is a test with NER in America with Amazon and Microsoft in Seattle, writing random stuff.\"}\n", "\n", "#Serialize data for endpoint\n", "data = json.loads(json.dumps(request_body))\n", "payload = json.dumps(data)\n", "\n", "#Endpoint invocation\n", "response = runtime_sm_client.invoke_endpoint(\n", " EndpointName=endpoint_name,\n", " ContentType=content_type,\n", " Body=payload)\n", "\n", "#Parse results\n", "result = json.loads(response['Body'].read().decode())['output']\n", "result" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Delete Endpoint" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Before leaving this exercise, it is a good practice to delete the resources created." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# sm_client.delete_endpoint(EndpointName=endpoint_name)\n", "# sm_client.delete_endpoint_config(EndpointConfigName=EndpointConfigName)\n", "# sm_client.delete_model(ModelName=ModelName)" ] } ], "metadata": { "instance_type": "ml.t3.medium", "kernelspec": { "display_name": "Python 3 (Data Science)", "language": "python", "name": "python3__SAGEMAKER_INTERNAL__arn:aws:sagemaker:us-west-2:236514542706:image/datascience-1.0" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.10" } }, "nbformat": 4, "nbformat_minor": 5 }