RAG技术下的文档智能检索

news2024/10/7 20:36:50

在数字化浪潮的推动下,信息检索已成为我们日常生活中不可或缺的一部分。然而,随着数据量的爆炸式增长,如何快速精准地从海量文档中检索出有价值的信息,成为了一个巨大的挑战。本文将带您走进 Pinecone 向量数据库的世界,探索如何利用这一前沿技术,结合检索增强生成(RAG)模型,实现对自定义文档的高效查询。这不仅是技术的飞跃,更是对传统检索方式的一次深刻革新。

向量数据库

向量数据库(Vector DB)现在非常流行。像 GPT-4o、Llama-3、Claude3.5 等大语言模型(LLMs)正基于专业使用案例和行业特定数据准备被行业采用。检索增强生成(RAG)—— 在推理期间将输入增强为与输入提示相关的数据,对于这些使用案例来说是一个令人兴奋的范式。

向量数据库提供了一种快速查询大量数据以找到最相关文档块的方法。与传统数据库相比,向量数据库在查询大维文本嵌入方面是高效的。

image.png

文档嵌入和标记化

首先处理文档的第一步是将其分成块,并获取每个块的嵌入。对于嵌入模型,我们使用的是北京智源人工智能研究院的嵌入模型“BGE-M3”,它是 1024 维的。

接下来,我们定义分块中允许的最大 Token。每个 Token 约为一个词的 3/4。通常,正确的数量是一个探索点,只能通过反复试验找到。如果预期答案遍布文档中的小文本部分,则较小的分块尺寸效果更好。较大的分块则更适合于更长、更详细的描述。较大的分块会倾向于从一个或几个较长的部分检索数据,而较短的部分则会偏向于具有有限上下文的较短文本片段。

python
复制代码
def get_embedding(text, model="BAAI/bge-m3"):
    # 替换换行符为空格
    text = text.replace("\n", " ")
    # 使用指定模型获取嵌入
    return client.embeddings.create(input=[text], model=model).data[0].embedding

def tokenize(text, max_tokens) -> pd.DataFrame:
    """ 将文本拆分为最大令牌数的块 """

    # 加载适用于bge-m3模型的分词器
    tokenizer = tiktoken.get_encoding("cl100k_base")

    df = pd.DataFrame({'title': ['0'], 'text': [text]})

    # 对文本进行分词,并保存令牌数量到新列中
    df['n_tokens'] = df.text.apply(lambda x: len(tokenizer.encode(x)))

    shortened = []

    # 遍历数据框
    for _, row in df.iterrows():
        # 如果文本为空,跳到下一行
        if row['text'] is None:
            continue

        # 如果令牌数大于最大令牌数,将文本拆分为多个块
        if row['n_tokens'] > max_tokens:
            shortened += split_into_many(row['text'], tokenizer, max_tokens)
        else:
            shortened.append(row['text'])

    df = pd.DataFrame(shortened, columns=['text'])
    df['n_tokens'] = df.text.apply(lambda x: len(tokenizer.encode(x)))
    df['embeddings'] = df.text.apply(lambda x: get_embedding(x))

    return df

def split_into_many(text: str, tokenizer: tiktoken.Encoding, max_tokens: int = 1024) -> list:
    """ 将字符串拆分为指定数量令牌的多个字符串 """

    # 将文本拆分为句子
    sentences = text.split(' ')

    # 获取每个句子的令牌数
    n_tokens = [len(tokenizer.encode(" " + sentence)) for sentence in sentences]

    chunks = []
    tokens_so_far = 0
    chunk = []

    # 遍历句子和令牌数的元组
    for sentence, token in zip(sentences, n_tokens):
        chunk.append(sentence)
        tokens_so_far += token + 1

        # 如果令牌数加上当前句子的令牌数大于最大令牌数,将块添加到块列表中并重置
        if tokens_so_far + token > max_tokens:
            chunks.append(" ".join(chunk))
            chunk = []
            tokens_so_far = 0

    return chunks

