2026年7月2日 周四晚上19:30,报名腾讯会议了解“如何构建自进化的动态知识库(Brain)”(限30人)
免费POC, 零成本试错
FDE知识库

FDE知识库

学习大模型的前沿技术与行业落地应用


收藏

视觉文档多模态RAG系统构建-Step by Step(附完整代码)

发布日期:2024-08-17 06:33:53 浏览次数: 3517
作者:颠覆式创新

微信搜一搜,关注“颠覆式创新”

导言

RAG是使用大模型,同时避免大模型幻觉, 且解决垂直业务领域的高效方式,而多模态的RAG构建又是融合多种数据, 包括音频,视频,文档的信息和知识构建RAG的有效手段,本文介绍了视觉文档多模态RAG系统的构建方式, 并附上完整代码。

通过阅读本文,你能够了解:

  1. 如何构建增加视觉文档的多模态RAG

  2. 获取完整代码


关注公众号,复制"视觉多模态RAG源码下载"并后台发送,取 完整代码

概述

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

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

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

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

  3. Streamlit用户界面:通过Streamlit应用程序演示该应用程序。


为什么要阅读本文?

你是否对利用像GPT-4o这样的先进基础模型的多模态能力来构建自己的AI应用程序感兴趣?那么你需要阅读该文章。    

无论您是一名市场营销专业人士,寻求从市场研究报告中获取见解,还是一名医疗从业者分析多模态医疗文件,或者一名法律专业人士处理复杂的法律文件,本文都为提供了宝贵的见解。

我将对每个概念进行彻底解释,并提供所有代码的详细解释。

多模态 RAG 的崛起

从基于文本的 RAG 模型向多模态 RAG 系统的转变代表了人工智能能力的重大飞跃。以下是一个快速概述:

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

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

  3. 新可能性:这种演变使得更全面和具有上下文丰富的人工智能应用成为可能。    

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

目录

  1. 设置虚拟环境并安装Python库

  2. 预处理非结构化数据

  3. 文本、表格和图像摘要

  4. 多模态检索器

  5. 多模态RAG链

  6. LLM评估

  7. 使用Streamlit的用户界面


设置虚拟环境并安装Python库

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

python3.10 -m venv venv


现在,让我们安装必要的包。您可以在GitHub存储库的主目录中的'requirements.txt'中找到它们。

pip install -r requirements.txt


现在,打开一个jupyter笔记本,比如说"your-project.ipynb"来开始编写您的代码。就是这样!我们现在已经准备好进入主要细节了。

这是多模式RAG项目的GitHub存储库:

GitHub - bhargobdeka/advanced-RAG-app: This repository will consist of advanced RAG applications.    

预处理非结构化数据

构建 RAG 应用程序的第一步是将上下文加载到数据库中,在这种情况下是使用 PDF 文档。

由于大型语言模型(LLM)的上下文窗口限制,我们无法直接将整个文档存储并传递到提示符中。这样做很可能会导致错误,因为它超过了最大token数。

为了克服这个问题,我们将从文档中提取不同的元素 - 图像、文本和表格。对于这个任务,我们将使用 Unstructured 库。

安装

首先,让我们安装该软件包(如果尚未通过pip安装)


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


请注意,系统中还需要 'tesseract' 和 'poppler' 库,以便无结构库能够处理文本提取以及从图像中提取文本。您可以使用 homebrew 安装这两个软件包(参见注释行)。

分区和分块


from unstructured.partition.pdf import partition_pdf


