一声棒喝,本不立文字
偏要著録,已是二义

aws-ml

用 Amazon Nova 多模态嵌入实现制造智能

Manufacturing intelligence with Amazon Nova Multimodal Embeddings

二〇二六年五月十二日 · 英文原文

在航空航天、汽车和重工业制造业中,技术文档常包含图像(如CAD图纸、热分析图),纯文本检索系统因无法处理视觉内容而失效。Amazon Nova Multimodal Embeddings将文本、图像和文档页面映射到共享向量空间,实现跨模态检索。本文基于Amazon Bedrock和Amazon S3 Vectors构建多模态检索系统,使用26个制造查询评估。多模态流水线在K=5时召回率达90%,生成质量评分4.88/5,而纯文本基线仅2.00/5。

如果你在航空航天、汽车或重工业制造业工作,你的组织很可能维护着庞大的技术文档库。这些文档将书面规格与工程图纸、CAD 图纸、检验照片、热分析图和疲劳曲线结合在一起。关于喷嘴喉部最高壁温的文本查询,其答案可能隐藏在一张热轮廓图中,而不是书面文字中。纯文本检索系统无法呈现这些信息,因为它们看不到图像内容。Amazon Nova Multimodal Embeddings 通过将文本、图像和文档页面映射到一个共享向量空间来解决这一差距。文本查询可以检索到工程图纸,图像查询可以检索到书面规格,因为两种模态共享同一个坐标系。在本文中,我们使用 Amazon Bedrock 上的 Amazon Nova Multimodal Embeddings 和 Amazon S3 Vectors 为航空航天制造文档构建了一个多模态检索系统。我们使用 26 个制造查询对系统进行了评估,并比较了纯文本流水线和多模态流水线之间的生成质量。

为什么多模态检索对制造业很重要

大多数制造文档都结合了文本、图表和图像。单个工单可能包含书面装配程序以及已完成步骤的带注释照片。检验报告将合格/不合格测量值与焊缝的射线图像配对。材料认证包括表格形式的机械性能和 S-N 疲劳曲线,工程师在设计评审时必须参考这些曲线。考虑本文数据集中视觉信息的一些具体示例:

纯文本检索系统通过 OCR 提取文本来处理这些文档,然后对提取的字符串进行嵌入和索引。当答案出现在文档的书面部分时,这种方法有效,但纯文本系统会遗漏图表中的空间关系、检验图像中的视觉模式以及图表中编码的定量信息。当你搜索涡轮泵中使用的轴承类型时,答案可能以带标签的标注形式出现在剖面图上,而 OCR 要么误读,要么剥离了其空间上下文。

多模态嵌入采用了一种不同的方法。该模型不将图像转换为文本然后嵌入文本,而是直接处理图像并生成与文本嵌入在同一空间中的向量。关于涡轮泵轴承的文本查询可以基于视觉理解匹配我们数据集中的剖面图,而不仅仅是 OCR 设法提取的任何文本。

Amazon Nova Multimodal Embeddings 概述

Amazon Nova Multimodal Embeddings 在 Amazon Bedrock 中可用,并为文本、图像和多页文档生成嵌入。文本、图像和文档模态投影到一个共享向量空间中,这意味着你可以直接计算文本嵌入和图像嵌入之间的余弦相似度。你可以配置 256、384、1024 或 3072 的嵌入维度。更高的维度捕获更多的语义细节,但需要更多的存储和计算来进行相似性搜索。在本文的评估中,我们使用 1024 维度作为检索质量和成本之间的实际平衡。该模型还支持 DOCUMENT_IMAGE 细节级别,这是一种专为包含图表、表格和带注释图表等混合内容的页面设计的处理模式。对于检索工作负载,模型接受一个 purpose 参数,设置为 GENERIC_INDEX(用于被索引的文档)或 GENERIC_RETRIEVAL(用于查询)。这种非对称嵌入方法改进了检索的向量空间,而无需手动格式化查询。

解决方案概述

我们在同一数据集上构建了两个并行检索流水线,以比较它们的下游生成质量。

下图显示了端到端流水线架构。源文档流经两条并行路径:流水线 A 使用 Amazon Nova Multimodal Embeddings 直接嵌入图像,而流水线 B 在嵌入之前通过 OCR 提取文本。两个流水线都将向量存储在 Amazon S3 Vectors 中。在查询时,检索到的上下文被输入到 Amazon Nova 2 Lite 以生成答案,LLM 评判器根据真实答案对每个答案进行评分。

