【RAG实践】Rerank,让大模型 RAG 更近一步

RAG+Rerank原理

上一篇【RAG实践】基于LlamaIndex和Qwen1.5搭建基于本地知识库的问答机器人

我们介绍了什么是RAG,以及如何基于LLaMaIndex和Qwen1.5搭建基于本地知识库的问答机器人,原理图和步骤如下:

图片

这里面主要包括包括三个基本步骤:

1. 索引 — 将文档库分割成较短的 Chunk,并通过编码器构建向量索引。

2. 检索 — 根据问题和 chunks 的相似度检索相关文档片段。

3. 生成 — 以检索到的上下文为条件,生成问题的回答。

更加完善的RAG技术还包含了很多点,如下是RAG技术的大图,魔搭社区也将逐步分析,希望提供更多更好更详细的RAG技术分享。

图片

本文主要关注在Rerank,本文中,Rerank可以在不牺牲准确性的情况下加速LLM的查询(实际上可能提高准确率),Rerank通过从上下文中删除不相关的节点,重新排序相关节点来实现这一点。

本文Rerank+RAG原理图:

图片

技术交流&资料

技术要学会分享、交流,不建议闭门造车。一个人可以走的很快、一堆人可以走的更远。

成立了大模型面试和技术交流群,相关资料、技术交流&答疑,均可加我们的交流群获取,群友已超过2000人,添加时最好的备注方式为:来源+兴趣方向,方便找到志同道合的朋友。

方式①、微信搜索公众号:机器学习社区,后台回复:加群
方式②、添加微信号:mlc2040,备注:来自CSDN + 技术交流

  • 重磅消息!《大模型面试宝典》(2024版) 正式发布!
  • 重磅消息!《大模型实战宝典》(2024版) 正式发布!

Rerank模型:bge-reranker-v2-m3

与embedding模型不同,Reranker使用问题和文档作为输入,直接输出相似度而不是embedding。本文通过向Reranker输入查询和段落来获得相关性分数。Reranker是基于交叉熵损失进行优化的,因此相关性得分不受特定范围的限制。bge-reranker-v2-m3适用于中英文双语Rerank场景。


LLM模型:通义千问1.5

Qwen1.5版本年前开源了包括0.5B、1.8B、4B、7B、14B、32B、72B和A2.7B-MoE在内的8种大小的基础和聊天模型,同时,也开源了量化模型。不仅提供了Int4和Int8的GPTQ模型,还有AWQ模型,以及GGUF量化模型。为了提升开发者体验,Qwen1.5的代码合并到Hugging Face Transformers中,开发者现在可以直接使用transformers>=4.37.0而无需trust_remote_code。

RAG框架:LLaMaIndex

LlamaIndex 是一个基于 LLM 的应用程序的数据框架,受益于上下文增强。 这种LLM系统被称为RAG系统,代表“检索增强生成”。LlamaIndex 提供了必要的抽象,可以更轻松地摄取、构建和访问私有或特定领域的数据,以便将这些数据安全可靠地注入 LLM 中,以实现更准确的文本生成。

图片


Embedding模型:GTE文本向量

文本表示是自然语言处理(NLP)领域的核心问题, 其在很多NLP、信息检索的下游任务中发挥着非常重要的作用。近几年, 随着深度学习的发展,尤其是预训练语言模型的出现极大的推动了文本表示技术的效果, 基于预训练语言模型的文本表示模型在学术研究数据、工业实际应用中都明显优于传统的基于统计模型或者浅层神经网络的文本表示模型。GTE主要关注基于预训练语言模型的文本表示。

图片

GTE-zh模型使用retromae初始化训练模型,之后利用两阶段训练方法训练模型:第一阶段利用大规模弱弱监督文本对数据训练模型,第二阶段利用高质量精标文本对数据以及挖掘的难负样本数据训练模型。

环境配置与安装

  1. python 3.10及以上版本

  2. pytorch 1.12及以上版本,推荐2.0及以上版本

  3. 建议使用CUDA 11.4及以上

安装依赖库

!pip install transformers -U
!pip install llama-index llama-index-llms-huggingface ipywidgets
!pip install sentence-transformers
import logging
import sys
from abc import ABC
from typing import Any, List

