引言
随着信息检索与生成式AI的深度融合,检索增强生成(RAG, Retrieval-Augmented Generation) 已成为AI领域的重要技术方向。传统RAG系统主要依赖文本数据,但真实世界中的信息往往包含图像、表格等多模态内容。多模态RAG(Multimodal RAG)通过结合文本与视觉信息,显著提升了系统的理解能力与应用场景。然而,如何科学、全面地评测多模态RAG系统的性能,是测试工程师必须掌握的核心技能。
本文将结合 EvalScope 多模态RAG评测实践,系统介绍多模态RAG的原理、评测流程、关键指标及代码实现,帮助测试工程师快速上手并深入理解评测要点。
一、RAG与多模态RAG简介
1.1 传统RAG的局限性
传统RAG系统通过以下流程工作:
- 检索:从大规模文本数据库中查找与用户问题相关的片段。
- 生成:将检索到的文本输入大语言模型(LLM),生成最终答案。
然而,传统RAG的局限性在于:
- 忽略非文本信息:无法处理图像、表格等非结构化数据。
- 上下文理解受限:仅依赖文本可能导致信息缺失或歧义。
1.2 多模态RAG的优势
多模态RAG通过以下改进,解决了传统RAG的不足:
- 多模态检索:支持文本、图片、表格的联合检索。
- 多模态生成:利用多模态LLM(如Qwen-VL、GPT-4o)结合文本与视觉信息生成答案。
- 更贴近真实场景:适用于医疗影像诊断、工业质检、农业识别等需结合图像的场景。
二、多模态RAG的评测流程
多模态RAG的评测分为四个核心步骤,每个步骤均需严格验证:
2.1 文档解析
目标:将PDF、扫描文档等非结构化数据转换为可检索的多模态元素(文本、图片、表格)。
关键技术:
- 工具:
unstructured
、MinerU
等库用于解析PDF。 - 实现细节:
- 图像提取:从PDF中提取高清图片,存储为独立文件。
- 文本与表格提取:分割文本段落和表格,保留结构信息。
- 示例代码:
from unstructured.partition.pdf import partition_pdf def extract_pdf_elements(file_path, output_image_path): elements = partition_pdf( filename=file_path, strategy="hi_res", # 高分辨率解析 extract_images_in_pdf=True, extract_image_block_output_dir=output_image_path # 图片保存路径 ) return elements
2.2 多模态向量存储
目标:将文本与图像统一编码为向量,存入向量数据库,便于后续检索。
关键技术:
- 嵌入模型:使用多模态模型(如CLIP、Chinese-CLIP)计算文本与图像的联合向量。
- 向量数据库:Chroma、FAISS 等支持高效相似性搜索。
- 实现细节:
- 统一编码:通过CLIP模型将文本和图像映射到同一向量空间。
- 向量存储:将向量与元数据(如图片URI)存入数据库。
- 示例代码:
from langchain_chroma import Chroma from evalscope.backend.rag_eval import VisionModel # 加载CLIP模型 vectorstore = Chroma( collection_name="mm_rag_clip", embedding_function=VisionModel.load(model_name="AI-ModelScope/chinese-clip-vit-large-patch14-336px") ) # 添加图片到向量库 image_uris = [os.path.join(image_path, img) for img in os.listdir(image_path) if img.endswith(".jpg")] vectorstore.add_images(uris=image_uris)
2.3 检索增强生成
目标:根据用户问题检索相关多模态内容,并生成答案。
关键技术:
- 相似性搜索:通过向量数据库找到最相关的文本和图像。
- 多模态生成:将检索到的内容输入多模态LLM生成答案。
- 实现细节:
- 检索策略:使用
similarity_search
查找Top-K相关结果。 - 生成策略:将检索到的文本和图像作为上下文输入LLM。
- 示例代码:
class RAGPipeline: def __init__(self, retriever, model): self.retriever = retriever self.model = model def invoke(self, question): # 检索相关上下文 context = self.retriever.invoke(question) # 生成答案 response = self.model.generate(context=context, question=question) return response
<
- 检索策略:使用