👋

Amazon Bedrock実装③:Lambda(Python3)で実装してみる

2023/11/05に公開

Bedrock勉強中

Bedrockの実装方法の調査メモ
Bedrockを実行するLambdaを作ってみる。具体的には、Lambda用のDockerイメージを作成し、そのイメージを使ってLambdaを作る。

使用するAWSサービス

IAMロール, ECR, Cloud9, Bedrock を使用します。

参考

作成するデータ

Cloud9環境で、以下3つのデータを作成します。

iam0001:~/environment/lambda-docker $ tree
.
├── Dockerfile_Lambda_Bedrock
├── lambda_function.py
└── requirements.txt

0 directories, 3 files

requirements.txtには必要なモジュールを指定します。

requirements.txt
boto3>=1.28.57
awscli>=1.29.57
botocore>=1.31.57
langchain==0.0.320

Dockerファイルでは、Lambda用のコンテナイメージを使います。また、Cloud9で動作テストができるようにリージョンを設定します。

Dockerfile_Lambda_Bedrock
ARG python_image_v="public.ecr.aws/lambda/python:3.11"
FROM ${python_image_v}

# リージョン情報を設定する
ENV AWS_DEFAULT_REGION=us-east-1

# Copy requirements.txt
COPY requirements.txt ${LAMBDA_TASK_ROOT}

# Copy function code
COPY lambda_function.py ${LAMBDA_TASK_ROOT}

# Install the specified packages
RUN pip install -r requirements.txt

# Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile)
CMD [ "lambda_function.handler" ]

LambdaのPython3スクリプトです。Lambda実行時にプロンプトを受け取るようにしています。
Lambda実行時のイベントは、{"prompt": "Human:What is AWS?\nAssistant:"}のようにprompt要素を含めるようにします。

lambda_function.py
import json
import boto3

def handler(event, context):
    # Boto3 セッションの作成
    session = boto3.Session()
    
    # Bedrock クライアントの作成
    bedrock_client = session.client(service_name='bedrock')
    bedrock_runtime_client = session.client(service_name='bedrock-runtime')
    
    # モデルの同期的呼び出し(Anthropic Claude-v2 の場合)
    prompt = event.get('prompt', 'prompt not found') 
    
    body = json.dumps({
        "prompt": prompt,
        "max_tokens_to_sample": 300,
        "temperature": 0.1,
        "top_k": 1,
        "stop_sequences": ["\n\nHuman"]
    })
    
    model_id = "anthropic.claude-v2"
    accept = "application/json"
    content_type = "application/json"
    
    response = bedrock_runtime_client.invoke_model(
        body=body,
        modelId=model_id,
        accept=accept,
        contentType=content_type
    )
    
    response_body = json.loads(response.get('body').read())
    print("Generated completion:")
    print(response_body.get('completion'))

    return 'Hello from AWS Lambda using Python ' + response_body.get('completion')

Cloud9環境で動作確認

Lambdaを作る前に、Cloud9環境でlambda_function.pyの動作確認をします。

Dockerイメージを作成します。

$ docker build -f Dockerfile_Lambda_Bedrock -t docker-lambda-bedrock:latest .

作成したDockerイメージを実行します。

docker run -p 9000:8080 docker-lambda-bedrock:latest

これで確認のための準備が完了しました。実際にlambda_function.pyを実行してみます。

iam0001:~/environment $ curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{"prompt": "Human:What is AWS?\nAssistant:"}'
"Hello from AWS Lambda using Python  AWS stands for Amazon Web Services. It is a cloud computing platform that provides a wide range of services including computing power, storage, databases, analytics, networking, mobile services, developer tools, management tools, IoT, security and more.\n\nSome key things to know about AWS:\n\n- It allows companies to access computing resources on demand without having to build and maintain their own infrastructure. This is known as infrastructure as a service (IaaS).\n\n- It offers services on a pay-as-you-go model, so you only pay for what you use. \n\n- It has data centers located around the world, which helps provide low latency and high availability.\n\n- It supports a wide range of use cases from web apps, mobile apps, gaming, data processing, IoT, machine learning and more. \n\n- Popular AWS services include EC2 (virtual servers), S3 (storage), Lambda (serverless computing), RDS (databases), Route 53 (DNS) and many more.\n\n- AWS dominates the cloud computing market though competitors include Microsoft Azure, Google Cloud Platform and others.\n\nSo in summary, AWS provides on-demand cloud computing services to individuals, companies and governments on a subscription basis. It allows companies to scale and deploy applications quickly without upfront infrastructure cost
iam0001:~/environment $ 

このように、質問の回答が返ってくれば成功です。(日本語を使う場合は、文字コード対応の処理が必要になると思います)

Lambdaを作る

動作確認で問題なければLambdaを作っていきます。Amazon ECRにDockerイメージをpushし、pushしたDockerイメージを使ってLambdaを作成します。ECRリポジトリbedrock01の作成は割愛します。

作業はCloud9環境で実施します。

Dockerイメージを作成する

ECRにpushするDockerイメージを作成します。検証で作成したDockerイメージを使います。

$ docker tag docker-lambda-bedrock:latest 111122223333.dkr.ecr.us-east-1.amazonaws.com/bedrock01:latest

DockerイメージをECRにpushする

さきほど作成したDockerイメージをECRにpushします。まずは、以下コマンドでCloud9からECRにログインする。

$ aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 111122223333.dkr.ecr.us-east-1.amazonaws.com

ECRにログインしたら、以下コマンドでDockerイメージをECRにpushする

docker push 111122223333.dkr.ecr.us-east-1.amazonaws.com/bedrock01:latest

Lambdaを作成する

以下のコマンドで、ECRにpushしたDockerイメージを使ってLambdaを作ります。

aws lambda create-function \
  --function-name bedrocklambda \
  --package-type Image \
  --code ImageUri=111122223333.dkr.ecr.us-east-1.amazonaws.com/bedrock01:latest \
  --role arn:aws:iam::111122223333:role/lambda-role

エラーなくコマンドが実行完了すれば成功。Lambda bedrocklambda が作成されます。このLambdaのタイムアウトは3秒になっていてそのままではタイムアウトが発生するので60秒くらいに設定します。

動作確認

Lambdaを実行し期待した挙動になるか確認します。
以下のようなテストイベントを作成し、Lambdaを実行します。

テストの結果、以下のように質問の回答が返ってきたら成功です。

以上です。

===

Discussion