HAQM Web Services ブログ

HAQM Bedrock のデータオートメーションを利用してマルチモーダルコンテンツからインサイトを取得する (一般提供が開始されました)

多くのアプリケーションは、さまざまなモダリティを通じて利用できるコンテンツとインタラクションする必要があります。これらのアプリケーションの一部は、保険金請求や医療費請求書などの複雑なドキュメントを処理します。モバイルアプリは、ユーザーが作成したメディアを分析する必要があります。組織は、ドキュメント、画像、音声、動画ファイルなどのデジタルアセットの上にセマンティックインデックスを構築する必要があります。しかし、非構造化マルチモーダルコンテンツからインサイトを取得するようセットアップするのは簡単ではありません。さまざまなデータ形式用の処理パイプラインを実装し、必要な情報を取得するために複数のステップを実行する必要があります。これは通常、複数のモデルを本番で使用し、(ファインチューニングやプロンプトエンジニアリングを通じた) そのコストの最適化、安全策 (例: ハルシネーションへの対策)、ターゲットアプリケーションとの統合 (データ形式を含む)、モデルの更新に対応する必要があることを意味します。

このプロセスを容易にするために、HAQM Bedrock のデータオートメーションのプレビューを AWS re:Invent の期間中に導入しました。これは、ドキュメント、画像、音声、動画などの非構造化マルチモーダルコンテンツからの価値あるインサイトの生成を効率化する HAQM Bedrock の機能です。Bedrock のデータオートメーションを利用すると、インテリジェントなドキュメント処理、メディア分析、および他のデータ中心のマルチモーダルオートメーションソリューションを構築するための開発時間と労力を削減できます。

Bedrock のデータオートメーションをスタンドアロン機能として使用したり、HAQM Bedrock のナレッジベースのパーサーとして使用したりして、マルチモーダルコンテンツから得たインサイトをインデックス化し、検索拡張生成 (RAG) のためにより関連性の高い応答を提供できます。

本日、Bedrock のデータオートメーションは、クロスリージョン推論エンドポイントのサポートとともに一般提供が開始され、より多くの AWS リージョンで利用できるようになり、さまざまな場所でシームレスにコンピューティングを使用するようになりました。プレビュー期間中のフィードバックに基づいて、精度を高め、画像や動画のロゴ認識のサポートも追加しました。

実際にどのように機能するかを見てみましょう。

HAQM Bedrock のデータオートメーションとクロスリージョン推論エンドポイントの併用
Bedrock のデータオートメーションプレビューについての公開ブログ記事には、HAQM Bedrock コンソールでビジュアルデモを使用してドキュメントや動画から情報を抽出する方法が記載されています。この機能がどのように動作し、カスタマイズするために何ができるのかを理解するために、コンソールのデモエクスペリエンスをお試しいただくことをお勧めします。この記事では、コンソールでのいくつかのステップから始めて、コードサンプルに従いながら、アプリケーションでの Bedrock のデータオートメーションの動作に焦点を当てます。

HAQM Bedrock コンソール[データオートメーション] セクションでは、初めてアクセスしたときに、クロスリージョンサポートを有効にするかどうかの確認が求められるようになりました。例:

コンソールのスクリーンショット。

API の観点から見ると、InvokeDataAutomationAsync オペレーションでは、使用するデータオートメーションプロファイルを指定するために、追加のパラメータ (dataAutomationProfileArn) が必要になりました。このパラメータの値は、リージョンと AWS アカウント ID によって異なります:

arn:aws:bedrock:<REGION>:<ACCOUNT_ID>:data-automation-profile/us.data-automation-v1

また、dataAutomationArn パラメータの名前が dataAutomationProjectArn に変更され、プロジェクトの HAQM リソースネーム (ARN) が含まれていることをより明確に示すようになりました。Bedrock のデータオートメーションを呼び出す際に、使用するプロジェクトまたはブループリントを指定しなければならなくなりました。ブループリントを渡すと、カスタム出力が得られます。引き続き標準のデフォルト出力を取得するには、arn:aws:bedrock:<REGION>:aws:data-automation-project/public-default を使用するようにパラメータ DataAutomationProjectArn を設定します。

