LLM之RAG实战(三十六)| 使用LangChain实现多模态RAG

       我们之前介绍的RAG,更多的是使用输入text来查询相关文档。在某些情况下,信息可以出现在图像或者表格中,然而,之前的RAG则无法检测到其中的内容。

      针对上述情况,我们可以使用多模态大模型来解决,比如GPT-4-Vision,它有非常好的图像理解能力,可以理解图像内部发生的事情。

       现在的问题与我们如何从矢量数据库中检索正确的图像。我们可以参考LangChain博客[1]中两种实现多模态RAG方法。

两种方法如下所示:

  1. Multimodal Embedding (using Open Clip Embedding)

  2. Multi-vector retriever with image summary

一、多模态嵌入(使用CLIP Embedding)

       根据langchain博客[1],多模态嵌入方法的准确率仅为60%,而多向量检索方法的准确率约为90%。然而,多模态嵌入方法非常划算,因为只调用一次GPT-4-Vision。

       对于多模态嵌入方法,我们需要使用Open CLIP Embeddings。CLIP(对比语言-图像预训练)是Open AI于2021年开发的一个嵌入模型,是一个在同一空间共享文本和图像嵌入的嵌入模型。

       多模态嵌入与其他RAG系统类似,现在唯一的区别是图像也嵌入了这个矢量数据库中。但是,这个模型不足以解释图像中的信息,例如,在某些情况下,图像中存在与数字相关的信息,或者数据库中的图像类型相似,嵌入无法从数据库中检索相关图像。

完整的代码可以参考langchain cookbook[2],下图是整体架构图:

下面稍微介绍一下几个关键步骤:

步骤1:从PDF中提取图像

       使用unstructured库抽取PDF信息,并创建一个文本和图像列表。提取的图像需要存储在特定的文件夹中。

# Extract images, tables, and chunk textfrom unstructured.partition.pdf import partition_pdfraw_pdf_elements = partition_pdf(    filename="LCM_2020_1112.pdf",    extract_images_in_pdf=True,    infer_table_structure=True,    chunking_strategy="by_title",    max_characters=4000,    new_after_n_chars=3800,    combine_text_under_n_chars=2000,    image_output_dir_path=path,)

步骤2:创建矢量数据库

        准备矢量数据库,并将图像URI和文本添加到矢量数据库中。

# Create chromavectorstore = Chroma(    collection_name="mm_rag_clip_photos", embedding_function=OpenCLIPEmbeddings())# Get image URIs with .jpg extension onlyimage_uris = sorted(    [        os.path.join(path, image_name)        for image_name in os.listdir(path)        if image_name.endswith(".jpg")    ])print(image_uris)# Add imagesvectorstore.add_images(uris=image_uris)# Add documentsvectorstore.add_texts(texts=texts)

步骤3:QnA管道

       最后一部分是Langchain QnA管道。

chain = (    {        "context": retriever | RunnableLambda(split_image_text_types),        "question": RunnablePassthrough(),    }    | RunnableLambda(prompt_func)    | model    | StrOutputParser())

      如上面的脚本所示,有两个重要的自定义函数在这个管道中发挥着重要作用,分别是:split_image_text_types和prompt_func。

       对于split_image_text_types函数,使用CLIP嵌入获取相关图像后,还需要将图像转换为base64格式,因为GPT-4-Vision的输入是base64格式。

       prompt_func函数是描述如何构建prompt工程。在这里,我们将“问题”和“base64图像”放在提示中。

二、带图像摘要的多向量检索器

       根据langchain的观察结果,该方法比多模态嵌入方法的准确性更高,它使用GPT-4V提取摘要。

      如果使用多矢量方法摘要时,需要提交文档中的所有图片进行摘要。当在矢量数据库中进行相似性搜索时,图像的摘要文本也可以提供信息。

       一般来说,摘要用于查找相关图像,相关图像输入到多模态LLM以回答用户查询。这两条信息需要分开,这就是为什么我们在这种情况下使用多向量检索器[3]的原因。

优点:图像检索精度高

缺点:这种方法非常昂贵,因为GPT-4-Vision非常昂贵,尤其是如果你想总结许多图像,如果你有成本问题,可能会是一个问题。

完整的代码可以参考langchain cookbook[4],下图是整体架构图:

       该方法也可以很好地回答图像中的问题,唯一的问题是整个过程比较缓慢,大概是因为GPT-4-Vision需要时间来处理整个事情。

下面稍微介绍一下几个关键步骤:

步骤1:提取图像

该步骤与上述多模态嵌入方法类似。

步骤2:生成文本和图像摘要

     使用generate_text_summarys和generate_mg_summarys函数生成每个文本和图像的摘要。数据结构,如下所示:

{"input":text, "summary":text_summaries}, {"input":table, "summary":table_summaries},{"input":image_base64, "summary":image_summaries }

        此结构将添加到多矢量检索器中。

