From 797d354a053c96697a0e9b2598aa83ad3c120e9f Mon Sep 17 00:00:00 2001 From: Kaustav Date: Thu, 27 Jul 2023 12:49:55 -0400 Subject: [PATCH 1/9] stable stack --- .../.gitignore | 10 + .../README.md | 99 ++++++++++ .../app.py | 32 ++++ .../cdk.json | 52 +++++ .../cdk_stablediffusion_python_stack.py | 181 ++++++++++++++++++ .../lambda/InvokeSagemakerEndpointLambda.py | 35 ++++ .../requirements.txt | 5 + .../source.bat | 13 ++ .../template.yaml | 16 ++ .../util/sagemaker_endpoint_construct.py | 66 +++++++ .../util/sagemaker_util.py | 35 ++++ 11 files changed, 544 insertions(+) create mode 100644 apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/.gitignore create mode 100644 apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/README.md create mode 100644 apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/app.py create mode 100644 apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/cdk.json create mode 100644 apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/cdk_stablediffusion_python/cdk_stablediffusion_python_stack.py create mode 100644 apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/lambda/InvokeSagemakerEndpointLambda.py create mode 100644 apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/requirements.txt create mode 100644 apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/source.bat create mode 100644 apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/template.yaml create mode 100644 apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/util/sagemaker_endpoint_construct.py create mode 100644 apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/util/sagemaker_util.py diff --git a/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/.gitignore b/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/.gitignore new file mode 100644 index 000000000..37833f8be --- /dev/null +++ b/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/.gitignore @@ -0,0 +1,10 @@ +*.swp +package-lock.json +__pycache__ +.pytest_cache +.venv +*.egg-info + +# CDK asset staging directory +.cdk.staging +cdk.out diff --git a/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/README.md b/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/README.md new file mode 100644 index 000000000..4031abce0 --- /dev/null +++ b/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/README.md @@ -0,0 +1,99 @@ +# AWS Service 1 to AWS Service 2 + +This pattern deploys a Stable diffusion model endpoint using AWS Sagemaker. It also adds a lambda and an API Gateway serve the endpoint + +Learn more about this pattern at Serverless Land Patterns: https://serverlessland.com/patterns/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python + +Important: this application uses various AWS services and there are costs associated with these services after the Free Tier usage - please see the [AWS Pricing page](https://aws.amazon.com/pricing/) for details. You are responsible for any AWS costs incurred. No warranty is implied in this example. + +## Requirements + +* [Create an AWS account](https://portal.aws.amazon.com/gp/aws/developer/registration/index.html) if you do not already have one and log in. The IAM user that you use must have sufficient permissions to make necessary AWS service calls and manage AWS resources. +* [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html) installed and configured +* [Git Installed](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) +* [Python, pip, virtuenv](https://docs.aws.amazon.com/cdk/latest/guide/work-with-cdk-python.html) installed +* [AWS Cloud Development Kit](https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html) (AWS CDK >= 2.2.0) Installed + +## Deployment Instructions + +1. Clone the project to your local working directory + + ```sh + git clone https://github.com/aws-samples/serverless-patterns + ``` + +2. Change directory to this pattern directory: + ```sh + cd serverless-patterns/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python + ``` +3. Create and activate the project's virtual environment. This allows the project's dependencies to be installed locally in the project folder, instead of globally. Note that if you have multiple versions of Python installed, where the `python` command references Python 2.x, then you can reference Python 3.x by using the `python3` command. You can check which version of Python is being referenced by running the command `python --version` or `python3 --version` + + ```sh + python3 -m venv .venv + source .venv/bin/activate + ``` + +4. Install the project dependencies + + ```sh +cdk deploy + python -m pip install -r requirements.txt + ``` + +5. Deploy the stack to your default AWS account and region. + + ```sh + cdk deploy + ``` + +6. The default instance count for inference is set to 1. The instance count can be changed by passing the instance_count_param. + + ```sh + cdk deploy --context instance_count_param=2 + + ``` + + +## How it works + +Explain how the service interaction works. + +## Testing + +1. Retrieve the Host URL of the API Gateway + +2. Retreive the API key from AWS Console + +3. Sample HTTP request to the API Gateway: + ``` + POST /prod/generateimage HTTP/1.1 + Host: + x-api-key: + Cache-Control: no-cache + { + "query": { + "prompt": "surprize me", + "negative_prompt": "(deformed iris, deformed pupils), (text), out of frame, low quality, jpeg artifacts, (bad art:1.1), plain, dull, (blurry:1.4), disfigured, bad art, deformed, poorly drawn, strange colors, blurry, boring, sketch, lacklustre, religious figure, religion, race, nudity, cropped", + "width": 512, + "height": 512, + "num_images_per_prompt": 1, + "num_inference_steps": 50, + "guidance_scale": 7.5 + } + } + + ``` + + +## Cleanup + +Run the given command to delete the resources that were created. It might take some time for the CloudFormation stack to get deleted. + +```sh +cdk destroy +``` + +---- +Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved. + +SPDX-License-Identifier: MIT-0 \ No newline at end of file diff --git a/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/app.py b/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/app.py new file mode 100644 index 000000000..05ddc62fb --- /dev/null +++ b/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/app.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python3 +import aws_cdk as cdk +import boto3 +from cdk_stablediffusion_python.cdk_stablediffusion_python_stack import CdkStablediffusionPythonStack +from util.sagemaker_util import * + +region_name = boto3.Session().region_name +env = {"region": region_name} + +# Text to Image model parameters +TXT2IMG_MODEL_ID = "model-txt2img-stabilityai-stable-diffusion-v2-1-base" + +# For Development +TXT2IMG_INFERENCE_INSTANCE_TYPE = "ml.g5.2xlarge" + +# For Production +#TXT2IMG_INFERENCE_INSTANCE_TYPE = "ml.g5.12xlarge" + +TXT2IMG_MODEL_INFO = get_sagemaker_uris(model_id=TXT2IMG_MODEL_ID, + instance_type=TXT2IMG_INFERENCE_INSTANCE_TYPE, + region_name=region_name) + +app = cdk.App() + +stack = CdkStablediffusionPythonStack( + app, + "Web3WorkshopStableDiffusionStack", + model_info=TXT2IMG_MODEL_INFO, + env=env +) + +app.synth() diff --git a/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/cdk.json b/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/cdk.json new file mode 100644 index 000000000..c9710ade4 --- /dev/null +++ b/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/cdk.json @@ -0,0 +1,52 @@ +{ + "app": "python3 app.py", + "watch": { + "include": [ + "**" + ], + "exclude": [ + "README.md", + "cdk*.json", + "requirements*.txt", + "source.bat", + "**/__init__.py", + "python/__pycache__", + "tests" + ] + }, + "context": { + "@aws-cdk/aws-lambda:recognizeLayerVersion": true, + "@aws-cdk/core:checkSecretUsage": true, + "@aws-cdk/core:target-partitions": [ + "aws", + "aws-cn" + ], + "@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true, + "@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true, + "@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true, + "@aws-cdk/aws-iam:minimizePolicies": true, + "@aws-cdk/core:validateSnapshotRemovalPolicy": true, + "@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true, + "@aws-cdk/aws-s3:createDefaultLoggingPolicy": true, + "@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true, + "@aws-cdk/aws-apigateway:disableCloudWatchRole": true, + "@aws-cdk/core:enablePartitionLiterals": true, + "@aws-cdk/aws-events:eventsTargetQueueSameAccount": true, + "@aws-cdk/aws-iam:standardizedServicePrincipals": true, + "@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true, + "@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": true, + "@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true, + "@aws-cdk/aws-route53-patters:useCertificate": true, + "@aws-cdk/customresources:installLatestAwsSdkDefault": false, + "@aws-cdk/aws-rds:databaseProxyUniqueResourceName": true, + "@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": true, + "@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": true, + "@aws-cdk/aws-ec2:launchTemplateDefaultUserData": true, + "@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": true, + "@aws-cdk/aws-redshift:columnId": true, + "@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2": true, + "@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": true, + "@aws-cdk/aws-apigateway:requestValidatorUniqueId": true, + "@aws-cdk/aws-kms:aliasNameRef": true + } +} diff --git a/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/cdk_stablediffusion_python/cdk_stablediffusion_python_stack.py b/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/cdk_stablediffusion_python/cdk_stablediffusion_python_stack.py new file mode 100644 index 000000000..303f7c030 --- /dev/null +++ b/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/cdk_stablediffusion_python/cdk_stablediffusion_python_stack.py @@ -0,0 +1,181 @@ +from aws_cdk import ( + Stack, Duration, + aws_iam as iam, + aws_ssm as ssm, + aws_lambda as _lambda, + aws_apigateway as apigateway, +) + +from constructs import Construct +from util.sagemaker_endpoint_construct import SageMakerEndpointConstruct +from datetime import datetime + +class CdkStablediffusionPythonStack(Stack): + + def __init__(self, scope: Construct, construct_id: str, model_info, **kwargs) -> None: + super().__init__(scope, construct_id, **kwargs) + + # Get the instance count parameter from the context or use a default value + instance_count_param = self.node.try_get_context("instance_count_param") + instance_count = int(instance_count_param) if instance_count_param else 1 + + role = iam.Role(self, "Gen-AI-SageMaker-Policy", assumed_by=iam.ServicePrincipal("sagemaker.amazonaws.com")) + role.add_managed_policy(iam.ManagedPolicy.from_aws_managed_policy_name("AmazonS3FullAccess")) + + sts_policy = iam.Policy(self, "sm-deploy-policy-sts", + statements=[iam.PolicyStatement( + effect=iam.Effect.ALLOW, + actions=[ + "sts:AssumeRole" + ], + resources=["*"] + )] + ) + + logs_policy = iam.Policy(self, "sm-deploy-policy-logs", + statements=[iam.PolicyStatement( + effect=iam.Effect.ALLOW, + actions=[ + "cloudwatch:PutMetricData", + "logs:CreateLogStream", + "logs:PutLogEvents", + "logs:CreateLogGroup", + "logs:DescribeLogStreams", + "ecr:GetAuthorizationToken" + ], + resources=["*"] + )] + ) + + ecr_policy = iam.Policy(self, "sm-deploy-policy-ecr", + statements=[iam.PolicyStatement( + effect=iam.Effect.ALLOW, + actions=[ + "ecr:*", + ], + resources=["*"] + )] + ) + + role.attach_inline_policy(sts_policy) + role.attach_inline_policy(logs_policy) + role.attach_inline_policy(ecr_policy) + + # Generate a unique model name + model_name = f"SDTxt2Img-{datetime.now().strftime('%Y%m%d%H%M%S')}" + + # Create a SageMaker endpoint that can be used to generate images from text + endpoint = SageMakerEndpointConstruct(self, "TXT2IMG", + project_prefix=f"GenAIDemo-{instance_count}", + role_arn=role.role_arn, + model_name=model_name, + model_bucket_name=model_info["model_bucket_name"], + model_bucket_key=model_info["model_bucket_key"], + model_docker_image=model_info["model_docker_image"], + variant_name="AllTraffic", + variant_weight=1, + instance_count=instance_count, + instance_type=model_info["instance_type"], + environment={ + "MMS_MAX_RESPONSE_SIZE": "20000000", + "SAGEMAKER_CONTAINER_LOG_LEVEL": "20", + "SAGEMAKER_PROGRAM": "inference.py", + "SAGEMAKER_REGION": model_info["region_name"], + "SAGEMAKER_SUBMIT_DIRECTORY": "/opt/ml/model/code", + }, + + deploy_enable=True + ) + + endpoint.node.add_dependency(sts_policy) + endpoint.node.add_dependency(logs_policy) + endpoint.node.add_dependency(ecr_policy) + + ssm.StringParameter(self, "txt2img_endpoint", parameter_name="txt2img_endpoint", + string_value=endpoint.endpoint_name) + + # Create a Lambda function to invoke the SageMaker endpoint + lambda_function = _lambda.Function( + self, + "InvokeSagemakerEndpointLambda", + function_name="InvokeSagemakerEndpointLambda", + runtime=_lambda.Runtime.PYTHON_3_9, + handler="InvokeSagemakerEndpointLambda.lambda_handler", + code=_lambda.Code.from_asset("lambda"), + environment={ + "SAGEMAKER_ENDPOINT_NAME": endpoint.endpoint_name, + }, + timeout=Duration.seconds(500) + ) + + # Add the necessary IAM permissions to the Lambda function to invoke the SageMaker endpoint + lambda_function.add_to_role_policy(iam.PolicyStatement( + effect=iam.Effect.ALLOW, + actions=["sagemaker:InvokeEndpoint"], + resources=[endpoint.endpoint_arn] + )) + + # Add the SageMaker endpoint as a dependency of the Lambda function + lambda_function.node.add_dependency(endpoint) + + # Create the REST API Gateway + api = apigateway.RestApi( + self, + "StableDiffusionAPI", + rest_api_name="StableDiffusionAPI" + ) + + # Store the API Gateway URL in an SSM Parameter + ssm.StringParameter( + self, + "api_gateway_url", + parameter_name="/StableDiffusionAPI/URL", + string_value=api.url, + ) + + # Add the usage plan + usage_plan = api.add_usage_plan( + "StableDiffusionAPIUsagePlan", + name="StableDiffusionAPIUsagePlan", + throttle=apigateway.ThrottleSettings( + rate_limit=1000, + burst_limit=2000 + ) + ) + # Create the API key + api_key = api.add_api_key("StableDiffusionAPIKey") + + # Associate the API key with the usage plan + usage_plan.add_api_key(api_key) + + # Store the API key in an SSM Parameter + ssm.StringParameter( + self, + "api_gateway_key", + parameter_name="/StableDiffusionAPI/APIKey", + string_value=api_key.key_id, # Store the API key value + ) + + # Create the API Gateway integration with the Lambda function + integration = apigateway.LambdaIntegration( + lambda_function, + proxy=True, + ) + + # Create a resource and attach the integration + resource = api.root.add_resource("generateimage") + method = resource.add_method( + http_method="POST", + integration=integration, + api_key_required=True + ) + # Add the API stage and associate it with the usage plan + stage = api.deployment_stage + usage_plan.add_api_stage( + api=api, + stage=api.deployment_stage + ) + + # Add dependency between Lambda function and API Gateway + api.node.add_dependency(lambda_function) + diff --git a/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/lambda/InvokeSagemakerEndpointLambda.py b/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/lambda/InvokeSagemakerEndpointLambda.py new file mode 100644 index 000000000..703f2f3db --- /dev/null +++ b/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/lambda/InvokeSagemakerEndpointLambda.py @@ -0,0 +1,35 @@ +import json +import os +import boto3 + + +def lambda_handler(event, context): + + # Extract the input data from the request body + input_payload = json.loads(event['body'])['query'] + + # Fetch the endpoint name from the environment variable + endpoint_name = os.environ['SAGEMAKER_ENDPOINT_NAME'] + + # Create a SageMaker runtime client + runtime = boto3.client('sagemaker-runtime') + + try: + """Query the SageMaker endpoint.""" + payload = json.dumps(input_payload) + response = runtime.invoke_endpoint(EndpointName=endpoint_name, + ContentType='application/json', + Body=payload) + query_response = response['Body'].read().decode('utf-8') + + # Return the result as the Lambda function response + return { + 'statusCode': 200, + 'body': query_response + } + except Exception as e: + # Handle any errors that occur during the invocation + return { + 'statusCode': 500, + 'body': str(e) + } diff --git a/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/requirements.txt b/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/requirements.txt new file mode 100644 index 000000000..b8fa8c302 --- /dev/null +++ b/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/requirements.txt @@ -0,0 +1,5 @@ +aws-cdk-lib==2.83.1 +constructs>=10.0.0,<11.0.0 +requests +boto3 +sagemaker \ No newline at end of file diff --git a/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/source.bat b/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/source.bat new file mode 100644 index 000000000..9e1a83442 --- /dev/null +++ b/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/source.bat @@ -0,0 +1,13 @@ +@echo off + +rem The sole purpose of this script is to make the command +rem +rem source .venv/bin/activate +rem +rem (which activates a Python virtualenv on Linux or Mac OS X) work on Windows. +rem On Windows, this command just runs this batch file (the argument is ignored). +rem +rem Now we don't need to document a Windows command for activating a virtualenv. + +echo Executing .venv\Scripts\activate.bat for you +.venv\Scripts\activate.bat diff --git a/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/template.yaml b/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/template.yaml new file mode 100644 index 000000000..269f82e41 --- /dev/null +++ b/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/template.yaml @@ -0,0 +1,16 @@ +AWSTemplateFormatVersion: '2010-09-09' +Transform: AWS::Serverless-2016-10-31 +Description: Serverless patterns - Service to Service description + +# Comment on each global +Globals: + + +# Comment each resource section to explain usage +Resources: + + +# List all common outputs for usage +Outputs: + + diff --git a/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/util/sagemaker_endpoint_construct.py b/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/util/sagemaker_endpoint_construct.py new file mode 100644 index 000000000..5743c5303 --- /dev/null +++ b/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/util/sagemaker_endpoint_construct.py @@ -0,0 +1,66 @@ +from aws_cdk import ( + aws_sagemaker as sagemaker, + aws_ssm as ssm, + CfnOutput +) +from constructs import Construct + + +class SageMakerEndpointConstruct(Construct): + + def __init__(self, scope: Construct, construct_id: str, + project_prefix: str, + role_arn: str, + model_name: str, + model_bucket_name: str, + model_bucket_key: str, + model_docker_image: str, + variant_name: str, + variant_weight: int, + instance_count: int, + instance_type: str, + environment: dict, + deploy_enable: bool) -> None: + super().__init__(scope, construct_id) + + model = sagemaker.CfnModel(self, f"{model_name}-Model", + execution_role_arn=role_arn, + containers=[ + sagemaker.CfnModel.ContainerDefinitionProperty( + image=model_docker_image, + model_data_url=f"s3://{model_bucket_name}/{model_bucket_key}", + environment=environment + ) + ], + model_name=f"{project_prefix}-{model_name}-Model" + ) + + config = sagemaker.CfnEndpointConfig(self, f"{model_name}-Config", + endpoint_config_name=f"{project_prefix}-{model_name}-Config", + production_variants=[ + sagemaker.CfnEndpointConfig.ProductionVariantProperty( + model_name=model.attr_model_name, + variant_name=variant_name, + initial_variant_weight=variant_weight, + initial_instance_count=instance_count, + instance_type=instance_type + ) + ] + ) + + self.deploy_enable = deploy_enable + if deploy_enable: + self.endpoint = sagemaker.CfnEndpoint(self, f"{model_name}-Endpoint", + endpoint_name=f"{project_prefix}-{model_name}-Endpoint", + endpoint_config_name=config.attr_endpoint_config_name + ) + + CfnOutput(scope=self, id=f"{model_name}EndpointName", value=self.endpoint.endpoint_name) + + @property + def endpoint_name(self) -> str: + return self.endpoint.attr_endpoint_name if self.deploy_enable else "not_yet_deployed" + + @property + def endpoint_arn(self) -> str: + return self.endpoint.ref if self.deploy_enable else "not_yet_deployed" diff --git a/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/util/sagemaker_util.py b/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/util/sagemaker_util.py new file mode 100644 index 000000000..dd336ef59 --- /dev/null +++ b/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/util/sagemaker_util.py @@ -0,0 +1,35 @@ +import sagemaker +from sagemaker import script_uris +from sagemaker import image_uris +from sagemaker import model_uris + +session = sagemaker.Session() + + +def get_sagemaker_uris(model_id, instance_type, region_name): + + MODEL_VERSION = "*" # latest + SCOPE = "inference" + + inference_image_uri = image_uris.retrieve(region=region_name, + framework=None, + model_id=model_id, + model_version=MODEL_VERSION, + image_scope=SCOPE, + instance_type=instance_type) + + inference_model_uri = model_uris.retrieve(model_id=model_id, + model_version=MODEL_VERSION, + model_scope=SCOPE) + + inference_source_uri = script_uris.retrieve(model_id=model_id, + model_version=MODEL_VERSION, + script_scope=SCOPE) + + model_bucket_name = inference_model_uri.split("/")[2] + model_bucket_key = "/".join(inference_model_uri.split("/")[3:]) + model_docker_image = inference_image_uri + + return {"model_bucket_name": model_bucket_name, "model_bucket_key": model_bucket_key, + "model_docker_image": model_docker_image, "instance_type": instance_type, + "inference_source_uri": inference_source_uri, "region_name": region_name} From 0b47a0640f344a0d971bf9191f8dc3e22d2bdb64 Mon Sep 17 00:00:00 2001 From: kaustavbecs Date: Thu, 27 Jul 2023 15:31:10 -0400 Subject: [PATCH 2/9] Final Commit --- .../README.md | 28 +++++++++--------- .../app.py | 29 +++++++++++-------- ...wLambdaSagemakerJumpstartendpointStack.py} | 26 ++++++++--------- 3 files changed, 45 insertions(+), 38 deletions(-) rename apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/{cdk_stablediffusion_python/cdk_stablediffusion_python_stack.py => stack/ApigwLambdaSagemakerJumpstartendpointStack.py} (89%) diff --git a/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/README.md b/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/README.md index 4031abce0..0e3fc3041 100644 --- a/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/README.md +++ b/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/README.md @@ -1,6 +1,6 @@ # AWS Service 1 to AWS Service 2 -This pattern deploys a Stable diffusion model endpoint using AWS Sagemaker. It also adds a lambda and an API Gateway serve the endpoint +This pattern deploys a Sagemaker Jumpstart model (Flan T5 XL) endpoint using AWS Sagemaker. It also adds a lambda and an API Gateway serve the endpoint Learn more about this pattern at Serverless Land Patterns: https://serverlessland.com/patterns/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python @@ -36,7 +36,6 @@ Important: this application uses various AWS services and there are costs associ 4. Install the project dependencies ```sh -cdk deploy python -m pip install -r requirements.txt ``` @@ -56,7 +55,13 @@ cdk deploy ## How it works -Explain how the service interaction works. +1. This pattern deploys a Sagemaker Jumpstart model (Flan T5 XL) endpoint using AWS Sagemaker. The model can be changed by changing the ```MODEL_ID``` attribute in app.py file + +2. The pattern also adds a lambda and an API Gateway query the endpoint + +3. The API Gateway is protected using an API Key. ```x-api-key``` header needs to be added to the HTTP request. + +It also adds a lambda and an API Gateway serve the endpoint. ## Testing @@ -64,26 +69,23 @@ Explain how the service interaction works. 2. Retreive the API key from AWS Console -3. Sample HTTP request to the API Gateway: +3. Send a sample HTTP request to the API Gateway: ``` POST /prod/generateimage HTTP/1.1 Host: x-api-key: Cache-Control: no-cache { - "query": { - "prompt": "surprize me", - "negative_prompt": "(deformed iris, deformed pupils), (text), out of frame, low quality, jpeg artifacts, (bad art:1.1), plain, dull, (blurry:1.4), disfigured, bad art, deformed, poorly drawn, strange colors, blurry, boring, sketch, lacklustre, religious figure, religion, race, nudity, cropped", - "width": 512, - "height": 512, - "num_images_per_prompt": 1, - "num_inference_steps": 50, - "guidance_scale": 7.5 - } + "query": { + "text_inputs": "A step by step recipe to make butter chicken:", + "max_length": 5000 + } } ``` +4. The API Gateway should respond with a JSON formatted response from the Sagamaker endpoint + ## Cleanup diff --git a/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/app.py b/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/app.py index 05ddc62fb..97fb66ec9 100644 --- a/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/app.py +++ b/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/app.py @@ -1,31 +1,36 @@ #!/usr/bin/env python3 import aws_cdk as cdk import boto3 -from cdk_stablediffusion_python.cdk_stablediffusion_python_stack import CdkStablediffusionPythonStack +from stack.ApigwLambdaSagemakerJumpstartendpointStack import ApigwLambdaSagemakerJumpstartendpointStack from util.sagemaker_util import * region_name = boto3.Session().region_name env = {"region": region_name} -# Text to Image model parameters -TXT2IMG_MODEL_ID = "model-txt2img-stabilityai-stable-diffusion-v2-1-base" -# For Development -TXT2IMG_INFERENCE_INSTANCE_TYPE = "ml.g5.2xlarge" +# Obtain the model ID from: https://sagemaker.readthedocs.io/en/v2.173.0/doc_utils/pretrainedmodels.html +# Here we are using Flan T5 XL Model +MODEL_ID = "huggingface-text2text-flan-t5-xl" -# For Production -#TXT2IMG_INFERENCE_INSTANCE_TYPE = "ml.g5.12xlarge" +# Change the instance type to match your model. +# For GPU Service Quota related issues, please raise a quota request from AWS console +INFERENCE_INSTANCE_TYPE = "ml.g5.2xlarge" -TXT2IMG_MODEL_INFO = get_sagemaker_uris(model_id=TXT2IMG_MODEL_ID, - instance_type=TXT2IMG_INFERENCE_INSTANCE_TYPE, +# Name of the stack: +STACK_NAME = "apigw-lambda-sagemaker-jumpstartendpoint-stack" + + + +MODEL_INFO = get_sagemaker_uris(model_id=MODEL_ID, + instance_type=INFERENCE_INSTANCE_TYPE, region_name=region_name) app = cdk.App() -stack = CdkStablediffusionPythonStack( +stack = ApigwLambdaSagemakerJumpstartendpointStack( app, - "Web3WorkshopStableDiffusionStack", - model_info=TXT2IMG_MODEL_INFO, + STACK_NAME, + model_info=MODEL_INFO, env=env ) diff --git a/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/cdk_stablediffusion_python/cdk_stablediffusion_python_stack.py b/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/stack/ApigwLambdaSagemakerJumpstartendpointStack.py similarity index 89% rename from apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/cdk_stablediffusion_python/cdk_stablediffusion_python_stack.py rename to apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/stack/ApigwLambdaSagemakerJumpstartendpointStack.py index 303f7c030..fc38ced41 100644 --- a/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/cdk_stablediffusion_python/cdk_stablediffusion_python_stack.py +++ b/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/stack/ApigwLambdaSagemakerJumpstartendpointStack.py @@ -10,7 +10,7 @@ from util.sagemaker_endpoint_construct import SageMakerEndpointConstruct from datetime import datetime -class CdkStablediffusionPythonStack(Stack): +class ApigwLambdaSagemakerJumpstartendpointStack(Stack): def __init__(self, scope: Construct, construct_id: str, model_info, **kwargs) -> None: super().__init__(scope, construct_id, **kwargs) @@ -19,7 +19,7 @@ def __init__(self, scope: Construct, construct_id: str, model_info, **kwargs) -> instance_count_param = self.node.try_get_context("instance_count_param") instance_count = int(instance_count_param) if instance_count_param else 1 - role = iam.Role(self, "Gen-AI-SageMaker-Policy", assumed_by=iam.ServicePrincipal("sagemaker.amazonaws.com")) + role = iam.Role(self, "SageMaker-Policy", assumed_by=iam.ServicePrincipal("sagemaker.amazonaws.com")) role.add_managed_policy(iam.ManagedPolicy.from_aws_managed_policy_name("AmazonS3FullAccess")) sts_policy = iam.Policy(self, "sm-deploy-policy-sts", @@ -62,11 +62,11 @@ def __init__(self, scope: Construct, construct_id: str, model_info, **kwargs) -> role.attach_inline_policy(ecr_policy) # Generate a unique model name - model_name = f"SDTxt2Img-{datetime.now().strftime('%Y%m%d%H%M%S')}" + model_name = f"JumpstartModel-{datetime.now().strftime('%Y%m%d%H%M%S')}" # Create a SageMaker endpoint that can be used to generate images from text - endpoint = SageMakerEndpointConstruct(self, "TXT2IMG", - project_prefix=f"GenAIDemo-{instance_count}", + endpoint = SageMakerEndpointConstruct(self, "Jumpstart", + project_prefix=f"Jumpstart-{instance_count}", role_arn=role.role_arn, model_name=model_name, model_bucket_name=model_info["model_bucket_name"], @@ -91,7 +91,7 @@ def __init__(self, scope: Construct, construct_id: str, model_info, **kwargs) -> endpoint.node.add_dependency(logs_policy) endpoint.node.add_dependency(ecr_policy) - ssm.StringParameter(self, "txt2img_endpoint", parameter_name="txt2img_endpoint", + ssm.StringParameter(self, "Jumpstart_endpoint", parameter_name="Jumpstart_endpoint", string_value=endpoint.endpoint_name) # Create a Lambda function to invoke the SageMaker endpoint @@ -121,29 +121,29 @@ def __init__(self, scope: Construct, construct_id: str, model_info, **kwargs) -> # Create the REST API Gateway api = apigateway.RestApi( self, - "StableDiffusionAPI", - rest_api_name="StableDiffusionAPI" + "APIForSagemakerEndpoint", + rest_api_name="APIForSagemakerEndpoint" ) # Store the API Gateway URL in an SSM Parameter ssm.StringParameter( self, "api_gateway_url", - parameter_name="/StableDiffusionAPI/URL", + parameter_name="/SagemakerAPI/URL", string_value=api.url, ) # Add the usage plan usage_plan = api.add_usage_plan( - "StableDiffusionAPIUsagePlan", - name="StableDiffusionAPIUsagePlan", + "APIForSagemakerUsagePlan", + name="APIForSagemakerUsagePlan", throttle=apigateway.ThrottleSettings( rate_limit=1000, burst_limit=2000 ) ) # Create the API key - api_key = api.add_api_key("StableDiffusionAPIKey") + api_key = api.add_api_key("SagemakerAPIKey") # Associate the API key with the usage plan usage_plan.add_api_key(api_key) @@ -152,7 +152,7 @@ def __init__(self, scope: Construct, construct_id: str, model_info, **kwargs) -> ssm.StringParameter( self, "api_gateway_key", - parameter_name="/StableDiffusionAPI/APIKey", + parameter_name="/SagemakerAPI/APIKey", string_value=api_key.key_id, # Store the API key value ) From cea4b9a4e466d63be503ef94cb795a45770184e4 Mon Sep 17 00:00:00 2001 From: kaustavbecs Date: Thu, 27 Jul 2023 15:35:11 -0400 Subject: [PATCH 3/9] Accessing AWS Sagemaker Endpoint via API Gateway and Lambda --- .../README.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/README.md b/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/README.md index 0e3fc3041..0e78c1755 100644 --- a/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/README.md +++ b/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/README.md @@ -1,4 +1,4 @@ -# AWS Service 1 to AWS Service 2 +# Accessing AWS Sagemaker Endpoint via API Gateway and Lambda This pattern deploys a Sagemaker Jumpstart model (Flan T5 XL) endpoint using AWS Sagemaker. It also adds a lambda and an API Gateway serve the endpoint @@ -55,17 +55,16 @@ Important: this application uses various AWS services and there are costs associ ## How it works -1. This pattern deploys a Sagemaker Jumpstart model (Flan T5 XL) endpoint using AWS Sagemaker. The model can be changed by changing the ```MODEL_ID``` attribute in app.py file +1. This pattern deploys a Sagemaker Jumpstart model (Flan T5 XL from HuggingFace) endpoint using AWS Sagemaker. The model can be changed by changing the ```MODEL_ID``` attribute in app.py file 2. The pattern also adds a lambda and an API Gateway query the endpoint 3. The API Gateway is protected using an API Key. ```x-api-key``` header needs to be added to the HTTP request. - -It also adds a lambda and an API Gateway serve the endpoint. + ## Testing -1. Retrieve the Host URL of the API Gateway +1. Retrieve the Host URL of the API Gateway from AWS Console 2. Retreive the API key from AWS Console From 3864004dbe54274fc3cae44f83657a9a74cc8fd5 Mon Sep 17 00:00:00 2001 From: kaustavbecs Date: Thu, 27 Jul 2023 15:57:00 -0400 Subject: [PATCH 4/9] Accessing AWS Sagemaker Endpoint via API Gateway and Lambda --- apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/README.md b/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/README.md index 0e78c1755..a0fc93e1d 100644 --- a/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/README.md +++ b/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/README.md @@ -1,6 +1,6 @@ # Accessing AWS Sagemaker Endpoint via API Gateway and Lambda -This pattern deploys a Sagemaker Jumpstart model (Flan T5 XL) endpoint using AWS Sagemaker. It also adds a lambda and an API Gateway serve the endpoint +This pattern deploys a Sagemaker Jumpstart model (Flan T5 XL) endpoint. It also adds a lambda and an API Gateway query the endpoint Learn more about this pattern at Serverless Land Patterns: https://serverlessland.com/patterns/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python @@ -59,7 +59,7 @@ Important: this application uses various AWS services and there are costs associ 2. The pattern also adds a lambda and an API Gateway query the endpoint -3. The API Gateway is protected using an API Key. ```x-api-key``` header needs to be added to the HTTP request. +3. The API Gateway is protected using an API Key. To query the Api Gateway, ```x-api-key``` header needs to be added to the HTTP request ## Testing From eb6fcceb9b007be17ee518ee5a53df60992bb935 Mon Sep 17 00:00:00 2001 From: kaustavbecs Date: Thu, 27 Jul 2023 16:11:33 -0400 Subject: [PATCH 5/9] Accessing AWS Sagemaker Endpoint via API Gateway and Lambda --- .../README.md | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/README.md b/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/README.md index a0fc93e1d..af28ca07d 100644 --- a/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/README.md +++ b/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/README.md @@ -1,6 +1,6 @@ # Accessing AWS Sagemaker Endpoint via API Gateway and Lambda -This pattern deploys a Sagemaker Jumpstart model (Flan T5 XL) endpoint. It also adds a lambda and an API Gateway query the endpoint +This pattern deploys a Sagemaker Jumpstart model (Flan T5 XL) endpoint. It also adds a lambda and an API Gateway to query the endpoint Learn more about this pattern at Serverless Land Patterns: https://serverlessland.com/patterns/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python @@ -11,7 +11,7 @@ Important: this application uses various AWS services and there are costs associ * [Create an AWS account](https://portal.aws.amazon.com/gp/aws/developer/registration/index.html) if you do not already have one and log in. The IAM user that you use must have sufficient permissions to make necessary AWS service calls and manage AWS resources. * [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html) installed and configured * [Git Installed](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) -* [Python, pip, virtuenv](https://docs.aws.amazon.com/cdk/latest/guide/work-with-cdk-python.html) installed +* [Python, pip, virtualenv](https://docs.aws.amazon.com/cdk/latest/guide/work-with-cdk-python.html) installed * [AWS Cloud Development Kit](https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html) (AWS CDK >= 2.2.0) Installed ## Deployment Instructions @@ -22,7 +22,7 @@ Important: this application uses various AWS services and there are costs associ git clone https://github.com/aws-samples/serverless-patterns ``` -2. Change directory to this pattern directory: +2. Change to the pattern directory: ```sh cd serverless-patterns/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python ``` @@ -49,30 +49,30 @@ Important: this application uses various AWS services and there are costs associ ```sh cdk deploy --context instance_count_param=2 - ``` ## How it works -1. This pattern deploys a Sagemaker Jumpstart model (Flan T5 XL from HuggingFace) endpoint using AWS Sagemaker. The model can be changed by changing the ```MODEL_ID``` attribute in app.py file +1. This pattern deploys a Sagemaker Jumpstart model (Flan T5 XL from HuggingFace) endpoint using AWS Sagemaker. The model can be changed by modifying the ```MODEL_ID``` attribute in app.py file. -2. The pattern also adds a lambda and an API Gateway query the endpoint +2. The pattern also adds a lambda and an API Gateway query the endpoint. -3. The API Gateway is protected using an API Key. To query the Api Gateway, ```x-api-key``` header needs to be added to the HTTP request +3. The API Gateway is protected using an API Key. To query the Api Gateway, ```x-api-key``` header needs to be added to the HTTP request. ## Testing -1. Retrieve the Host URL of the API Gateway from AWS Console +1. Retrieve the Host URL of the API Gateway from AWS Console. -2. Retreive the API key from AWS Console +2. Retrieve the API key from AWS Console. 3. Send a sample HTTP request to the API Gateway: ``` POST /prod/generateimage HTTP/1.1 Host: x-api-key: + Content-Type: application/json Cache-Control: no-cache { "query": { @@ -94,6 +94,11 @@ Run the given command to delete the resources that were created. It might take s cdk destroy ``` +## Author bio +Kaustav Dey, +https://www.linkedin.com/in/kaustavbecs/ +Solution Architect + ---- Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved. From c6ae984cd0af23702905cc934c3c50be54d915f4 Mon Sep 17 00:00:00 2001 From: kaustavbecs Date: Thu, 27 Jul 2023 17:06:35 -0400 Subject: [PATCH 6/9] Accessing AWS Sagemaker Endpoint via API Gateway and Lambda --- .../example-pattern.json | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/example-pattern.json diff --git a/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/example-pattern.json b/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/example-pattern.json new file mode 100644 index 000000000..1f3744fa7 --- /dev/null +++ b/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/example-pattern.json @@ -0,0 +1,58 @@ +{ + "title": "Accessing AWS Sagemaker Endpoint via API Gateway and Lambda", + "description": "This pattern deploys a Sagemaker Jumpstart model (Flan T5 XL) endpoint. It also adds a lambda and an API Gateway to query the endpoint", + "language": "Python", + "level": "300", + "framework": "CDK", + "introBox": { + "headline": "How it works", + "text": [ + "This pattern deploys a Sagemaker Jumpstart model (Flan T5 XL from HuggingFace) endpoint using AWS Sagemaker. The model can be changed by modifying the MODEL_ID attribute in app.py file.", + "The pattern also adds a lambda and an API Gateway query the endpoint.", + "The API Gateway is protected using an API Key. To query the Api Gateway, x-api-key header needs to be added to the HTTP request." + ] + }, + "gitHub": { + "template": { + "repoURL": "https://github.com/aws-samples/serverless-patterns/tree/main/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python", + "templateURL": "serverless-patterns/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python", + "projectFolder": "apigw-lambda-sagemaker-jumpstartendpoint-cdk-python", + "templateFile": "stack/ApigwLambdaSagemakerJumpstartendpointStack.py" + } + }, + "resources": { + "bullets": [ + { + "text": "Zero-shot prompting for the Flan-T5 foundation model in Amazon SageMaker JumpStart", + "link": "https://aws.amazon.com/blogs/machine-learning/zero-shot-prompting-for-the-flan-t5-foundation-model-in-amazon-sagemaker-jumpstart/" + }, + { + "text": "Instruction fine-tuning for FLAN T5 XL with Amazon SageMaker Jumpstart", + "link": "https://aws.amazon.com/blogs/machine-learning/instruction-fine-tuning-for-flan-t5-xl-with-amazon-sagemaker-jumpstart/" + } + ] + }, + "deploy": { + "text": [ + "cdk deploy" + ] + }, + "testing": { + "text": [ + "See the GitHub repo for detailed testing instructions." + ] + }, + "cleanup": { + "text": [ + "Delete the stack: cdk destroy." + ] + }, + "authors": [ + { + "name": "Kaustav Dey", + "image": "https://avatars.githubusercontent.com/u/13236519", + "bio": "Solution Architect at AWS", + "linkedin": "kaustavbecs" + } + ] +} From aa853b1e46af844a06e03b9a55bccf4d6dde4264 Mon Sep 17 00:00:00 2001 From: kaustavbecs Date: Thu, 27 Jul 2023 17:11:01 -0400 Subject: [PATCH 7/9] Accessing AWS Sagemaker Endpoint via API Gateway and Lambda --- .../example-pattern.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/example-pattern.json b/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/example-pattern.json index 1f3744fa7..f583b3be3 100644 --- a/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/example-pattern.json +++ b/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/example-pattern.json @@ -52,7 +52,7 @@ "name": "Kaustav Dey", "image": "https://avatars.githubusercontent.com/u/13236519", "bio": "Solution Architect at AWS", - "linkedin": "kaustavbecs" + "linkedin": "https://www.linkedin.com/in/kaustavbecs/" } ] } From 91708803251f858bd49995f6ef1bdc7a6fed4017 Mon Sep 17 00:00:00 2001 From: David Boyne Date: Mon, 7 Aug 2023 14:02:08 +0100 Subject: [PATCH 8/9] Update example-pattern.json --- .../example-pattern.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/example-pattern.json b/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/example-pattern.json index f583b3be3..0b1dafefb 100644 --- a/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/example-pattern.json +++ b/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/example-pattern.json @@ -1,15 +1,15 @@ { - "title": "Accessing AWS Sagemaker Endpoint via API Gateway and Lambda", - "description": "This pattern deploys a Sagemaker Jumpstart model (Flan T5 XL) endpoint. It also adds a lambda and an API Gateway to query the endpoint", + "title": "Accessing Amazon SageMaker Endpoint via API Gateway and Lambda", + "description": "This pattern deploys a SageMaker Jumpstart model (Flan T5 XL) endpoint. It also uses a Lambda function and API Gateway to integrate the endpoint", "language": "Python", "level": "300", "framework": "CDK", "introBox": { "headline": "How it works", "text": [ - "This pattern deploys a Sagemaker Jumpstart model (Flan T5 XL from HuggingFace) endpoint using AWS Sagemaker. The model can be changed by modifying the MODEL_ID attribute in app.py file.", - "The pattern also adds a lambda and an API Gateway query the endpoint.", - "The API Gateway is protected using an API Key. To query the Api Gateway, x-api-key header needs to be added to the HTTP request." + "This pattern deploys a Amazon SageMaker Jumpstart model (Flan T5 XL from HuggingFace) endpoint using Amazon SageMaker. The model can be changed by modifying the MODEL_ID attribute in app.py file.", + "The pattern also adds a Lambda function with API Gateway integration to query the endpoint.", + "The API Gateway is protected using an API Key. To query the API Gateway endpoint, x-api-key header needs to be added to the HTTP request." ] }, "gitHub": { From 34c8653cebaec5e61cc6b3ee3c2e5f6e167bcbba Mon Sep 17 00:00:00 2001 From: David Boyne Date: Mon, 7 Aug 2023 14:04:08 +0100 Subject: [PATCH 9/9] Update README.md --- .../README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/README.md b/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/README.md index af28ca07d..3d9f141f4 100644 --- a/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/README.md +++ b/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python/README.md @@ -1,6 +1,6 @@ -# Accessing AWS Sagemaker Endpoint via API Gateway and Lambda +# Accessing Amazon SageMaker Endpoint via API Gateway and Lambda -This pattern deploys a Sagemaker Jumpstart model (Flan T5 XL) endpoint. It also adds a lambda and an API Gateway to query the endpoint +This pattern deploys a SageMaker Jumpstart model (Flan T5 XL) endpoint. It also adds a Lambda function and API Gateway integration to query the endpoint Learn more about this pattern at Serverless Land Patterns: https://serverlessland.com/patterns/apigw-lambda-sagemaker-jumpstartendpoint-cdk-python @@ -54,7 +54,7 @@ Important: this application uses various AWS services and there are costs associ ## How it works -1. This pattern deploys a Sagemaker Jumpstart model (Flan T5 XL from HuggingFace) endpoint using AWS Sagemaker. The model can be changed by modifying the ```MODEL_ID``` attribute in app.py file. +1. This pattern deploys a SageMaker Jumpstart model (Flan T5 XL from HuggingFace) endpoint using Amazon SageMaker. The model can be changed by modifying the ```MODEL_ID``` attribute in app.py file. 2. The pattern also adds a lambda and an API Gateway query the endpoint. @@ -83,7 +83,7 @@ Important: this application uses various AWS services and there are costs associ ``` -4. The API Gateway should respond with a JSON formatted response from the Sagamaker endpoint +4. The API Gateway should respond with a JSON formatted response from the SageMaker endpoint ## Cleanup @@ -102,4 +102,4 @@ Solution Architect ---- Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved. -SPDX-License-Identifier: MIT-0 \ No newline at end of file +SPDX-License-Identifier: MIT-0