下图显示了数据集中的三个示例文档。从左到右:一个喷嘴组件 CAD 图纸、一份焊缝检验报告和一张 Inconel 718 疲劳 S-N 曲线。每种文档类型呈现的信息都难以仅通过文本提取来捕获。

解决方案演练

本节将介绍关键的实施步骤,从生成嵌入到构建向量索引和运行查询。完整代码可在 GitHub 上的配套笔记本中找到。

前提条件

要遵循本文的操作,你需要在 AWS 账户中配置以下资源和访问权限:

本文中的示例代码仅供教育目的提供,未经生产使用审查。在部署到生产环境之前,请根据组织的安全要求进行审查和测试。

生成多模态嵌入

为制造图像生成嵌入需要对 Amazon Bedrock 进行一次 InvokeModel 调用。请求指定图像字节、所需的嵌入维度和细节级别。对于像 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 Vectors 索引

Amazon S3 Vectors 提供了一个托管的向量存储和查询层。我们创建一个向量桶和一个配置为余弦相似度的索引,然后以 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,
)

查询索引

在查询时,我们使用 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})")

此查询将扭矩规格图像和法兰螺栓孔图案图作为前两个结果检索出来,两者都包含答案。纯文本系统需要 OCR 提取正确地从工程图纸中捕获扭矩值,这对于复杂的技术图纸来说并不总是可靠的。

评估方法

我们分两个阶段评估系统:检索质量(系统是否找到正确的文档?)和生成质量(语言模型能否从检索到的上下文中产生正确的答案?)。评估数据集包含源自航空航天制造文档的 26 个查询,每个查询都有真实相关的文档 ID 和参考答案。以下小节描述了每个阶段的工作方式。

检索评估

对于每个查询,我们使用 GENERIC_RETRIEVAL 目的生成一个文本嵌入,查询多模态 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 时计算三个指标:Recall@K(在前 K 个结果中找到的相关文档的比例)、MRR(衡量第一个相关结果出现的位置有多高)和 NDCG@K(归一化折损累计增益,当相关文档排名更高时给予更多权重)。

使用 LLM 作为评判器的生成评估

对于生成评估,两个流水线都为每个查询检索前五个结果。多模态流水线将检索到的图像直接作为多模态上下文传递给 Amazon Nova 2 Lite。纯文本流水线将 OCR 提取的文本作为字符串上下文传递。

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"]

每个生成的答案都使用 Anthropic Claude Sonnet 4.5 作为 LLM 评判器,根据真实参考进行评分。评判器接收查询、真实答案和生成的答案,然后分配 1-5 的分数并附上简要说明。

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": <int>, "reason": "<string>"}'
    )

    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"]

通过分别评估检索和生成,你可以精确定位每个流水线成功或失败的地方。如果生成器无法从提供的上下文格式中提取信息,流水线可能检索到正确的文档,但仍然产生错误的答案。

评估结果

我们使用源自航空航天制造数据集的 26 个查询评估了多模态流水线。每个查询都有一个或多个真实相关的文档 ID。检索指标衡量系统在不同 K 值(返回的结果数量)下呈现正确文档的效果。

多模态检索指标

多模态流水线在 K=5 时实现了 90% 的召回率,这意味着它在前五个结果中呈现了大部分相关文档,在 K=10 时上升到 96%。0.92 的 MRR 表明第一个相关结果通常出现在位置 1。在 K=10 时召回率低于 1.0 的两个查询涉及相关信息分散在 PDF 和独立图像中的文档,其中两个相关来源之一出现在前 10 名之外。

下图显示了 K=3、5 和 10 时的多模态检索指标。MRR 衡量第一个相关结果出现的位置有多高。Recall@K 衡量在前 K 个结果中找到的相关文档的比例。NDCG@K 衡量排名质量,当相关文档在列表中排名更高时给予更多权重。

生成质量:纯文本 vs. 多模态

检索指标衡量系统是否找到正确的文档。生成指标衡量下游语言模型能否从检索到的上下文中产生正确的答案。我们将每个流水线的前五个检索结果传递给 Amazon Nova 2 Lite 以生成答案,然后使用 Anthropic Claude Sonnet 4.5 作为 LLM 评判器,以 1-5 的等级对每个答案根据真实答案进行评分。

