Amazon Bedrock の Cross Region Inference を試す

## Cross Region Inference が出ました

https://docs.aws.amazon.com/bedrock/latest/userguide/cross-region-inference.html

今北産業すると、

* Quotas に引っ掛かってスロットリングしても
* 空いているリージョンで推論できる仕組みが
* できたよ

## やってみる

Doc を見ながらいきます。

https://docs.aws.amazon.com/bedrock/latest/userguide/cross-region-inference-view.html

推論するには、Cross Region Inference するには、今までの ModelId ではなく、ModelIdInference Identifier を取得する必要があります。

InferenceProfileIdentifier を取得するために、 ListInferenceProfiles API を叩きます。

```bash
aws bedrock list-inference-profiles
```
```json:出力
{
    "inferenceProfileSummaries": [
        …
        {
            "inferenceProfileName": "US Anthropic Claude 3.5 Sonnet",
            "models": [
                {
                    "modelArn": "arn:aws:bedrock:us-east-1::foundation-model/anthropic.claude-3-5-sonnet-20240620-v1:0"
                },
                {
                    "modelArn": "arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20240620-v1:0"
                }
            ],
            "description": "Routes requests to Anthropic Claude 3.5 Sonnet in us-east-1 and us-west-2.",
            "createdAt": "2024-08-26T00:00:00Z",
            "updatedAt": "2024-08-26T00:00:00Z",
            "inferenceProfileArn": "arn:aws:bedrock:us-east-1:290000338583:inference-profile/us.anthropic.claude-3-5-sonnet-20240620-v1:0",
            "inferenceProfileId": "us.anthropic.claude-3-5-sonnet-20240620-v1:0",
            "status": "ACTIVE",
            "type": "SYSTEM_DEFINED"
        },
        …
    ]
}
```

対応しているモデル・リージョン一覧がわかりますね。
今回は 3.5 sonnet で試すため、`us.anthropic.claude-3-5-sonnet-20240620-v1:0` を使います。

無事 InferenceProfileIdentifier を取得できました。

この情報を使って Converse API でリクエストを投げます。

https://docs.aws.amazon.com/bedrock/latest/userguide/cross-region-inference-use.html

`ModelId` に `us.anthropic.claude-3-5-sonnet-20240620-v1:0` を使ってみます。
(結局 ModelId 引数を使うのね)

```python:test.py
import boto3
from pprint import pprint
brt = boto3.client(service_name='bedrock-runtime',region_name='us-west-2')
response = brt.converse(
    modelId = "us.anthropic.claude-3-5-sonnet-20240620-v1:0",
    messages = [
        {
            'role':'user',
            'content':[
                { 'text': 'あなたは誰ですか？' }
            ]
        }
    ],
)
pprint(response)
```
```text:出力
{'ResponseMetadata': {'HTTPHeaders': {'connection': 'keep-alive',
                                      'content-length': '565',
                                      'content-type': 'application/json',
                                      'date': 'Wed, 28 Aug 2024 01:02:08 GMT',
                                      'x-amzn-requestid': '51ff9583-e7d9-4560-a0c5-36f92254dce6'},
                      'HTTPStatusCode': 200,
                      'RequestId': '51ff9583-e7d9-4560-a0c5-36f92254dce6',
                      'RetryAttempts': 0},
 'metrics': {'latencyMs': 2886},
 'output': {'message': {'content': [{'text': 'はじめまして。私はClaudeという人工知能のアシスタントです。Anthropic社によって開発されました。人間のように会話ができますが、感情や意識は持ち合わせていません。ユーザーの皆さまのお手伝いをさせていただくのが私の役割です。どのようなことでもお気軽にお尋ねください。'}],
                        'role': 'assistant'}},
 'stopReason': 'end_turn',
 'usage': {'inputTokens': 17, 'outputTokens': 113, 'totalTokens': 130}}
gokazu@b0be838161ee simple-bedrock-invoke % python converse/converse.py
{'ResponseMetadata': {'HTTPHeaders': {'connection': 'keep-alive',
                                      'content-length': '529',
                                      'content-type': 'application/json',
                                      'date': 'Wed, 28 Aug 2024 01:02:51 GMT',
                                      'x-amzn-requestid': 'ad9ba778-63e4-482b-82ee-913abb773953'},
                      'HTTPStatusCode': 200,
                      'RequestId': 'ad9ba778-63e4-482b-82ee-913abb773953',
                      'RetryAttempts': 0},
 'metrics': {'latencyMs': 3050},
 'output': {'message': {'content': [{'text': 'はじめまして。私はClaudeという人工知能のアシスタントです。Anthropic社によって開発されました。人間の皆さまのお手伝いをさせていただくのが私の役目です。どのようなことでも、できる限りサポートさせていただきますので、お気軽にお尋ねください。'}],
                        'role': 'assistant'}},
 'stopReason': 'end_turn',
 'usage': {'inputTokens': 17, 'outputTokens': 100, 'totalTokens': 117}}
```

バッチリ結果を取得できました。

## どこのリージョンを使った！？

ただ、レスポンスからはどのリージョンを使ったかはわかりません。

今回は boto3 で `region_name=us-west-2` を指定していたので、us-west-2 の CWL を見てみます。

```text:CWL
{
    "schemaType": "ModelInvocationLog",
    "schemaVersion": "1.0",
    "timestamp": "2024-08-28T01:02:48Z",
    "accountId": "XXXXXX",
    "identity": {
        "arn": "XXXXXX"
    },
    "region": "us-west-2",
    "requestId": "XXXXXX",
    "operation": "Converse",
    "modelId": "us.anthropic.claude-3-5-sonnet-20240620-v1:0",
    "input": {
        "inputContentType": "application/json",
        "inputBodyJson": {
            "messages": [
                {
                    "role": "user",
                    "content": [
                        {
                            "text": "あなたは誰ですか？"
                        }
                    ]
                }
            ]
        },
        "inputTokenCount": 17
    },
    "output": {
        "outputContentType": "application/json",
        "outputBodyJson": {
            "output": {
                "message": {
                    "role": "assistant",
                    "content": [
                        {
                            "text": "はじめまして。私はClaudeという人工知能のアシスタントです。Anthropic社によって開発されました。人間の皆さまのお手伝いをさせていただくのが私の役目です。どのようなことでも、できる限りサポートさせていただきますので、お気軽にお尋ねください。"
                        }
                    ]
                }
            },
            "stopReason": "end_turn",
            "metrics": {
                "latencyMs": 3050
            },
            "usage": {
                "inputTokens": 17,
                "outputTokens": 100,
                "totalTokens": 117
            }
        },
        "outputTokenCount": 100
    },
    "inferenceRegion": "us-east-1"
}
```

このように最後に inferenceRegion が残っていました。

今回は boto3 では us-west-2 を明示的に使ったのに、`us-east-1` にルーティングされてますね。(違うリージョンになるまで何回か試しましたｗ)

Bedrock のログ機能を有効化していれば、実際どこのリージョンを使って推論したかがわかるようになっています。


以上、雑検証でした。