🧠

Amazon Bedrockのバッチ推論を試してみた

2024/09/07に公開

2024年8月21日にAmazon Bedrockでバッチ推論がサポートされたので、実際にマネジメントコンソール上で試してみました。

https://aws.amazon.com/jp/about-aws/whats-new/2024/08/amazon-bedrock-fms-batch-inference-50-price/

事前準備

  • S3の作成
  • Bedrockで使用するモデルの有効化

Amazon Bedrockのバッチ推論

何ができるのか

S3に保存されているデータに対して実行すると、複数の推論リクエストを非同期的に実行し、大量のリクエストを効率的に処理できます。それだけではなく、オンデマンド推論料金と比較して50%低い料金で使用できます。

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

クォーター

クォータ 最大 サービスクォータを通じて調整可能 説明
ベースモデルの同時バッチ推論ジョブ 3 はい ベースモデルで進行中にできるバッチ推論ジョブの最大数。
カスタムモデル用の同時バッチ推論ジョブ 3 はい カスタム
バッチ推論入力ファイルあたりのレコード数 50,000 はい バッチ推論ジョブの入力ファイルに含めることができるレコードの最大数。
バッチ推論ジョブあたりのレコード数 50,000 はい バッチ推論ジョブに含めることができるレコードの最大数。
バッチ推論ジョブあたりの最小レコード数 1,000 いいえ バッチ推論ジョブに含めることができるレコードの最小数。
バッチ推論入力ファイルサイズ 200MB はい バッチ推論のために送信される単一ファイルの最大サイズ (バイト単位)。
バッチ推論ジョブのサイズ 1GB はい バッチ推論ジョブに含まれるすべての入力ファイルの最大累積サイズ。

https://docs.aws.amazon.com/bedrock/latest/userguide/quotas.html#quotas-batch

使用できるモデル

オレゴンリージョンと東京リージョンだけ記載しておきます(2024年9月7日時点)。

モデル オレゴン 東京
Amazon Titan Text Embeddings V2 ×
Amazon Titan Multimodal Embeddings G1 ×
Anthropic Claude 3 Sonnet ×
Anthropic Claude 3.5 Sonnet
Anthropic Claude 3 Haiku
Anthropic Claude 3 Opus ×
Meta Llama 3.1 8B Instruct ×
Meta Llama 3.1 70B Instruct ×
Meta Llama 3.1 405B Instruct ×
Mistral AI Mistral Large 2 (24.07) ×
Mistral AI Mistral Small × ×

https://docs.aws.amazon.com/bedrock/latest/userguide/batch-inference-supported.html

入力するデータについて

バッチ推論を使用するためには、jsonlでファイルを作成する必要があります。
recordIdは任意のIDで、modelInputは使用するモデルのmodelInputと一致させる必要があります。
例えば、Claude3 Haikuモデルを使用する場合は以下のようになります。

{
    "recordId": "CALL0000001", 
    "modelInput": {
        "anthropic_version": "bedrock-2023-05-31", 
        "max_tokens": 1024,
        "messages": [ 
            { 
                "role": "user", 
                "content": [
                    {
                        "type": "text", 
                        "text": "Summarize the following call transcript: ..." 
                    } 
                ]
            }
        ]
    }
}

https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-anthropic-claude-messages.html

実際に試してみた

実際に推論バッチを試してみました。
今回使用するモデルはClaude3 Haikuとします。

事前準備

バッチ推論に必要なjsonlを作成します。
適当に1000レコードのjsonlを作成するpythonコードを置いときます。

jsonl作成コード
import json
import random

# 日本に関する質問のテンプレート
questions = [
    "日本の{category}について、{aspect}は何ですか?",
    "{place}にある有名な{landmark}の名前を教えてください。",
    "日本の{era}時代に起こった重要な{event}は何ですか?",
    "{industry}分野で日本が世界に誇る{innovation}とは何ですか?",
    "日本の{art_form}における{technique}の特徴を説明してください。",
    "{region}地方の有名な{specialty}を2つ挙げてください。",
    "日本の{tradition}における{element}の意味を教えてください。",
    "{sport}で日本が獲得した初めての{achievement}は何年ですか?",
    "日本の{science_field}分野で{discovery}を行った科学者は誰ですか?",
    "{natural_feature}として知られる日本の{location}はどこですか?"
]

