GenAI: Using Amazon Bedrock, API Gateway, Lambda and S3
Tags: aws, serverless, ai, bedrock
Published: 2024-05-20 13:42:33

<!-- wp:paragraph {"align":"center"} -->
<p class="has-text-align-center">About Me: <a href="http://analisys.co/acerca-de/">Jhon Robert Quintero H.</a></p>
<!-- /wp:paragraph -->

<!-- wp:image {"id":771,"sizeSlug":"full","linkDestination":"none"} -->
<figure class="wp-block-image size-full"><img src="https://analisys.co/wp-content/uploads/2024/05/Amazon-Bedrock2.drawio-2.png" alt="Bedrock" class="wp-image-771"/></figure>
<!-- /wp:image -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Introduction</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>I was thrilled to be a speaker at the <a href="https://www.facebook.com/reel/473847328435703">XIII Meeting SOFTHARD 2024</a>, hosted by the <a href="https://www.facebook.com/IngenieriasUNIAJC">Faculty of Engineering</a> of the <a class="app-aware-link " data-test-app-aware-link="" href="https://www.linkedin.com/company/uniajc/" target="_self" rel="noopener">Institución Universitaria Antonio José Camacho</a> . Here's a snapshot of the key takeaways from my presentation on Generative AI, focusing on Amazon Bedrock, API Gateway, Lambda, and S3. Buckle up for an exciting ride!</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Amazon Bedrock</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Picture this: Amazon Bedrock is your magic wand for building and scaling generative AI applications with foundation models. It's like having a fully managed AI factory at your fingertips!</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><!-- wp:list-item -->
<li><strong>Fully Managed Service</strong>: Say goodbye to the nitty-gritty of managing infrastructure.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Choose Your Model</strong>: It’s like a buffet of the best AI models from AI21 Labs, Anthropic, Cohere, Meta, and Stability. Just pick what you need!</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Customize with Your Data</strong>: Make your model truly yours.</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:image {"id":776,"sizeSlug":"large","linkDestination":"none"} -->
<figure class="wp-block-image size-large"><img src="https://analisys.co/wp-content/uploads/2024/05/brandchoice-1024x357.png" alt="" class="wp-image-776"/></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>For instance, Anthropic’s Claude model is the hotshot for tasks like summarization and complex reasoning, while Stability AI’s Stable Diffusion model is your go-to for generating unique images, art, and designs. Need copywriting help? Cohere Command's got your back!</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":4} -->
<h4 class="wp-block-heading">Anthropic’s Claude 3 Model</h4>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Meet Claude 3, the genius in the room! It's smarter, faster, and cheaper than GPT 3.5T, and it’s got vision, literally!</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>With<a href="https://www.anthropic.com/news/claude-3-family"> Claude 3</a>, you can do:</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><!-- wp:list-item -->
<li>Dialogue and role-play</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Summarization and Q&amp;A</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Translation</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Database querying and retrieval</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Coding-related tasks</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Classification, metadata extraction, and analysis</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Text and content generation</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Content moderation</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:heading {"level":4} -->
<h4 class="wp-block-heading">Amazon’s Titan Model</h4>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The <a href="https://aws.amazon.com/bedrock/titan/?gclid=CjwKCAjwo6GyBhBwEiwAzQTmcxOlKNZ3Z7U5Yg1LD9beAyTDLLeLX6oOQmoFOajg5He6N4VrgUpFLhoC0T0QAvD_BwE&amp;trk=0eaabb80-ee46-4e73-94ae-368ffb759b62&amp;sc_channel=ps&amp;ef_id=CjwKCAjwo6GyBhBwEiwAzQTmcxOlKNZ3Z7U5Yg1LD9beAyTDLLeLX6oOQmoFOajg5He6N4VrgUpFLhoC0T0QAvD_BwE:G:s&amp;s_kwcid=AL!4422!3!692006004685!e!!g!!amazon%20titan!21048268554!159639952775">Titan</a> model is another powerhouse. Here’s what it can do:</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><!-- wp:list-item -->
<li><strong>Text Embeddings</strong>: Converts text into numerical form for searching, retrieving, and clustering. Think of it as translating words into a secret numerical language.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Image Generator</strong>: Create stunning images with just a few words. It’s like having a personal artist at your service!</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Customizing Amazon Titan models</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>You can now <a href="https://aws.amazon.com/blogs/aws/customize-models-in-amazon-bedrock-with-your-own-data-using-fine-tuning-and-continued-pre-training/">customize foundation models</a> (FMs) with your own data in <a href="https://aws.amazon.com/bedrock/">Amazon Bedrock</a> to build applications that are specific to your domain, organization, and use case. With custom models, you can create unique user experiences that reflect your company’s style, voice, and services.</p>
<!-- /wp:paragraph -->