流水线 平均评判分数 归一化 (0–1)
多模态 (MME) 4.88 / 5 0.977
纯文本 (OCR) 2.00 / 5 0.400

表 2:由 LLM 作为评判器评分的生成质量。 多模态流水线检索图像并直接传递给生成器,而纯文本流水线传递 OCR 提取的文本。

多模态流水线在 88% 的查询(26 个中的 23 个)上得分更高,平均为 4.88 分(满分 5 分)。纯文本流水线平均得分为 2.00,26 个查询中有 17 个得分为 1(完全错误)。像热分析轮廓图、疲劳曲线、工艺流程图和 CAD 标注标签这样的视觉内容显示出最大的改进。对于两个流水线都得分较高(4 或 5)的少数查询,答案恰好以清晰的格式化文本出现,OCR 可以可靠地捕获,例如表格布局中的材料名称或数值。

下图显示了两个流水线的 LLM 评判分数(1-5)分布。多模态流水线集中在 5 分,而纯文本流水线对于需要视觉内容理解的查询集中在 1 分。

这些结果表明检索质量直接影响答案质量。当系统检索到正确的文档但只将 OCR 文本传递给生成器时,它会丢失答案所依赖的视觉信息。多模态流水线通过将原始图像传递给多模态生成器来避免这种有损转换。

实施复杂性和成本

除了准确性之外,多模态流水线构建起来更直接,运行成本也更低。纯文本流水线每个文档需要两次模型调用(一次用于 OCR 文本提取,一次用于文本嵌入),外加提示工程来处理不同的文档布局。多模态流水线每个文档只需要一次嵌入调用,没有中间提取步骤,将实施复杂性和每个文档的摄取成本大致减半。

清理

为避免持续产生费用,请在完成评估后删除 S3 Vectors 索引和桶。GitHub 上的配套笔记本包含这些清理命令(为安全起见已注释掉)。以下代码片段显示了如何删除索引和向量桶:

# Delete indexes
s3vectors.delete_index(vectorBucketName=S3_VECTOR_BUCKET, indexName=MME_INDEX)
s3vectors.delete_index(vectorBucketName=S3_VECTOR_BUCKET, indexName=TEXT_ONLY_INDEX)

# Delete vector bucket
s3vectors.delete_vector_bucket(vectorBucketName=S3_VECTOR_BUCKET)

Amazon Bedrock 嵌入推理按请求计费,无需管理持久性基础设施。

结论

对于包含大量视觉内容的文档集合,多模态嵌入弥补了纯文本系统无法解决的检索差距。在本文的航空航天制造数据集上,多模态流水线在 K=5 时实现了 90% 的召回率(K=10 时为 96%)和近乎完美的生成质量(4.88/5),而纯文本流水线得分为 2.00/5,因为 OCR 无法可靠地从工程图纸、热图和流程图中捕获信息。

借助 Amazon Bedrock 上的 Amazon Nova Multimodal Embeddings,你可以在不管理嵌入模型基础设施的情况下构建此功能。Amazon S3 Vectors 提供了一个向量存储和查询层,无需集群管理或容量规划。

要亲自尝试,请从 GitHub 克隆配套代码示例,并在 Amazon SageMaker AI 或你的本地环境中运行。你可以通过替换示例数据集和查询来使流水线适应你自己的制造文档。有关更多模式和示例,请参阅以下资源:

关于作者

Adewale Akinfaderin Adewale 是 Amazon Bedrock 的高级数据科学家 - 生成式 AI,他在 AWS 为基础模型和生成式 AI 应用的尖端创新做出贡献。他的专长在于可复现的端到端 AI/ML 方法、实际实施以及帮助全球客户制定和开发跨学科问题的可扩展解决方案。他拥有两个物理学研究生学位和一个工程学博士学位。

Matthew Lydon Matthew 是 Amazon Web Services 航空航天与卫星团队的解决方案架构师。他已支持超过 1,000 个航空航天客户,范围从立方星初创公司到重型运载火箭制造商。他的技术重点包括 ITAR 限制工作负载的安全 AI 实施、发动机测试数据处理、用于工程仿真的 HPC 以及卫星图像处理。Matthew 领导航空航天行业的生成式 AI 研讨会。

译自 aws-ml · 录于 二〇二六年五月十二日