df = tokenize(text, 100)

这里是一个最大块大小为 100 个标记的示例数据框架:

image.png

创建向量数据库索引并上传数据

创建了数据框架后,就可以为嵌入创建索引,并将它们上传到 Pinecone 数据库中。这里注意,因为 Pinecone 不允许一次性添加大量的块,所以意味着需要一些批处理过程。

python
复制代码
    def __init__(self, batch_size: int = 10) -> None:
        self.batch_size = batch_size

    # 从输入DataFrame中生成块
    def to_batches(self, df: pd.DataFrame) -> Iterator[pd.DataFrame]:
        splits = self.splits_num(df.shape[0])
        if splits <= 1:
            yield df
        else:
            for chunk in np.array_split(df, splits):
                yield chunk

    # 确定DataFrame包含多少块
    def splits_num(self, elements: int) -> int:
        return round(elements / self.batch_size)

    __call__ = to_batches

df_batcher = BatchGenerator(300)

index_name = 'overview-of-nvidia'

# Check whether the index with the same name already exists - if so, delete it
if index_name in pc.list_indexes():
    pc.delete_index(index_name)

pc.create_index(index_name, dimension=len(df['content_vector'][0]), spec=ServerlessSpec(
    cloud="aws",
    region="us-east-1"
  ))

index = pc.Index(name=index_name)

# 上传内容向量
for batch_df in df_batcher(df):
    index.upsert(vectors=zip(batch_df.vector_id, batch_df.content_vector))

查询数据库

添加向量之后,只需要输入一个相同维度(1024)的查询向量,以找到具有最接近嵌入和相似度分数的行。下面的函数将这些行映射到原始数据框,并提供文本和余弦相似度。

ini
复制代码
content_mapped = dict(zip(df.vector_id,df.text))
     
# 使用指定命名空间中的标题查询文章并打印结果。
def query_article(query, top_k=3):

    # 基于标题列创建向量嵌入
    embedded_query = client.embeddings.create(input = [query], model="BAAI/bge-m3").data[0].embedding

    # 使用标题向量作为参数传递的查询命名空间
    query_result = index.query(vector=embedded_query,
                                      top_k=3)

    # 查询结果
    print(f'\n查询结果: {query}')
    if not query_result.matches:
        print('没有查询结果')

    matches = query_result.matches
    ids = [res.id for res in matches]
    scores = [res.score for res in matches]
    df = pd.DataFrame({'id':ids,
                       'score':scores,
                       'content': [content_mapped[_id] for _id in ids],
                       })

    counter = 0
    for k,v in df.iterrows():
        counter += 1
        print(f'{v.content} (score = {v.score})')
    print('\n')

    return df

查询及结果如下:

image.png

Pinecone 并非唯一的向量数据库提供者,还有如 Weviate、Chroma 等,它们都采用类似的架构来创建索引、上传和查询文档。像 Langchain 和 Llamaindex 这样的框架抽象了大部分样板代码,有助于简化对 RAG 的采用。

结语

跟随本文的介绍,我们见证了 Pinecone 向量数据库在文档检索领域的强大潜力。通过 RAG 技术,我们不仅提升了检索的速度和准确性,更开启了对文档深层次理解和应用的新视角。这项技术的运用,不仅限于信息检索,更可能成为推动各行各业智能化转型的关键力量。在未来,我们有理由相信,向量数据库和 RAG 技术将在构建更加智能、高效的信息生态系统中发挥更加重要的作用。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算机图形学games101——MVP

首先记得一个知识点 在旋转矩阵中&#xff0c;旋转矩阵的逆矩阵就是旋转矩阵的转置&#xff0c;这个矩阵是正交矩阵 我们需要做到的就是观测变换&#xff0c;这个变换包括视图变换和投影变换&#xff08;投影变换包含正交变换和透视变换&#xff09; 三维变换复习 首先复习…

