构建用于视觉问答的多模态 RAG 系统

概述

在本文中,我将指导您构建一个使用 OpenAI 的 GPT-4o 模型的多模态 RAG 聊天应用程序。您将学习以下内容:

  • 多模态 RAG 聊天应用程序:创建一个应用程序,通过从 PDF 文档中检索信息来实现视觉问答。

  • 无缝解析:使用 Unstructured 库无缝解析文本、表格和图像。

  • 性能评估:使用 DeepEval 库提供的各种指标评估聊天机器人的性能。

  • Streamlit UI:通过 Streamlit 应用程序演示该应用程序。

为什么要阅读这个?

你是否有兴趣利用像 GPT-4o 这样的先进基础模型的多模态能力来构建自己的 AI 应用程序?那么你来对地方了!

无论你是寻求市场研究报告见解的市场营销专业人士,分析多模态医疗文件的医疗从业者,还是处理复杂法律文件的法律专业人士,这篇文章都为你提供了宝贵的见解。

我将详细解释每个概念,并提供所有代码的详细说明。话虽如此,让我们开始吧! 🎬

多模态 RAG 的崛起

从基于文本的 RAG 模型过渡到多模态 RAG 系统标志着 AI 能力的重大飞跃。以下是快速概述:

  • 起源:RAG 这个术语是在 2021 年 4 月提出的,通过基于文本的知识增强语言输出。

  • 进展:随着 2024 年 5 月发布的 GPT-4o 等模型,我们现在可以整合视觉信息,允许同时处理图像、表格和文本。

  • 新可能性:这一演变使得更全面和上下文丰富的 AI 应用成为可能。

在本文中,我将展示一个案例研究,使用多模态 RAG 框架对我在 Neurocomputing 上发表的研究文章进行问答。该文章包含文本、表格和图形,我们将探索 GPT-4o 的视觉能力如何回答复杂问题。

让我们开始编码吧!🎬

设置虚拟环境并安装 Python 库

首先,让我们使用以下命令设置虚拟环境:

python3.10 -m venv venv  

现在,让我们安装必要的软件包。您可以在 GitHub 仓库的主目录中的“requirements.txt”中找到它们。

pip install -r requirements.txt  

现在,打开一个 Jupyter Notebook,比如“your-project.ipynb”,开始编写您的代码。就这样!我们现在准备进入主要细节。

这是多模态 RAG 项目的工作 GitHub 仓库:

预处理非结构化数据

要构建一个 RAG 应用程序,我们的第一步是将上下文加载到数据库中,这里使用的是 PDF 文档。由于大型语言模型(LLM)的上下文窗口限制,我们无法将整个文档直接存储并传递到提示中。这样做很可能会导致错误,因为它超过了最大标记数。

为了解决这个问题,我们将首先从文档中提取不同的元素——图像、文本和表格。为此任务,我们将使用 Unstructured 库。

安装

首先让我们安装这个包(如果尚未通过 pip 安装的话)

#%brew install tesseract poppler  
%pip install -q "unstructured[all-docs]"  

请注意,我们还需要系统中的“tesseract”和“poppler”库,以便 unstructured 库能够处理文本提取以及从图像中提取文本。您可以使用 homebrew 安装这两个包(请参见注释行)。

分区和块划分

from unstructured.partition.pdf import partition_pdf  
  
elements = partition_pdf(  
    filename="TAGIV.pdf", # mandatory  
    strategy="hi_res",                                     # mandatory to use ``hi_res`` strategy  
    extract_images_in_pdf=True,                            # mandatory to set as ``True``  
    extract_image_block_types=["Image", "Table"],          # optional  
    extract_image_block_to_payload=False,                  # optional  
    extract_image_block_output_dir="saved_images",  # optional - only works when ``extract_image_block_to_payload=False``  
    )  

我们将使用 partition_pdf 模块对文档进行分区,并从我们的文件‘TAGIV.pdf’中提取不同的元素。我们将设置 hi_res 策略以提取高质量的图像和表格。可选参数 extract_image_block_typesextract_image_block_output_dir 指定仅提取图像和表格,并将其保存到名为 “saved_images” 的目录中。

我们将使用 chunk_by_title 方法对元素进行块划分,该方法用于根据“标题或标题”将提取的元素划分为块。这适用于通常由不同部分和子部分组成的研究文章,例如引言、方法、结果等。

from unstructured.chunking.title import chunk_by_title # might be better for an article   
from typing import Any  
  
chunks = chunk_by_title(elements)  
  
# different category in the document  
category_counts = {}  
  
