Amazon Bedrockのバッチ推論を試してみた
2024年8月21日にAmazon Bedrockでバッチ推論がサポートされたので、実際にマネジメントコンソール上で試してみました。
事前準備
- S3の作成
- Bedrockで使用するモデルの有効化
Amazon Bedrockのバッチ推論
何ができるのか
S3に保存されているデータに対して実行すると、複数の推論リクエストを非同期的に実行し、大量のリクエストを効率的に処理できます。それだけではなく、オンデマンド推論料金と比較して50%低い料金で使用できます。
クォーター
クォータ | 最大 | サービスクォータを通じて調整可能 | 説明 |
---|---|---|---|
ベースモデルの同時バッチ推論ジョブ | 3 | はい | ベースモデルで進行中にできるバッチ推論ジョブの最大数。 |
カスタムモデル用の同時バッチ推論ジョブ | 3 | はい | カスタム |
バッチ推論入力ファイルあたりのレコード数 | 50,000 | はい | バッチ推論ジョブの入力ファイルに含めることができるレコードの最大数。 |
バッチ推論ジョブあたりのレコード数 | 50,000 | はい | バッチ推論ジョブに含めることができるレコードの最大数。 |
バッチ推論ジョブあたりの最小レコード数 | 1,000 | いいえ | バッチ推論ジョブに含めることができるレコードの最小数。 |
バッチ推論入力ファイルサイズ | 200MB | はい | バッチ推論のために送信される単一ファイルの最大サイズ (バイト単位)。 |
バッチ推論ジョブのサイズ | 1GB | はい | バッチ推論ジョブに含まれるすべての入力ファイルの最大累積サイズ。 |
使用できるモデル
オレゴンリージョンと東京リージョンだけ記載しておきます(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 | × | × |
入力するデータについて
バッチ推論を使用するためには、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: ..."
}
]
}
]
}
}
実際に試してみた
実際に推論バッチを試してみました。
今回使用するモデルは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が多い処理に最適だと思いました。
Discussion