步骤3:创建多矢量检索器

      使用下面的python脚本将上述数据结构添加到多向量检索器中,我们还需要指定矢量数据库。

# The vectorstore to use to index the summariesvectorstore = Chroma(    collection_name="mm_rag_cj_blog", embedding_function=OpenAIEmbeddings())# Create retrieverretriever_multi_vector_img = create_multi_vector_retriever(    vectorstore,    text_summaries,    texts,    table_summaries,    tables,    image_summaries,    img_base64_list,)

     使用create_multi_vector_requirer函数初始化多向量。langchain中的MultiVectorRetriever是一个创建多向量检索器的类,在这里我们需要添加向量存储、文档存储和key_id作为输入。

      该案例中,我们的文档存储设置为InMemoryStore,将不会持久化。因此需要使用另一个langchain存储类来使其持久化,可以参考[5]。

       docstore很重要,它存储我们的图像和文本,而不是摘要。摘要存储在矢量存储中。

def create_multi_vector_retriever(    vectorstore, text_summaries, texts, table_summaries, tables, image_summaries, images):    """    Create retriever that indexes summaries, but returns raw images or texts    """    # Initialize the storage layer    store = InMemoryStore()    id_key = "doc_id"    # Create the multi-vector retriever    retriever = MultiVectorRetriever(        vectorstore=vectorstore,        docstore=store,        id_key=id_key,    )    # Helper function to add documents to the vectorstore and docstore    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 in enumerate(doc_summaries)        ]        retriever.vectorstore.add_documents(summary_docs)        retriever.docstore.mset(list(zip(doc_ids, doc_contents)))    # Add texts, tables, and images    # Check that text_summaries is not empty before adding    if text_summaries:        add_documents(retriever, text_summaries, texts)    # Check that table_summaries is not empty before adding    if table_summaries:        add_documents(retriever, table_summaries, tables)    # Check that image_summaries is not empty before adding    if image_summaries:        add_documents(retriever, image_summaries, images)    return retriever

步骤4:QnA管道

       最后一步与前面的方法类似。只有检索器不同,现在我们使用的是多向量检索器。

三、结论

       如果使用多模态RAG,这两种方法是合适的。其实谷歌也发布了他们的多模态嵌入[6],亚马逊也有Titan多模态嵌入[7]。相信在未来,多模态嵌入将有许多选择。

参考文献:

[1] https://blog.langchain.dev/multi-modal-rag-template/

[2] https://github.com/langchain-ai/langchain/blob/master/cookbook/multi_modal_RAG_chroma.ipynb

[3] https://python.langchain.com/docs/modules/data_connection/retrievers/multi_vector

[4] https://github.com/langchain-ai/langchain/blob/master/cookbook/Multi_modal_RAG.ipynb

[5] https://python.langchain.com/docs/integrations/stores/file_system

[6] https://cloud.google.com/vertex-ai/docs/generative-ai/embeddings/get-multimodal-embeddings

[7] https://docs.aws.amazon.com/bedrock/latest/userguide/titan-multiemb-models.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/499138.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【微服务】Sentinel(流量控制)

文章目录 1.基本介绍1.Sentinel是什么2.Sentinel主要特性3.Sentinel核心功能1.流量控制2.熔断降级3.消息削峰填谷 4.Sentinel两个组成部分 2.Sentinel控制台显示1.需求分析2.下载3.运行1.进入cmd2.输入java -jar sentinel-dashboard-1.8.0.jar3.查看默认端口8080 4.访问1.账号和…

数据结构课设-基于Python的校园导航系统(附源码)

