logo

Using Amazon Bedrock to generate images with Titan Image Generator models and AWS Lambda

The goal of this article is to document how one can test the Titan Image models in Amazon Bedrock using AWS Lambda. This article will be a quick start guide that can be adapted to suit your needs in the future. For developing the AWS Lambda, the AWS SAM framework will be used.

Published Jan 15, 2024
1. Create a skeleton SAM project
Using the sam init command, create a new skeleton project. This sample will use a Python lambda that is exposed via an API Gateway. The Hello World Example sam template has been followed to create the skeleton project.
1
sam init
Once the sam init command is finished running, tweak the generated code to suit theuse case you are working on.
Below is the template.yaml that has been generated for this article.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
amazon-bedrock-images-titan-image-generator

Sample SAM Template for amazon-bedrock-images-titan-image-generator

# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
Function:
Timeout: 60
MemorySize: 512

# You can add LoggingConfig parameters such as the Logformat, Log Group, and SystemLogLevel or ApplicationLogLevel. Learn more here https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html#sam-function-loggingconfig.
LoggingConfig:
LogFormat: JSON
Resources:
AmazonBedrockFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: bedrock/
Handler: app.lambda_handler
Runtime: python3.12
Architectures:
- x86_64
Policies:
- Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- "bedrock:InvokeModel"
Resource: "*"
Events:
AmazonBedrock:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /bedrock
Method: get