import pandas as pd
import torch
from IPython.display import display, HTML
from llama_index.core import QueryBundle
from llama_index.core import (
    SimpleDirectoryReader,
    VectorStoreIndex,
    Settings,
    ServiceContext,
    set_global_service_context,
)
from llama_index.core.base.embeddings.base import BaseEmbedding, Embedding
from llama_index.core.postprocessor import SentenceTransformerRerank
from llama_index.core.prompts import PromptTemplate
from llama_index.core.retrievers import VectorIndexRetriever
from llama_index.llms.huggingface import HuggingFaceLLM
from modelscope import snapshot_download
from transformers import AutoModelForSequenceClassification, AutoTokenizer

logging.basicConfig(stream=sys.stdout, level=logging.INFO)
logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stdout))

加载大语言模型

因为Qwen本次支持了Transformers,使用HuggingFaceLLM加载模型,模型为(Qwen1.5-4B-Chat)

# Model names 
qwen2_4B_CHAT = "qwen/Qwen1.5-4B-Chat"

selected_model = snapshot_download(qwen2_4B_CHAT)

SYSTEM_PROMPT = """You are a helpful AI assistant.
"""

query_wrapper_prompt = PromptTemplate(
    "[INST]<<SYS>>\n" + SYSTEM_PROMPT + "<</SYS>>\n\n{query_str}[/INST] "
)

llm = HuggingFaceLLM(
    context_window=4096,
    max_new_tokens=2048,
    generate_kwargs={"temperature": 0.0, "do_sample": False},
    query_wrapper_prompt=query_wrapper_prompt,
    tokenizer_name=selected_model,
    model_name=selected_model,
    device_map="auto",
    # change these settings below depending on your GPU
    model_kwargs={"torch_dtype": torch.float16},
)

下载数据并加载文档:

!wget https://modelscope.oss-cn-beijing.aliyuncs.com/resource/rag/xianjiaoda.md
!mkdir -p /mnt/workspace/custom_data
!mv /mnt/workspace/xianjiaoda.md /mnt/workspace/custom_data
documents = SimpleDirectoryReader("/mnt/workspace/data/xianjiaoda/").load_data()
documents

构建embedding类:

加载GTE模型,使用GTE模型构造Embedding类

embedding_model = "iic/nlp_gte_sentence-embedding_chinese-base"
class ModelScopeEmbeddings4LlamaIndex(BaseEmbedding, ABC):
    embed: Any = None
    model_id: str = "iic/nlp_gte_sentence-embedding_chinese-base"

    def __init__(
            self,
            model_id: str,
            **kwargs: Any,
    ) -> None:
        super().__init__(**kwargs)
        try:
            from modelscope.models import Model
            from modelscope.pipelines import pipeline
            from modelscope.utils.constant import Tasks
            # 使用modelscope的embedding模型(包含下载)
            self.embed = pipeline(Tasks.sentence_embedding, model=self.model_id)

        except ImportError as e:
            raise ValueError(
                "Could not import some python packages." "Please install it with `pip install modelscope`."
            ) from e

    def _get_query_embedding(self, query: str) -> List[float]:
        text = query.replace("\n", " ")
        inputs = {"source_sentence": [text]}
        return self.embed(input=inputs)['text_embedding'][0].tolist()

    def _get_text_embedding(self, text: str) -> List[float]:
        text = text.replace("\n", " ")
        inputs = {"source_sentence": [text]}
        return self.embed(input=inputs)['text_embedding'][0].tolist()

    def _get_text_embeddings(self, texts: List[str]) -> List[List[float]]:
        texts = list(map(lambda x: x.replace("\n", " "), texts))
        inputs = {"source_sentence": texts}
        return self.embed(input=inputs)['text_embedding'].tolist()

    async def _aget_query_embedding(self, query: str) -> List[float]:
        return self._get_query_embedding(query)

建设索引:

加载数据后,基于文档对象列表(或节点列表),建设他们的index,就可以方便的检索他们。

embeddings = ModelScopeEmbeddings4LlamaIndex(model_id=embedding_model)
service_context = ServiceContext.from_defaults(embed_model=embeddings, llm=llm)
set_global_service_context(service_context)

