Amazon Nova Embeddingsを用いたインテリジェント音声検索の構築:意味的音声理解への深堀り
本文の状態
日本語全文を表示中
詳細モードで約17分の本文を読めます。
Amazonは、音声コンテンツを検索可能なインテリジェントデータに変換するAmazon Novaマルチモーダル埋め込みを発表した。この技術は、トーン、感情、音楽的特徴、環境音などの音響的特徴を捉え、コンテンツ理解と検索機能を強化する。
Source Article
元記事を日本語で読む
本文に関係しない購読案内、埋め込み通知、サイト内プロモーションは除いています。
コンテンツの理解と検索機能を強化したいとお考えの場合、オーディオ埋め込みは強力な解決策となります。本稿では、Amazon Nova Multimodal Embeddings を使用して、トーン、感情、音楽的特徴、環境音などの音響特性を捉え、検索可能なインテリジェントなデータへとオーディオコンテンツを変換する方法について解説します。
これらのライブラリ内で特定のコンテンツを検索することは、実際には技術的な課題を伴います。手動による文字起こし、メタデータのタグ付け、音声からテキストへの変換といった従来の検索方法は、発話された言葉を捕捉・検索する際には効果的です。しかし、これらのテキストベースのアプローチは、トーン、感情、音楽的特徴、環境音といった音響特性ではなく、言語的な内容に焦点を当てています。オーディオ埋め込みはこのギャップを解消します。これらは、意味的および音響的特性の両方をエンコードする高密度な数値ベクトルとしてオーディオを表現し、高次元空間に配置します。これらの表現により、自然言語クエリを用いたセマンティック検索、類似の音響を持つオーディオのマッチング、メタデータタグだけでなく「どのような音か」に基づいたコンテンツの自動分類が可能になります。2025年10月28日に発表された Amazon Nova Multimodal Embeddings は、Amazon Bedrock で利用可能なマルチモーダル埋め込みモデルです[1]。これは、テキスト、ドキュメント、画像、動画、オーディオを単一のモデルでサポートし、高精度なクロスモーダル検索を実現する統一された埋め込みモデルです。
この投稿では、オーディオ埋め込みの理解、Amazon Novaマルチモーダル埋め込みの実装、およびオーディオコンテンツのための実用的な検索システムの構築について解説します。埋め込みがオーディオをベクトルとしてどのように表現するかを理解し、Amazon Novaの技術的な機能を探求し、オーディオライブラリのインデックス作成とクエリに関する実践的なコード例を確認します。最終的には、本番環境対応のオーディオ検索機能をデプロイするための知識を身につけることができます。
オーディオ埋め込みの理解:基本概念
オーディオコンテンツのベクトル表現
オーディオエンベッディングを、音のための座標系と想像してください。GPS座標が地球上の場所を特定するのと同様に、エンベッディングはオーディオコンテンツを高次元空間内の特定のポイントにマッピングします。Amazon Nova Multimodal Embeddingsでは、3,072(デフォルト)、1,024、384、または256の4つの次元オプションが提供されます[1]。各エンベッディングはfloat32配列です。個々の次元は、リズム、ピッチ、音色、感情的トーン、および意味的な意味など、音響的かつ意味的特徴を符号化しており、これらはトレーニング中にモデルのニューラルネットワークアーキテクチャを通じて学習されます。Amazon Novaは、エンベッディングを階層的に構造化する技術であるMatryoshka Representation Learning (MRL)を使用しています[1]。MRLをロシアのマトリョーシカ(入れ子人形)のように考えてください。3,072次元のエンベッディングにはすべての情報が含まれていますが、最初の256次元のみを抽出しても正確な結果が得られます。エンベッディングは一度生成し、精度とストレージコストのバランスが取れるサイズを選択します。異なる次元を試す際にオーディオを再処理する必要はありません—階層構造により、希望するサイズに切り詰めることができます。
類似度の測定方法: 類似したオーディオを検索したい場合、2つのエンベッディングv₁およびv₂間のコサイン類似度(cosine similarity)を計算します[1]:
similarity = (v₁ · v₂) / (||v₁|| × ||v₂||)
コサイン類似度はベクトル間の角度を測定し、-1 から 1 の値を返します。1 に近い値ほど、意味的な類似度が高いことを示します。エンベッディングをベクターデータベースに保存する場合、距離指標(距離 = 1 - 類似度)を使用して k-最近傍法 (k-nearest neighbor, k-NN) 検索を実行し、クエリに対して最も類似度の高い上位 k 個のエンベッディングを取得します。
実世界の例: 「バイオリンでメロディを演奏する」と「チェロで同様のメロディを演奏する」という 2 つのオーディオクリップがあり、それぞれ v₁ および v₂ というエンベッディングを生成すると仮定します。コサイン類似度が 0.87 の場合、これらはベクター空間内で互いに近くにクラスタリングされ、強い音響的および意味的な関連性を示します。一方、「ドラムを伴うロック音楽」という異なるオーディオクリップは v₃ を生成し、v₁ に対するコサイン類似度は 0.23 となり、エンベッディング空間内で遠く離れた位置に配置されます。
オーディオ処理アーキテクチャとモダリティ
エンドツーエンドのワークフローの理解: 技術的な詳細に深入する前に、オーディオエンベッディングが実際にどのように機能するかを見てみましょう。主なワークフローは 2 つあります。