名前が示すように、InvokeDataAutomationAsync オペレーションは非同期です。入力と出力の設定を渡した後、結果の準備ができたら、出力設定で指定された HAQM Simple Storage Service (HAQM S3) バケットに書き込まれます。notificationConfiguration パラメータを使用して、Bedrock のデータオートメーションから HAQM EventBridge の通知を受け取ることができます。

Bedrock のデータオートメーションでは、2 つの方法で出力を設定できます:

  • [標準出力] は、ドキュメントのセマンティクス、動画の章の概要、音声トランスクリプトなど、データタイプに関連する事前定義済みのインサイトを提供します。標準出力を使用すると、わずか数ステップで必要なインサイトをセットアップできます。
  • [カスタム出力] を使用すると、ブループリントを使用して抽出のニーズを指定し、よりカスタマイズされたインサイトを得ることができます。

新しい機能が実際に動作している様子を見るために、プロジェクトを作成し、標準出力設定をカスタマイズします。ドキュメントでは、マークダウンではなく、プレーンテキストを選択します。なお、これらの設定ステップは、Bedrock Data Automation API を使用して自動化できます。

コンソールのスクリーンショット。

動画では、完全な音声トランスクリプトと動画全体の要約が必要です。また、各章の要約も要求します。

コンソールのスクリーンショット。

ブループリントを設定するには、HAQM Bedrock コンソールのナビゲーションペインの [データオートメーション] セクションで [カスタム出力設定] を選択します。そこで、[US-Driver-License] サンプルブループリントを検索します。より多くの例やアイデアを得るために、他のサンプルブループリントを参照できます。

サンプルブループリントは編集できないため、[アクション] メニューを使用してブループリントを複製し、プロジェクトに追加します。そこで、ブループリントを変更し、生成 AI を使用して必要な形式でデータを抽出または計算できるカスタムフィールドを追加することで、抽出するデータをファインチューニングできます。

コンソールのスクリーンショット。

米国の運転免許証の画像を S3 バケットにアップロードします。その後、AWS SDK for Python (Boto3) を通じて Bedrock のデータオートメーションを利用するこのサンプル Python スクリプトを使用して、画像からテキスト情報を抽出します:

import json
import sys
import time

import boto3

DEBUG = False

AWS_REGION = '<REGION>'
BUCKET_NAME = '<BUCKET>'
INPUT_PATH = 'BDA/Input'
OUTPUT_PATH = 'BDA/Output'

PROJECT_ID = '<PROJECT_ID>'
BLUEPRINT_NAME = 'US-Driver-License-demo'

# 表示するフィールド
BLUEPRINT_FIELDS = [
    'NAME_DETAILS/FIRST_NAME',
    'NAME_DETAILS/MIDDLE_NAME',
    'NAME_DETAILS/LAST_NAME',
    'DATE_OF_BIRTH',
    'DATE_OF_ISSUE',
    'EXPIRATION_DATE'
]

# AWS SDK for Python (Boto3) clients
bda = boto3.client('bedrock-data-automation-runtime', region_name=AWS_REGION)
s3 = boto3.client('s3', region_name=AWS_REGION)
sts = boto3.client('sts')


def log(data):
    if DEBUG:
        if type(data) is dict:
            text = json.dumps(data, indent=4)
        else:
            text = str(data)
        print(text)

def get_aws_account_id() -> str:
    return sts.get_caller_identity().get('Account')


def get_json_object_from_s3_uri(s3_uri) -> dict:
    s3_uri_split = s3_uri.split('/')
    bucket = s3_uri_split[2]
    key = '/'.join(s3_uri_split[3:])
    object_content = s3.get_object(Bucket=bucket, Key=key)['Body'].read()
    return json.loads(object_content)


def invoke_data_automation(input_s3_uri, output_s3_uri, data_automation_arn, aws_account_id) -> dict:
    params = {
        'inputConfiguration': {
            's3Uri': input_s3_uri
        },
        'outputConfiguration': {
            's3Uri': output_s3_uri
        },
        'dataAutomationConfiguration': {
            'dataAutomationProjectArn': data_automation_arn
        },
        'dataAutomationProfileArn': f"arn:aws:bedrock:{AWS_REGION}:{aws_account_id}:data-automation-profile/us.data-automation-v1"
    }

    response = bda.invoke_data_automation_async(**params)
    log(response)

    return response