Ubuntu20.04配置TurtleBot3 Waffle Pi远程控制

这里写目录标题 0. 机器人配置1. Ubuntu20.04配置TurtleBot3 Waffle Pi远程控制1.1 TurtleBot3 Waffle Pi端配置1.2 PC端配置1.2.1 安装turtlebot3的环境配置1.2.2 创建项目并安装Turtlebot31.2.3 配置环境变量 1.3 PC端与TurtleBot3进行通信1.3.1 PC端与机器人端互PING和SSH连…

ATA-L2水声功率放大器驱动水声换能器的测试研究

随着水声通信技术的发展&#xff0c;水下通信设备也开始逐步走向实用化&#xff0c;为了满足其实际的使用要求&#xff0c;功率放大器的设计需要具有高效率的特性&#xff0c;并能在水下长时间连续可靠的工作。 压电陶瓷换能器主要负责电信号与声信号之间的转换&#xff0c;换能…

ruoyi-cloud登录接口实现滑块验证码

一、前言 ruoyi项目默认的验证码是这样的 今天来尝试增加滑块验证码&#xff0c;我们用到的是tianai-captcha。 文档地址&#xff1a;http://doc.captcha.tianai.cloud/ 源码地址&#xff1a;https://gitee.com/tianai/tianai-captcha 下面来看具体的步骤。 二、后端 在g…

JL-33 手持式气象站/便携式气象站 小型气象站厂家 微型气象站

产品概述 手持式气象站是一款携带方便&#xff0c;操作简单&#xff0c;集多项气象要素于一体的可移动式气象观测仪器。产品采用传感器及芯片&#xff0c;能同时对空气温度、空气湿度、风速、风向、光照、大气压力、颗粒物、噪声等要素进行准确测量、记录并存储。仪器带有机械…

游泳哪个牌子好?6大游泳耳机选购技巧总结分享

游泳耳机作为水上运动爱好者和游泳专业人士的必备装备&#xff0c;不仅要能够抵御水的侵入&#xff0c;还要提供清晰的音质和舒适的佩戴体验。在市面上&#xff0c;不同品牌的游泳耳机琳琅满目&#xff0c;选择起来可能会令人头疼。本文旨在为您提供一份详尽的游泳耳机选购指南…

详细解释下flutter初始示例的代码

详细解释下flutter初始示例的代码 main 首句导入需要的包 类似于其他语言的import main函数为入口函数 包裹MyApp类 MyApp 这个类继承自无状态类 可见myapp不管理任何状态 build方法是所有widget内必须实现的方法 此处返回一个 ChangeNotferiProvider 可以看到它用于管理应…

2024年低碳发展与地球科学国际会议 (LCDES 2024)

2024年低碳发展与地球科学国际会议 (LCDES 2024) 2024 International Conference on Low Carbon Development and Earth Science 【重要信息】 大会地点&#xff1a;长沙 大会官网&#xff1a;http://www.iclcdes.com 投稿邮箱&#xff1a;iclcdessub-conf.com 【注意&#xf…

一个opencv实现检测程序

引言 图像处理是计算机视觉中的一个重要领域&#xff0c;它在许多应用中扮演着关键角色&#xff0c;如自动驾驶、医疗图像分析和人脸识别等。边缘检测是图像处理中的基本任务之一&#xff0c;它用于识别图像中的显著边界。本文将通过一个基于 Python 和 OpenCV 的示例程序&…

《昇思25天学习打卡营第6天|网络构建》

文章目录 前言&#xff1a;今日所学&#xff1a;1. 定义模型类2. 模型层3. 模型参数 前言&#xff1a; 在第六节中我们学习了网络构建&#xff0c;了解了神经网络模型是由神经网络层和Tensor操作构成&#xff0c;我们使用的mindspore.nn中提供了常见的升级网络层的实现&#x…

c++边界处理机制