図 1 – エンドツーエンドのオーディオエンベッディングワークフロー
データ取り込みとインデックス作成の流れ: 取り込みフェーズでは、オーディオライブラリを一括処理します。オーディオファイルを Amazon S3 にアップロードし、非同期 API を使用して埋め込みを生成します。長時間のオーディオファイル(30 秒以上)の場合、モデルは自動的にそれらをより小さなチャンクに分割し、時間的なメタデータを付加します。これらの埋め込みは、ファイル名、再生時間、ジャンルなどのメタデータとともにベクトルデータベースに保存されます。これはオーディオライブラリ全体に対して一度だけ実行されます。
ランタイム検索の流れ: ユーザーが検索を実行すると、テキスト「アップビートなジャズピアノ」や別のオーディオクリップなど、クエリに対する埋め込みを生成するために同期 API を使用します。クエリは短く、ユーザーは高速な結果を期待するため、同期 API は低レイテンシの応答を提供します。ベクトルデータベースは k-NN 検索を実行して、最も類似したオーディオ埋め込みを見つけ、関連するメタデータとともに結果を返します。この一連の検索はミリ秒単位で完了します。
オーディオのみの入力を送信する場合、時間畳み込みネットワークまたはトランスフォーマーベースのアーキテクチャが、スペクトロ・テンポラル(周波数-時間)パターンを分析して音響信号を処理します。生波形で動作するのではなく、Amazon Novaはメルスペクトログラムや学習された音響特徴量などのオーディオ表現に基づいて動作するため、高サンプリングレートのオーディオを効率的に処理できます[1]。オーディオは時間的コンテキストを必要とする連続データです。ユーザーのオーディオセグメント(最大30秒)は、時間的に受容野を持つアーキテクチャを通過し、時間全体にわたる音響パターンを捉えます[1]。このアプローチは、リズム、韻律、プロソディ(抑揚)、そして複数秒にわたる長距離の音響依存関係を捉え、オーディオコンテンツの豊かな性質を完全に保持します。
API操作とリクエスト構造
同期埋め込み生成の使用時: 遅延が重要なリアルタイムアプリケーションで埋め込みが必要な場合、invoke_model APIを使用してランタイム検索を行ってください[1]。例えば、ユーザーが検索クエリを送信し、そのクエリテキストが短く、高速なユーザー体験を提供したい場合、同期APIが最適です:
import boto3
import json
Bedrock Runtime クライアントを作成する。
bedrock_runtime = boto3.client("bedrock-runtime", region_name="us-east-1")
検索クエリのリクエストボディを定義する。
request_body = {
"taskType": "SINGLE_EMBEDDING", # 単一アイテムに使用
"singleEmbeddingParams": {
"embeddingPurpose": "GENERIC_RETRIEVAL", # クエリには GENERIC_RETRIEVAL を使用
"embeddingDimension": 1024, # 次元サイズを選択
"text": {
"truncationMode": "END", # 長い入力の処理方法
"value": "jazz piano music" # 検索クエリ
}
}
}
Nova Embeddings モデルを呼び出す。
response = bedrock_runtime.invoke_model(
body=json.dumps(request_body),
modelId="amazon.nova-2-multimodal-embeddings-v1:0",
contentType="application/json"
)
応答から埋め込み(embedding)を抽出する。
response_body = json.loads(response["body"].read())
embedding = response_body["embeddings"][0]["embedding"] # float32 配列
リクエストパラメータの理解:
- taskType: 単一アイテムの場合は SINGLE_EMBEDDING を、チャンク処理の場合は SEGMENTED_EMBEDDING(セグメンテッド・エンベッディング)を選択します [1, 2]
- embeddingPurpose: 使用ケースに最適化されたエンベッディングを生成します。コンテンツのインデックス作成には GENERIC_INDEX(ジェネリック・インデックス)、クエリには GENERIC_RETRIEVAL(ジェネリック・リトリーバル)、ドキュメント検索には DOCUMENT_RETRIEVAL(ドキュメント・リトリーバル)を使用します [1]
- embeddingDimension: 出力次元数を選択します(3072, 1024, 384, 256)[1]
- truncationMode: コンテキスト長を超える入力の処理方法。END は末尾で切り捨て、START は先頭で切り捨てます [1]
返される結果: API はエンベッディングを含む JSON オブジェクトを返します:
{
"embeddings": [
{
"embedding": [0.123, -0.456, 0.789, ...], // float32 配列
"embeddingLength": 1024
}
]
}
非同期処理を使用すべき場面: Amazon Nova Multimodal Embeddings は、大量のコンテンツを処理するための2つのアプローチをサポートしています。それは非同期 API とバッチ API です。それぞれをいつ使用すべきか理解することで、ワークフローを最適化できます。
非同期 API: 同期 API の制限を超える大規模な個別のオーディオまたはビデオファイルを処理する必要がある場合、start_async_invoke API を使用します [1]。これは以下に最適です:
- 単一の大容量ファイル(数時間にわたる録音、フル尺の動画など)の処理
- 分割が必要なファイル(30秒を超えるもの)
- 即時ではなく、数時間以内の結果を必要とする場合
response = bedrock_runtime.start_async_invoke(
modelId="amazon.nova-2-multimodal-embeddings-v1:0",
modelInput=model_input,
outputDataConfig={
"s3OutputDataConfig": {"s3Uri": "s3://amzn-s3-demo-bucket/output/"}
}
)
invocation_arn = response["invocationArn"]
ジョブのステータスをポーリング
job = bedrock_runtime.get_async_invoke(invocationArn=invocation_arn)
status = job["status"] # "InProgress" | "Completed" | "Failed"
ジョブが完了すると、出力は JSONL 形式(1行に1つのJSONオブジェクト)で Amazon S3 に書き込まれます。AUDIO_VIDEO_COMBINED モードの場合、embedding-audio-video.jsonl [1] に出力が見つかります。
バッチ API: 単一のジョブで数千の音声ファイルを処理する必要がある場合は、バッチ推論 API を使用してください [3]。
これは以下に最適です:
- 音声ライブラリ全体(数千〜数百万ファイル)の一括処理
- バッチ価格によるコスト最適化
- 24〜48時間待機できる、時間敏感でないインデックス作成操作
- 多数の小〜中規模ファイルの効率的な処理
バッチ API は大規模な運用においてよりコスト効率に優れ、ジョブ管理を自動で処理します。すべての入力ファイルを含むマニフェスト ファイルを送信すると、サービスはそれらを並列で処理し、結果を S3 に書き込みます。
非同期とバッチの選択:
- 単一の大きなファイルまたはリアルタイムでのセグメンテーションが必要ですか? → 非同期 API を使用
- 大量のファイルをバッチ処理する必要がありますか? → バッチ API を使用
- 数時間以内に結果が必要ですか? → 非同期 API を使用
- コスト削減のために 24〜48 時間の待機が可能ですか? → バッチ API を使用
バッチ推論の詳細については、Amazon Bedrock のバッチ推論ドキュメント をご覧ください。[3]
セグメンテーションと時間メタデータ
セグメンテーションが必要な理由: 音声ファイルが 30 秒を超える場合、それらをセグメント化する必要があります [1]。2 時間のポッドキャストがあり、ホストが AI について議論している特定の 30 秒間のセグメントを見つけたいと想像してください。セグメンテーションによりこれが可能になります。
chunking(チャンキング:データの分割)は segmentationConfig パラメータで制御できます:
"segmentationConfig": {
"durationSeconds": 15 # 15 秒ごとに 1 つの埋め込みを生成
}
この設定は、5 分(300 秒)の音声ファイルを 20 のセグメントに処理し(300 ÷ 15 = 20)、20 の埋め込みを生成します [1]。各セグメントには、元のファイル内での位置を示す時間メタデータが付けられます。
セグメント化された出力の理解: 非同期 API は、時間メタデータ付きでセグメント化された埋め込みを JSONL に書き出します [1]:
{"startTime": 0.0, "endTime": 15.0, "embedding": [...]}
{"startTime": 15.0, "endTime": 30.0, "embedding": [...]}
{"startTime": 30.0, "endTime": 45.0, "embedding": [...]}
セグメント化された出力の解析方法:
import json
from boto3 import client
s3 = client("s3", region_name="us-east-1")
S3からJSONLファイルを読み込む
response = s3.get_object(Bucket="bucket", Key="output/embedding-audio-video.jsonl")
content = response['Body'].read().decode('utf-8')
segments = []
for line in content.strip().split('\n'):
if line:
segment = json.loads(line)
segments.append({
'start': segment['startTime'],
'end': segment['endTime'],
'embedding': segment['embedding'],
'duration': segment['endTime'] - segment['startTime']
})
print(f"Processed {len(segments)} segments")
print(f"First segment: {segments[0]['start']:.1f}s - {segments[0]['end']:.1f}s")
print(f"Embedding dimension: {len(segments[0]['embedding'])}")
実世界のユースケース—時系列検索: 分割されたエンベッディング(埋め込み)を、時間メタデータとともにベクターデータベースに保存できます。誰かが「請求に関する顧客の苦情」と検索した場合、タイムスタンプ付きの特定の15秒間のセグメントを取得し、数時間におよぶ通話録音内の関連する瞬間への正確なナビゲーションを提供します。録音全体を聞く必要はありません。
ベクターストレージとインデックス化戦略
アーキテクチャへの参照: 2.2節では、エンドツーエンドのワークフロー図を示しました。ここでは、ベクターデータベースコンポーネント、つまりインgestionフェーズとランタイム検索フェーズの両方で埋め込みが格納されるストレージ層に深く掘り下げています。これは、インデックス化されたオーディオ埋め込みを高速な検索クエリに接続する重要なコンポーネントです。
ストレージ要件の理解: 埋め込みはfloat32配列であり、次元ごとに4バイトを必要とします。必要なリソースは以下の通りです:
- 3,072次元: 埋め込みあたり12,288バイト(12 KB)
- 1,024次元: 埋め込みあたり4,096バイト(4 KB)
- 384次元: 埋め込みあたり1,536バイト(1.5 KB)
- 256次元: 埋め込みあたり1,024バイト(1 KB)
計算例: 1,024次元の埋め込みを持つ100万個のオーディオクリップの場合、メタデータやインデックス構造を除いて、4 GBのベクターストレージが必要です。
次元サイズの選択: 大きな次元はより詳細な表現を提供しますが、より多くのストレージと計算リソースを必要とします。小さな次元は、検索パフォーマンスとリソース効率の間の実用的なバランスを提供します。1,024次元から始めてください—これはほとんどのアプリケーションで優れた精度を提供しつつ、コストを管理可能な範囲に保ちます。
Amazon S3 Vectorsの使用: Amazon S3 Vectors [2] を使用して、埋め込みの格納とクエリを実行できます:
s3vectors = boto3.client("s3vectors", region_name="us-east-1")
ベクトルインデックスの作成
s3vectors.create_index(
vectorBucketName="audio-vectors",
indexName="audio-embeddings",
dimension=1024,
dataType="float32",
distanceMetric="cosine"
)
メタデータ付きの埋め込み(embedding)を保存
s3vectors.put_vectors(
vectorBucketName="audio-vectors",
indexName="audio-embeddings",
vectors=[{
"key": "audio:track_12345",
"data": {"float32": embedding},
"metadata": {
"filename": "track_12345.mp3",
"duration": 180.5,
"genre": "jazz",
"upload_date": "2025-10-28"
}
}]
)
メタデータが検索を強化する方法: メタデータの属性は埋め込み(embedding)と併用され、より豊かな検索結果を提供します。ベクトルデータベースから結果を取得する際、メタデータはユーザーに表示される情報をフィルタリング、ソート、表示するために活用されます。例えば、ジャンル(genre)フィールドによりジャズの録音のみをフィルタリングでき、再生時間(duration)により特定の長さ範囲内のトラックを検索でき、ファイル名(filename)は再生用の実際のオーディオファイルへのパスを提供します。アップロード日(upload_date)は、最新のコンテンツを優先したりデータの鮮度を追跡したりするのに役立ちます。この埋め込み(embedding)由来の意味的類似性と構造化されたメタデータの組み合わせにより、強力な検索体験が実現します。
ベクトルのクエリ: k-NN(k近傍)検索は、最も類似度の高い上位k個のベクトルを取得します [2]:
vectorBucketName="audio-vectors",
indexName="audio-embeddings",
queryVector={"float32": query_embedding},
topK=10, # Return 10 most similar results
returnDistance=True,
returnMetadata=True
)
for result in response["vectors"]:
print(f"Key: {result['key']}")
print(f"Distance: {result['distance']:.4f}") # Lower = more similar
print(f"Metadata: {result['metadata']}")
Using Amazon OpenSearch Service: OpenSearch provides native k-NN search with HNSW (Hierarchical Navigable Small World) indexes for sub-linear query time complexity [1]. This means your searches stay fast even as your audio library grows to millions of files.
Index configuration:
"mappings": {
"properties": {
"audio_embedding": {
"type": "knn_vector",
"dimension": 1024,
"method": {
"name": "hnsw",
"space_type": "cosinesimil",
"engine": "nmslib",
"parameters": {"ef_construction": 512, "m": 16}
}
},
"metadata": {"type": "object"}
}
}
}
Batch Optimization and Production Patterns
Why batch processing matters: When you process multiple audio files, batch inference improves throughput by reducing network latency overhead [1]. Instead of making separate API calls for each file, you can process them more efficiently.
Example batch pattern:
texts = ["jazz music", "rock music", "classical music"]
vectors = []
for text in texts:
response = bedrock_runtime.invoke_model(
body=json.dumps({
"taskType": "SINGLE_EMBEDDING",
"singleEmbeddingParams": {
"embeddingDimension": 1024,
"text": {"truncationMode": "END", "value": text}
}
}),
modelId="amazon.nova-2-multimodal-embeddings-v1:0",
contentType="application/json"
)
embedding = json.loads(response["body"].read())["embeddings"][0]["embedding"]
vectors.append(embedding)
Vector store への一括書き込み
s3vectors.put_vectors(
vectorBucketName="audio-vectors",
indexName="audio-embeddings",
vectors=[
{"key": f"text:{text}", "data": {"float32": emb}}
for text, emb in zip(texts, vectors)
]
)
多言語サポート: 本モデルは200以上の言語でテキスト入力をサポートしています [1]。これにより、強力なクロスモーダル検索シナリオが可能になります。顧客は英語でインデックス付けされたオーディオコンテンツをスペイン語で検索することも、その逆も可能です。埋め込み(embedding)は言語を超えた意味を捉えます。
Amazon Nova オーディオマルチモーダル埋め込みの深掘り
技術仕様
モデルアーキテクチャ: Amazo
同じ出来事を3媒体で確認
同じ出来事を扱う別媒体の記事です。見出しと公開時刻を比較できます。
今日のまとめ
AIデイリーブリーフで今日の重要ニュースをまとめ読み