LLM之RAG实战(八)| 使用Neo4j和LlamaIndex实现多模态RAG

       人工智能和大型语言模型领域正在迅速发展。一年前,没有人使用LLM来提高生产力。时至今日,很难想象我们大多数人或多或少都在使用LLM提供服务,从个人助手到文生图场景。由于大量的研究和兴趣,LLM每天都在变得越来越好、越来越聪明。不仅如此,他们的理解也开始跨越多种模态。随着GPT-4-Vision和随后的其他LLM的引入,今天的LLM似乎可以很好地处理和理解图像。以下是ChatGPT描述图像中内容的一个示例。

       正如所观察到的,ChatGPT非常善于理解和描述图像。我们可以在RAG应用程序中使用其理解图像的能力,在该应用程序中,我们现在可以将文本和图片中的信息结合起来,生成比以往任何时候都更准确的答案,而不仅仅依靠文本来生成准确和最新的答案。使用LlamaIndex,实现多模态RAG pipeline非常容易。受(https://github.com/run-llama/llama_index/blob/main/docs/examples/multi_modal/gpt4v_multi_modal_retrieval.ipynb)的启发,来测试是否可以使用Neo4j作为数据库来实现多模态RAG应用程序。

       要使用LlamaIndex实现多模态RAG管道,只需实例化两个矢量存储,一个用于图像,另一个用于文本,然后查询这两个矢量,以便检索相关信息以生成最终答案。

       多模态RAG首先需要将数据分为图像和文本,然后分别进行embedding并单独构建索引。对于文本,我们将使用ada-002文本嵌入模型;而对于图像,我们将采用[双编码器模型CLIP](https://github.com/openai/CLIP),CLIP可以将文本和图像嵌入到同一嵌入空间中。当最终用户提出问题时,执行两个向量的相似性搜索:一个用于查找相关图像,另一个用于文档。结果被输入到多模态LLM中,该LLM为用户生成答案,展示了处理和利用混合媒体进行信息检索和响应生成的综合方法。

数据预处理

        我们将使用[Medium](https://github.com/tomasonjo/blog-datasets/blob/main/articles.zip)作为RAG应用程序的基础数据集。这些文章包含了关于Neo4j图形数据科学库以及将Neo4j与LLM框架相结合的大量信息。从Medium下载的文章是HTML格式。因此,我们需要使用一些编码来分别提取文本和图像。

def process_html_file(file_path):    with open(file_path, "r", encoding="utf-8") as file:        soup = BeautifulSoup(file, "html.parser")    # Find the required section    content_section = soup.find("section", {"data-field": "body", "class": "e-content"})    if not content_section:        return "Section not found."    sections = []    current_section = {"header": "", "content": "", "source": file_path.split("/")[-1]}    images = []    header_found = False    for element in content_section.find_all(recursive=True):        if element.name in ["h1", "h2", "h3", "h4"]:            if header_found and (current_section["content"].strip()):                sections.append(current_section)            current_section = {                "header": element.get_text(),                "content": "",                "source": file_path.split("/")[-1],            }            header_found = True        elif header_found:            if element.name == "pre":                current_section["content"] += f"```{element.get_text().strip()}```\n"            elif element.name == "img":                img_src = element.get("src")                img_caption = element.find_next("figcaption")                caption_text = img_caption.get_text().strip() if img_caption else ""                images.append(ImageDocument(image_url=img_src))            elif element.name in ["p", "span", "a"]:                current_section["content"] += element.get_text().strip() + "\n"    if current_section["content"].strip():        sections.append(current_section)    return images, sections

       不会详细介绍解析代码,但我们根据标题h1–h4分割文本并提取图像链接。然后,我们只需通过此函数运行所有文章,即可提取所有相关信息。

all_documents = []all_images = []# Directory to search in (current working directory)directory = os.getcwd()# Walking through the directoryfor root, dirs, files in os.walk(directory):    for file in files:        if file.endswith(".html"):            # Update the file path to be relative to the current directory            images, documents = process_html_file(os.path.join(root, file))            all_documents.extend(documents)            all_images.extend(images)text_docs = [Document(text=el.pop("content"), metadata=el) for el in all_documents]print(f"Text document count: {len(text_docs)}") # Text document count: 252print(f"Image document count: {len(all_images)}") # Image document count: 328

       总共得到252个文本块和328个图像。

对数据创建索引

       如前所述,我们必须实例化两个矢量存储,一个用于图像,另一个用于文本。CLIP嵌入模型的尺寸为512,而ada-002的尺寸为1536。

text_store = Neo4jVectorStore(    url=NEO4J_URI,    username=NEO4J_USERNAME,    password=NEO4J_PASSWORD,    index_name="text_collection",    node_label="Chunk",    embedding_dimension=1536)image_store = Neo4jVectorStore(    url=NEO4J_URI,    username=NEO4J_USERNAME,    password=NEO4J_PASSWORD,    index_name="image_collection",    node_label="Image",    embedding_dimension=512)storage_context = StorageContext.from_defaults(vector_store=text_store)

      现在向量索引已经创建好了,我们使用MultiModalVectorStoreIndex来索引这两种模态的信息。

# Takes 10 min without GPU / 1 min with GPU on Google collabindex = MultiModalVectorStoreIndex.from_documents(    text_docs + all_images, storage_context=storage_context, image_vector_store=image_store)

       MultiModalVectorStoreIndex使用文本和图像嵌入模型来计算嵌入,并在Neo4j中存储和索引结果。仅为图像存储URL,而不是实际的base64或图像的其他表示。

多模态RAG pipeline

       这段代码是直接从LlamaIndex多模式烹饪书中复制的。我们首先定义一个多模态LLM和prompt template,然后将所有内容组合为一个查询引擎。

openai_mm_llm = OpenAIMultiModal(    model="gpt-4-vision-preview", max_new_tokens=1500)qa_tmpl_str = (    "Context information is below.\n"    "---------------------\n"    "{context_str}\n"    "---------------------\n"    "Given the context information and not prior knowledge, "    "answer the query.\n"    "Query: {query_str}\n"    "Answer: ")qa_tmpl = PromptTemplate(qa_tmpl_str)query_engine = index.as_query_engine(    multi_modal_llm=openai_mm_llm, text_qa_template=qa_tmpl)

       现在我们可以继续测试它的性能了。

query_str = "How do vector RAG application work?"response = query_engine.query(query_str)print(response)

        我们还可以可视化检索提取的图像以及用于帮助提供最终答案的图像。

       LLM得到了两个相同的图像作为输入,说明数据集中有重复的图。然而,我对CLIP嵌入感到惊喜,因为他们能够检索到该系列中最相关的图像。在生产环境中,一般需要对数据做预处理,去除重复数据,本文不做此介绍。

结论

       LLM的发展速度比我们历史上习惯的要快,并且跨越了多种模态。我坚信,到明年年底,LLM将很快能够理解视频,因此能够在与你交谈时获得非语言提示。另一方面,我们可以使用图像作为RAG管道的输入,并增强传递给LLM的各种信息,使响应更好、更准确。使用LlamaIndex和Neo4j实现多模式RAG管道非常简单。

参考文献:

[1] https://blog.llamaindex.ai/multimodal-rag-pipeline-with-llamaindex-and-neo4j-a2c542eb0206

[2] https://github.com/tomasonjo/blogs/blob/master/llm/neo4j_llama_multimodal.ipynb

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

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

相关文章

网站使用https认证

随着网络的普及和依赖程度的增加,网站安全性问题也日益凸显。为了确保用户和网站之间的数据传输安全,采用HTTPS认证已经变得至关重要。 1.数据安全是首要任务 在互联网上,信息传输是网站运作的基础。然而,未加密的传输容易受到中…

计算机网络——计算机网络的概述(一)

前言: 面对马上的期末考试,也为了以后找工作,需要掌握更多的知识,而且我们现实生活中也已经离不开计算机,更离不开计算机网络,今天开始我们就对计算机网络的知识进行一个简单的学习与记录。 目录 一、什么…

案例136:基于微信小程序的公交信息在线查询系统

文末获取源码 开发语言:Java 框架:SSM JDK版本:JDK1.8 数据库:mysql 5.7 开发软件:eclipse/myeclipse/idea Maven包:Maven3.5.4 小程序框架:uniapp 小程序开发软件:HBuilder X 小程序…

使用Velero备份、恢复k8s集群上的资源

一、Velero简介 Velero提供备份和恢复 Kubernetes 集群资源和持久卷的工具。 Velero功能: 对群集进行备份,并在丢失时进行还原。将集群资源迁移到其他集群。 Velero 包括: 在群集上运行的服务器在本地运行的命令行客户端 开源地址&…

【终极教程】Cocos2dx服务端重构(优化cocos2dx服务端)

文章目录 概述问题概述1. 代码混淆代码加密具体步骤测试和配置阶段IPA 重签名操作步骤2. 缺乏文档3. 缺乏推荐的最佳实践4. 性能问题 总结 概述 Cocos2dx是一个非常流行的跨平台游戏引擎,开发者可以使用这个引擎来开发iOS、Android和Web游戏。同时,Coco…

SSTI模板注入(Flask+Jinja2)

文章目录 一、前置知识1.1 模板引擎1.2 渲染 二、SSTI模板注入2.1 原理2.2 沙箱逃逸沙箱逃逸payload讲解其他重要payload 2.3 过滤绕过 三、PasecaCTF-2019-Web-Flask SSTI 一、前置知识 1.1 模板引擎 模板引擎(这里特指用于Web开发的模板引擎)是为了使…

nodejs+vue+ElementUi会员制停车场车位系统

总之,智能停车系统使停车场管理工作规范化,系统化,程序化,避免停车场管理的随意性,提高信息处理的速度和准确性,能够及时、准确、有效的查询和修改停车场情况。 三、任务:小组任务和个人任务 智…

Linux中vim中进行替换/批量替换

Linux中vim中进行替换/批量替换 一:在 Vim 中进行文本替换的操作是通过使用 :s(substitute)命令来实现的。这里是一些基本的替换命令 替换当前行的第一个匹配项: :s/old/new/这将替换当前行中第一个出现的 “old” 为 “new”。 替换当前行的所有匹配项…

工作实践篇 Flink(一:flink提交jar)

一:参数 flink 模式 – standalone 二:步骤 1. 将本地测试好的代码进行本地运行。确保没问题,进行打包。 2. 找到打好的jar包,将jar包上传到对应的服务器。 3. 执行flink命令,跑代码。 /opt/flink/flink-1.13.6/bi…

ASP.Net实现姓名添加查询(三层架构)

目录 演示功能: 点击启动生成页面 点击搜索模糊查询 点击添加跳转新界面 点击Button添加姓名 步骤: 1、建文件 2、添加引用关系 3、根据数据库中的列写Models下的XueshengModels类 4、DAL下的DBHelper(对数据库进行操作)…

轻量Http客户端工具VSCode和IDEA

文章目录 前言Visual Studio Code 的插件 REST Client编写第一个案例进阶,设置变量进阶,设置Token 前言 作为一个WEB工程师,在日常的使用过程中,HTTP请求是必不可少的。我们采用的HTTP工具有如下: Postman Insomnia Ap…

MyBatis见解3

8.MyBatis的关联查询 8.3.一对多查询 需求:查询所有用户信息及用户关联的账户信息。 分析:用户信息和他的账户信息为一对多关系,并且查询过程中如果用户没有账户信息,此时也要将用户信息查询出来,此时左外连接查询比…

Spring和Spring Boot框架中怎么理解Bean这个核心概念

在Spring和Spring Boot框架中,Bean是一个核心概念。要理解Spring Boot中的Bean,我们可以从以下几个方面进行: 定义: Bean是Spring框架中的一个对象,由Spring容器管理。当我们在应用程序中需要某个对象时,我…

Deepin更换仿Mac主题

上一篇博客说了要写一篇deepin系统的美化教程 先看效果图: 准备工作: 1.你自己 嘻嘻嘻 2.能上网的deepin15.11电脑 首先去下载主题 本次需要系统美化3部分:1.图标 2.光标 3.壁纸 开始之前,请先把你的窗口特效打开,…

华为设备命令行操作基础

熟悉VRP命令行并且熟练掌握VRP配置是高效管理华为网络设备的必备基础。 设备初始化启动 管理员和工程师如果要访问在通用路由平台VRP上运行的华为产品,首先要进入启动程序。开机界面信息提供了系统启动的运行程序和正在运行的VRP版本及其加载路径。启动完成以后&am…

spring aop实际开发中怎么用,Spring Boot整合AOP,spring boot加spring mvc一起使用aop,项目中使用aop

前言:本文不介绍 AOP 的基本概念、动态代理方式实现 AOP,以及 Spring 框架去实现 AOP。本文重点介绍 Spring Boot 项目中如何使用 AOP,也就是实际项目开发中如何使用 AOP 去实现相关功能。 如果有需要了解 AOP 的概念、动态代理实现 AOP 的&…

【PHP手麻系统源码】基于mysql+laravel+vue开发的医院手术麻醉系统源码,实现围术期患者数据的自动采集与共享

手麻系统作为医院信息化系统的一环,由监护设备数据采集系统和麻醉信息管理系统两个子部分组成。手麻信息系统覆盖了患者术前、术中、术后的手术过程,可以实现麻醉信息的电子化和手术麻醉全过程动态跟踪。 以服务围术期临床业务工作的开展为核心&#xf…

分布式搜索elasticsearch概念

什么是elasticsearch? elasticsearch是一款非常强大的开源搜索引擎,可以帮助我们从海量数据中快速找到需要的内容 目录 elasticsearch的场景 elasticsearch的发展 Lucene篇 Elasticsearch篇 elasticsearch的安装 elasticsearch的场景 elasticsear…

BigQuery 分区表简介和使用

大纲 什么是分区表 我们先看定义: 分区表是一种数据库表设计和管理技术,它将表中的数据划分为逻辑上的多个分区,每个分区包含一组特定的数据。每个分区都根据定义的分区键(通常是一个列或字段)的值进行分类&#xff…

构建创新学习体验:企业培训系统技术深度解析

企业培训系统在现代企业中发挥着越来越重要的作用,它不仅仅是传统培训的延伸,更是技术创新的结晶。本文将深入探讨企业培训系统的关键技术特点,并通过一些简单的代码示例,展示如何在实际项目中应用这些技术。 1. 前端技术&#…