🐙

ローカルからbedrockのAPIでcohereやclaudeを使ってみる

2024/06/25に公開

ローカルからBedrockのAPIを叩きたい。
boto3でできるようなのでやってみる。

準備@コンソール

IAMユーザに権限付与

  • ”BedrockUsers”と名付けたユーザグループに
    AmazonBedrockFullAccess のポリシーをアタッチ

  • IAMユーザを”BedrockUsers”と名付けたユーザグループに追加する

  • IAMユーザのアクセスキーも事前に発行しておく。

    • セキュリティ認証 > アクセスキー > アクセスキーの作成

モデルのアクセス付与

東京リージョンでbedrockを触りたいので、リージョンを東京に変更。

サイドバーから「モデルアクセス」を選択。
利用したいモデルのモデルアクセスをリクエストする。

今回は

  • 接続チェックのためにチャット用でAnthropicのClaudeのモデルを扱いたいため、Anthropic (2) > Claudeを選択
  • cohere の embeddingモデルで日本語を扱いたいため Cohere (2) > Embed Multilingualを選択

Cohere(コーヒア)とは、生成AI関連のスタートアップ企業であり、オラクル、エヌビディア(NVIDIA)、セールスフォース・ベンチャーズ(Salesforce Ventures)、センチネルワン(SentinelOne)などが支援しているみたいです。

今回はcohere の embeddingモデルで日本語を扱いたいため
Cohere (2) > Embed Multilingualを選択します。
リクエスト可能になると「アクセスが付与されました」と表示される。リクエストをした際は数分でアクセス付与された。

準備@ローカル

アクセスキー設定

プロファイル名は「besdrock_profile」とする

> aws configure --profile bedrock_profile
AWS Access Key ID [None]: (先ほど発行したアクセスキー)
AWS Secret Access Key [None]: (先ほど発行したシークレットアクセスキー)
Default region name [None]: ap-northeast-1 (← 東京リージョンに指定)
Default output format [None]: json

プロファイルが有効になったことを確認

> aws --profile bedrock_profile sts get-caller-identity
{
    "UserId": "(アクセスキー)",
    "Account": "(アカウントID)",
    "Arn": "arn:aws:iam::(アカウントID):user/(作成したユーザ)"
}

modelの確認

公式サイトにも載ってはいるが、動かないものもあったりなかったりなので、コマンドラインで確認してみる。

