Using Replicate Models with AWS Services

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.

Figure 1: Schematic representation of the project created for the purpose of sending images to 'replicate' models and saving the results obtained to the S3 bucket service.

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.

Figure 2: Screenshot showing where to start creating an AWS Lambda service.

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.

Figure-3: Screenshot showing the configurations that need to be made when creating a 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.

Figure 4 shows the screenshot of the 'Create API' button, which represents the first step in creating the AWS API Gateway service that will serve as a trigger for the AWS Lambda Service.

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.

Figure-5: This is the screenshot showing how to make the HTTP option in the API service to be created.

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.

Figure-6: Screenshot showing how to add a trigger to AWS Lambda service

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.

Figure-7: The configurations made when adding a trigger are shown.

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.

Figure-8 is a screenshot showing how to access the URL information of the API Gateway service set up to trigger the AWS Lambda service.

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üresiPricing of Lambda ServiceAPI Gateway Service PricingSave to S3 pricingtotal pricingNumber of Uses with $1
Ücretlendirme15.4 sn0.00003234 USD3.3e-9 USD0,00000043 USD0.000032773 USD30513 Kullanım

For Our Project:

Runtime of Lambda -1 ServiceiPricing of Lambda-1 ServiceRuntime of Lambda -2 ServiceiPricing of Lambda-2 Service API Gateway Service Pricing (2X)Save to S3 pricingtotal pricingNumber of Uses with $1
Ücretlendirme0.4 sn0.000000084 USD1 sn0.000000210 USD6.6e-9 USD0,00000043 USD0.00000073 USD1369863 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