一月份的数据结构课设完成后,我对Python的了解也更加深刻。现将课设报告及源码开源,不足之处希望大家指正。源码我放在博客主页的资源中,需要的话大家自行下载(用户信息保存在 users.json 文件中,地图信息保存在 campu…

GooglePlay无法下载应用问题

问题如下 解决方法 1、实际上是因为google尚未添加apk downloader扩展程序 2、添加该扩展程序后,在应用中搜索应用名即可 欧克!下载完成

IDEA设置内存大小不生效

IDEA设置内存大小不生效 100%可行的方法 -Xms512m -Xmx4096m1.首先要找对idea加载的是哪个配置文件。 2.找到idea启动文件夹,编辑idea.bat 添加打印修改文件路径的代码,运行idea.bat打印一下你的配置文件路径,找到路径 修改 然后运行idea.…

机器学习作业二之KNN算法

KNN(K- Nearest Neighbor)法即K最邻近法,最初由 Cover和Hart于1968年提出,是一个理论上比较成熟的方法,也是最简单的机器学习算法之一。该方法的思路非常简单直观:如果一个样本在特征空间中的K个最相似&…

vs2022 关于Python项目无法识别中文的解决方法

这是针对于vs2022安装和使用教程(详细)-CSDN博客 Python项目无法识别中文的解决方法的文章 一、问题 1.输入代码 print("你好Hello world!") 2.启动,发现代码里有中文报错 二、解决方法 1.选择菜单栏里的工具->…

超实用的Maven指南

文章目录 实战记录📝Maven 指令大全 🌟找到没有被使用的jar(analyze)分析jar是被哪个maven引入(tree)🌟 dependencies(Maven依赖)build-resources(资源导入&a…

如何提高知识库系统管理水平?

我们都有过这样的经历--遇到问题或紧急请求时,第一时间就是向知识库系统寻求帮助。很多时候,当你翻遍了无穷无尽的文档,却发现没有任何东西能够摆脱此时的困境,这时,向服务台提交工单成了不可避免的解决方式&#xff0…

基于Java的新生入学报到管理系统的设计与实现(论文+源码+PPT)_kaic

摘 要 21世纪的今天,随着社会的不断发展与进步,人们对于信息科学化的认识,已由低层次向高层次发展,由原来的感性认识向理性认识提高,管理工作的重要性已逐渐被人们所认识,科学化的管理,使信息…

2024年2月游戏手柄线上电商(京东天猫淘宝)综合热销排行榜

鲸参谋监测的线上电商(京东天猫淘宝)游戏手柄品牌销售数据已出炉!2月游戏手柄销售数据呈现出强劲的增长势头。 根据鲸参谋数据显示,今年2月游戏手柄月销售量累计约43万件,同比去年上涨了78%;销售额累计达1…

Stable Diffusion 模型分享:SDXL Unstable Diffusers ☛ YamerMIX(混合风格)

本文收录于《AI绘画从入门到精通》专栏,专栏总目录:点这里,订阅后可阅读专栏内所有文章。 文章目录 模型介绍生成案例案例一案例二案例三案例四案例五案例六案例七案例八下载地址模型介绍

每日一题 --- 快乐数[力扣][Go]

快乐数 题目:202. 快乐数 编写一个算法来判断一个数 n 是不是快乐数。 「快乐数」 定义为: 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到…

Spring用到了哪些设计模式?

目录 Spring 框架中⽤到了哪些设计模式?工厂模式单例模式1.饿汉式,线程安全2.懒汉式,线程不安全3.懒汉式,线程安全4.双重检查锁(DCL, 即 double-checked locking)5.静态内部类6.枚举单例 代理模…

AI 文字转语音工具以及它们的官网收集(值得收藏)

目前比较成熟的 AI 文字转语音工具以及它们的官网: 百度语音合成 (https://ai.baidu.com/tech/speech/tts): 百度语音合成是百度 AI 推出的语音合成服务,支持多种语言和音色,可以用于语音播报、智能客服、有声阅读等场景。 阿里云…

使用Kaggle API快速下载Kaggle数据集

前言 在使用Kaggle网站下载数据集时,直接在网页上点击下载可能会很慢,甚至会出现下载失败的情况。本文将介绍如何使用Kaggle API快速下载数据集。 具体步骤 安装Kaggle API包 在终端中输入以下命令来安装Kaggle API相关的包: pip install…

对 CSS 工程化的理解

CSS 工程化是为了解决以下问题: 宏观设计:CSS 代码如何组织、如何拆分、模块结构怎样设计?编码优化:怎样写出更好的 CSS?构建:如何处理我的 CSS,才能让它的打包结果最优?可维护性&a…

【计算机网络】第 11、12 问:流量控制和可靠传输机制有哪些?

目录 正文流量控制的基本方法停止-等待流量控制基本原理滑动窗口流量控制基本原理 可靠传输机制1. 停止-等待协议2. 后退 N 帧协议(GBN)3. 选择重传协议(SR) 正文 流量控制涉及对链路上的帧的发送速率的控制,以使接收…

哪些开放式耳机平价又好用的?五款超平价品牌推荐深度测评分享!

在当今快节奏的生活中,高品质的音频设备已成为放松身心的重要途径之一。开放式耳机,凭借其出色的音频表现和舒适的佩戴体验,正逐渐成为音乐爱好者的新选择。它们特有的开放设计不仅减轻了耳罩带来的压迫感,还使得用户仿佛置身于音…

四种常用限流算法、固定窗口限流算法、滑动窗口限流算法、漏桶限流算法和令牌桶限流算法

什么是限流? 限流可以被视为服务降级的一种形式,其核心目标是通过控制输入和输出流量来保护系统。通常,一个系统的处理能力是可以预估的,为了确保系统的稳定运行,当流量达到预定的阈值时,必须采取措施限制进…

vue中使用jsmind生成脑图

项目部分参数&#xff1a; vue&#xff1a;2.6.10 node:16.20.0 1、使用命令行安装jsmind&#xff1a; npm i jsmind -S 2、在文件中引入jsmind&#xff0c;并编写渲染jsmind的代码&#xff1a;&#xff1a; <template><!-- jsmind容器 --><divid"jsmi…