# 質問のバリエーションを増やすための辞書
variations = {
    "category": ["文学", "音楽", "映画", "アニメ", "漫画", "料理", "建築", "ファッション", "テクノロジー", "スポーツ"],
    "aspect": ["代表的な作品", "有名な人物", "重要な出来事", "特徴的な要素", "国際的な影響"],
    "place": ["東京", "京都", "大阪", "奈良", "北海道", "沖縄", "富士山", "日本アルプス", "瀬戸内海"],
    "landmark": ["寺院", "神社", "城", "庭園", "タワー", "橋", "美術館", "公園"],
    "era": ["縄文", "弥生", "飛鳥", "奈良", "平安", "鎌倉", "室町", "安土桃山", "江戸", "明治", "大正", "昭和"],
    "event": ["戦争", "改革", "発明", "文化運動", "自然災害", "条約締結"],
    "industry": ["自動車", "エレクトロニクス", "ロボット工学", "アニメーション", "ゲーム", "環境技術"],
    "innovation": ["製品", "技術", "生産方式", "デザイン哲学", "ビジネスモデル"],
    "art_form": ["書道", "陶芸", "華道", "歌舞伎", "能", "俳句", "浮世絵"],
    "technique": ["筆遣い", "釉薬", "構図", "演技法", "韻律", "色彩"],
    "region": ["関東", "関西", "東北", "九州", "中部", "四国", "中国"],
    "specialty": ["料理", "工芸品", "農産物", "祭り", "方言", "観光地"],
    "tradition": ["茶道", "武道", "神道", "仏教", "正月行事", "七五三"],
    "element": ["作法", "精神性", "象徴", "儀式", "道具"],
    "sport": ["柔道", "相撲", "野球", "サッカー", "フィギュアスケート", "卓球"],
    "achievement": ["金メダル", "世界選手権", "新記録", "国際大会優勝"],
    "science_field": ["物理学", "化学", "生物学", "医学", "宇宙科学", "地球科学"],
    "discovery": ["新元素", "新理論", "新物質", "新種", "新技術"],
    "natural_feature": ["活火山", "温泉", "森林", "島", "湖", "滝"],
    "location": ["北アルプス", "屋久島", "知床半島", "白神山地", "小笠原諸島"]
}

def generate_question():
    template = random.choice(questions)
    for key in variations.keys():
        if key in template:
            template = template.replace("{" + key + "}", random.choice(variations[key]))
    return template

def create_record(index):
    return {
        "recordId": f"JP{index:04d}",
        "modelInput": {
            "anthropic_version": "bedrock-2023-05-31",
            "max_tokens": 1024,
            "messages": [
                {
                    "role": "user",
                    "content": [
                        {
                            "type": "text",
                            "text": generate_question()
                        }
                    ]
                }
            ]
        }
    }

# 1000個のレコードを生成してJSONLファイルに書き込む
with open('japan_questions_1000.jsonl', 'w', encoding='utf-8') as f:
    for i in range(1, 1001):
        json.dump(create_record(i), f, ensure_ascii=False)
        f.write('\n')

print("1000個のレコードを含むJSONLファイルが生成されました。")

作成したjsonlをS3にアップロードして下さい。今回はinput/にアップロードします。

jobの作成

実際にマネジメントコンソールからjobを作成します。
Bedrockの画面へ行き、サイドバーからBatch Inferenceをクリック。
その後、Create jobをクリック。

jobを作成する画面に遷移するので、任意の条件でCreate batch inference jobをクリック。


Batch inference jobsにてjobの一覧が表示されます(何回か失敗したので、Failedがあります)。StatusがCompletedになれば成功です。

Outputを確認する

処理が終了すると、指定したS3のoutputにて2つのファイルが生成されます。

  • {inputのファイル名}.out
  • manifest.json.out

{inputのファイル名}.out

jsonlの結果がまとまったファイルで、今回だと下記のようなレコードが1000レコード存在します。

{
    "modelInput": {
        "anthropic_version": "bedrock-2023-05-31",
        "max_tokens": 1024,
        "messages": [
            {
                "role": "user",
                "content": [
                    {
                        "type": "text",
                        "text": "日本の仏教における儀式の意味を教えてください。"
                    }
                ]
            }
        ]
    },
    "modelOutput": {
        "id": "msg_bdrk_01BgJUaYdbBB4oCAxGvQVmFP",
        "type": "message",
        "role": "assistant",
        "model": "claude-3-haiku-20240307",
        "content": [
            { 
                "type": "text",
                "text": "日本の仏教における主な儀式の意味は以下のようなものがあります。\n\n1. 葬式(葬儀)\n- 死者の供養と弔う心を表す\n- 仏教的な見方で死を受け入れ、来世への旅立ちを支える意味がある\n\n2. 法事(施餓鬼、追善供養など)\n- 先祖や亡くなった人の供養\n- 来世での往生を願う\n\n3. 正月の行事(初詣、初午、初詣など)\n- 新年を仏教的に祝福し、清浄な一年を過ごすことを願う\n- 仏様や神社への参詣によって、こころを新たにする意味がある\n\n4. 仏教行事(お盆、お彼岸など)\n- 死者の供養と来世への旅立ちを祝福する\n- 自分自身の生きる道しるべを得る機会と考えられている\n\nこのように、日本の仏教の儀式には、供養、弔い、清浄、新生、自己修養などの意味が込められています。家族や地域での絆を深めるシーンにもなっています。"
            }
        ],
        "stop_reason": "end_turn",
        "stop_sequence": null,
        "usage": {
            "input_tokens": 27,
            "output_tokens": 352
        }
    },
    "recordId":"JP0001"
}

manifest.json.out

jobの結果を記載したjsonとなっています。

{
  "totalRecordCount": 1000,
  "processedRecordCount": 1000,
  "successRecordCount": 1000,
  "errorRecordCount": 0,
  "inputTokenCount": 30501,
  "outputTokenCount": 351862
}

まとめ

Amazon Bedrockでバッチ推論が可能になったので、実際に試してみました。今回は純粋なテキストで検証してみましたが、PDFのテキスト抽出や記事要約といったinputTokenが多い処理に最適だと思いました。

Fusic 技術ブログ

Discussion