def wait_for_data_automation_to_complete(invocation_arn, loop_time_in_seconds=1) -> dict:
    while True:
        response = bda.get_data_automation_status(
            invocationArn=invocation_arn
        )
        status = response['status']
        if status not in ['Created', 'InProgress']:
            print(f" {status}")
            return response
        print(".", end='', flush=True)
        time.sleep(loop_time_in_seconds)


def print_document_results(standard_output_result):
    print(f"Number of pages: {standard_output_result['metadata']['number_of_pages']}")
    for page in standard_output_result['pages']:
        print(f"- Page {page['page_index']}")
        if 'text' in page['representation']:
            print(f"{page['representation']['text']}")
        if 'markdown' in page['representation']:
            print(f"{page['representation']['markdown']}")


def print_video_results(standard_output_result):
    print(f"Duration: {standard_output_result['metadata']['duration_millis']} ms")
    print(f"Summary: {standard_output_result['video']['summary']}")
    statistics = standard_output_result['statistics']
    print("Statistics:")
    print(f"- Speaket count: {statistics['speaker_count']}")
    print(f"- Chapter count: {statistics['chapter_count']}")
    print(f"- Shot count: {statistics['shot_count']}")
    for chapter in standard_output_result['chapters']:
        print(f"Chapter {chapter['chapter_index']} {chapter['start_timecode_smpte']}-{chapter['end_timecode_smpte']} ({chapter['duration_millis']} ms)")
        if 'summary' in chapter:
            print(f"- Chapter summary: {chapter['summary']}")


def print_custom_results(custom_output_result):
    matched_blueprint_name = custom_output_result['matched_blueprint']['name']
    log(custom_output_result)
    print('\n- Custom output')
    print(f"Matched blueprint: {matched_blueprint_name}  Confidence: {custom_output_result['matched_blueprint']['confidence']}")
    print(f"Document class: {custom_output_result['document_class']['type']}")
    if matched_blueprint_name == BLUEPRINT_NAME:
        print('\n- Fields')
        for field_with_group in BLUEPRINT_FIELDS:
            print_field(field_with_group, custom_output_result)


def print_results(job_metadata_s3_uri) -> None:
    job_metadata = get_json_object_from_s3_uri(job_metadata_s3_uri)
    log(job_metadata)

    for segment in job_metadata['output_metadata']:
        asset_id = segment['asset_id']
        print(f'\nAsset ID: {asset_id}')

        for segment_metadata in segment['segment_metadata']:
            # 標準出力
            standard_output_path = segment_metadata['standard_output_path']
            standard_output_result = get_json_object_from_s3_uri(standard_output_path)
            log(standard_output_result)
            print('\n- Standard output')
            semantic_modality = standard_output_result['metadata']['semantic_modality']
            print(f"Semantic modality: {semantic_modality}")
            match semantic_modality:
                case 'DOCUMENT':
                    print_document_results(standard_output_result)
                case 'VIDEO':
                    print_video_results(standard_output_result)
            # カスタム出力
            if 'custom_output_status' in segment_metadata and segment_metadata['custom_output_status'] == 'MATCH':
                custom_output_path = segment_metadata['custom_output_path']
                custom_output_result = get_json_object_from_s3_uri(custom_output_path)
                print_custom_results(custom_output_result)


def print_field(field_with_group, custom_output_result) -> None:
    inference_result = custom_output_result['inference_result']
    explainability_info = custom_output_result['explainability_info'][0]
    if '/' in field_with_group:
        # グループの一部のフィールド用
        (group, field) = field_with_group.split('/')
        inference_result = inference_result[group]
        explainability_info = explainability_info[group]
    else:
        field = field_with_group
    value = inference_result[field]
    confidence = explainability_info[field]['confidence']
    print(f'{field}: {value or '<EMPTY>'}  Confidence: {confidence}')