1.vector std::vector&#xff1a;std::vector 是动态数组&#xff0c;它会在运行时动态地调整存储空间大小&#xff0c;因此当访问超出边界时&#xff0c;会触发运行时异常 std::out_of_range。可以通过try-catch块来捕获这种异常来处理越界访问。 #include <iostream>…

十五、【源码】给代理对象设置属性

源码地址&#xff1a;https://github.com/spring-projects/spring-framework 仓库地址&#xff1a;https://gitcode.net/qq_42665745/spring/-/tree/15-proxy-set-property 给代理对象设置属性 之前的代码是创建Bean进行判断&#xff0c;要不要进行代理&#xff0c;如果代理…

console 报错 之 Uncaught (in promise) RangeError: Maximum call stack size exceeded

1. 背景 demo 环境报错。。。 2. 报错问题 3. 问题原因 vue 报错: “RangeError: Maximum call stack size exceeded” 报错通常是由于无限的递归 导致的。当使用 Vue 路由时&#xff0c;如果设置不当&#xff0c;会导致无限的递归&#xff0c;最终导致栈溢出&#xff0c;即…

【TypeScript】TS入门到实战(详解:高级类型)

目录 第三章、TypeScript的数据类型 3.1 TypeScript的高级类型 3.1.1 class 3.1.1.1 熟悉class类 3.1.1.2 class类继承的两种方式 3.1.1.3 class类的5种修饰符 3.1.2 类型兼容 3.1.3 交叉类型 3.1.4 泛型 3.1.4.1 创建泛型函数 3.1.4.2 泛型函数的调用 3.1.4.3 泛型…

【操作与配置】Linux的CPU深度学习环境

Conda安装 可浏览官网&#xff1a;Miniconda — Anaconda 文档 这四条命令会快速而且悄悄地安装最新的64位安装程序&#xff0c;然后清理安装过程中产生的文件。如果需要安装 Linux 版本的其他版本或架构的 Miniconda&#xff0c;只需要在命令中更改安装程序的名称。 mkdir …

【C++】const详解

&#x1f4e2;博客主页&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01; &#x1f4e2;本文作为 JohnKi &#xff0c;引用了部分大佬的案例 &#x1f4e2;未来很长&#xff0c;…

【Kali-linux for WSL】图形化界面安装

文章目录 前言图形化界面安装 前言 之前在WSL中安装了Kali 启动之后发现什么都没有&#xff01;&#xff01;&#xff01; 那我还怎么学习渗透技术&#xff1f;&#xff1f;&#xff1f; 看来&#xff0c;得改进下我的kali-linux for wsl&#xff0c;安装个图形化界面 图形化…

JCR一区级 | Matlab实现BO-Transformer-LSTM多变量回归预测

JCR一区级 | Matlab实现BO-Transformer-LSTM多变量回归预测 目录 JCR一区级 | Matlab实现BO-Transformer-LSTM多变量回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现BO-Transformer-LSTM多变量回归预测&#xff0c;贝叶斯优化Transformer结合LSTM长…

【Python】Python中的常量与变量

常量与变量 导读一、新建项目二、常量2.1 字面常量2.2 特殊常量 三、变量3.1 变量的定义3.2 变量的命名3.2.1 关键字 结语 导读 大家好&#xff0c;很高兴又和大家见面啦&#xff01;&#xff01;&#xff01; 在上一篇内容中我们详细介绍了Python环境的搭建过程&#xff0c;…

一键转换,高效管理:引领文件批量改后缀名与TXT转DOCX格式新潮流

在这个数字化时代&#xff0c;文件管理和格式转换成为了我们日常工作中不可或缺的一部分。然而&#xff0c;手动更改文件后缀名以及将TXT文件转换为DOCX格式&#xff0c;不仅耗时耗力&#xff0c;还容易出错。幸运的是&#xff0c;我们有了文件批量改名高手这款强大的工具&…