index = VectorStoreIndex.from_documents(documents)

加载Rerank模型:

rerank_llm_name = "AI-ModelScope/bge-reranker-v2-m3"
downloaded_rerank_model = snapshot_download(rerank_llm_name)
rerank_llm = SentenceTransformerRerank(model=downloaded_rerank_model, top_n=3)

首先,我们尝试使用Rerank,同时对查询+问答进行计时,检索召回top_k=10,Rerank重排top_n=3看看处理检索到的上下文的输出需要多长时间。

from time import time

query_engine = index.as_query_engine(similarity_top_k=10, node_postprocessors=[rerank_llm])

now = time()
response = query_engine.query("西安交大由哪几个学校合并的")
print(response)
print(f"Elapsed: {round(time() - now, 2)}s")

输出和计时:

图片

打印上下文context:

图片

然后,我们尝试不加Rerank的情况下,查询和问答并计时:

from time import time

query_engine = index.as_query_engine(similarity_top_k=10)

now = time()
response = query_engine.query("西安交大由哪几个学校合并的")
print(response)
print(f"Elapsed: {round(time() - now, 2)}s")

输出和计时:

图片

打印上下文context:

图片

正如我们所看到的,具有Rerank功能的retrieval引擎在更短的时间(本文速度提升了约2倍)内生成了准确的输出。虽然两种响应本质上都是正确的,但未经rerank的retrieval引擎包含了大量不相关的信息,从而影响了查询和推理的速度 - 我们可以将这种现象归因于“上下文窗口无效数据的污染”。

通俗易懂讲解大模型系列

  • 重磅消息!《大模型面试宝典》(2024版) 正式发布!

  • 重磅消息!《大模型实战宝典》(2024版) 正式发布!

  • 做大模型也有1年多了,聊聊这段时间的感悟!

  • 用通俗易懂的方式讲解:不要再苦苦寻觅了!AI 大模型面试指南(含答案)的最全总结来了!

  • 用通俗易懂的方式讲解:我的大模型岗位面试总结:共24家,9个offer

  • 用通俗易懂的方式讲解:大模型 RAG 在 LangChain 中的应用实战

  • 用通俗易懂的方式讲解:一文讲清大模型 RAG 技术全流程

  • 用通俗易懂的方式讲解:如何提升大模型 Agent 的能力?

  • 用通俗易懂的方式讲解:ChatGPT 开放的多模态的DALL-E 3功能,好玩到停不下来!

  • 用通俗易懂的方式讲解:基于扩散模型(Diffusion),文生图 AnyText 的效果太棒了

  • 用通俗易懂的方式讲解:在 CPU 服务器上部署 ChatGLM3-6B 模型

  • 用通俗易懂的方式讲解:使用 LangChain 和大模型生成海报文案

  • 用通俗易懂的方式讲解:ChatGLM3-6B 部署指南

  • 用通俗易懂的方式讲解:使用 LangChain 封装自定义的 LLM,太棒了

  • 用通俗易懂的方式讲解:基于 Langchain 和 ChatChat 部署本地知识库问答系统

  • 用通俗易懂的方式讲解:在 Ubuntu 22 上安装 CUDA、Nvidia 显卡驱动、PyTorch等大模型基础环境

  • 用通俗易懂的方式讲解:Llama2 部署讲解及试用方式

  • 用通俗易懂的方式讲解:基于 LangChain 和 ChatGLM2 打造自有知识库问答系统

  • 用通俗易懂的方式讲解:一份保姆级的 Stable Diffusion 部署教程,开启你的炼丹之路

  • 用通俗易懂的方式讲解:对 embedding 模型进行微调,我的大模型召回效果提升了太多了

  • 用通俗易懂的方式讲解:LlamaIndex 官方发布高清大图,纵览高级 RAG技术

  • 用通俗易懂的方式讲解:为什么大模型 Advanced RAG 方法对于AI的未来至关重要?

  • 用通俗易懂的方式讲解:使用 LlamaIndex 和 Eleasticsearch 进行大模型 RAG 检索增强生成

  • 用通俗易懂的方式讲解:基于 Langchain 框架,利用 MongoDB 矢量搜索实现大模型 RAG 高级检索方法

  • 用通俗易懂的方式讲解:使用Llama-2、PgVector和LlamaIndex,构建大模型 RAG 全流程

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

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

