开启RAG进阶:混合检索(关键字&向量)+重排序(原理讲解与示例体验)

前言

前面我们分享了,RAG的两种实现方式:关键字检索向量检索

我们也了解了关键字检索和向量检索在实际的应用中,有各自的特点和局限性。

2023年9月,Microsoft Azure AI 在官方博客上发布了一篇题为《Azure 认知搜索:通过混合检索和排序能力超越向量搜索》的文章。该文对在 RAG 架构的生成式 AI 应用中引入混合检索和重排序技术进行了全面的实验数据评估,量化了该技术组合对改善文档召回率和准确性方面的显著效果。

一张图表快速回顾关键字检索和向量检索的特点

检索方式特点局限性
关键字检索1.领域外搜索:无论单词的含义如何,单词只是单词。 2.边输入边搜索:检索速度快。 3.确切短语匹配:对产品名、人名、零件编号等特别有用。关键字检索可能会受到一些问题的影响,例如同义词、拼写错误等,这可能会导致一些相关的文档被漏掉或者一些不相关的文档被检索到。
向量检索除了能够实现复杂语义的文本查找,还有其他优势: 1.容错性:处理模糊描述、拼写错误; 2.多模态理解:支持文本、图像、音视频等相似匹配; 3.多语言理解:跨语言理解,如输入中文匹配英文;相似语义理解;在某些情况下,呈现的效果不佳,比如: 1.搜索一个人或物体的名字(例如,伊隆·马斯克,iPhone 15) 2.搜索缩写词或短语(例如,RAG,RLHF) 3.搜索 ID(例如, gpt-3.5-turbo , titan-xlarge-v1.01 )

从我们汇总的信息可以比较直观的看出,我们本文要专题分享混合检索的原因了。
在这里插入图片描述

什么是混合检索?

接下来我们就先来了解下到底什么是混合检索,可能从我们以上综合提到了两个检索方式,也已经能推断出来了。

没错,在RAG系统中,混合搜索最常见指向量检索和关键词检索的组合。在不同场景中,实际应用会有不同方式,从概念上讲:混合检索是结合了两种或者多种搜索算法提高搜索结果相关性的搜索技术

在这里插入图片描述

混合检索的原理

关于关键字检索和向量检索,还有另外一种表述:

关键字检索(稀疏表示)、向量检索(稠密表示)。

基于关键字的搜索和向量搜索都返回一组单独的结果,通常是按计算的相关性排序的搜索结果列表。必须将这些单独的搜索结果集组合在一起。

有许多不同的策略可以将两个列表的排名结果合并为一个单一的排名,一般来说,搜索结果通常是首先评分的。这些分数可以根据指定的指标(例如余弦距离)计算,也可以仅根据搜索结果列表中的排名进行计算。

然后,计算出的分数用一个参数进行加权,该参数决定了每个算法的权重并影响结果的重新排名。

在这里插入图片描述

通常,alpha 取一个介于 0 和 1 之间的值,其中

alpha = 1:纯向量搜索

alpha = 0:纯关键字搜索

下面,您可以看到关键字和向量搜索之间融合的最小示例,其中包含基于排名和 .alpha = 0.5

