20
4

祝🎉東京リージョンにClaude3ファミリーが登場!早速バージニア北部と対決させてみた!

Posted at

はじめに

AWS Summit Tokyoでアナウンスのあった通り、東京リージョンにAnthropicのClaude3ファミリーのHaiku3.5 Sonnetが登場しました!!

スクリーンショット 2024-07-30 21.48.08.png

スクリーンショット_2024-08-06_5_54_05.png

当初7月予定とアナウンスされていましたが、予定通りにいかないのが世の常。
そんな中、7月リリースを信じ続けたBedrockerもこれで漸く8月を迎えることができます。。。

早速ですが、東京リージョンとバージニア北部とで出力対決をやってみようと思います!

コード

東京リージョンのBedrockコンソールからモデルアクセスを有効化したら、profile_nameにご自身のAWSアカウントのプロフィールを入力してください。

このコードでは下記の3つの質問を2つのリージョンで2つのモデルを使ってそれぞれ10回実行して平均応答時間を計測させています。

  • 質問
    • AWSについて教えて下さい
    • 日本一高い山はなんですか?
    • 太陽系の8つの惑星を、太陽からの距離が近い順にリストアップしてください
import streamlit as st
import boto3
import json
import time
from concurrent.futures import ThreadPoolExecutor, as_completed
from statistics import mean

st.set_page_config(layout="wide")

# カスタムCSSを追加
st.markdown("""
<style>
    .output-container {
        display: flex;
        flex-direction: column;
    }
    .fixed-height-output {
        min-height: 200px;
        height: 400px;
        overflow-y: auto;
        border: 1px solid #ccc;
        padding: 10px;
        margin-bottom: 10px;
        flex-grow: 1;
    }
</style>
""", unsafe_allow_html=True)

models = {
    "東京 - Claude 3 Haiku": {
        "model_id": "anthropic.claude-3-haiku-20240307-v1:0",
        "region": "ap-northeast-1"
    },
    "東京 - Claude 3.5 Sonnet": {
        "model_id": "anthropic.claude-3-5-sonnet-20240620-v1:0",
        "region": "ap-northeast-1"
    },
    "バージニア北部 - Claude 3 Haiku": {
        "model_id": "anthropic.claude-3-haiku-20240307-v1:0",
        "region": "us-east-1"
    },
    "バージニア北部 - Claude 3.5 Sonnet": {
        "model_id": "anthropic.claude-3-5-sonnet-20240620-v1:0",
        "region": "us-east-1"
    },
}

session = boto3.Session(profile_name="プロフィール名を入力")

st.title("Bedrock Claude 3: 東京 vs バージニア北部")

FIXED_PROMPTS = [
    "AWSについて教えて下さい",
    "日本一高い山はなんですか?",
    "太陽系の8つの惑星を、太陽からの距離が近い順にリストアップしてください"
]

col1, col2 = st.columns(2)
with col1:
    num_tests = st.slider("テスト実行回数を決めてください", min_value=1, max_value=10, value=5, step=1)

def invoke_model(model_name, model_info, prompt):
    try:
        bedrock = session.client(service_name='bedrock-runtime', region_name=model_info['region'])

        body = json.dumps({
            "anthropic_version": "bedrock-2023-05-31",
            "max_tokens": 300,
            "messages": [
                {"role": "user", "content": prompt}
            ]
        })

        start_time = time.time()

        response = bedrock.invoke_model(
            body=body,
            modelId=model_info['model_id'],
            accept='application/json',
            contentType='application/json'
        )
        
        end_time = time.time()

        response_body = json.loads(response.get('body').read())
        
        response_text = response_body.get('content')[0].get('text')

        return {
            "response": response_text,
            "time_taken": round(end_time - start_time, 2)
        }
        
    except Exception as e:
        return {"response": f"Error: {str(e)}", "time_taken": 0}

def run_test(model_name, model_info, prompt):
    results = []
    for _ in range(num_tests):
        result = invoke_model(model_name, model_info, prompt)
        results.append(result)
    
    avg_time = mean([r["time_taken"] for r in results])
    return {
        "response": results[0]["response"],
        "time_taken": avg_time,
        "all_times": [r["time_taken"] for r in results]
    }