for element in chunks:  
    category = str(type(element))  
    if category in category_counts:  
        category_counts[category] += 1  
    else:  
        category_counts[category] = 1  
  
# Unique_categories will have unique elements  
unique_categories = set(category_counts.keys())  
category_counts   
{"<class 'unstructured.documents.elements.CompositeElement'>": 200,  
 "<class 'unstructured.documents.elements.Table'>": 3,  
 "<class 'unstructured.documents.elements.TableChunk'>": 2}  

块划分显示有三个独特的类别:

  • CompositeElements

  • Table

  • TableChunk

CompositeElements’ 是不同文本的集合,可能是段落、部分、页脚、公式等。还有三个 ‘Table’ 结构,以及两个 ‘TableChunk’,通常表示表格的一部分或片段。因此,可能一个表格跨页分割,只有一部分被划分。

_我在文档中确实有四个表格,但只有三个被完全解析。_🤔

过滤

接下来,我们将简化文档元素,以便分别处理文本和表格数据以进行进一步处理。为此,我们将定义一个 Pydantic 模型,以标准化文档元素,并根据其类型将其分类为“text”或“table”。

from pydantic import BaseModel  
  
class Element(BaseModel):  
    type: str  
    text: Any  
  
  
# 按类型分类  
categorized_elements = []  
for element in chunks:  
    if "unstructured.documents.elements.CompositeElement" in str(type(element)):  
        categorized_elements.append(Element(type="text", text=str(element)))  
    elif "unstructured.documents.elements.Table" in str(type(element)):  
        categorized_elements.append(Element(type="table", text=str(element)))  
  
# 文本  
text_elements = [e for e in categorized_elements if e.type == "text"]  
  
# 表格  
table_elements = [e for e in categorized_elements if e.type == "table"]  

我们将遍历文档元素的块,识别每个元素的类型,并将其附加到分类列表中。最后,我们将此列表过滤为文本和表格元素的单独列表。至此,预处理步骤已完成。

文本、表格和图像摘要

为了为后面使用多向量检索器做准备,我们需要为文本、表格和图像元素创建摘要。这些摘要将存储在向量存储中,以便在我们将输入查询传递到提示中时实现语义搜索。

文本和表格摘要

让我们开始文本和表格摘要。首先,我们将设置一个提示模板,指示AI充当专家研究助理,负责总结表格和文本。接下来,我们将创建一个链,处理每个文本和表格元素,通过这个提示和GPT-4o模型,生成简洁的摘要。

为了提高效率,我们将同时批量处理五个文本或表格元素,使用max_concurrency参数。

%pip install -q langchain langchain-chroma unstructured[all-docs] pydantic lxml langchainhub langchain-openai  
  
from langchain_core.output_parsers import StrOutputParser  
from langchain_core.prompts import ChatPromptTemplate  
from langchain_openai import ChatOpenAI  
  
## 检索器  
  
# 提示  
prompt_text = """You are an expert Research Assistant tasked with summarizing tables and texts from research articles. \   
Give a concise summary of the text. text chunk: {element} """  
  
prompt = ChatPromptTemplate.from_template(prompt_text)  
  
# 摘要链  
model = ChatOpenAI(temperature=0, model="gpt-4o")  
summarize_chain = {"element": lambda x: x} | prompt | model | StrOutputParser()  
  
# 应用于文本  
texts = [i.text for i in text_elements]  
text_summaries = summarize_chain.batch(texts, {"max_concurrency": 5})  
  
# 应用于表格  
tables = [i.text for i in table_elements]  
table_summaries = summarize_chain.batch(tables, {"max_concurrency": 5})  

图像摘要

接下来,我们将设置一些函数来帮助我们总结图像。我们将定义三个关键函数:encode_imageimage_summarizegenerate_img_summaries

  1. encode_image:此函数以二进制读取模式(‘rb’)打开图像文件,并返回其 base64 编码的字符串表示。

  2. image_summarize:此函数使用一个包含提示的 HumanMessage 对象,指示模型如何总结图像。它还包括 base64 编码的图像数据,格式为数据 URL,以便直接在内容中嵌入图像。

  3. generate_img_summaries:此函数处理给定目录中的所有 JPG 图像,为每个图像生成摘要,并返回 base64 编码的图像。

这些函数将使我们能够高效地总结和处理图像,将其无缝集成到我们的多模态 RAG 应用中。

以下是完整代码:

## getting image summaries  
import base64  
import os  
  
from langchain_core.messages import HumanMessage  
  
  
def encode_image(image_path):  
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值