Taste of Tech Topics

Acroquest Technology株式会社のエンジニアが書く技術ブログ

Amazon Nova モデルと Bedrock Knowledge Base で動画検索を実現する

こんにちは、機械学習チーム YAMALEX の駿です。
YAMALEX は Acroquest 社内で発足した、会社の未来の技術を創る、機械学習がメインテーマのデータサイエンスチームです。
(詳細はリンク先をご覧ください。)

突然ですが、動画を検索したくなることってありますよね。

それも、動画のタイトルにはなっていないんだけど、こんなことを話してたんだよな、というざっくりとした記憶しかなく、どうしても見つけることができないこと、あると思います。

あるいは Google 検索などができれば良いのですが、自社内にある動画や、仕事で使う動画となると、そう簡単にはいきません。

そんな困りごとを解決するためのツールを Amazon Nova モデルと Amazon Bedrock Knowledge Base で作成してみました。

Bedrock Knowledge Base を使うことで、ドキュメントの取り込み・検索部分を自前で開発する必要がなく、動画を要約した結果をS3に置くだけで簡単に連携できます。

すなわち、開発コストを最小限に抑えつつ高性能なアプリを開発できます。

構成図

1. 動画検索で実現したいこと

動画のタイトルにその文言が含まれれば、タイトルで検索をかけることができますが、動画の一部で話していただけ、などの内容はなかなか文字列で検索することが困難です。

あるいは、どれか特定の動画に興味があるのではなく、同じ話題の動画を広く検索したい、ということもあるかもしれません。

今回の動画検索ではそのようなあいまいな検索を行うために、 Bedrock Knowledge Base でベクトル検索を行うことを考えます。

2. 実現方法

大まかな手順は以下の通りです。

  1. 動画をAmazon Nova モデルで要約できるようにする
  2. 要約結果を Bedrock Knowledge Base に取り込めるようにする
  3. 動画の検索処理を実現する
  4. 検索画面を作成する

それぞれ、もう少し詳しく説明します。

2.1. 動画をAmazon Nova モデルで要約できるようにする


モデルで要約する

Amazon Nova モデルはテキスト、画像に加えて、動画を入力に入れられます。

下記プロンプトとともに動画とそれを文字起こししたものを入力し、要約文を作成してもらいました。

今回は Acroquest の YouTube にアップロードされている動画の内、再生時間が1分以下のものを選択し、 S3 にアップロードしました。

S3 にアップロードするとイベントを受け取った Lambda がこれらの動画の説明文を Amazon Nova Lite に生成させ、 テキストファイルを S3 にアップロードします。

このテキストファイルが後ほど Knowledge Base で取り込む対象になります。

system_prompt = [
    {
        "text": dedent("""\
            あなたのタスクは、与えられた動画を解析し、何が映っているかを説明することです。
            動画を文字起こしした結果を「文字起こし:xxx」の部分に記載しています。説明の材料としてつかってください。
            あなたの返答は、厳密に、動画の説明文のみで構成されている必要があります。
            できるだけ詳細に説明してください。
            要約は日本語で返してください。
        """)
    }
]
use_messages = [
    {
        "role": "user",
        "content": [
            {"text": f"動画名: {filename}"},
            {
                "video": {
                    "format": "mp4",
                    "source": {"bytes": b64_content},
                },
            },
            {"text": f"文字起こし: {transcript}"},
            {"text": "この動画を日本語で説明してください。"},
        ],
    }
]
config = {"temperature": 0}
body = {
    "schemaVersion": "messages-v1",
    "system": system_prompt,
    "messages": use_messages,
    "inferenceConfig": config,
}

response = bedrock_agent.invoke_model(
    modelId=MODEL_ID,
    body=json.dumps(body),
    contentType="application/json",
)
model_response = json.loads(response["body"].read())
content = model_response["output"]["message"]["content"][0]["text"]

下のようなレスポンスが返ってきます。

動画は、リモートワーク中のITエンジニアが食べたいアンパンのランキングを紹介しています。

まず、第4位は「アンパン九十五円」で、オーソドックスなしっとり生地とこしあんが滑らかな食感で甘すぎないのが特徴です。
第3位は「たっぷりホイップワンパン百十七円」で、クリームがぎっしり詰まっていて食べた時の満足感が高いのが特徴です。
第2位は「高級通販百十四円」で、消しの実がまぶされており、お饅頭のような上品な味わいと厚みがあります。
第1位は「薄皮つ板百三十七円」で、食べやすい二口サイズで、あんこの密度が高く、手も汚れません。

