The primary goal of our project is to send images to "replicate" models using AWS Lambda services and capture the outputs obtained from these models, then save these outputs to S3 buckets. We decided to use AWS Lambda in our project as it offers dynamic functionality and provides cost based on processing time.
In the operation of the project, the first step involves converting an image provided by users into base64 format and transmitting it to our AWS Lambda functions via API Gateway. This process initiates the processing of the image and starts the main operation of our project. The first Lambda function directs this image to 'replicate' models and completes its task.
Then, the second Lambda function comes into play and takes the outputs of the 'replicate' models. It makes these outputs available through the API Gateway service. Thanks to this approach, there is no unnecessary waiting as the functions are charged for every second they remain open. This ensures that our project operates efficiently and in a cost-saving manner.
Creating an AWS Lambda Service
Log in to the AWS Management Console to create an AWS Lambda service. Then click on the 'Services' tab or type 'Lambda' into the 'Search' section and select the 'Lambda' tab from the results that appear. On the screen that opens, press the 'İşlev Oluştur' or 'Create function' button.
After clicking the 'Create Function' button, you should select information such as how to create the lambda service you want to create, its name, programming language, and role. Once you have made your selections, if you press the 'Create Function' or 'İşlev Oluştur' button, you will have created the "Lambda" Service.
Adding a Trigger to AWS Lambda Service
To add a trigger to the Lambda service, you first need to create the trigger. In this project, the 'AWS API Gateway' service will be used as the trigger. To create the 'API Gateway' service, after logging into the AWS Management Console, type 'API Gateway' into the 'Search' section and select the 'API Gateway' tab from the results that appear. After clicking on the 'API Gateway' tab, press the 'Create API' button.
In this project, HTTP will be used as the API type. After clicking the 'Create API' button, on the page that opens, click the 'Build' button in the 'HTTP API' section. Then, name the API you have created. After naming it, click the 'Next' button to proceed and finally, when you press the 'Create' button, you will have created the 'API Gateway' service.
After the 'API Gateway' service is created, to use the 'API Gateway' service as a trigger in the 'Lambda' service, open the Lambda service we created from the 'AWS Lambda Console' page and press the 'Add Trigger' button.
After clicking the 'Add Trigger' button, select the 'API Gateway' service as the trigger. On the opened page, to select the name of the 'API Gateway' service we created earlier, choose the 'Use existing API' option and create the trigger by clicking the 'Add' button.
Sending Data to AWS API Gateway Service
AWS API Gateway is a powerful service offered by AWS, and using this service makes it quite easy to facilitate data communication between different applications and systems. For example, you can use the API Gateway to transmit user information obtained from your web application or data sent by the client to AWS Lambda functions.
The structure of the data sent via the API Gateway can vary depending on user needs and application requirements. However, generally, the data sent to the API Gateway is transmitted with an HTTP request (for example, a POST or PUT request) and is usually structured in data formats like JSON or XML within the body of these requests. Below is an example of the data sent to the API Gateway in JSON format.
{
"kullaniciAdi": "ornek_kullanici",
"email": "ornek@example.com",
"yas": 30,
"mesaj": "Merhaba, bu bir örnek mesajdır."
}
For our project, since we want to send an image as data, we first convert the image to base64 format and then send it to the 'API Gateway' service. The following Python code example is written to send an image to the 'API Gateway' service.
import base64
import requests
def convert_base64(img_path):
with open(image_path , "rb") as image_file:
image_data = image_file.read()
return base64.b64encode(image_data).decode("utf-8")
def send_image(img_path, api_gateway_url):
request_data = {
"image": convert_base64(img_path)
}
response = requests.post(api_gateway_url, json=request_data)
if response.status_code == 200:
print("Resim başarıyla yüklendi.")
else:
print(f"Resim yükleme hatası: {response.status_code}")
if __name__ == "__main__":
image_path = "./deneme.jpg"
api_gateway_url = "https://8tldf2jx1c.execute-api.eu-central-1.amazonaws.com/cagdasblog"
# Resmi API'ya POST isteği ile gönderin.
send_image(image_path, api_gateway_url)
To access the 'api_gateway_url' information, click on the 'Configuration' tab in the Lambda service. Then, in the tab that opens, go to the 'Triggers' section and retrieve the information in the 'API endpoint' section of your trigger.
Sending Images to Replicate Models with AWS Lambda
After converting the images on our local device to base64 format, this data is transmitted to the “API Gateway” service. The “Lambda” service, triggered by the incoming image to the “API Gateway” service, receives, processes, and converts this image into an input format suitable for the “replicate” model. The outcome of the “replicate” model is set up to be sent to the “API Gateway” service, which triggers a second “Lambda” service that will write the result to an “S3 Bucket”. A “Webhook” is used to enable the result of the “Replicate” model to be sent to another service. After everything is completed, the image is given as input to the “replicate” model, and the Lambda service completes its code execution. You can access the Python code in the “Lambda” service below.
import json
import base64
import replicate
import os
def lambda_handler(event, context):
# TODO implement
try:
os.environ["REPLICATE_API_TOKEN"] = "r************************"
print('lambda foksiyonu başlatıldı!!!!')
body = json.loads(event['body'])
base64_image = body["image"]
data_uri = f"data:image/jpeg;base64,{base64_image}"
print('Görüntü Alındı ve İşlendi!')
model = replicate.models.get("catacolabs/cartoonify")
version = model.versions.get("f109015d60170dfb20460f17da8cb863155823c85ece1115e1e9e4ec7ef51d3b")
print('Model Oluşturuldu!')
prediction = replicate.predictions.create(
version=version,
input={"img": data_uri},
webhook="https://**********.execute-api.eu-central-1.amazonaws.com/replicate-app",
webhook_events_filter=["completed"])
# https://**********.execute-api.eu-central-1.amazonaws.com/replicate-app => sonuçları göndermek istediğimiz API Gateway'in url'i
print("Görüntü replicate'a gönderildi!!")
return {
'statusCode': 200,
'body': json.dumps('Görüntü başarı ile replicate'a gönderildi!')
}
except Exception as e:
print('hata!!!', e)
return {
'statusCode': 500,
'body': json.dumps('Hata: ' + str(e))
}
Printing the Result of the Replicate Model to S3 Bucket with AWS Lambda
After the replication models generate results, these results are transmitted to the second service called the "API Gateway," which serves as the trigger for it. Subsequently, the "Lambda" service retrieves these results from the "API Gateway" service and performs the final stage, which is writing to the "S3" bucket. You can access the Python code in the Lambda service from below.
import json
import boto3
import requests
s3 = boto3.client('s3')
print('s3 bucket servisine baglandı')
def lambda_handler(event, context):
try:
body = json.loads(event['body'])
output = body["output"]
print('____output alindi_____')
res = requests.get(output)
print('____response alindi_____')
upload_image_to_s3(res.content, 'cagdastest1', 'webhook_6.png')
print('resim s3 bucketina yülendi')
return {
'statusCode': 200,
'body': json.dumps('Dosya okundu ve islendi!')
}
except Exception as e:
print('--------------------------------',e)
return {
'statusCode': 500,
'body': json.dumps('Hata: ' + str(e))
}
def upload_image_to_s3(image_bytes, bucket_name, object_key):
# Görüntüyü S3 kovasına yükleyin
s3_client = boto3.client('s3')
s3_client.put_object(Bucket=bucket_name, Key=object_key, Body=image_bytes)
Pricing and Profit Made
The process of a single "Lambda" service taking the image and sending it to the "Replicate" models and waiting for the result until it's received is quite time-consuming. This is disadvantageous for us because "Lambda" services are charged per operation, making our project quite cost-effective for us.
Below, you will find the cost analysis table for the project we have undertaken, as well as the cost analysis table for the project completed using only a single "Lambda" service. You can assess the profit and loss ratios by looking at these tables.
For a Project Made with a Single Lambda:
Lambda Servisinin Çalışma Süresi | Pricing of Lambda Service | API Gateway Service Pricing | Save to S3 pricing | total pricing | Number of Uses with $1 | |
Ücretlendirme | 15.4 sn | 0.00003234 USD | 3.3e-9 USD | 0,00000043 USD | 0.000032773 USD | 30513 Kullanım |
For Our Project:
Runtime of Lambda -1 Servicei | Pricing of Lambda-1 Service | Runtime of Lambda -2 Servicei | Pricing of Lambda-2 Service | API Gateway Service Pricing (2X) | Save to S3 pricing | total pricing | Number of Uses with $1 | |
Ücretlendirme | 0.4 sn | 0.000000084 USD | 1 sn | 0.000000210 USD | 6.6e-9 USD | 0,00000043 USD | 0.00000073 USD | 1369863 Kullanım |
When examining the pricing in the tables, as can be seen, the project we conducted is approximately 45 times cheaper than a project that only uses a single "Lambda" service. In the project, the TencentArc/GFPGAN replicate model was used. This model employs an NVIDIA T4 GPU, 16GB of GPU RAM, and 8GB of system RAM. The cost of this configuration is 0.000225 US Dollars per second. For 1,000,000 usages, the replicate cost is 225 US Dollars, and the AWS fee is 0.73 US Dollars.
NOT: The cost per millisecond for the Lambda service is $0.0000000021 USD. The first 300 million calls for the API Gateway service cost $1.00 USD. The initial cost of saving the first 1000 data in the S3 service is $0.00043 USD. The calculations in the tables are based on this information.
Conclusion
Of course, below is an example of a results section based on the information you provided:
When we reach the end of our project, we clearly see the power of the integration of AWS Lambda and "replicate" models. The features of dynamic scalability and cost based on processing time have allowed us to optimize our project both in terms of cost and performance.
Çağdaş Yılmaz
cagdas.yilmaz@golive.com.tr