def main() -> None:
    if len(sys.argv) < 2:
        print("Please provide a filename as command line argument")
        sys.exit(1)
      
    file_name = sys.argv[1]
    
    aws_account_id = get_aws_account_id()
    input_s3_uri = f"s3://{BUCKET_NAME}/{INPUT_PATH}/{file_name}" # ファイル
    output_s3_uri = f"s3://{BUCKET_NAME}/{OUTPUT_PATH}" # フォルダ
    data_automation_arn = f"arn:aws:bedrock:{AWS_REGION}:{aws_account_id}:data-automation-project/{PROJECT_ID}"

    print(f"Invoking Bedrock Data Automation for '{file_name}'", end='', flush=True)

    data_automation_response = invoke_data_automation(input_s3_uri, output_s3_uri, data_automation_arn, aws_account_id)
    data_automation_status = wait_for_data_automation_to_complete(data_automation_response['invocationArn'])

    if data_automation_status['status'] == 'Success':
        job_metadata_s3_uri = data_automation_status['outputConfiguration']['s3Uri']
        print_results(job_metadata_s3_uri)


if __name__ == "__main__":
    main()

スクリプトの初期設定には、入力と出力で使用する S3 バケットの名前、バケット内の入力ファイルの場所、結果の出力パス、Bedrock のデータオートメーションからカスタム出力を取得するために使用するプロジェクト ID、および出力に表示するブループリントフィールドが含まれます。

入力ファイルの名前を渡してスクリプトを実行します。出力には、Bedrock のデータオートメーションによって抽出された情報が表示されます。[US-Driver-License] が一致し、運転免許証の名前と日付が出力に表示されます。

python bda-ga.py bda-drivers-license.jpeg

Invoking Bedrock Data Automation for 'bda-drivers-license.jpeg'................Success

Asset ID: 0

- Standard output
Semantic modality: DOCUMENT
Number of pages: 1
- Page 0
NEW JERSEY

Motor Vehicle
 Commission

AUTO DRIVER LICENSE

Could DL M6454 64774 51685                      CLASS D
        DOB 01-01-1968
ISS 03-19-2019          EXP     01-01-2023
        MONTOYA RENEE MARIA 321 GOTHAM AVENUE TRENTON, NJ 08666 OF
        END NONE
        RESTR NONE
        SEX F HGT 5'-08" EYES HZL               ORGAN DONOR
        CM ST201907800000019 CHG                11.00

[SIGNATURE]



- Custom output
Matched blueprint: US-Driver-License-copy  Confidence: 1
Document class: US-drivers-licenses

- Fields
FIRST_NAME: RENEE  Confidence: 0.859375
MIDDLE_NAME: MARIA  Confidence: 0.83203125
LAST_NAME: MONTOYA  Confidence: 0.875
DATE_OF_BIRTH: 1968-01-01  Confidence: 0.890625
DATE_OF_ISSUE: 2019-03-19  Confidence: 0.79296875
EXPIRATION_DATE: 2023-01-01  Confidence: 0.93359375

想定どおり、出力には、Bedrock のデータオートメーションプロジェクトに関連付けられたブループリントから選択した情報が表示されます。

同様に、私の同僚である Mike Chambers動画ファイルに対して同じスクリプトを実行します。出力サイズを小さくするために、完全な音声トランスクリプトや動画に表示されるテキストは表示しません。

python bda.py mike-video.mp4
Invoking Bedrock Data Automation for 'mike-video.mp4'..........................................................................................................................................................................................................................................................................Success

Asset ID: 0

- Standard output
Semantic modality: VIDEO
Duration: 810476 ms
Summary: In this comprehensive demonstration, a technical expert explores the capabilities and limitations of Large Language Models (LLMs) while showcasing a practical application using AWS services.He begins by addressing a common misconception about LLMs, explaining that while they possess general world knowledge from their training data, they lack current, real-time information unless connected to external data sources.

To illustrate this concept, he demonstrates an "Outfit Planner" application that provides clothing recommendations based on location and weather conditions.Using Brisbane, Australia as an example, the application combines LLM capabilities with real-time weather data to suggest appropriate attire like lightweight linen shirts, shorts, and hats for the tropical climate.

The demonstration then shifts to the HAQM Bedrock platform, which enables users to build and scale generative AI applications using foundation models.The speaker showcases the "OutfitAssistantAgent," explaining how it accesses real-time weather data to make informed clothing recommendations.Through the platform's "Show Trace" feature, he reveals the agent's decision-making process and how it retrieves and processes location and weather information.

