Amazon Nova マルチモーダル埋め込みによる製造業のインテリジェンス向上
AWS は、Amazon Nova Multimodal Embeddings を活用したマルチモーダル検索システムを製造業向けに構築し、テキストだけでは抽出できない図面やグラフ内の情報を検索可能にする実証を行いました。
キーポイント
製造文書の複雑性と限界
航空宇宙や自動車産業の文書には仕様書だけでなく、CAD 図面や熱分析プロットなどの視覚情報が不可欠だが、従来のテキスト抽出ベースの検索ではこれらの情報を捉えられない。
マルチモーダル埋め込みによる解決
Amazon Nova Multimodal Embeddings は、テキスト、画像、ドキュメントページを共通のベクトル空間にマッピングし、テキストクエリで図面を検索したり、画像クエリで仕様書を検索したりすることを可能にする。
実証環境と評価結果
Amazon Bedrock と Amazon S3 Vectors を組み合わせたシステムを構築し、26 の製造業関連クエリにおいて、テキスト専用パイプラインと比較して生成品質が向上したことを評価した。
具体的な活用事例
トルク仕様表が図面内に埋め込まれている場合や、ロケットエンジンノズルの熱分布がカラーコンタープロットで示されている場合など、視覚的要素に依存する情報の検索が可能になった。
画像とテキストの統合埋め込み生成
Amazon Nova Multimodal Embeddings モデルを使用し、画像(PNG)を「GENERIC_INDEX」目的で、検索クエリを「GENERIC_RETRIEVAL」目的でそれぞれ 1024 次元のベクトルとして生成します。
Amazon S3 Vectors を活用したベクターインデックス構築
Cosine 類似度計測を採用し、バッチ処理(50 件)で画像埋め込みを S3 Vectors に格納して管理可能な検索基盤を構築します。
多様なデータ形式からの効率的な情報検索
テキストクエリから生成した埋め込みベクトルと、インデックス内の画像埋め込みベクトルを比較することで、図面などの非構造化データから特定の仕様情報を取得します。
影響分析・編集コメントを表示
影響分析
本記事は、製造業のようなドキュメントに視覚情報が密接に絡み合う業界において、AI のマルチモーダル能力が持つ具体的な価値を明確に示しています。テキスト中心の検索から脱却し、図面やグラフ内の暗黙知を検索可能にする技術的転換点となり、エンジニアリング設計や品質管理の効率化に直結する実用性を有します。
編集コメント
製造業の文書管理における「見えない情報」を可視化する技術として、マルチモーダル検索の実装事例は非常に示唆に富んでいます。特に複雑な図面やグラフを自然言語で検索できる点は、現場のエンジニアリング業務に即した画期的な進展と言えます。
航空宇宙、自動車、あるいは重工業の製造業に携わる方であれば、貴社組織は膨大な量の技術文書リポジトリを維持していることでしょう。これらの文書には、文章による仕様書に加え、エンジニアリング図面、CAD 図面、検査写真、熱解析プロット、疲労曲線などが組み合わされています。ノズル喉部における最大壁温に関するテキストクエリの答えが、文章ではなく熱等値線図の中に隠されている可能性があります。テキストのみを対象とした検索システムでは、画像コンテンツを認識できないため、そのような情報を引き出すことができません。
Amazon Nova Multimodal Embeddings は、テキスト、画像、およびドキュメントページを共有ベクトル空間にマッピングすることで、このギャップを埋めます。テキストクエリでエンジニアリング図面を検索でき、画像クエリで文章による仕様書を検出できるのは、両方のモダリティが同じ座標系を共有しているためです。
本稿では、Amazon Bedrock および Amazon S3 Vectors 上で Amazon Nova Multimodal Embeddings を活用し、航空宇宙製造業向けの文書に対する多モーダル検索システムを構築します。本システムは 26 の製造業向けクエリで評価され、テキスト専用パイプラインと多モーダルパイプラインにおける生成品質が比較されます。
なぜマルチモーダル検索が製造業において重要なのか
ほとんどの製造業文書は、テキスト、図面、画像を組み合わせて構成されています。1 つの作業指示書には、記述された組立手順と、完了した工程を注釈付きで撮影した写真が併記されていることがあります。検査報告書では、合格/不合格の測定値と溶接継手の放射線写真が対になっています。材料認証書には、設計レビュー時にエンジニアが参照する必要がある表形式の機械的特性と S-N 疲労曲線の両方が含まれています。
本記事で使用されたデータセットからの視覚情報の具体的な例をいくつか考えてみましょう。トルク仕様表は独立したテキストとして保存されるのではなく、図面内に描かれています。色分けされた熱等値線図は、ロケットエンジンノズル全体にわたる最高温度を可視化するために使用されています。製造プロセスフローチャートでは、品質保留点が意思決定のダイヤモンド記号と色分けされたゲートによって視覚的にラベル付けされており、関連するサイクルタイムは図面自体への注釈として表示されます。
テキストのみを扱う検索システムは、OCR を通じて文書からテキストを抽出し、その抽出された文字列を埋め込み・インデックス化することでこれらの文書を処理します。これは回答が文書の記述部分に含まれている場合には機能しますが、テキストのみのシステムでは図における空間関係や検査画像における視覚的パターン、プロットやチャートに符号化された定量的情報を捉えることができません。ターボポンプで使用されているベアリングの種類を検索した場合、その答えは断面図上のラベル付き注釈として現れる可能性がありますが、OCR はこれを誤って読み取ったり、空間的文脈を除去してしまったりします。
マルチモーダル埋め込みは異なるアプローチを採用しています。画像をテキストに変換してから埋め込むのではなく、モデルが画像を直接処理し、テキスト埋め込みと同じ空間にベクトルを生成します。ターボポンプのベアリングに関するテキストクエリは、OCR が抽出したテキストに基づくだけでなく、視覚的理解に基づいて、データセット内の断面図と照合することができます。
Amazon Nova マルチモーダル埋め込みの概要
Amazon Nova マルチモーダル埋め込み は Amazon Bedrock で利用可能であり、テキスト、画像、複数ページのドキュメントに対する埋め込みを生成します。テキスト、画像、ドキュメントの各モダリティは単一の共有ベクトル空間に投影されるため、テキスト埋め込みと画像埋め込みの間で直接コサイン類似度を計算することが可能です。
埋め込み次元は、256、384、1024、または 3072 から設定できます。より高い次元はより多くの意味的詳細を捉えますが、類似度検索にはより多くのストレージと計算リソースを必要とします。本記事での評価では、検索品質とコストの間の実用的なバランスとして、1024 次元を使用しています。また、このモデルは DOCUMENT_IMAGE という詳細レベルをサポートしており、これはチャート、表、注釈付き図など混合コンテンツを含むページ向けの処理モードです。
検索ワークロードにおいては、GENERIC_INDEX(インデックス化されるドキュメント用)または GENERIC_RETRIEVAL(クエリ用)のいずれかに設定された purpose パラメータを受け入れます。この非対称な埋め込みアプローチは、手動でのクエリフォーマットを必要とせずに、検索のためのベクトル空間を改善します。
ソリューション概要
下流生成品質を比較するために、同じデータセット上で 2 つの並列な検索パイプラインを構築しました。
データセット – CAD 図面、検査レポート、テストプロット、材料仕様、プロセスフローチャートなどの 15 のスタンドアロン技術画像と、組立手順、ホットファイア試験レポート、エンジニアリング変更通知、材料認証書、不適合報告書などの 5 つの多ページ PDF ドキュメントです。これらのドキュメントには、合成された航空宇宙製造データが含まれています。
パイプライン A(マルチモーダル) – Amazon Nova Multimodal Embeddings を使用して、各画像を直接埋め込み、各 PDF ページをドキュメントイメージとして埋め込んだ後、Amazon Simple Storage Service (Amazon S3) のベクトルインデックスに読み込みます。
パイプライン B、テキストベースの比較対象 – 各画像と PDF ページを Amazon Nova 2 Lite に送信して OCR テキスト抽出を行い、抽出されたテキストを Amazon Nova Multimodal Embeddings(テキストのみ入力)を使用して埋め込み、その後、別の Amazon S3 Vectors インデックスに読み込みます。OCR ステップには以下のプロンプトが使用されます:
注:テキスト抽出用の OCR プロンプト
"この画像から表示されているすべてのテキストを、そのままの形で正確に抽出してください。すべての数値、ラベル、注釈、表の内容、ヘッダー、フッターを含めてください。構造(表、リスト、セクション)は可能な限り維持してください。抽出されたテキストのみを返し、解説は含めないでください。"
評価 – 多モーダルインデックスに対して 26 の製造業関連クエリを実行し、検索指標(Recall@K、Mean Reciprocal Rank (MRR)、NDCG@K)を取得します。その後、両方のパイプラインにおいてコンテキストを検索し、Amazon Nova 2 Lite を使用して回答を生成します。各回答は、大規模言語モデル(LLM)による判定者を用いて正解データと比較してスコアリングされます。
以下の図は、エンドツーエンドのパイプラインアーキテクチャを示しています。ソースドキュメントは 2 つの並列パスを流れます:パイプライン A は画像を直接 Amazon Nova Multimodal Embeddings で埋め込みます。一方、パイプライン B は OCR を通じてテキストを抽出してから埋め込みます。両方のパイプラインともベクトルを Amazon S3 Vectors に保存します。クエリ実行時には、検索されたコンテキストが回答生成のために Amazon Nova 2 Lite に供給され、大規模言語モデル(LLM)による判定者が各回答を正解データと比較してスコアリングを行います。
以下の図は、データセットからの 3 つのサンプルドキュメントを示しています。左から右へ:ノズルアセンブリの CAD ダイアグラム、溶接検査レポート、および Inconel 718 の疲労 S-N カーンです。各ドキュメントタイプは、テキスト抽出だけでは捉えることが難しい情報を提示しています。
ソリューションウォークスルー
このセクションでは、埋め込みベクトルの生成からベクトルインデックスの構築、クエリの実行に至るまでの主要な実装ステップを順を追って解説します。完全なコードは、GitHub のコンパニオンノートブックで利用可能です。
前提条件
本記事を追いかけるには、AWS アカウント内で以下のリソースとアクセス設定が必要です:
- us-east-1 リージョンで Amazon Bedrock にアクセスできる AWS アカウント
- amazon.nova-2-multimodal-embeddings-v1:0 および us.amazon.nova-2-lite-v1:0 モデルへのアクセス権限の有効化
- Amazon SageMaker AI ノートブックインスタンス、またはローカルの Python 環境
- boto3, numpy, pandas, matplotlib, Pillow, pdf2image, tqdm を含む Python 3.10 以上
- Amazon Bedrock InvokeModel API、Amazon S3 API、および Amazon S3 Vectors API に対する IAM 権限
本記事のサンプルコードは教育目的のために提供されており、本番環境での使用に向けてレビューされていません。本番環境へのデプロイ前に、組織のセキュリティ要件に基づいて必ず確認とテストを行ってください。
マルチモーダル埋め込みの生成
製造業向けの画像に対して埋め込みを生成するには、Amazon Bedrock に対する InvokeModel 呼び出しを1回行うだけで十分です。リクエストでは、画像のバイトデータ、希望する埋め込み次元数、および詳細レベルを指定します。CAD 図面のような単独の画像には STANDARD_IMAGE を使用し、テキストとグラフィックが混在する PDF ページに対しては、モデルが表やグラフコンテンツに対して追加処理を適用するため、DOCUMENT_IMAGE の方がより良い結果をもたらします。
import base64, json, boto3
bedrock_runtime = boto3.client("bedrock-runtime", region_name="us-east-1")
MODEL_ID = "amazon.nova-2-multimodal-embeddings-v1:0"
with open("dataset/nozzle_assembly_diagram.png", "rb") as f:
b64_data = base64.b64encode(f.read()).decode("utf-8")
request_body = {
"taskType": "SINGLE_EMBEDDING",
"singleEmbeddingParams": {
"embeddingPurpose": "GENERIC_INDEX",
"embeddingDimension": 1024,
"image": {
"format": "png",
"detailLevel": "STANDARD_IMAGE",
"source": {"bytes": b64_data},
},
},
}
response = bedrock_runtime.invoke_model(
modelId=MODEL_ID,
body=json.dumps(request_body),
accept="application/json",
contentType="application/json",
)
embedding = json.loads(response["body"].read())["embeddings"][0]["embedding"]
print(f"Embedding dimension: {len(embedding)}") # 1024
Amazon S3 ベクトルインデックスの構築
Amazon S3 Vectors は、管理されたベクトルストレージおよびクエリレイヤーを提供します。コサイン類似度(cosine similarity)用に構成されたベクトルバケットとインデックスを作成し、50 件ごとのバッチで埋め込みデータをインポートします。
s3vectors = boto3.client("s3vectors", region_name="us-east-1")
ベクトルバケットとインデックスの作成
s3vectors.create_vector_bucket(vectorBucketName="manufacturing-vectors")
s3vectors.create_index(
vectorBucketName="manufacturing-vectors",
indexName="manufacturing-multimodal",
dataType="float32",
dimension=1024,
distanceMetric="cosine",
)
メタデータ付きの埋め込みバッチをインポート
vectors = [
{
"key": "img-nozzle_assembly_diagram",
"data": {"float32": embedding},
"metadata": {
"source_file": "nozzle_assembly_diagram.png",
"type": "image",
},
}
]
s3vectors.put_vectors(
vectorBucketName="manufacturing-vectors",
indexName="manufacturing-multimodal",
vectors=vectors,
)
インデックスのクエリ実行
クエリ実行時には、GENERIC_RETRIEVAL 目的でテキスト埋め込みを生成し、query_vectors を呼び出して最も類似度の高いドキュメントを取得します。GENERIC_RETRIEVAL 目的は、モデルに対してクエリとドキュメントのマッチングに最適な埋め込みを生成するよう指示するものです。
query = "What is the torque specification for the chamber flange bolts?"
request_body = {
"taskType": "SINGLE_EMBEDDING",
"singleEmbeddingParams": {
"embeddingPurpose": "GENERIC_RETRIEVAL",
"embeddingDimension": 1024,
"text": {"truncationMode": "END", "value": query},
},
}
response = bedrock_runtime.invoke_model(
modelId=MODEL_ID, body=json.dumps(request_body),
accept="application/json", contentType="application/json",
)
query_embedding = json.loads(response["body"].read())["embeddings"][0]["embedding"]
results = s3vectors.query_vectors(
vectorBucketName="manufacturing-vectors",
indexName="manufacturing-multimodal",
queryVector={"float32": query_embedding},
topK=5,
returnDistance=True,
returnMetadata=True,
)
for v in results["vectors"]:
print(f" {v['key']} (distance: {v['distance']:.4f})")
This query retrieves the torque specifications image and the flange bolt pattern diagram as the top results, both of which contain the answer. A text-only system would need the OCR extraction to have correctly captured the torque values from the engineering drawing, which is not always reliable for complex technical diagrams.
評価手法
私たちはシステムを2段階で評価しました。1つ目は検索の質(システムが適切な文書を見つけられるか)であり、2つ目は生成の質(言語モデルが検索されたコンテキストから正しい回答を生成できるか)です。評価用データセットには、航空宇宙製造に関する文書から導き出された 26 のクエリが含まれており、それぞれに正解となる関連文書の ID と参照回答が付与されています。以下の各サブセクションで、それぞれの段階がどのように機能するかを説明します。
検索評価
各クエリに対して、GENERIC_RETRIEVAL という目的でテキスト埋め込み(embedding)を生成し、マルチモーダル S3 Vectors インデックスを検索して、返された文書を正解となる関連文書の ID と比較します。
query = "What is the torque specification for the chamber flange bolts?"
query_embed = generate_text_embedding(
query, dim=1024, purpose="GENERIC_RETRIEVAL"
)
results = s3vectors.query_vectors(
vectorBucketName="manufacturing-vectors",
indexName="manufacturing-multimodal",
queryVector={"float32": query_embed},
topK=10,
returnDistance=True,
returnMetadata=True,
)
retrieved_ids = [v["key"] for v in results["vectors"]]
私たちは K=3, 5, 10 の各ケースで 3 つの指標を計算します。Recall@K(上位 K 件の結果に含まれる関連文書の割合)、MRR(最初の関連結果がどの程度高い順位に表示されるかを測定するもの)、そして NDCG@K(Normalized Discounted Cumulative Gain、関連文書がより上位にランク付けされた場合に高い評価を与える指標)です。
LLM-as-Judge を用いた生成評価
生成評価においては、両方のパイプラインで各クエリに対して上位 5 件の結果を抽出します。マルチモーダル・パイプラインでは、取得した画像をそのまま Amazon Nova 2 Lite にマルチモーダル文脈として渡します。一方、テキストのみのパイプラインでは、OCR で抽出されたテキストを文字列形式の文脈として渡します。
def generate_answer_multimodal(query, retrieved_keys):
"""取得した画像をマルチモーダルコンテキストとして直接渡す。"""
content_blocks = []
for key in retrieved_keys[:5]:
img_path = vector_key_to_image_path(key)
with open(img_path, "rb") as f:
img_bytes = f.read()
content_blocks.append({"text": f"取得したドキュメント:"})
content_blocks.append({
"image": {"format": "png", "source": {"bytes": img_bytes}}
})
content_blocks.append({
"text": (
f"上記の画像を注意深く確認してください。"
f"以下の質問に簡潔かつ正確に答えてください。\n\n"
f"質問:{query}\n\n回答:"
)
})
response = bedrock_runtime.converse(
modelId="us.amazon.nova-2-lite-v1:0",
messages=[{"role": "user", "content": content_blocks}],
inferenceConfig={"maxTokens": 500, "temperature": 0.1},
)
return response["output"]["message"]["content"][0]["text"]
各生成された回答は、Anthropic Claude Sonnet 4.5 を LLM ジャッジ(LLM judge)として用いて、正解参照データに対してスコアリングされます。ジャッジはクエリ、正解回答、および生成された回答を受け取り、1~5 の範囲でスコアを付与し、簡潔な説明を添えます。
必ず JSON 形式で返してください。translation フィールドのみ。他のフィールド (technical_terms 等) は一切追加しないこと — 余計なフィールドを書こうとして本文翻訳がトークン上限で打ち切られる事故を防ぐため:
{"translation": "翻訳全文"}
def judge_correctness(query, generated_answer, ground_truth):
prompt = (
"あなたは評価者です。生成された回答を正解(ground truth)と比較し、1〜5 のスケールで採点してください。\n\n"
"1 = 完全に間違っているか無関係\n"
"2 = 部分的に関連はあるが主に誤り\n"
"3 = ある程度正しいが重要な情報が欠落している\n"
"4 = ほぼ正確だが若干の省略あり\n"
"5 = 完全に正確で完全\n\n"
f"質問:{query}\n"
f"正解:{ground_truth}\n"
f"生成された回答:{generated_answer}\n\n"
'JSON オブジェクトのみを返してください: {"score": , "reason": ""}'
)
response = bedrock_runtime.converse(
modelId="us.anthropic.claude-sonnet-4-5-20250929-v1:0",
messages=[{"role": "user", "content": [{"text": prompt}]}],
inferenceConfig={"maxTokens": 200, "temperature": 0.0},
)
return response["output"]["message"]["content"][0]["text"]
検索と生成を別々に評価することで、各パイプラインがどこで成功し、どこで失敗するかを特定できます。例えば、正しいドキュメントを検索できたとしても、生成モデルが提供されたコンテキスト形式から情報を抽出できない場合、間違った回答を出力することがあります。
必ず JSON 形式で返してください。translation フィールドのみ。他のフィールド (technical_terms 等)は一切追加しないこと — 余計なフィールドを書こうとして本文翻訳がトークン上限で打ち切られる事故を防ぐため:
{"translation": "翻訳全文"}
評価結果
航空機製造データセットから導き出された26のクエリに対して、マルチモーダルパイプラインを評価しました。各クエリには1つ以上の正解となる関連ドキュメントIDが設定されています。検索指標は、返される結果の数(K)を変化させた際に、システムがどの程度正確なドキュメントを上位に表示できるかを測定するものです。
マルチモーダル検索指標
マルチモーダルパイプラインは、K=5 の時点で90パーセントの再現率を達成しており、これは最初の5件以内の結果に最も関連性の高いドキュメントがほとんど含まれていることを意味します。また、K=10 ではこの数値が96パーセントまで上昇します。MRR(平均順位)が 0.92 であることは、最初の関連結果が通常1位に表示される傾向があることを示しています。K=10 で再現率が 1.0 に満たない2つのクエリは、関連情報が PDF と独立した画像の両方にまたがって記載されているドキュメントに関連するものであり、そのうちの一つの関連ソースが上位10件から外れているケースです。
以下のチャートは、K=3, 5, 10 におけるマルチモーダル検索指標を示しています。MRR は最初の関連結果がリスト上でどの程度高い位置に表示されるかを測定します。Recall@K(再現率@K)は、上位 K 件の結果に見つかった関連ドキュメントの割合を測定します。NDCG@K(正規化された累積割引順位値@K)はランキングの品質を測定し、関連ドキュメントがリスト上でより高い位置にある場合に高い評価を与えます。
生成品質:テキスト単一型とマルチモーダル型の比較
*検索指標*は、システムが適切な文書を見つけられたかを測定します。*生成指標*は、取得されたコンテキストから下流の言語モデルが正しい回答を生成できるかを測定します。各パイプラインから上位 5 つの結果を取得し、Amazon Nova 2 Lite に渡して回答を生成させました。その後、Anthropic Claude Sonnet 4.5 を LLM ジャッジとして用い、1~5 段階のスケールで正解(ground truth)と比較して各回答にスコアを付けました。
<tb
原文を表示
If you work in aerospace, automotive, or heavy industry manufacturing, your organization likely maintains vast repositories of technical documents. These documents combine written specifications with engineering diagrams, CAD drawings, inspection photographs, thermal analysis plots, and fatigue curves. A text query about maximum wall temperature at the nozzle throat might have its answer locked inside a thermal contour plot rather than written prose. Text-only retrieval systems can’t surface that information because they don’t see the image content.
Amazon Nova Multimodal Embeddings addresses this gap by mapping text, images, and document pages into a shared vector space. A text query can retrieve an engineering diagram, and an image query can retrieve a written specification, because both modalities share the same coordinate system.
In this post, we build a multimodal retrieval system for aerospace manufacturing documents using Amazon Nova Multimodal Embeddings on Amazon Bedrock and Amazon S3 Vectors. We evaluate the system on 26 manufacturing queries and compare generation quality between a text-only pipeline and the multimodal pipeline.
Why multimodal retrieval matters for manufacturing
Most manufacturing documents combine text, diagrams, and images. A single work order might contain written assembly procedures alongside annotated photographs of completed steps. An inspection report pairs pass/fail measurements with radiographic images of weld joints. A material certification includes both tabular mechanical properties and S-N fatigue curves that an engineer must reference during design review.
Consider a few concrete examples of visual information from the dataset used in this post: A torque specification table is depicted inside an engineering drawing rather than stored as standalone text. A color-coded thermal contour plot is used to visualize peak temperatures across a rocket engine nozzle. A manufacturing process flow chart labels quality hold points visually with decision diamonds and color-coded gates, and the associated cycle times appear as annotations on the diagram itself.
Text-only retrieval systems handle these documents by extracting text through OCR, then embedding and indexing the extracted strings. This works when answers appear in the written portions of a document, but text-only systems miss the spatial relationships in diagrams, the visual patterns in inspection images, and the quantitative information encoded in plots and charts. When you make a search for the type of bearings used in the turbopump, the answer might appear as a labeled callout on a cross-section diagram that OCR either misreads or strips of its spatial context.
Multimodal embeddings take a different approach. Instead of converting images to text and then embedding the text, the model processes the image directly and produces a vector in the same space as text embeddings. A text query about turbopump bearings can match against the cross-section diagram in our dataset based on visual understanding, not just whatever text OCR managed to extract.
Amazon Nova Multimodal Embeddings overview
Amazon Nova Multimodal Embeddings is available in Amazon Bedrock and generates embeddings for text, images, and multipage documents. Text, image, and document modalities project into a single shared vector space, which means you can compute cosine similarity between a text embedding and an image embedding directly.
You can configure embedding dimensions from 256, 384, 1024, or 3072. Higher dimensions capture more semantic detail but require more storage and compute for similarity search. For the evaluation in this post, we use 1024 dimensions as a practical balance between retrieval quality and cost. The model also supports a DOCUMENT_IMAGE detail level, a processing mode designed for pages containing mixed content such as charts, tables, and annotated diagrams.
For retrieval workloads, the model accepts a purpose parameter set to either GENERIC_INDEX (for documents being indexed) or GENERIC_RETRIEVAL (for queries). This asymmetric embedding approach improves the vector space for retrieval without requiring manual query formatting.
Solution overview
We built two parallel retrieval pipelines on the same dataset to compare their downstream generation quality.
Dataset – 15 standalone technical images (CAD diagrams, inspection reports, test plots, material specifications, process flow charts) and five multi-page PDFs (assembly procedures, hot-fire test reports, engineering change notices, material certifications, non-conformance reports). These documents contain synthetic aerospace manufacturing data.
Pipeline A, Multimodal – Embed each image directly and each PDF page as a document image using Amazon Nova Multimodal Embeddings, then ingest into an Amazon Simple Storage Service (Amazon S3) Vectors index.
Pipeline B, Text-only baseline – Send each image and PDF page to Amazon Nova 2 Lite for OCR text extraction, embed the extracted text using Amazon Nova Multimodal Embeddings (text-only input), then ingest into a separate Amazon S3 Vectors index. The following prompt is used for the OCR step:
Note: OCR prompt for text extraction
"Extract ALL visible text from this image exactly as it appears. Include all numbers, labels, annotations, table contents, headers, and footnotes. Preserve the structure (tables, lists, sections) as much as possible. Return only the extracted text, no commentary."Evaluation – Run 26 manufacturing queries against the multimodal index for retrieval metrics (Recall@K, Mean Reciprocal Rank (MRR), NDCG@K). Then, for both pipelines, retrieve context and generate answers using Amazon Nova 2 Lite, scoring each answer against ground truth with a large language model (LLM) judge.
The following diagram shows the end-to-end pipeline architecture. Source documents flow through two parallel paths: Pipeline A embeds images directly with Amazon Nova Multimodal Embeddings, while Pipeline B extracts text through OCR before embedding. Both pipelines store vectors in Amazon S3 Vectors. At query time, retrieved context feeds into Amazon Nova 2 Lite for answer generation, and an LLM judge scores each answer against ground truth.
The following figure shows three sample documents from the dataset. From left to right: a nozzle assembly CAD diagram, a weld inspection report, and an Inconel 718 fatigue S-N curve. Each document type presents information that’s difficult to capture through text extraction alone.
Solution walkthrough
This section walks through the key implementation steps, from generating embeddings to building the vector index and running queries. The complete code is available in the companion notebook on GitHub.
Prerequisites
To follow along with this post, you need the following resources and access configured in your AWS account:
- An AWS account with access to Amazon Bedrock in us-east-1
- Model access enabled for amazon.nova-2-multimodal-embeddings-v1:0 and us.amazon.nova-2-lite-v1:0
- An Amazon SageMaker AI notebook instance or local Python environment
- Python 3.10+ with boto3, numpy, pandas, matplotlib, Pillow, pdf2image, and tqdm
- IAM permissions for Amazon Bedrock InvokeModel, Amazon S3, and Amazon S3 Vectors APIs
The sample code in this post is provided for educational purposes and hasn’t been reviewed for production use. Review and test it against your organization’s security requirements before deploying to production environments.
Generating multimodal embeddings
Generating an embedding for a manufacturing image requires a single InvokeModel call to Amazon Bedrock. The request specifies the image bytes, the desired embedding dimension, and the detail level. For standalone images like CAD diagrams, we use STANDARD_IMAGE. For PDF pages with mixed text and graphics, DOCUMENT_IMAGE produces better results because the model applies additional processing for tabular and chart content.
import base64, json, boto3
bedrock_runtime = boto3.client("bedrock-runtime", region_name="us-east-1")
MODEL_ID = "amazon.nova-2-multimodal-embeddings-v1:0"
with open("dataset/nozzle_assembly_diagram.png", "rb") as f:
b64_data = base64.b64encode(f.read()).decode("utf-8")
request_body = {
"taskType": "SINGLE_EMBEDDING",
"singleEmbeddingParams": {
"embeddingPurpose": "GENERIC_INDEX",
"embeddingDimension": 1024,
"image": {
"format": "png",
"detailLevel": "STANDARD_IMAGE",
"source": {"bytes": b64_data},
},
},
}
response = bedrock_runtime.invoke_model(
modelId=MODEL_ID,
body=json.dumps(request_body),
accept="application/json",
contentType="application/json",
)
embedding = json.loads(response["body"].read())["embeddings"][0]["embedding"]
print(f"Embedding dimension: {len(embedding)}") # 1024Building the Amazon S3 Vectors index
Amazon S3 Vectors provides a managed vector storage and query layer. We create a vector bucket and an index configured for cosine similarity, then ingest embeddings in batches of 50.
s3vectors = boto3.client("s3vectors", region_name="us-east-1")
# Create vector bucket and index
s3vectors.create_vector_bucket(vectorBucketName="manufacturing-vectors")
s3vectors.create_index(
vectorBucketName="manufacturing-vectors",
indexName="manufacturing-multimodal",
dataType="float32",
dimension=1024,
distanceMetric="cosine",
)
# Ingest a batch of embeddings with metadata
vectors = [
{
"key": "img-nozzle_assembly_diagram",
"data": {"float32": embedding},
"metadata": {
"source_file": "nozzle_assembly_diagram.png",
"type": "image",
},
}
]
s3vectors.put_vectors(
vectorBucketName="manufacturing-vectors",
indexName="manufacturing-multimodal",
vectors=vectors,
)Querying the index
At query time, we generate a text embedding with GENERIC_RETRIEVAL purpose, then call query_vectors to retrieve the most similar documents. The GENERIC_RETRIEVAL purpose tells the model to improve the embedding for query-document matching.
query = "What is the torque specification for the chamber flange bolts?"
request_body = {
"taskType": "SINGLE_EMBEDDING",
"singleEmbeddingParams": {
"embeddingPurpose": "GENERIC_RETRIEVAL",
"embeddingDimension": 1024,
"text": {"truncationMode": "END", "value": query},
},
}
response = bedrock_runtime.invoke_model(
modelId=MODEL_ID, body=json.dumps(request_body),
accept="application/json", contentType="application/json",
)
query_embedding = json.loads(response["body"].read())["embeddings"][0]["embedding"]
results = s3vectors.query_vectors(
vectorBucketName="manufacturing-vectors",
indexName="manufacturing-multimodal",
queryVector={"float32": query_embedding},
topK=5,
returnDistance=True,
returnMetadata=True,
)
for v in results["vectors"]:
print(f" {v['key']} (distance: {v['distance']:.4f})")This query retrieves the torque specifications image and the flange bolt pattern diagram as the top results, both of which contain the answer. A text-only system would need the OCR extraction to have correctly captured the torque values from the engineering drawing, which is not always reliable for complex technical diagrams.
Evaluation methodology
We evaluated the system in two stages: retrieval quality (does the system find the right documents?) and generation quality (can a language model produce a correct answer from the retrieved context?). The evaluation dataset contains 26 queries derived from the aerospace manufacturing documents, each with ground truth relevant document IDs and a reference answer. The following subsections describe how each stage works.
Retrieval evaluation
For each query, we generate a text embedding with GENERIC_RETRIEVAL purpose, query the multimodal S3 Vectors index, and compare the returned documents against the ground truth relevant document IDs.
query = "What is the torque specification for the chamber flange bolts?"
query_embed = generate_text_embedding(
query, dim=1024, purpose="GENERIC_RETRIEVAL"
)
results = s3vectors.query_vectors(
vectorBucketName="manufacturing-vectors",
indexName="manufacturing-multimodal",
queryVector={"float32": query_embed},
topK=10,
returnDistance=True,
returnMetadata=True,
)
retrieved_ids = [v["key"] for v in results["vectors"]]We compute three metrics at K=3, 5, and 10: Recall@K (fraction of relevant documents found in the top K results), MRR (measuring how high the first relevant result appears), and NDCG@K (Normalized Discounted Cumulative Gain, giving more credit when relevant documents rank higher).
Generation evaluation with LLM-as-Judge
For generation evaluation, both pipelines retrieve the top five results for each query. The multimodal pipeline passes the retrieved images directly to Amazon Nova 2 Lite as multimodal context. The text-only pipeline passes the OCR-extracted text as string context.
def generate_answer_multimodal(query, retrieved_keys):
"""Pass retrieved images directly as multimodal context."""
content_blocks = []
for key in retrieved_keys[:5]:
img_path = vector_key_to_image_path(key)
with open(img_path, "rb") as f:
img_bytes = f.read()
content_blocks.append({"text": f"Retrieved document:"})
content_blocks.append({
"image": {"format": "png", "source": {"bytes": img_bytes}}
})
content_blocks.append({
"text": (
f"Review each image above carefully. "
f"Answer the following question concisely and precisely.\n\n"
f"Question: {query}\n\nAnswer:"
)
})
response = bedrock_runtime.converse(
modelId="us.amazon.nova-2-lite-v1:0",
messages=[{"role": "user", "content": content_blocks}],
inferenceConfig={"maxTokens": 500, "temperature": 0.1},
)
return response["output"]["message"]["content"][0]["text"]Each generated answer is scored against the ground truth reference using Anthropic Claude Sonnet 4.5 as an LLM judge. The judge receives the query, the ground truth answer, and the generated answer, then assigns a score from 1–5 with a brief explanation.
def judge_correctness(query, generated_answer, ground_truth):
prompt = (
"You are an evaluation judge. Score the generated answer compared "
"to the ground truth on a scale of 1-5.\n\n"
"1 = Completely wrong or irrelevant\n"
"2 = Partially relevant but mostly incorrect\n"
"3 = Somewhat correct but missing key information\n"
"4 = Mostly correct with minor omissions\n"
"5 = Fully correct and complete\n\n"
f"Question: {query}\n"
f"Ground Truth: {ground_truth}\n"
f"Generated Answer: {generated_answer}\n\n"
'Respond with ONLY a JSON object: '
'{"score": , "reason": ""}'
)
response = bedrock_runtime.converse(
modelId="us.anthropic.claude-sonnet-4-5-20250929-v1:0",
messages=[{"role": "user", "content": [{"text": prompt}]}],
inferenceConfig={"maxTokens": 200, "temperature": 0.0},
)
return response["output"]["message"]["content"][0]["text"]By evaluating retrieval and generation separately, you can pinpoint where each pipeline succeeds or fails. A pipeline might retrieve the correct document but still produce a wrong answer if the generator can’t extract the information from the provided context format.
Evaluation results
We evaluated the multimodal pipeline on 26 queries derived from the aerospace manufacturing dataset. Each query has one or more ground truth relevant document IDs. Retrieval metrics measure how well the system surfaces the correct documents at different values of K (the number of results returned).
Multimodal retrieval metrics
The multimodal pipeline achieves 90 percent recall at K=5, meaning it surfaces most relevant documents within the first five results, rising to 96 percent at K=10. An MRR of 0.92 indicates that the first relevant result typically appears in position 1. The two queries where recall falls below 1.0 at K=10 involve documents with relevant information split across a PDF and a standalone image, where one of the two relevant sources appears outside the top 10.
The following chart shows multimodal retrieval metrics at K=3, 5, and 10. MRR measures how high the first relevant result appears. Recall@K measures the fraction of relevant documents found in the top K results. NDCG@K measures ranking quality, giving more credit when relevant documents appear higher in the list.
Generation quality: text-only vs. multimodal
*Retrieval metrics* measure whether the system finds the right documents. *Generation metrics* measure whether a downstream language model can produce a correct answer from the retrieved context. We passed the top five retrieved results from each pipeline to Amazon Nova 2 Lite for answer generation, then scored each answer against ground truth using Anthropic Claude Sonnet 4.5 as an LLM judge on a 1–5 scale.
<tb
関連記事
今日のまとめ
AI日報で今日の重要ニュースをまとめ読み