相关文章

【无标题】系统思考—心智模式

“直到你使无意识变为有意识&#xff0c;它将指导你的生活并且你会称之为命运。”—卡尔荣格 心智模式深藏于我们内心之中&#xff0c;它潜移默化地影响着我们对世界的理解和判断。往往这些影响是如此隐蔽&#xff0c;以至于我们自己都未必察觉到是什么在驱动我们的选择、决策…

ES7-10:async和await、异步迭代..

1-ES7新特性 indexof如果没有就返回-1&#xff0c;有就返回索引 如果仅仅查找数据是否在数组中,建议使用includes,如果是查找数据的索引位置,建议使用indexOf更好一些 2-ES8-async和await 所有的需要异步处理的Promise对象都写在async中await等待结果 async、await 使异步操…

【MATLAB源码-第184期】基于matlab的FNN预测人民币美元汇率 输出预测图误差图RMSE R2 MAE MBE等指标

操作环境&#xff1a; MATLAB 2022a 1、算法描述 前馈神经网络&#xff08;Feedforward Neural Network, FNN&#xff09;是最简单也是应用最广泛的人工神经网络之一。在许多领域&#xff0c;尤其是数据预测方面&#xff0c;FNN已经展现出了卓越的性能和强大的适应性。 一、…

贪心算法|406.根据身高重建队列

