Deploy Endpoint#
Follow THIS to deploy a syn endpoint on sagemaker
Invoke Endpoint#
Let invoke the deployed endpoint
import boto3import jsonimport base64import iofrom PIL import Image# create sagemaker runtime clientsm_client = boto3.client("sagemaker-runtime")# endpoint nameendpoint_name = "sdxl-1-0-jumpstart-2024-01-24-09-54-52-906"
Let create a request body with prompt and invoke the endpoint
# payload requestpayload = json.dumps({"text_prompts": [{"text": "wife and baby","weight": 1.0}],"cfg_scale": 15,"samples": 1,"seed": 3,"style_preset": "anime","num_inference_steps": 30,"height": 1024,"width": 1024})# invoke endpointresponse = sm_client.invoke_endpoint(EndpointName=endpoint_name,ContentType="application/json",Body=payload)
Finally parse response, decode base64 response and save image
data = response['Body'].read().decode('utf-8')data = json.loads(data)imgstring = data['artifacts'][0]['base64']# decode imageimgdata = base64.b64decode(imgstring)# save imagefilename = 'some_image.jpg'with open(filename, 'wb') as f:f.write(imgdata)# open image in notebookimage = Image.open(io.BytesIO(imgdata))display(image)
Lambda Function#
Let create a lambda function which invoke the endpoint and save image to S3. Project structure
|--Dockerfile|--requirements.txt|--index.py
Handler code
"""lambda call sagemaker diffusion model"""import sagemakerfrom stability_sdk_sagemaker.predictor import StabilityPredictorfrom stability_sdk.api import GenerationRequest, GenerationResponse, TextPromptfrom PIL import Imageimport ioimport base64import boto3import datetimeimport jsonimport os#STYLE = "anime"s3_client = boto3.client("s3")sagemaker_session = sagemaker.Session()deployed_model = StabilityPredictor(endpoint_name=os.environ["ENDPOINT_NAME"], sagemaker_session=sagemaker_session)def decode_and_show(model_response: GenerationResponse) -> None:"""Decodes and displays an image from SDXL outputArgs:model_response (GenerationResponse): The response object from the deployed SDXL model.Returns:None"""# file namename = datetime.datetime.now().strftime("%m-%d-%Y-%H-%M-%S")# keykey = f"diffuision/{name}.png"# imageimage = model_response.artifacts[0].base64image_data = base64.b64decode(image.encode())s3_client.upload_fileobj(io.BytesIO(image_data), os.environ["BUCKET_NAME"], key)# signed urlsign_url = s3_client.generate_presigned_url("get_object",Params={"Bucket": os.environ["BUCKET_NAME"], "Key": key},ExpiresIn=3600,)# image = Image.open(io.BytesIO(image_data))# image.save("hehe.png")return sign_urldef handler(event, context):"""handler"""# parse prompttry:prompt = event["queryStringParameters"]["prompt"]except:prompt = "fish"try:style = event["queryStringParameters"]["style"]except:style = "anime"# call modeloutput = deployed_model.predict(GenerationRequest(text_prompts=[TextPrompt(text=prompt)],style_preset=style,seed=3,height=1024,width=1024,))# save image to s3try:url = decode_and_show(output)except:url = "ERROR"# returnreturn {"statusCode": 200,"headers": {"Access-Control-Allow-Origin": "*","Access-Control-Allow-Headers": "Content-Type","Access-Control-Allow-Methods": "OPTIONS,GET",},"body": json.dumps({"url": url,}),}
Here is Dockerfile
FROM public.ecr.aws/lambda/python:3.9# create code dir inside containerRUN mkdir ${LAMBDA_TASK_ROOT}/source# copy code to containerCOPY "requirements.txt" ${LAMBDA_TASK_ROOT}/source# copy handler function to containerCOPY ./index.py ${LAMBDA_TASK_ROOT}# install dependencies for running time environmentCOPY ./package/ ${LAMBDA_TASK_ROOT}# set the CMD to your handlerCMD [ "index.handler" ]
And requirements.txt
sagemakerstability-sdk[sagemaker] @ git+https://github.com/Stability-AI/stability-sdk.git@sagemaker