if st.button("テスト実行"):
    progress_bar = st.progress(0)
    status_text = st.empty()
    status_text.text("テストを開始します...")

    all_results = {}
    
    for prompt in FIXED_PROMPTS:
        all_results[prompt] = {}
        with ThreadPoolExecutor(max_workers=4) as executor:
            future_to_model = {executor.submit(run_test, model_name, model_info, prompt): model_name 
                               for model_name, model_info in models.items()}
            
            for i, future in enumerate(as_completed(future_to_model)):
                model_name = future_to_model[future]
                all_results[prompt][model_name] = future.result()
                progress = (len(all_results) - 1 + (i + 1) / len(models)) / len(FIXED_PROMPTS)
                progress_bar.progress(progress)
                status_text.text(f"{prompt} - {model_name} のテストが完了しました。")

    status_text.text("すべてのテストが完了しました。")
    progress_bar.empty()

    st.subheader("テスト結果")
    
    for prompt in FIXED_PROMPTS:
        st.markdown(f"## プロンプト: {prompt}")
        col1, col2 = st.columns(2)
        
        def display_test_results(model_name):
            data = all_results[prompt][model_name]
            st.markdown(f"**{model_name}** (Model ID: {models[model_name]['model_id']})")
            st.markdown(f"平均応答時間: {data['time_taken']:.2f}")
            st.markdown("応答例:")
            st.markdown('<div class="output-container">', unsafe_allow_html=True)
            st.markdown(f'<div class="fixed-height-output">{data["response"]}</div>', unsafe_allow_html=True)
            st.markdown('</div>', unsafe_allow_html=True)
            st.markdown("---")

        with col1:
            st.subheader("東京リージョン (ap-northeast-1)")
            for model_name in ["東京 - Claude 3 Haiku", "東京 - Claude 3.5 Sonnet"]:
                display_test_results(model_name)

        with col2:
            st.subheader("バージニア北部リージョン (us-east-1)")
            for model_name in ["バージニア北部 - Claude 3 Haiku", "バージニア北部 - Claude 3.5 Sonnet"]:
                display_test_results(model_name)

else:
    st.info("「テスト実行」ボタンを押してテストを開始してください。")

東京リージョン vs バージニア北部

下記のコマンドを実行するとブラウザが開きます。

streamlit run app.py

デフォルトではテスト実行回数のスライドバーが5なので、10に合わせて「テスト実行」ボタンを押すとテスト開始です。

スクリーンショット 2024-08-06 5.58.08.png

結果

平均応答時間 東京 Haiku 東京 Sonnet バージニア北部 Haiku バージニア北部ン Sonnet
AWSについて教えて下さい 2.68秒 5.01秒 4.39秒 7.20秒
日本一高い山はなんですか? 1.55秒 5.14秒 3.27秒 6.95秒
太陽系の8つの惑星を、太陽からの距離が近い順にリストアップしてください 1.31秒 4.14秒 2.12秒 5.95秒

スクリーンショット 2024-08-06 6.01.45.png

スクリーンショット 2024-08-06 6.02.13.png

スクリーンショット 2024-08-06 6.02.32.png

スクリーンショット 2024-08-06 6.02.49.png

スクリーンショット 2024-08-06 6.03.06.png

スクリーンショット 2024-08-06 6.03.22.png

今回のケースでは東京リージョンの方がバージニア北部リージョンと比較して、平均応答時間がHaikuで約1.8倍、Sonnetで約1.4倍速く返ってきてることが確認できました!!

終わりに

東京リージョンに強力なClaude3ファミリーがGAしたことで、レスポンス速度が向上したことは勿論ですが、特にAPIアクセスであっても国内のインフラストラクチャで完結させたいという企業ニーズに応えられるようになったので、日本市場におけるAIサービスの適用範囲が広がりましたね。

なんでも、使用頻度の多いリージョンは要望が強いと判断されるらしいので、今後のモデル拡充に一役買うためにも東京リージョンでガンガン使っていきましょう!!

おまけ

Bedrockを活用した生成AIアプリ開発入門本を共著がお陰様で重版になりました。
ハンズオンも豊富でBedrockの入門に最適な本となっておりますので是非興味のある方はお手にとってみてください!

Amazon Bedrock 生成AIアプリ開発入門

20
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
4