% aws --profile bedrock_profile bedrock list-foundation-models
{
    "modelSummaries": [
        {
            "modelArn": "arn:aws:bedrock:ap-northeast-1::foundation-model/amazon.titan-text-express-v1:0:8k",
            "modelId": "amazon.titan-text-express-v1:0:8k",
            "modelName": "Titan Text G1 - Express",
            "providerName": "Amazon",
            "inputModalities": [
                "TEXT"
            ],
            "outputModalities": [
                "TEXT"
            ],
            "responseStreamingSupported": true,
            "customizationsSupported": [],
            "inferenceTypesSupported": [],
            "modelLifecycle": {
                "status": "ACTIVE"
            }
        },
        {
            "modelArn": "arn:aws:bedrock:ap-northeast-1::foundation-model/amazon.titan-text-express-v1",
            "modelId": "amazon.titan-text-express-v1",
            "modelName": "Titan Text G1 - Express",
            "providerName": "Amazon",
            "inputModalities": [
                "TEXT"
            ],
            "outputModalities": [
                "TEXT"
            ],
            "responseStreamingSupported": true,
            "customizationsSupported": [],
            "inferenceTypesSupported": [
                "ON_DEMAND"
            ],
            "modelLifecycle": {
                "status": "ACTIVE"
            }
        },
        {
            "modelArn": "arn:aws:bedrock:ap-northeast-1::foundation-model/amazon.titan-embed-text-v1:2:8k",
            "modelId": "amazon.titan-embed-text-v1:2:8k",
            "modelName": "Titan Embeddings G1 - Text",
            "providerName": "Amazon",
            "inputModalities": [
                "TEXT"
            ],
            "outputModalities": [
                "EMBEDDING"
            ],
            "responseStreamingSupported": false,
            "customizationsSupported": [],
            "inferenceTypesSupported": [],
            "modelLifecycle": {
                "status": "ACTIVE"
            }
        },
        {
            "modelArn": "arn:aws:bedrock:ap-northeast-1::foundation-model/amazon.titan-embed-text-v1",
            "modelId": "amazon.titan-embed-text-v1",
            "modelName": "Titan Embeddings G1 - Text",
            "providerName": "Amazon",
            "inputModalities": [
                "TEXT"
            ],
            "outputModalities": [
                "EMBEDDING"
            ],
            "responseStreamingSupported": false,
            "customizationsSupported": [],
            "inferenceTypesSupported": [
                "ON_DEMAND"
            ],
            "modelLifecycle": {
                "status": "ACTIVE"
            }
        },
        {
            "modelArn": "arn:aws:bedrock:ap-northeast-1::foundation-model/anthropic.claude-instant-v1:2:18k",
            "modelId": "anthropic.claude-instant-v1:2:18k",
            "modelName": "Claude Instant",
            "providerName": "Anthropic",
            "inputModalities": [
                "TEXT"
            ],
            "outputModalities": [
                "TEXT"
            ],
            "responseStreamingSupported": true,
            "customizationsSupported": [],
            "inferenceTypesSupported": [],
            "modelLifecycle": {
                "status": "ACTIVE"
            }
        },
        {
            "modelArn": "arn:aws:bedrock:ap-northeast-1::foundation-model/anthropic.claude-instant-v1",
            "modelId": "anthropic.claude-instant-v1",
            "modelName": "Claude Instant",
            "providerName": "Anthropic",
            "inputModalities": [
                "TEXT"
            ],
            "outputModalities": [
                "TEXT"
            ],
            "responseStreamingSupported": true,
            "customizationsSupported": [],
            "inferenceTypesSupported": [
                "ON_DEMAND"
            ],
            "modelLifecycle": {
                "status": "ACTIVE"
            }
        },
        {
            "modelArn": "arn:aws:bedrock:ap-northeast-1::foundation-model/anthropic.claude-v2:1:18k",
            "modelId": "anthropic.claude-v2:1:18k",
            "modelName": "Claude",
            "providerName": "Anthropic",
            "inputModalities": [
                "TEXT"
            ],
            "outputModalities": [
                "TEXT"
            ],
            "responseStreamingSupported": true,
            "customizationsSupported": [],
            "inferenceTypesSupported": [
                "PROVISIONED"
            ],
            "modelLifecycle": {
                "status": "ACTIVE"
            }
        },
        {
            "modelArn": "arn:aws:bedrock:ap-northeast-1::foundation-model/anthropic.claude-v2:1:200k",
            "modelId": "anthropic.claude-v2:1:200k",
            "modelName": "Claude",
            "providerName": "Anthropic",
            "inputModalities": [
                "TEXT"
            ],
            "outputModalities": [
                "TEXT"
            ],
            "responseStreamingSupported": true,
            "customizationsSupported": [],
            "inferenceTypesSupported": [
                "PROVISIONED"
            ],
            "modelLifecycle": {
                "status": "ACTIVE"
            }
        },
        {
            "modelArn": "arn:aws:bedrock:ap-northeast-1::foundation-model/anthropic.claude-v2:1",
            "modelId": "anthropic.claude-v2:1",
            "modelName": "Claude",
            "providerName": "Anthropic",
            "inputModalities": [
                "TEXT"
            ],
            "outputModalities": [
                "TEXT"
            ],
            "responseStreamingSupported": true,
            "customizationsSupported": [],
            "inferenceTypesSupported": [
                "ON_DEMAND"
            ],
            "modelLifecycle": {
                "status": "ACTIVE"
            }
        },
        {
            "modelArn": "arn:aws:bedrock:ap-northeast-1::foundation-model/cohere.embed-english-v3",
            "modelId": "cohere.embed-english-v3",
            "modelName": "Embed English",
            "providerName": "Cohere",
            "inputModalities": [
                "TEXT"
            ],
            "outputModalities": [
                "EMBEDDING"
            ],
            "responseStreamingSupported": false,
            "customizationsSupported": [],
            "inferenceTypesSupported": [
                "ON_DEMAND"
            ],
            "modelLifecycle": {
                "status": "ACTIVE"
            }
        },
        {
            "modelArn": "arn:aws:bedrock:ap-northeast-1::foundation-model/cohere.embed-multilingual-v3",
            "modelId": "cohere.embed-multilingual-v3",
            "modelName": "Embed Multilingual",
            "providerName": "Cohere",
            "inputModalities": [
                "TEXT"
            ],
            "outputModalities": [
                "EMBEDDING"
            ],
            "responseStreamingSupported": false,
            "customizationsSupported": [],
            "inferenceTypesSupported": [
                "ON_DEMAND"
            ],
            "modelLifecycle": {
                "status": "ACTIVE"
            }
        }
    ]
}

anthropic.claude-v2:1 があるかを確認してみる