![最后如果您也对AI大模型感兴趣想学习却苦于没有方向👀
小编给自己收藏整理好的学习资料分享出来给大家💖
👉获取方式:
😝有需要的小伙伴,可以保存图片到wx扫描二v码关注免费领取【保证100%免费】🆓

在这里插入图片描述

一、全套 AGI 大模型学习路线

AI 大模型时代的精彩学习之旅:从根基铸就到前沿探索,牢牢掌握人工智能核心技能!

在这里插入图片描述

二、640 套 AI 大模型报告合集

此套涵盖 640 份报告的精彩合集,全面涉及 AI 大模型的理论研究、技术实现以及行业应用等诸多方面。无论你是科研工作者、工程师,还是对 AI 大模型满怀热忱的爱好者,这套报告合集都将为你呈上宝贵的信息与深刻的启示。

在这里插入图片描述

三、AI 大模型经典 PDF 书籍

伴随人工智能技术的迅猛发展,AI 大模型已然成为当今科技领域的一大热点。这些大型预训练模型,诸如 GPT-3、BERT、XLNet 等,凭借其强大的语言理解与生成能力,正在重塑我们对人工智能的认知。而以下这些 PDF 书籍无疑是极为出色的学习资源。
在这里插入图片描述
在这里插入图片描述

阶段 1:AI 大模型时代的基础认知

  • 目标:深入洞悉 AI 大模型的基本概念、发展历程以及核心原理。

  • 内容

    • L1.1 人工智能概述与大模型起源探寻。
    • L1.2 大模型与通用人工智能的紧密关联。
    • L1.3 GPT 模型的辉煌发展历程。
    • L1.4 模型工程解析。
    • L1.4.1 知识大模型阐释。
    • L1.4.2 生产大模型剖析。
    • L1.4.3 模型工程方法论阐述。
    • L1.4.4 模型工程实践展示。
    • L1.5 GPT 应用案例分享。

阶段 2:AI 大模型 API 应用开发工程

  • 目标:熟练掌握 AI 大模型 API 的运用与开发,以及相关编程技能。

  • 内容

    • L2.1 API 接口详解。
    • L2.1.1 OpenAI API 接口解读。
    • L2.1.2 Python 接口接入指南。
    • L2.1.3 BOT 工具类框架介绍。
    • L2.1.4 代码示例呈现。
    • L2.2 Prompt 框架阐释。
    • L2.2.1 何为 Prompt。
    • L2.2.2 Prompt 框架应用现状分析。
    • L2.2.3 基于 GPTAS 的 Prompt 框架剖析。
    • L2.2.4 Prompt 框架与 Thought 的关联探讨。
    • L2.2.5 Prompt 框架与提示词的深入解读。
    • L2.3 流水线工程阐述。
    • L2.3.1 流水线工程的概念解析。
    • L2.3.2 流水线工程的优势展现。
    • L2.3.3 流水线工程的应用场景探索。
    • L2.4 总结与展望。

阶段 3:AI 大模型应用架构实践

  • 目标:深刻理解 AI 大模型的应用架构,并能够实现私有化部署。

  • 内容

    • L3.1 Agent 模型框架解读。
    • L3.1.1 Agent 模型框架的设计理念阐述。
    • L3.1.2 Agent 模型框架的核心组件剖析。
    • L3.1.3 Agent 模型框架的实现细节展示。
    • L3.2 MetaGPT 详解。
    • L3.2.1 MetaGPT 的基本概念阐释。
    • L3.2.2 MetaGPT 的工作原理剖析。
    • L3.2.3 MetaGPT 的应用场景探讨。
    • L3.3 ChatGLM 解析。
    • L3.3.1 ChatGLM 的特色呈现。
    • L3.3.2 ChatGLM 的开发环境介绍。
    • L3.3.3 ChatGLM 的使用示例展示。
    • L3.4 LLAMA 阐释。
    • L3.4.1 LLAMA 的特点剖析。
    • L3.4.2 LLAMA 的开发环境说明。
    • L3.4.3 LLAMA 的使用示例呈现。
    • L3.5 其他大模型介绍。

阶段 4:AI 大模型私有化部署

  • 目标:熟练掌握多种 AI 大模型的私有化部署,包括多模态和特定领域模型。

  • 内容

    • L4.1 模型私有化部署概述。
    • L4.2 模型私有化部署的关键技术解析。
    • L4.3 模型私有化部署的实施步骤详解。
    • L4.4 模型私有化部署的应用场景探讨。

学习计划:

  • 阶段 1:历时 1 至 2 个月,构建起 AI 大模型的基础知识体系。
  • 阶段 2:花费 2 至 3 个月,专注于提升 API 应用开发能力。
  • 阶段 3:用 3 至 4 个月,深入实践 AI 大模型的应用架构与私有化部署。
  • 阶段 4:历经 4 至 5 个月,专注于高级模型的应用与部署。
    在这里插入图片描述

](https://i-blog.csdnimg.cn/direct/b49a33f354f44397806e03ad277153d7.png)

我们用一个小例子加深下体验

基于关键字检索的排序

python代码解读复制代码import time


class MyEsConnector:
    def __init__(self, es_client, index_name, keyword_fn):
        self.es_client = es_client
        self.index_name = index_name
        self.keyword_fn = keyword_fn

    def add_documents(self, documents):
        '''文档灌库'''
        if self.es_client.indices.exists(index=self.index_name):
            self.es_client.indices.delete(index=self.index_name)
        self.es_client.indices.create(index=self.index_name)
        actions = [
            {
                "_index": self.index_name,
                "_source": {
                    "keywords": self.keyword_fn(doc),
                    "text": doc,
                    "id": f"doc_{i}"
                }
            }
            for i, doc in enumerate(documents)
        ]
        helpers.bulk(self.es_client, actions)
        time.sleep(1)

    def search(self, query_string, top_n=3):
        '''检索'''
        search_query = {
            "match": {
                "keywords": self.keyword_fn(query_string)
            }
        }
        res = self.es_client.search(
            index=self.index_name, query=search_query, size=top_n)
        return {
            hit["_source"]["id"]: {
                "text": hit["_source"]["text"],
                "rank": i,
            }
            for i, hit in enumerate(res["hits"]["hits"])
        }
        
        from chinese_utils import to_keywords  # 使用中文的关键字提取函数

# 引入配置文件
ELASTICSEARCH_BASE_URL = os.getenv('ELASTICSEARCH_BASE_URL')
ELASTICSEARCH_PASSWORD = os.getenv('ELASTICSEARCH_PASSWORD')
ELASTICSEARCH_NAME= os.getenv('ELASTICSEARCH_NAME')

es = Elasticsearch(
    hosts=[ELASTICSEARCH_BASE_URL],  # 服务地址与端口
    http_auth=(ELASTICSEARCH_NAME, ELASTICSEARCH_PASSWORD),  # 用户名,密码
)


# 创建 ES 连接器
es_connector = MyEsConnector(es, "demo_es_rrf", to_keywords)

# 文档灌库
es_connector.add_documents(documents)

# 关键字检索
keyword_search_results = es_connector.search(query, 3)

print(json.dumps(keyword_search_results, indent=4, ensure_ascii=False))

基于向量检索的排序

python代码解读复制代码# 创建向量数据库连接器
vecdb_connector = MyVectorDBConnector("demo_vec_rrf", get_embeddings)

# 文档灌库
vecdb_connector.add_documents(documents)

# 向量检索
vector_search_results = {
    "doc_"+str(documents.index(doc)): {
        "text": doc,
        "rank": i
    }
    for i, doc in enumerate(
        vecdb_connector.search(query, 3)["documents"][0]
    )
}  # 把结果转成跟上面关键字检索结果一样的格式

print(json.dumps(vector_search_results, indent=4, ensure_ascii=False))

基于 RRF 的融合排序

python代码解读复制代码def rrf(ranks, k=1):
    ret = {}
    # 遍历每次的排序结果
    for rank in ranks:
        # 遍历排序中每个元素
        for id, val in rank.items():
            if id not in ret:
                ret[id] = {"score": 0, "text": val["text"]}
            # 计算 RRF 得分
            ret[id]["score"] += 1.0/(k+val["rank"])
    # 按 RRF 得分排序,并返回
    return dict(sorted(ret.items(), key=lambda item: item[1]["score"], reverse=True))
    
    import json

# 融合两次检索的排序结果
reranked = rrf([keyword_search_results, vector_search_results])

print(json.dumps(reranked, indent=4, ensure_ascii=False))

我们看下各自的执行结果

python代码解读复制代码# 背景说明:在医学中“小细胞肺癌”和“非小细胞肺癌”是两种不同的癌症

query = "非小细胞肺癌的患者"

documents = [
    "玛丽患有肺癌,癌细胞已转移",
    "刘某肺癌I期",
    "张某经诊断为非小细胞肺癌III期",
    "小细胞肺癌是肺癌的一种"
]

query_vec = get_embeddings([query])[0]
doc_vecs = get_embeddings(documents)

print("Cosine distance:")
for vec in doc_vecs:
    print(cos_sim(query_vec, vec))
js代码解读复制代码{
    "doc_2": {
        "text": "张某经诊断为非小细胞肺癌III期",
        "rank": 0
    },
    "doc_0": {
        "text": "玛丽患有肺癌,癌细胞已转移",
        "rank": 1
    },
    "doc_3": {
        "text": "小细胞肺癌是肺癌的一种",
        "rank": 2
    }
}
js代码解读复制代码{
    "doc_3": {
        "text": "小细胞肺癌是肺癌的一种",
        "rank": 0
    },
    "doc_2": {
        "text": "张某经诊断为非小细胞肺癌III期",
        "rank": 1
    },
    "doc_0": {
        "text": "玛丽患有肺癌,癌细胞已转移",
        "rank": 2
    }
}
js代码解读复制代码{
    "doc_2": {
        "score": 1.5,
        "text": "张某经诊断为非小细胞肺癌III期"
    },
    "doc_3": {
        "score": 1.3333333333333333,
        "text": "小细胞肺癌是肺癌的一种"
    },
    "doc_0": {
        "score": 0.8333333333333333,
        "text": "玛丽患有肺癌,癌细胞已转移"
    }
}

我们可以看到混合检索的效果是最好的。

混合检索 + 重排序

我们在上述的讲解过程中,提到了重排序,为什么会再引入重排序呢?

混合检索能够结合不同检索技术的优势,以获得更好的召回结果。然而,在不同检索模式下的查询结果需要进行合并和归一化(将数据转换为统一的标准范围或分布,以便更好地进行比较、分析和处理),然后再一并提供给大模型。在这个过程中,我们需要引入一个评分系统:重排序模型(Rerank Model)。

在大多数情况下,由于计算查询与数百万个文档之间的相关性得分将会非常低效,通常会在进行重排序之前进行一次前置检索。因此,重排序一般放在搜索流程的最后阶段,非常适合用于合并和排序来自不同检索系统的结果。

然而,重排序并不是只适用于不同检索系统的结果合并。即使在单一检索模式下,引入重排序步骤也能有效帮助改进文档的召回效果,例如在关键词检索之后加入语义重排序。

总结

RAG部分,我们陆陆续续分享了好几篇文章,从了解RAG到RAG与Fine tune的对比,再到RAG的实操:文档切片的方法、关键字检索、向量检索。

本文更是综合我们过往的知识,给大家分享了通过混合检索和排序能力超越向量搜索,让我们了解了为什么需要混合检索,为什么需要重排序,以及通过简单的例子也让大家体验了各自基本的效果。希望给大家接下来构建自己的RAG能够起到帮助的作用。

将混合检索与重排序技术应用于生产级RAG系统并不是一件简单的事情。它需要开发者克服数据处理的复杂性、模型训练的巨大挑战,以及算法优化的繁琐工作。在这一过程中,我们不仅要关注技术的实现,更要确保系统的稳定性和扩展性,以适应不断增加的用户需求和数据量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值