Lets build a full stack application to call Stable Diffusion AI model. We will first build the backend then frontend. Backend includes: 1) SageMaker 2) Lambda 3) Api Gateway. And Frontend includes react web app deployed in Amplify.
Live URL to convert your text to image
- Stable Diffusion Generative AI Fullstack Application
- Build Backend
- Build Frontend
- Convert React JS app into Mobile App
- References
- Create SageMaker Domain may take more than 30 mins.
- Create profile
Now we have a SageMaker model endpoint. Let’s look at how we call it from Lambda. We use the SageMaker runtime API action and the Boto3 sagemaker-runtime.invoke_endpoint().
Select Runtime Python 3.7
and use x86_64 architecture.
Add below permissions to AWSLambdaBasicExecutionRole
"Version": "2012-10-17",
"Statement": [
// add this one for S3 bucket and sagemaker invocation
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"sagemaker:InvokeEndpoint",
"s3:*"
],
"Resource": "*"
},
{
"Sid": "VisualEditor2",
"Effect": "Allow",
"Action": "logs:CreateLogGroup",
"Resource": "arn:aws:logs:us-east-1:605024711850:*"
},
{
"Sid": "VisualEditor3",
"Effect": "Allow",
"Action": [
"logs:CreateLogStream",
"logs:PutLogEvents",
"s3:*"
],
"Resource": "arn:aws:logs:us-east-1:605024711850:log-group:/aws/lambda/invoke-text-to-image-stable-diffusion-model:*"
}
]
}
create bucket called as stabled
Environment variables (2)
The environment variables below are encrypted at rest with the default Lambda service key.
Key
Value
AWS_SM_EP jumpstart-example-infer-model-txt2img-s-2023-02-16-01-51-11-187
OUT_S3_BUCKET_NAME testbucket-rupesh
Go to configuration->General Configuration->Timeout Edit and change to 10min
- Add
AWSLambda-Python37-SciPy1x
layer fornumpy
- Add
Matplotlib
layer
import boto3
import io
import json
import numpy as np
import matplotlib.pyplot as plt
import uuid
import os
endpoint_name = os.environ['AWS_SM_EP']
s3 = boto3.resource('s3', region_name='us-east-1')
bucket_name = os.environ['OUT_S3_BUCKET_NAME']
s3_client = boto3.client('s3', region_name='us-east-1')
def query_endpoint(text):
runtime = boto3.client('runtime.sagemaker')
encoded_text = json.dumps(text).encode("utf-8")
response = runtime.invoke_endpoint(
EndpointName=endpoint_name, ContentType='application/x-text', Body=encoded_text, Accept='application/json')
return response
def parse_response(query_response):
response_dict = json.loads(query_response['Body'].read())
return response_dict['generated_image'], response_dict['prompt']
def upload_image(img, prmpt):
print('uploading image')
plt.figure(figsize=(12, 12))
plt.imshow(np.array(img))
plt.axis('off')
plt.title(prmpt)
img_data = io.BytesIO()
plt.savefig(img_data, format='png')
img_data.seek(0)
image_name = prmpt+str(uuid.uuid4())+'.png'
s3.Object(bucket_name, image_name).put(
Body=img_data, ContentType='image/png')
return s3_client.generate_presigned_url(ClientMethod='get_object', Params={'Bucket': bucket_name, 'Key': image_name}, ExpiresIn=1000)
def lambda_handler(event, context):
print("Received event: "+json.dumps(event, indent=2))
data = json.loads(json.dumps(event))
text = data['data']
print(text)
response = query_endpoint(text)
img, prmpt = parse_response(response)
# Display hallucinated image
url = upload_image(img, prmpt)
return {
'statusCode': 200,
'headers': {
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'OPTIONS,POST,GET'
},
'body': url
}
You can create an API by following these steps:
- On the API Gateway console, choose the REST API
- Choose Build.
- Select New API.
- For API name¸ enter a name (for example, BreastCancerPredition).
- Leave Endpoint Type as Regional.
- Choose Create API.
- On the Actions menu, choose Create resource.
- Enter a name for the resource (for example, predictbreastcancer).
- After the resource is created, on the Actions menu, choose Create Method to create a POST method.
- For Integration type, select Lambda Function.
- For Lambda function, enter the function you created.
When the setup is complete, you can deploy the API to a stage
- On the Actions menu, choose Deploy API.
- Create a new stage called test.
- Choose Deploy.
This step gives you the invoke URL.
For more information on creating an API with API Gateway, see Creating a REST API in Amazon API Gateway. In addition, you can make the API more secure using various methods.
Now that you have an API and a Lambda function in place, let’s look at the test data.
- Use the POST request
https://mko6b9drb2.execute-api.us-east-1.amazonaws.com/test/stabled
- Use body
{"data":"vanilla cake"}
- Send it will take around 20-25 sec to get you pre-signed url for image.
The easiest way to create a React application is by using the command create-react-app. Install this package using the following command in your command prompt or terminal:
👉 Make sure you have npm installed.
npx create-react-app stabledapp
cd stabledapp
npm start
-
Create a new GitHub repo for your app with this name
amplify-react-stabledapp
Description:Stable Diffusion from Stability AI and AWS Sagemaker. Full stack application with AWS API gateway and Amplify React App
-
Open a new terminal and navigate back to your app's root folder, for example,
stabledapp
-
Using create-react-app will automatically initialize the git repo and make an initial commit.
git init git add . git commit -m "initial commit" git remote add origin [email protected]:username/reponame.git git branch -M main git push -u origin main
In this step, you will connect the GitHub repository you just created to the AWS Amplify service. This will enable you to build, deploy, and host your app on AWS.
-
In the AWS Amplify service console, select Get Started under Amplify Hosting.
-
Select GitHub as the repository service and select Continue.
-
Authenticate with GitHub and return to the Amplify console. Choose the repository and main branch you created earlier, then select Next.
-
Accept the default build settings and select Next.
-
Review the final details and choose Save and deploy.
-
AWS Amplify will now build your source code and deploy your app at
https://...amplifyapp.com.
-
Once the build completes, select the thumbnail to see your web app up and running live. https://main.d32ou2x1stz40z.amplifyapp.com/
In this step, you will make some changes to the code using your text editor and push the changes to the main branch of your app.
- Edit src/App.js with the code below and save.
import React from 'react';
import logo from './logo.svg';
import './App.css';
function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h1>Hello from V2</h1>
</header>
</div>
);
}
export default App;
- Push the changes to GitHub in the command prompt (Windows) or terminal (macOS) to automatically kick off a new build:
git add .
git commit -m “changes for v2”
git push origin main
- Once the build is complete, select the thumbnail in the AWS Amplify console to view your updated app.
# Install Capacitor
npm i @capacitor/core
npm i -D @capacitor/cli
# Install cocoapods for ios app
brew install cocoapods
# Initialize your Capacitor config
npx cap init
# Create your Android and iOS projects
npm i @capacitor/android @capacitor/ios
npx cap add android
npx cap add ios
# Build app
npm run build
npx cap sync
# Open iOS project
npx cap open ios
- https://aws.amazon.com/blogs/machine-learning/call-an-amazon-sagemaker-model-endpoint-using-amazon-api-gateway-and-aws-lambda/
- https://aws.amazon.com/getting-started/hands-on/build-react-app-amplify-graphql/module-one/?e=gs2020&p=build-a-react-app-intro
- https://www.youtube.com/watch?v=IwHt_QpIa8A ( convert in to mobile app using capacitor)
- https://capacitorjs.com/docs/getting-started convert react app to mobile app