力扣题目链接 class Solution { public:static bool cmp(const vector<int>& a, const vector<int>& b) {if (a[0] b[0]) return a[1] < b[1];return a[0] > b[0];}vector<vector<int>> reconstructQueue(vector<vector<int>…

鸿蒙应用开发之图案密码锁组件

前面学习了导航组件,现在来学习另一个密码设置和验证组件,这种组件比较常用。因为当用触屏手机之后,屏幕上就可以滑动操作,比普通PC电脑要多一些功能了。早前的密码都是输入数字,没有滑动输入九宫格的密码。 大体如下面的界面: 采用这种密码,一般情况下是不用记住数字,…

Vue - 你知道Vue中key的工作原理吗

难度级别:中级及以上 提问概率:80% 在Vue项目开发中,并不推荐使用索引做为key,以为key必须是唯一的,可以使用服务端下发的唯一ID值,也不推荐使用随机值做为key,因为如果每次渲染都监听到不一样的key,那么节点将无法复用,这与Vue节省…

Kotlin:常用标准库函数(let、run、with、apply、also)

一、let 扩展函数 Kotlin标准库函数let可用于范围确定和空检查。当调用对象时&#xff0c;let执行给定的代码块并返回其最后一个表达式的结果。对象可以通过引用(默认情况下)或自定义名称在块中访问。 let扩展函数源码 let.kt文件代码 fun main() {println("isEmpty $is…

企业如何防止内部人员泄密(实用方法分享)

“老干妈配方遭泄露”事件你们一定有所耳闻吧&#xff01; 2016年5月&#xff0c;“老干妈”工作人员发现&#xff0c;本地另一家食品加工企业生产的一款产品与老干妈品牌同款产品相似度极高。 经查&#xff0c;涉嫌窃取此类技术的企业从未涉足该领域&#xff0c;绝无此研发能…

C/S医学检验LIS实验室信息管理系统源码 医院LIS源码

LIS系统即实验室信息管理系统。LIS系统能实现临床检验信息化&#xff0c;检验科信息管理自动化。其主要功能是将检验科的实验仪器传出的检验数据经数据分析后&#xff0c;自动生成打印报告&#xff0c;通过网络存储在数据库中&#xff0c;使医生能够通过医生工作站方便、及时地…

基于Java+SpringBoot+Vue音乐网站(源码+文档+部署+讲解)

一.系统概述 随着我国经济的高速发展与人们生活水平的日益提高&#xff0c;人们对生活质量的追求也多种多样。尤其在人们生活节奏不断加快的当下&#xff0c;人们更趋向于足不出户解决生活上的问题&#xff0c;音乐管理展现了其蓬勃生命力和广阔的前景。与此同时&#xff0c;为…

[【JSON2WEB】 13 基于REST2SQL 和 Amis 的 SQL 查询分析器

【JSON2WEB】01 WEB管理信息系统架构设计 【JSON2WEB】02 JSON2WEB初步UI设计 【JSON2WEB】03 go的模板包html/template的使用 【JSON2WEB】04 amis低代码前端框架介绍 【JSON2WEB】05 前端开发三件套 HTML CSS JavaScript 速成 【JSON2WEB】06 JSON2WEB前端框架搭建 【J…

06 Php学习:字符串

PHP 中的字符串变量 在 PHP 中&#xff0c;字符串是一种常见的数据类型&#xff0c;用于存储文本数据。字符串变量可以包含字母、数字、符号等字符&#xff0c;并且可以进行各种操作和处理。以下是关于 PHP 中字符串变量的一些重要信息&#xff1a; 定义字符串变量&#xff1…

3 突破编程_前端_SVG(rect 矩形)

1 rect 元素的基本属性和用法 在SVG中&#xff0c;<rect> 元素用于创建矩形。 <rect> 元素有一些基本的属性&#xff0c;可以用来定义矩形的形状、位置、颜色等。以下是这些属性的详细解释&#xff1a; x 和 y &#xff1a;这两个属性定义矩形左上角的位置。 x …

Day:005 | Python爬虫:高效数据抓取的编程技术(爬虫效率)

爬虫之多线程-了解 单线程爬虫的问题 因为爬虫多为IO密集型的程序&#xff0c;而IO处理速度并不是很快&#xff0c;因此速度不会太快如果IO卡顿&#xff0c;直接影响速度 解决方案 考虑使用多线程、多进程 原理&#xff1a; 爬虫使用多线程来处理网络请求&#xff0c;使用线程…

服务器云主机进入黑洞了怎么解决

黑洞是指服务器受进犯流量超过本机房黑洞阈值时&#xff0c;云核算服务商屏蔽服务器的外网拜访。当服务器进入黑洞一段时间后&#xff0c;假如体系监控到进犯流量中止&#xff0c;黑洞会主动解封。 1&#xff1a;进入“黑洞”了&#xff0c;该怎么办&#xff1f; 由于黑洞是各…

unable to find a medium containing a live file system解决办法!

背景&#xff1a; 用Ventoy制作U盘系统安装盘&#xff0c;只需要把ISO镜像拷进去就可以&#xff0c;可以放多少个镜像取决于U盘的大小&#xff0c;无需重复制作。Ventoy 将U盘的第一个分区默认格式化为exFAT文件系统来存放ISO文件。 但是&#xff0c;今天鲲鹏920平台安装银河…

第十三届蓝桥杯C/C++大学B组真题题解(一)

1、扫雷 #include <bits/stdc.h> using namespace std; int n,m; const int N110; int g[N][N]; int dx[8]{-1,-1,-1,0,1,1,1,0}; int dy[8]{-1,0,1,1,1,0,-1,-1}; int dfs(int x,int y){int ans0;for(int i0;i<8;i){int axdx[i],bydy[i];if(a<0||a>n-1||b<0…

水牛社:互联网赚钱秘籍,免费项目,你真敢要吗?

免费是最贵的。真正理解并使用这句话的只有少数人&#xff0c;今天在网上分享一下免费项目背后的逻辑&#xff0c;抛开现象&#xff0c; 本质是最重要的。 我从事互联网工作15年。不管是过去还是现在&#xff0c;总有人喜欢问有没有免费项目&#xff1f; 其实我平时懒得回答…

面试经典算法系列之链表2 -- 环形链表

面试经典算法8-环形链表 LeetCode.141 公众号&#xff1a;阿Q技术站 问题描述 给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&am…

day7 nest商业项目初探·三(java转ts全栈/3R教室)

背景&#xff1a;从头一点点学起太慢了&#xff0c;直接看几个商业项目吧&#xff0c;看看根据Java的经验&#xff0c;自己能看懂多少&#xff0c;然后再系统学的话也会更有针对性。今天看下一个项目 * 【法国 | 3.75w】Nextjs&#xff1a;小雯工作室创意官网 &#xff08;2023…