リモートワーク中に食べたいアンパンのランキングを紹介し、気になるものがあったら購入を勧めています。
動画の冒頭では、キーボードの画像が映し出され、その下に「アクロクエストテクノロジー」のロゴが並んでいます。
その後、キーボードのアップショットが映し出され、キーボードの文字が日本語で表示されています。
次に、キーボードの横に、クリーニング用のスプレー缶、綿棒、そして白い布が置かれています。
そして、キーボードの上に白い布を置き、その布でキーボードを拭く動作が繰り返されます。
最後に、キーボードが映し出され、その下に「アクロクエストテクノロジー」のロゴが並んでいます。

なお、今回は短い動画のみを対象にしているため、APIに直接動画を投げる方式を取っていますが、 ファイルサイズが大きい場合は、S3にアップロードしたものを読み込ませる、細切れに区切ったものを渡し、後からマージする などの手段が必要になります。

2.2. 要約結果を Bedrock Knowledge Base に取り込めるようにする


Knowledge Base で取り込む

次に Knowledge Base で同期を行い上記説明文を取り込むのですが、そのまま取り込むだけだと、元の動画とアップロードしたテキストファイルの紐づけができません。

これを解決するために Knowledge Base の機能である、 metadata.json を使用します。

この JSON ファイルに記載したものは Knowledge Base の同期時に OpenSearch Serverless にメタデータとして保存され、検索時に取得することができます。

今回は下記のように、メタデータとして、動画のURLを指定しました。 検索後の画面表示に使用します。

{
  "metadataAttributes": {
    "original_path": "s3://bucket/path/to/video.mp4"
  }
}

動画の説明文と対応する metadata.json の配置が完了したら、 Knowledge Base を同期します。

2.3. 動画の検索処理を実現する


検索する

検索時は Knowledge Base の Retrive API を使用しました。

また、検索後にスコアの下限で閾値を設けることで、リランクをした結果関連度が低いと判断された動画が検索結果に含まれないようにしました。

const input = {
  knowledgeBaseId,
  retrievalQuery: {
    text: query.trim(),
  }
  retrievalConfiguration: {
    vectorSearchConfiguration: {
      numberOfResults: 20,
      overrideSearchType: "HYBRID",
      rerankingConfiguration: {
        bedrockRerankingConfiguration: {
          modelConfiguration: {
            modelArn: AMAZON_RERANK_MODEL,
          },
          numberOfRerankedResults: 10,
        },
        type: "BEDROCK_RERANKING_MODEL",
      },
    },
  },
};
const command = new RetrieveCommand(input);
return client.send(command);

下記のように動画の概要と動画ファイルのパスを取得できました。

{
  "retrievalResults": [{
    "content": {
      "text": "動画は、リモートワーク中のITエンジニアが食べたいアンパンのランキングを紹介しています……",
      "type": "TEXT"
    },
    "location": {
      "s3Location": {
        "uri": "s3://bucket/path/to/summary.txt"
      },
      "type": "S3"
    },
    "metadata": {
      "original_path": "s3://bucket/path/to/video.mp4"
    }
  }]
}

2.4. 検索画面を作成する

今回は上記検索を行う画面を bolt.new を使って作成しました。

私はあまりフロントが得意ではないのですが、日本語で指示するだけで、とてもいいアプリができたと思います。

作成した検索アプリ

検索結果

3. 結果

3.1. 動画に含まれる文言で検索してみる

まずは動画のタイトルにも、生成AIによる要約文にも含まれるキーワードで検索してみました。

期待する動画が第一の検索結果に表示されることを確認できます。

「あの動画をまた見たいのに、従来の検索ではヒットしない」といったときにこのアプリを使えば、見たい動画にすぐにアクセスできます。

「美味しいあんパン」

3.2. 動画には含まれない文言で検索してみる

次にタイトル、要約文には含まれないが、ベクトル検索で拾えそうな内容で検索してみました。

こちらも、2018年にサンフランシスコで行われた Elastic{ON} というカンファレンスに参加した際の様子を映した動画がヒットしています。

今回は Elastic{ON} の動画しか入っていないのですが、他の海外カンファレンスの動画を取り込んでおけば、「特定の動画が見たいわけではないが、似たような動画を広く取ってきたい」を実現できます。

「海外カンファレンスの様子」

まとめ

現在、Bedrock Knowledge Base に直接動画を入力することはできませんが、 Amazon Nova を使って説明文を生成することで、間接的に動画検索を実現することができました。

動画をエンベディングすることで同じ機能を自前で実装することは可能ですが、 Bedrock Knowledge Base を使う利点は取り込みと検索を簡単に組み込めることだと思います。

取り込みはファイルをS3に置いて「同期」を行うのみ、検索も Retrieve API を呼ぶだけです。 Retrieve APIを使えばリランクで検索結果を改善することも簡単に行えます。

Acroquest Technologyでは、キャリア採用を行っています。
  • Azure OpenAI/Amazon Bedrock等を使った生成AIソリューションの開発
  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • マイクロサービス、DevOps、最新のOSSクラウドサービスを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。 www.wantedly.com