elements = partition_pdf(filename="TAGIV.pdf", # mandatorystrategy="hi_res", # mandatory to use ``hi_res`` strategyextract_images_in_pdf=True,# mandatory to set as ``True``extract_image_block_types=["Image", "Table"],# optionalextract_image_block_to_payload=False,# optionalextract_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)Output:# 文档中的不同类别category_counts = {}
for element in chunks:category = str(type(element))if category in category_counts:category_counts[category] += 1else:category_counts[category] = 1{"": 200, "": 3, "": 2}


分块显示有三个唯一的类别:

•CompositeElements

•Table

•TableChunk

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

文档中有四个表,只有三个被完全解析。?

过滤

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


from pydantic import BaseModelclass Element(BaseModel):type: strtext: 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 StrOutputParserfrom langchain_core.prompts import ChatPromptTemplatefrom langchain_openai import ChatOpenAI

检索器

提示

prompt_text = """您是一名专家研究助理,负责总结研究文章中的表格和文本。给出文本的简洁总结。文本块:{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})Apply to tablestables = [i.text for i in table_elements]table_summaries = summarize_chain.batch(tables, {"max_concurrency": 5})


           
图像摘要            
           

接下来,我们将设置函数来帮助我们总结我们的图像。我们将定义三个关键函数:`encode_image`,`image_summarize` 和 `generate_img_summaries`。            
           
1. encode_image:此函数以二进制读取模式('rb')打开图像文件,并返回其 base64 编码的字符串表示。            
           
2. image_summarize:此函数使用包含指示模型如何总结图像的提示的 HumanMessage 对象。它还包括 base64 编码的图像数据,格式化为数据 URL 以直接嵌入内容中的图像。            
           
3. generate_img_summaries:此函数处理给定目录中的所有 JPG 图像,为每个图像生成摘要并返回 base64 编码的图像。            
           
这些函数将使我们能够高效地总结和处理图像,并将它们无缝集成到我们的多模态 RAG 应用程序中。            
           
以下是完整的代码:
           
                    

## 获取图像摘要import base64import osfrom langchain_core.messages import HumanMessage
def encode_image(image_path):"""获取base64字符串"""with open(image_path, "rb") as image_file:return base64.b64encode(image_file.read()).decode("utf-8")def image_summarize(img_base64, prompt):"""生成图像摘要"""chat = ChatOpenAI(model="gpt-4o", max_tokens=1024)
msg = chat.invoke([HumanMessage(content=[{"type": "text", "text": prompt},{"type": "image_url","image_url": {"url": f"data:image/jpg;base64,{img_base64}"},},])])return msg.content
def generate_img_summaries(path):"""生成图像摘要和base64编码字符串path: 通过Unstructured提取的.jpg文件列表的路径"""
# 存储base64编码的图像img_base64_list = []
# 存储图像摘要image_summaries = []
# 提示prompt = """您是一名助手,负责为检索摘要图像。\这些摘要将被嵌入并用于检索原始图像。\给出一份简洁的图像摘要,以便更好地进行检索。"""
# 应用于图像for img_file in sorted(os.listdir(path)):if img_file.endswith(".jpg"):img_path = os.path.join(path, img_file)base64_image = encode_image(img_path)img_base64_list.append(base64_image)image_summaries.append(image_summarize(base64_image, prompt))
return img_base64_list, image_summaries





fpath = "saved_images" 图像摘要img_base64_list, image_summaries = generate_img_summaries(fpath)


多模态检索器

有了我们的摘要准备好了,我们可以创建我们的多模态检索器。

多向量检索器

我们将建立一个多向量检索器,它接受向量存储、文档存储、id_key 和 search_kwargs 作为输入。这种方法允许我们单独索引内容摘要,同时存储原始内容,从而实现高效的检索。请注意,这只是执行多模态 RAG 的一种方式;另一种方法可能涉及使用多模态嵌入来使用CLIP嵌入文本和图像,然后将原始图像和文本块传递给多模态 LLM。我可能会在未来的博客文章中探索这一点。?

我们的检索器利用 Chroma 向量存储来存储内容摘要的嵌入,并使用 InMemoryStore 来存储完整内容。这种设置使得通过摘要进行语义搜索,同时在需要时检索相应的完整内容成为可能。每个文档都使用 UUID 分配一个唯一标识符,这是检索器所必需的。

为了简化向向量存储添加摘要和向文档存储添加原始内容的过程,我们将添加一个名为 add_documents 的辅助函数。该函数确保只添加可用的摘要。


import uuid
from langchain.retrievers.multi_vector import MultiVectorRetriever from langchain.storage import InMemoryStorefrom langchain_chroma import Chromafrom langchain_core.documents import Documentfrom langchain_openai import OpenAIEmbeddingsdef create_multi_vector_retriever(vectorstore, text_summaries, texts, table_summaries, tables, image_summaries, images):"""创建检索器,索引摘要,但返回原始图像、表格或文本"""


# 初始化存储层store = InMemoryStore()id_key = "doc_id"
# 创建多向量检索器retriever = MultiVectorRetriever(vectorstore=vectorstore,docstore=store,id_key=id_key,search_kwargs={"k": 2}# 限制为前 2 个结果)
# 添加文档到向量存储和文档存储的辅助函数def add_documents(retriever, doc_summaries, doc_contents):doc_ids = [str(uuid.uuid4()) for _ in doc_contents]summary_docs = [Document(page_content=s, metadata={id_key: doc_ids[i]}) for i, s inenumerate(doc_summaries)]retriever.vectorstore.add_documents(summary_docs)retriever.docstore.mset(list(zip(doc_ids, doc_contents)))


# 添加文本、表格和图像# 在添加之前检查 text_summaries 不为空if text_summaries:add_documents(retriever, text_summaries, texts)# 在添加之前检查 table_summaries 不为空if table_summaries:add_documents(retriever, table_summaries, tables)# 在添加之前检查 image_summaries 不为空if image_summaries:add_documents(retriever, image_summaries, images)


return retriever


创建检索器


# 用于索引摘要的向量存储vectorstore = Chroma(collection_name="mm_tagiv_paper", embedding_function=OpenAIEmbeddings())


# 创建检索器retriever_multi_vector_img = create_multi_vector_retriever(vectorstore,text_summaries,texts,table_summaries,tables,image_summaries,img_base64_list,)

             
               
测试以及完整代码              
               

代码组织结构如下:

advanced-RAG-app/              
             
├── utils/              
│ ├── __init__.py              
│ ├── image_processing.py              
│ ├── rag_chain.py              
│ ├── rag_evaluation.py              
│ └── retriever.py              
             
└── main.py              
└── requirements.txt

关注公众号,复制"视觉多模态RAG源码下载"并后台发送,取 完整代码

53AI,企业落地大模型首选服务商

产品:场景落地咨询+大模型应用平台+行业解决方案

承诺:免费POC验证,效果达标后再合作。零风险落地应用大模型,已交付160+中大型企业

联系我们

售前咨询
186 6662 7370
预约演示
185 8882 0121

微信扫码

添加专属顾问

回到顶部

加载中...

扫码咨询

扫码登录
登录即表示您同意《53AI网站服务协议》
服务协议

欢迎您使用【53AI 官方网站】(以下简称“本网站”或“我们”)。本《会员服务协议》(以下简称“本协议”)是您(以下简称“会员”或“用户”)与【深圳市博思协创网络科技有限公司】之间关于注册、登录及使用本网站会员服务所订立的法律协议。

在您注册或登录前,请务必审慎阅读、充分理解各条款内容,特别是免除或限制责任的条款、知识产权条款、争议解决条款等。此类条款将以加粗形式提示您注意。 当您通过微信公众号授权、手机验证码验证或其他方式成功登录本网站时,即视为您已完全理解并同意接受本协议的全部内容。

一、 定义

本网站:指由【深圳市博思协创网络科技有限公司】运营的,域名为【53ai.com】的网站及相关移动端页面。

会员服务:指本网站向注册会员提供的知识库文章查阅、内容检索及其他相关增值服务。

知识库内容:指本网站发布的包括但不限于文字、图表、数据、研究报告、行业分析等数字化内容资源。

二、 账号注册与登录

登录方式:本网站支持以下登录方式,您可根据实际情况选择:

微信公众号授权登录:您同意将您的微信OpenID信息授权给本网站,用于创建或关联会员账号。

手机验证码登录:您需提供真实有效的手机号码,并通过短信验证码完成身份验证与登录/注册。

账号安全:您的账号仅限您本人使用,禁止赠与、借用、租用、转让或售卖。因您保管不善导致的账号被盗、密码泄露等损失,由您自行承担。

实名认证:根据相关法律法规要求,我们可能要求您在特定功能下完成实名认证。如您拒绝提供,可能无法使用部分或全部服务。

未成年人保护:若您未满18周岁,请在法定监护人的陪同下阅读本协议,并在征得监护人同意后使用本服务。

三、 服务内容与规范

知识库查阅权限:会员登录后,有权按照其会员等级对应的权限范围,在线浏览、检索本网站知识库中的相关文章及内容。

服务变更:我们有权根据业务发展需要,调整、变更或终止部分服务内容,并将以网站公告、公众号消息等方式提前通知。

禁止行为:您在使用服务时不得实施以下行为:

利用技术手段批量爬取、下载、转存知识库内容;

将知识库内容用于商业目的或未经授权地向第三方传播;

干扰本网站正常运行或侵犯其他用户合法权益;

发布违法违规信息或从事违反公序良俗的活动。

四、 知识产权声明

权利归属:本网站知识库中的排版设计、软件代码等内容的知识产权均归【公司全称】或原权利人所有,受《中华人民共和国著作权法》等法律保护。

有限许可:本网站授予会员一项非独占、不可转让、不可转授权的普通许可,仅限于个人学习、研究之目的在线查阅知识库内容。

侵权追责:未经书面许可,任何单位或个人不得以任何形式复制、转载、摘编、镜像、汇编或以其他方式使用上述内容。一经发现,我们保留追究其法律责任的权利。

五、 个人信息保护

我们重视对您个人信息的保护。关于我们如何收集、使用、存储和保护您的个人信息,请单独阅读 《隐私政策》。

您通过微信公众号授权或手机号验证所提供的信息,我们将严格按照《个人信息保护法》的规定处理,仅用于身份识别、服务提供及安全验证等必要用途。

您可以随时通过网站设置或联系客服行使查阅、更正、删除个人信息及撤回授权同意的权利。

六、 免责声明

内容准确性:知识库内容仅供参考,不构成专业建议。我们不对其完整性、准确性、时效性作任何明示或暗示的保证,您应自行判断并承担使用风险。

不可抗力:因自然灾害、政策法规变化、网络故障、第三方平台接口异常(如微信接口维护、运营商短信通道故障)等不可抗力导致的服务中断或延迟,我们不承担违约责任。

第三方链接:本网站可能包含指向第三方网站的链接,该等网站的内容和服务不受我们控制,请您自行甄别风险。

七、 违约责任

如您违反本协议约定,我们有权视情节采取警告、限制功能、暂停服务、注销账号等措施,并保留要求赔偿损失的权利。

如因您的违约行为导致我们遭受行政处罚、第三方索赔或商誉损失,您应承担全部赔偿责任(包括但不限于罚款、赔偿金、律师费、公证费等)。

八、 法律适用与争议解决

本协议的订立、执行和解释均适用中华人民共和国大陆地区法律。

因本协议产生的或与本协议有关的任何争议,双方应友好协商解决;协商不成的,任何一方均可向【公司所在地】有管辖权的人民法院提起诉讼。

九、 其他

本协议构成双方就本服务达成的完整协议,取代此前任何口头或书面约定。

本协议任一条款被认定为无效或不可执行的,不影响其他条款的效力。

我们对本协议享有最终解释权,并在法律允许的范围内保留随时修改的权利。修改后的协议一经公布即生效,继续使用服务即视为同意修订内容。


已查阅