The technical implementation details are explored as the speaker configures the OutfitAssistant using HAQM Bedrock.The agent's workflow is designed to be fully serverless and managed within the HAQM Bedrock service.

Further diving into the technical aspects, the presentation covers the AWS Lambda console integration, showing how to create action group functions that connect to external services like the OpenWeatherMap API.The speaker emphasizes that LLMs become truly useful when connected to tools providing relevant data sources, whether databases, text files, or external APIs.

The presentation concludes with the speaker encouraging viewers to explore more AWS developer content and engage with the channel through likes and subscriptions, reinforcing the practical value of combining LLMs with external data sources for creating powerful, context-aware applications.
Statistics:
- Speaket count: 1
- Chapter count: 6
- Shot count: 48
Chapter 0 00:00:00:00-00:01:32:01 (92025 ms)
- Chapter summary: A man with a beard and glasses, wearing a gray hooded sweatshirt with various logos and text, is sitting at a desk in front of a colorful background.He discusses the frequent release of new large language models (LLMs) and how people often test these models by asking questions like "Who won the World Series?" The man explains that LLMs are trained on general data from the internet, so they may have information about past events but not current ones.He then poses the question of what he wants from an LLM, stating that he desires general world knowledge, such as understanding basic concepts like "up is up" and "down is down," but does not need specific factual knowledge.The man suggests that he can attach other systems to the LLM to access current factual data relevant to his needs.He emphasizes the importance of having general world knowledge and the ability to use tools and be linked into agentic workflows, which he refers to as "agentic workflows." The man encourages the audience to add this term to their spell checkers, as it will likely become commonly used.
Chapter 1 00:01:32:01-00:03:38:18 (126560 ms)
- Chapter summary: The video showcases a man with a beard and glasses demonstrating an "Outfit Planner" application on his laptop.The application allows users to input their location, such as Brisbane, Australia, and receive recommendations for appropriate outfits based on the weather conditions.The man explains that the application generates these recommendations using large language models, which can sometimes provide inaccurate or hallucinated information since they lack direct access to real-world data sources.

The man walks through the process of using the Outfit Planner, entering Brisbane as the location and receiving weather details like temperature, humidity, and cloud cover.He then shows how the application suggests outfit options, including a lightweight linen shirt, shorts, sandals, and a hat, along with an image of a woman wearing a similar outfit in a tropical setting.