% aws --profile bedrock_profile bedrock get-foundation-model --model-identifier anthropic.claude-v2:1 
{
    "modelDetails": {
        "modelArn": "arn:aws:bedrock:ap-northeast-1::foundation-model/anthropic.claude-v2:1",
        "modelId": "anthropic.claude-v2:1",
        "modelName": "Claude",
        "providerName": "Anthropic",
        "inputModalities": [
            "TEXT"
        ],
        "outputModalities": [
            "TEXT"
        ],
        "responseStreamingSupported": true,
        "customizationsSupported": [],
        "inferenceTypesSupported": [
            "ON_DEMAND"
        ],
        "modelLifecycle": {
            "status": "ACTIVE"
        }
    }
}

できそうなので

pythonからのAPIアクセス

チャットでお試し

  • 省略するがpoetryなどでboto3をインストールする
  • コードを作成
% vi runtime-chat-test.py

import boto3
import json
boto3_session = boto3.Session(profile_name="bedrock_profile", region_name="ap-northeast-1")

bedrock = boto3_session.client(service_name='bedrock-runtime')
                                                                           
body = json.dumps({
         "prompt": "\n\nHuman:ジュビロ磐田について小学生でもわかるように説明してくださ:い。\n\nAssistant:",
         "max_tokens_to_sample": 1024,
         "temperature": 0.1,
         "top_p": 0.9,
})

modelId = 'anthropic.claude-v2:1'
accept = 'application/json'
contentType = 'application/json'

response = bedrock.invoke_model(body=body, modelId=modelId, accept=accept, contentType=contentType)

response_body = json.loads(response.get('body').read())

print(response_body.get('completion'))

実行

% poetry run python runtime-chat-test.py
 ジュビロ磐田は日本のプロサッカーチームです。

- 1917年に創設され、100年以上の歴史があります。
- 本拠地は静岡県磐田市のヤマハスタジアムです。
- チームカラーはオレンジと黒です。
- 過去にJリーグで2回優勝した強豪チームです。
- 主力選手にFW山口蛍、MF長友佑都、GK西川周作などがいます。

ジュビロとはポルトガル語で「喜び」という意味です。つまり、ジュビロ磐田は「磐田の喜び」といったチーム名です。

サポーターの人たちは熱心で、ホームスタジアムはいつも大勢の声援で盛り上がっています。

小学生にもわかりやすい説明になっているでしょうか。ご不明な点があれば遠慮なく質問してください。

ちょっと山口蛍とかいないのでハルシネーションですが、まあいいでしょう。

embeddingお試し

import boto3
import json

import numpy as np

boto3_session = boto3.Session(profile_name="bedrock_profile", region_name="ap-northeast-1")

bedrock_client = boto3_session.client(service_name='bedrock-runtime')

def bedrock_embedding(input_str: str):
    # print(input_str)
    bedrock_body = {
        "texts": [input_str], # listで与える。
        "input_type": "search_document",
        "truncate": "NONE",
        "embedding_types": ["float"]
    }
    body_bytes = json.dumps(bedrock_body)
    # print(body_bytes)
    response = bedrock_client.invoke_model(
        body=body_bytes,
        contentType="application/json",
        accept="*/*",
        modelId="cohere.embed-multilingual-v3",
    )
    response_body = json.loads(response.get("body").read())
    # print(response_body)

    # print(response_body.get("inputTextTokenCount"))
    embedding = response_body.get("embeddings")
    return embedding

def cosine_similarity(v1, v2):
    v1 = np.array(v1)
    v2 = np.array(v2)
    return np.dot(v1, v2.T) / (np.linalg.norm(v1) * np.linalg.norm(v2))


a = bedrock_embedding("埋め込みの実験のためのサンプルテキストです").get('float')
b = bedrock_embedding("私はジュビロ磐田サポーター").get('float')
c = bedrock_embedding("This is Sample Text. for Experimental of embeddings.").get('float')


print(cosine_similarity(a, b))
print(cosine_similarity(b, c))
print(cosine_similarity(a, c))

参考
https://www.divx.co.jp/media/techblog-231222
https://qiita.com/sergicalsix/items/d5c7a0a420a213309bfc

https://github.com/aws-samples/amazon-bedrock-samples/blob/main/multimodal/Titan/embeddings/v2/Titan-V2-Embeddings.ipynb

https://docs.aws.amazon.com/ja_jp/bedrock/latest/userguide/model-parameters-embed.html

https://dev.classmethod.jp/articles/amazon-bedrock-titan-embeddings/

Discussion