<!-- wp:image {"id":777,"sizeSlug":"large","linkDestination":"none"} -->
<figure class="wp-block-image size-large"><img src="https://analisys.co/wp-content/uploads/2024/05/finetunning-1024x399.png" alt="" class="wp-image-777"/></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>With <a href="https://docs.aws.amazon.com/bedrock/latest/userguide/what-is-bedrock.html">fine-tuning</a>, you can increase model accuracy by providing your own task-specific labeled training dataset and further specialize your FMs. You can train models using your own data in a secure environment with customer-managed keys. <a href="https://docs.aws.amazon.com/bedrock/latest/userguide/custom-models.html">Continued pre-training</a> helps models become more specific to your domain.</p>
<!-- /wp:paragraph -->

<!-- wp:image {"id":774,"sizeSlug":"large","linkDestination":"none"} -->
<figure class="wp-block-image size-large"><img src="https://analisys.co/wp-content/uploads/2024/05/pretraining-1024x337.png" alt="" class="wp-image-774"/></figure>
<!-- /wp:image -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Knowledge Bases for Amazon Bedrock</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>It lets you put text documents, like articles or reports, into a knowledge base. It also automatically creates vector representations of text documents, which are called embeddings. These embeddings can be used for retrieval-augmented generation. This is a key feature of the Amazon Bedrock service. It lets you use your own data to enhance foundation models.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Stores embeddings in your vector database (<a href="https://docs.aws.amazon.com/bedrock/latest/userguide/knowledge-base-setup.html">Amazon OpenSearch</a>). Retrieves embeddings and augments prompts.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Solution Design: Text Summarization</h3>
<!-- /wp:heading -->

<!-- wp:image {"id":764,"sizeSlug":"full","linkDestination":"none"} -->
<figure class="wp-block-image size-full"><img src="https://analisys.co/wp-content/uploads/2024/05/Amazon-Bedrock2.drawio.png" alt="Bedrock" class="wp-image-764"/></figure>
<!-- /wp:image -->

<!-- wp:paragraph -->
<p>Let’s dive into the cool stuff! Here’s how I designed a text summarization solution using Bedrock, API Gateway, Lambda, and S3.</p>
<!-- /wp:paragraph -->

<!-- wp:list {"ordered":true} -->
<ol><!-- wp:list-item -->
<li><strong>Bedrock</strong>: Our star player.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>API Gateway</strong>: Acts as the doorman, directing client requests to the right Lambda function.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Lambda Function</strong>: Processes the text and sends it to Bedrock for summarization.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>S3 Bucket</strong>: Stores the summarized text.</li>
<!-- /wp:list-item --></ol>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>Check out the source code below. It’s like a recipe for your favorite dish – just follow the steps and enjoy the result!</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":4} -->
<h4 class="wp-block-heading">Python Source Code</h4>
<!-- /wp:heading -->

<!-- wp:code -->
<pre class="wp-block-code"><code>import boto3
import botocore.config
import json
import base64
from datetime import datetime
from email import message_from_bytes


def extract_text_from_multipart(data):
    msg = message_from_bytes(data)

    text_content = ''

    if msg.is_multipart():
        for part in msg.walk():
            if part.get_content_type() == "text/plain":
                text_content += part.get_payload(decode=True).decode('utf-8') + "\n"

    else:
        if msg.get_content_type() == "text/plain":
            text_content = msg.get_payload(decode=True).decode('utf-8')

    return text_content.strip() if text_content else None