Outputs:
# ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
# Find out more about other implicit resources you can reference within SAM
# https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
AmazonBedrockApi:
Description: API Gateway endpoint URL for Prod stage for the Amazon Bedrock function
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/bedrock/"
AmazonBedrockFunction:
Description: Amazon Bedrock Lambda Function ARN
Value: !GetAtt AmazonBedrockFunction.Arn
AmazonBedrockFunctionIamRole:
Description: Implicit IAM Role created for Amazon Bedrock function
Value: !GetAtt AmazonBedrockFunctionRole.Arn
2. Deploy initial sam stack
Deploy the initial sam stack using the sam deploy command.
1
sam deploy --guided --profile <aws profile name>
In the output section of the sam deploy command will be an AmazonBedrockApi endpoint as per the image below.
![AWS Sam deploy output](https://assets.community.aws/a/2b0kG8xRj9UYGjM4t7GqyFRTIGM.webp?imgSize=720x178AWS Sam deploy output)
Click onto the AmazonBedrockApi link to validate it is running as expected.
![Live API Gateway Endpoint](https://assets.community.aws/a/2b0kJxSit2bc8nUJZDHSRfZKZoo.webp?imgSize=610x149Live API Gateway Endpoint)
3. Enable the Titan Image models.
At the time of writing (14th December 2023), the Titan Image models are only available in certain regions. For this demo, we will configure resources in the us-east-1 (North Virginia) region as the required models are available in that region.
Navigate to the Amazon Bedrock service in the North Virginia region and select model access on the left hand menu.
![Amazon Bedrock menu options](https://assets.community.aws/a/2b0kQe5K2SHS1SruVWZ6tuvJIYt.webp?imgSize=292x647Amazon Bedrock menu options-)
Select the Titan Image Generator models and click Request model access
![Amazon Bedrock Titan Image Models — Request Access](https://assets.community.aws/a/2b0kTljHeJryam3SQM3iiW7n5UM.webp?imgSize=720x95Amazon Bedrock Titan Image Models — Request Access)
4. Update the lambda code to call Amazon Bedrock
In this section, the lambda code will be updated to call the Titan Image Generator model in Amazon Bedrock.
Note: For python boto3 examples — see the following AWS Link
The boto3 library currently configured for python on AWS Lambda does not support the bedrock-runtime client. If you are to load bedrock-runtime from boto3 — you get the following error
1
"ERROR", "errorMessage": "Unknown service: 'bedrock-runtime'. Valid service names are: accessanalyzer, account, acm, acm-pca
To get around this, we can update the boto3 dependency in requirements.txt to specify which version of boto3 should be used
1
boto3=1.34.0
Or we can use a lambda layer — which is what we are going to do in this example.
Note: All code will be shared at the end of this article which also shows
The updated template.yml looks like the following
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
amazon-bedrock-images-titan-image-generator

Sample SAM Template for amazon-bedrock-images-titan-image-generator

# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
Function:
Timeout: 60
MemorySize: 512

# You can add LoggingConfig parameters such as the Logformat, Log Group, and SystemLogLevel or ApplicationLogLevel. Learn more here https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html#sam-function-loggingconfig.
LoggingConfig:
LogFormat: JSON
Resources:
Boto3Layer:
Type: AWS::Serverless::LayerVersion
Properties:
LayerName: boto3-layer
Description: Boto3 Layer
ContentUri: ./dependencies/boto3/
CompatibleRuntimes:
- python3.12
CompatibleArchitectures:
- x86_64
Metadata:
BuildMethod: python3.12
BuildArchitecture: x86_64
AmazonBedrockFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: bedrock/
Handler: app.lambda_handler
Runtime: python3.12
Architectures:
- x86_64
Policies:
- Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- "bedrock:InvokeModel"
Resource: "*"
Layers:
- !Ref Boto3Layer
Events:
AmazonBedrock:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /bedrock
Method: get

Outputs:
# ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
# Find out more about other implicit resources you can reference within SAM
# https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
AmazonBedrockApi:
Description: API Gateway endpoint URL for Prod stage for the Amazon Bedrock function
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/bedrock/"
AmazonBedrockFunction:
Description: Amazon Bedrock Lambda Function ARN
Value: !GetAtt AmazonBedrockFunction.Arn
AmazonBedrockFunctionIamRole:
Description: Implicit IAM Role created for Amazon Bedrock function
Value: !GetAtt AmazonBedrockFunctionRole.Arn
The final lambda code to call a Titan Image Generator AI model in Amazon Bedrock is as follows.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import json
import logging
import boto3
from botocore.exceptions import ClientError
import base64

logger = logging.getLogger(__name__)

bedrock_runtime_client = boto3.client('bedrock-runtime', region_name='us-east-1' )


def lambda_handler(event, context):

if "queryStringParameters" not in event:
return {
'statusCode': 400,
'body': 'No query string parameters passed in'
}

if "prompt" not in event["queryStringParameters"]:
return {
'statusCode': 400,
'body': 'Prompt needs to be passed in the query string parameters'
}

query_string_parameters = event["queryStringParameters"]
prompt = query_string_parameters["prompt"]

image_data = invoke_titan_image(prompt)

print(f"image_data: {image_data}")
html_content = """
<!DOCTYPE html>
<html>
<head>
<title>Amazon Bedrock - Titan Image Generator Model</title>
</head>
<body>
<img src="{}" alt="Base64 Image">
</body>
</html>
"""
.format(f"data:image/png;base64,{image_data}")

# Return HTML content as the response
return {
'statusCode': 200,
'body': html_content,
'headers': {
'Content-Type': 'text/html',
},
}

def invoke_titan_image(prompt, style_preset=None):

try:
body = json.dumps(
{
"taskType": "TEXT_IMAGE",
"textToImageParams": {
"text":prompt, # Required
# "negativeText": "<text>" # Optional
},
"imageGenerationConfig": {
"numberOfImages": 1, # Range: 1 to 5
"quality": "premium", # Options: standard or premium
"height": 768, # Supported height list in the docs
"width": 1280, # Supported width list in the docs
"cfgScale": 7.5, # Range: 1.0 (exclusive) to 10.0
"seed": 42 # Range: 0 to 214783647
}
}
)
response = bedrock_runtime_client.invoke_model(
body=body,
modelId="amazon.titan-image-generator-v1",
accept="application/json",
contentType="application/json"
)

response_body = json.loads(response["body"].read())
base64_image_data = response_body["images"][0]

return base64_image_data

except ClientError:
logger.error("Couldn't invoke Titan Image Generator Model")
raise
6. Build code and deploy
Then we can perform a build using the following command to download the required dependencies and finally deploy the code using the following commands
1
2
sam build
sam deploy
7. Test the code
By calling the API Gateway endpoint with a query string parameter of prompt — we can now test the solution.
 
1
E.g. https://<api gateway endpoint>/Prod/bedrock?prompt=a dog swimming should yield a result similar to the following
![Response from Titam Image model for a dog swimming](https://assets.community.aws/a/2b0lD5r8hLwLcTfbeBTCmGvq6zk.webp?imgSize=720x434Response from Titam Image model for a dog swimming)
The above sample could be improved by using a HTTP Post request instead of a GET request but the purpose of this article was to get a working solution as quickly as possible.
8. Code
If you wish to view the code for this sample project — it can be viewed on GitHub.