Throughout the demonstration, the man points out the limitations of current language models in providing accurate and up-to-date information without external data connections.He also highlights the need to edit prompts and adjust settings within the application to refine the output and improve the accuracy of the generated recommendations.
Chapter 2 00:03:38:18-00:07:19:06 (220620 ms)
- Chapter summary: The video demonstrates the HAQM Bedrock platform, which allows users to build and scale generative AI applications using foundation models (FMs). [speaker_0] introduces the platform's overview, highlighting its key features like managing FMs from AWS, integrating with custom models, and providing access to leading AI startups.The video showcases the HAQM Bedrock console interface, where [speaker_0] navigates to the "Agents" section and selects the "OutfitAssistantAgent" agent. [speaker_0] tests the OutfitAssistantAgent by asking it for outfit recommendations in Brisbane, Australia.The agent provides a suggestion of wearing a light jacket or sweater due to cool, misty weather conditions.To verify the accuracy of the recommendation, [speaker_0] clicks on the "Show Trace" button, which reveals the agent's workflow and the steps it took to retrieve the current location details and weather information for Brisbane.The video explains that the agent uses an orchestration and knowledge base system to determine the appropriate response based on the user's query and the retrieved data.It highlights the agent's ability to access real-time information like location and weather data, which is crucial for generating accurate and relevant responses.
Chapter 3 00:07:19:06-00:11:26:13 (247214 ms)
- Chapter summary: The video demonstrates the process of configuring an AI assistant agent called "OutfitAssistant" using HAQM Bedrock. [speaker_0] introduces the agent's purpose, which is to provide outfit recommendations based on the current time and weather conditions.The configuration interface allows selecting a language model from Anthropic, in this case the Claud 3 Haiku model, and defining natural language instructions for the agent's behavior. [speaker_0] explains that action groups are groups of tools or actions that will interact with the outside world.The OutfitAssistant agent uses Lambda functions as its tools, making it fully serverless and managed within the HAQM Bedrock service. [speaker_0] defines two action groups: "get coordinates" to retrieve latitude and longitude coordinates from a place name, and "get current time" to determine the current time based on the location.The "get current weather" action requires calling the "get coordinates" action first to obtain the location coordinates, then using those coordinates to retrieve the current weather information.This demonstrates the agent's workflow and how it utilizes the defined actions to generate outfit recommendations.Throughout the video, [speaker_0] provides details on the agent's configuration, including its name, description, model selection, instructions, and action groups.The interface displays various options and settings related to these aspects, allowing [speaker_0] to customize the agent's behavior and functionality.
Chapter 4 00:11:26:13-00:13:00:17 (94160 ms)
- Chapter summary: The video showcases a presentation by [speaker_0] on the AWS Lambda console and its integration with machine learning models for building powerful agents. [speaker_0] demonstrates how to create an action group function using AWS Lambda, which can be used to generate text responses based on input parameters like location, time, and weather data.The Lambda function code is shown, utilizing external services like OpenWeatherMap API for fetching weather information. [speaker_0] explains that for a large language model to be useful, it needs to connect to tools providing relevant data sources, such as databases, text files, or external APIs.The presentation covers the process of defining actions, setting up Lambda functions, and leveraging various tools within the AWS environment to build intelligent agents capable of generating context-aware responses.
Chapter 5 00:13:00:17-00:13:28:10 (27761 ms)
- Chapter summary: A man with a beard and glasses, wearing a gray hoodie with various logos and text, is sitting at a desk in front of a colorful background.He is using a laptop computer that has stickers and logos on it, including the AWS logo.The man appears to be presenting or speaking about AWS (HAQM Web Services) and its services, such as Lambda functions and large language models.He mentions that if a Lambda function can do something, then it can be used to augment a large language model.The man concludes by expressing hope that the viewer found the video useful and insightful, and encourages them to check out other videos on the AWS developers channel.He also asks viewers to like the video, subscribe to the channel, and watch other videos.

知っておくべきこと
HAQM Bedrock のデータオートメーションは現在、米国東部 (バージニア北部) と米国西部 (オレゴン) の 2 つの AWS リージョンでクロスリージョン推論を介してご利用いただけます。これらのリージョンから Bedrock のデータオートメーションを利用する場合、米国東部 (オハイオ、バージニア北部) と米国西部 (北カリフォルニア、オレゴン) の 4 つのリージョンのいずれかでクロスリージョン推論を使用してデータを処理できます。これらのリージョンはすべて米国内にあるため、データは同じ地域内で処理されます。2025 年後半には、欧州とアジアのさらに多くのリージョンのサポートを追加する予定です。

プレビュー、およびクロスリージョン推論を使用する場合と比較して、料金に変更はありません。詳細については、「HAQM Bedrock の料金」にアクセスしてください。

また、Bedrock のデータオートメーションには、きめ細かな暗号化コントロールのための AWS Key Management Service (AWS KMS) カスタマーマネージドキーのサポート、インターネット経由ではなく、仮想プライベートクラウド (VPC) 内の Bedrock Data Automation API に直接接続するための AWS PrivateLink、コストを追跡し、AWS Identity and Access Management (IAM) でタグベースのアクセスポリシーを強制適用するための Bedrock のデータオートメーションのリソースとジョブのタグ付けなど、セキュリティ、ガバナンス、管理性に関連する多数の機能も含まれるようになりました。

このブログ記事では Python を利用しましたが、Bedrock のデータオートメーションはどの AWS SDK でもご利用いただけます。例えば、バックエンドのドキュメント処理アプリケーションには Java、.NET、または Rust、画像、動画、または音声ファイルを処理するウェブアプリケーションには JavaScript、エンドユーザーが提供するコンテンツを処理するネイティブモバイルアプリには Swift を、それぞれご利用いただけます。マルチモーダルデータからインサイトを取得するのがこれまでになく簡単になりました。

詳細 (コードサンプルを含む) については、次の記事をお読みください:

Danilo

私たちの取り組みについて、どのように感じましたか? この 1 分間のアンケートにぜひご協力ください!

原文はこちらです。