def generate_summary_from_bedrock(content:str) -&gt;str:
    prompt = f"""Summarize the following meeting notes: {content} """

    body = json.dumps({"inputText": prompt, 
                       "textGenerationConfig":{
                           "maxTokenCount":4096,
                           "stopSequences":&#91;],
                           "temperature":0,
                           "topP":1
                       },
                      }) 

    modelId = 'amazon.titan-tg1-large' # change this to use a different version from the model provider
    accept = 'application/json'
    contentType = 'application/json'
        
    try:
        boto3_bedrock = boto3.client('bedrock-runtime')
        response = boto3_bedrock.invoke_model(body=body, modelId=modelId, accept=accept, contentType=contentType)
        response_body = json.loads(response.get('body').read())
    
        summary = response_body.get('results')&#91;0].get('outputText')
        return summary

    except Exception as e:
        print(f"Error generating the summary: {e}")
        return ""

def save_summary_to_s3_bucket(summary, s3_bucket, s3_key):

    s3 = boto3.client('s3')

    try:
        s3.put_object(Bucket = s3_bucket, Key = s3_key, Body = summary)
        print("Summary saved to s3")

    except Exception as e:
        print("Error when saving the summary to s3")


def lambda_handler(event,context):

    decoded_body = base64.b64decode(event&#91;'body'])

    text_content = extract_text_from_multipart(decoded_body)

    if not text_content:
        return {
            'statusCode':400,
            'body':json.dumps("Failed to extract content")
        }


    summary = generate_summary_from_bedrock(text_content)

    if summary:
        current_time = datetime.now().strftime('%H%M%S') #UTC TIME, NOT NECCESSARILY YOUR TIMEZONE
        s3_key = f'summary-output/{current_time}.txt'
        s3_bucket = 'bedrock-analisys-co'

        save_summary_to_s3_bucket(summary, s3_bucket, s3_key)

    else:
        print("No summary was generated")


    return {
        'statusCode':200,
        'body':json.dumps("Summary generation finished")
    }

    </code></pre>
<!-- /wp:code -->

<!-- wp:heading {"level":4} -->
<h4 class="wp-block-heading">Text Generation Configuration</h4>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Understanding the <code>textGenerationConfig</code> parameters is key for tweaking the model's behavior:</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":4} -->
<h4 class="wp-block-heading"><strong>maxTokenCount</strong>:</h4>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>This sets the maximum number of tokens (words or subwords) that the text generation model can produce. It helps control the length of the generated text.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Think of this as setting the maximum length for a speech. Just like a speechwriter might say, "Your speech should be no longer than 500 words," the maxTokenCount controls the length of the generated text, ensuring it doesn’t run on indefinitely.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":4} -->
<h4 class="wp-block-heading"><strong>stopSequences</strong>:</h4>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>This is a list of sequences (e.g., newline characters) that, if encountered during text generation, will cause the generation to stop.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Imagine you’re listening to a song that has a specific note that signals the end, like a grand finale. Similarly, stopSequences act like these finishing notes; they are predefined sequences that, when detected, tell the model to stop generating more text.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":4} -->
<h4 class="wp-block-heading"><strong>temperature</strong>:</h4>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>This parameter controls the "creativity" or "randomness" of the text generation. A lower temperature (e.g., 0) will result in more conservative, predictable text, while a higher temperature (e.g., 1) will produce more diverse and potentially more creative text.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Picture a painter with a palette of colors. A lower temperature is like having only a few colors to choose from, resulting in a more predictable and uniform painting. A higher temperature is like having a wide variety of colors, leading to a more vibrant and unexpected artwork.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":4} -->
<h4 class="wp-block-heading"><strong>topP</strong>:</h4>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>This is a technique called "nucleus sampling" that limits the text generation to the most likely tokens, based on the model's probability distribution. A value of 1 means no filtering, while a lower value (e.g., 0.9) will restrict the generation to the top 90% of the most likely tokens.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Imagine a buffet where you want to sample the most popular dishes. A topP value of 1 means you can choose from the entire spread. A lower topP value, like 0.9, means you’re only selecting from the top 90% of the most popular dishes, skipping the least likely choices to ensure a satisfying and high-quality meal.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>These parameters let you fine-tune the model’s behavior to suit your needs. Feel free to experiment and find the perfect balance!</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Video Demo</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Stay tuned for the video demo where I'll walk you through the entire process. <a href="https://youtu.be/MXbXWGBBOzU">Seeing is believing, right?</a></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Related Post: <a href="https://analisys.co/2023/07/11/designing-a-highly-scalable-system-on-aws/">Designing a Highly Scalable System on AWS (analisys.co)</a></p>
<!-- /wp:paragraph -->