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.
1
sam init
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
1
sam deploy --guided --profile <aws profile name>
1
"ERROR", "errorMessage": "Unknown service: 'bedrock-runtime'. Valid service names are: accessanalyzer, account, acm, acm-pca
1
boto3=1.34.0
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
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
1
2
sam build
sam deploy
1
E.g. https://<api gateway endpoint>/Prod/bedrock?prompt=a dog swimming should yield a result similar to the following