当前位置: 首页 > article >正文

多维度信息捕捉:利用向量、稀疏向量、全文搜索及张量实现RAG的极致性能

开源 AI 原生数据库 Infinity 0.2 release 正式发布,提供了 2 种新数据类型:稀疏向量Sparse Vector 和 张量Tensor,在此前的全文搜索和向量搜索之外, Infinity 提供了更多的召回手段,如下图所示,用户可以采用任意 N 路召回(N ≥ 2)进行混合搜索,这是目前功能最强大的 RAG 专用数据库。

1. 混合搜索(多路召回)

我们知道,仅仅依靠向量搜索(默认情况下,它用来特指稠密向量)并不总能提供令人满意的结果。当用户问题中的特定关键词与存储的数据不准确匹配时,这种问题尤为明显。这是因为向量本身不具备精确语义表征能力:一个词,一句话,乃至一篇文章,都可以只用一个向量来表示,这时向量本质上表达的是这段文字的 “语义”,也就是这段文字跟其他文字在一个上下文窗口内共同出现概率的压缩表示 ,因此向量天然无法表示精确的查询。例如如果用户询问 “2024 年 3 月我们公司财务计划包含哪些组合”,那么很可能得到的结果是其他时间段的数据,或者得到运营计划,营销管理等其他类型的数据。
因此,在一种好的解决方案是,利用基于关键词的全文搜索提供精确查询,它跟向量搜索共同工作,这就是全文搜索 + 向量搜索 的 2 路召回,又被称为混合搜索(hybrid search)。
多路召回,在 RAG 的使用场景中,有时候还被解释为其他选择:
一种是仍然用向量搜索,但是采用多种方式将改写查询,然后合并多个查询的返回结果,这其实解决的仍然是向量本身语义表征粒度难以控制的问题,并不能解决向量无法进行精确查询的问题。
另一种就是引入稀疏向量,跟稠密向量组合到一起提供混合搜索(hybrid search)。稀疏向量跟稠密向量并不是一回事,它并没有稠密向量那种针对语义的压缩表示,而是试图针对全文搜索的一种替代,它解决的是全文搜索过程中如何针对倒排索引的词典进一步对关键词进行裁剪、扩展和定义权重。这样,一篇原始文档,就可以用这些裁剪后的关键词组成的稀疏向量来表征。例如下边的例子,上边是稠密向量,下边则是稀疏向量,它的维度一般要远高于稠密向量,例如会有 3 万维,由于大多数维度并没有值,因此可以采用 (位置,值)的形式表达向量中每个存在权重的维度。

[0.2, 0.3, 0.5, 0.7,......] 
[{331: 0.5}, {14136: 0.7}]

把文本转为稀疏向量最知名和有代表性的工作就是 SPLADE (参考文献 [1]),它利用一个标准的预训练数据,将文档中的冗余词删除,并且增加扩展词,从而形成一个标准的 3 万维的稀疏向量输出。这里的冗余词删除,其实就类似传统搜索引擎中分词过程中的 “去停用词”(在构建索引的过程中,将英文中的 the、a、等频率很高但信息密度很低的词跳过,这并不影响整体召回的效果,中文也同样的道理);增加相应扩展,也类似传统搜索引擎的查询同义词等扩展技术。站在使用的角度,它可以把任何文档都表征为一个 3 万维的稀疏向量,向量每个维度表征这个单词的权重。在典型的信息检索 ( Information Retrieval) 评测任务中,采用 SPLADE 稀疏向量取得了比传统搜索引擎基于 BM25排序方式更好的表现。而利用稀疏向量 + 稠密向量的混合搜索,其效果在近期的一篇采用 BGE M3 embedding 模型的论文中也得到了验证(参考文献 [2]),在典型评测中,取得了比 BM25 要好很多的效果:

那么看起来,似乎稠密向量 + 稀疏向量就是更好的多路召回方案,采用全文搜索 + 稠密向量,似乎没有必要?

2. 三路召回优势

我们知道, RAG 在技术上总是会遇到很多挑战,尽管信息检索理论为 RAG 提供了很多支撑,包括信息检索的评测等,但在实际中仍然会遇到很多问题。稀疏向量通过预训练模型删除了很多无用词,并增加了许多用来做查询扩展的词,这在通用查询任务上必然会表现更好,然而在实际使用中,依然有大量用户提问的关键词,并不在生成稀疏向量的预训练模型中,例如各种机器型号,说明书,专用词汇等等,用 3 万维表达全部关键词,还是多语言,依然会有诸多信息损失,此外还有各类业务所必须的短语查询等等,这些都是必须采用全文搜索才能实现的功能。因此,近期 IBM 的研究文章(参考文献 [3])对比了各种召回方式的组合,包括 BM25,稠密向量,BM25 + 稠密向量, 稠密向量 + 稀疏向量,以及 BM25 + 稠密向量 + 稀疏向量,最终得出结论:采用 3 路召回是所有组合中最适合 RAG 的选择,而 Infinity 已经完全内置了这种混合搜索功能。
3 路召回表现好非常容易理解,因为稠密向量可以表征语义, 稀疏向量可以在训练数据类似的场景下提供更好的精确召回,而关键词全文搜索则在各种场景下提供更加鲁棒的精确召回选择。3 种查询选择,一种都不能少,这使得 RAG 的方案设计更加复杂化,如果这些查询方式不能在一个数据库内完成,就需要用户组合多个数据库的 pipeline 来完成这一个功能,从而引入更多的工程 tricks 和复杂度,也影响了 RAG 技术的推广。例如:采用向量数据库提供稠密向量搜索和稀疏向量搜索,采用 Elasticsearch 提供关键词全文搜索,因此确保两者的数据同步就带来了技术挑战,如果一个文档在一个存储中存在,但在另一个存储中却不存在,就会带来一些错误的查询结果,所以可能需要一些其他 workaround :例如再引入一个 OLTP 数据库如 PostgreSQL 用来存放元数据,然后用一些对象存储来存放原始的文档数据,两者结合向量数据库和 Elasticsearch 来提供最终的数据同步,这是一个非常复杂的后端架构。 而如果采用 Infinity ,就无需依赖这种复杂架构,3 种格式的存储,连同原始数据一起,一次全部插入且保证数据 ACID ,3 路召回的混合搜索,一条语句就可以完成,方便且高效。

排序策略

三路召回完成后,一个直接的问题就是如何进行融合排序。Infinity 内置了多种融合排序算法:

  1. Reciprocal Rank Fusion (RRF) 算法,它是这样工作的:为每路召回的结果列表中的每个文档都根据其排序位置分配一个分数,通常,得分是其排名的倒数。例如,排名第一的文档得分为 1,排名第二的得分为 0.5,排名第三的得分为 0.33,以此类推。那么最终文档的得分就是各路召回结果的累加。RRF 算法的好处在于鲁棒性,它的简单使得这种排序不容易过拟合,针对各种用户的不同场景无需大量参数调整就可以适应。
  2. 简单权重加权融合,RRF 算法非常鲁棒,但它完全按照各路召回的排名进行打分,丢掉了原始召回中的相似度信息。在某些情况下,仍然需要进一步控制。例如这样一个问题 “请问型号为 ADX-156 的机器不能工作该如何处理”,我们需要对关键词得分提升权重。
  3. 基于外部模型的重排序,Infinity 原生支持基于 ColBERT 的重排序功能,关于这部分细节,我们在下文进一步讲解。

Infinity 提供了强大的排序组合机制,给用户提供多样化选择,如下图的 2 个例子:

第一种是 3 路召回的结果直接用 RRF 融合排序后返回。使用方式极其简单:

res = table_obj.output(['*']).match_vector('vec', [3.0, 2.8, 2.7, 3.1], 'float', 'ip', 1) .match_sparse('sparse_vec', {"indices": [0, 10, 20], "values": [0.1, 0.2, 0.3]}, 'float', 'ip', 1) .match_text('title, body', 'hello world', 'topn=10') .fusion('rrf') .to_pl()

第二种向量搜索用 ColBERT 重排序,然后结果跟关键词全文搜索做权重叠加再返回。

res = table_obj.output(['*']) .match_vector('vec', [3.0, 2.8, 2.7, 3.1], 'float', 'ip', 1) .match_sparse('sparse_vec', {"indices": [0, 10, 20], "values": [0.1, 0.2, 0.3]}, 'float', 'ip', 1) .fusion('match_tensor','column_name=t;search_tensor=[[0.0, -10.0, 0.0, 0.7], [9.2, 45.6, -55.8, 3.5]];tensor_data_type=float;match_method=MaxSim;topn=2') .match_text('title, body', 'hello world', 'topn=10')                .fusion('weighted_sum', 'weights=0.8, 0.2') .to_pl()

这些召回和融合排序手段,使得 Infinity 可以为 RAG 提供最强大易用的多路召回能力。在多路召回之外,Infinity 0.2 release 还引入了 引入了一种全新的数据类型——Tensor,在计算机科学中,Tensor 可以用来表达多个向量,多维数组,或者一个矩阵,为什么要支持这种类型呢?这要从 ColBERT 谈起。 ColBERT(参考文献 [4])是一种排序模型,距离今天已经有四年了,是信息检索领域近年来引用次数非常多的知名论文。目前排序模型的架构有这样几类范式:

  • 双编码器。以 BERT 模型为例,它针对查询和文档分别编码,最后再经过一个 Pooling 层,使得输出仅包含一个向量。在查询时的 Ranking 阶段,只需要计算两个向量相似度即可,如下图所示。双编码器既可以用于 Ranking 也可以用于 Reranking 阶段。由于双编码器针对查询和文档分别编码,因此无法捕获查询和文档的 Token 之间的复杂交互关系。

  • 交叉编码器(Cross Encoder)。Cross-Encoder 使用单编码器模型来同时编码查询和文档,它能够捕捉查询和文档之间的复杂交互关系,因此通常能够提供更精准的搜索排序结果。Cross-Encoder 并不输出查询和文档的 Token 所对应的向量,而是再添加一个分类器直接输出查询和文档的相似度得分。它的缺点在于,由于需要在查询时对每个文档和查询共同编码,这使得排序的速度非常慢,因此 Cross-Encoder 只能用于最终结果的重排序。

  • 延迟交互模型( Late Interaction Model ),就是以 ColBERT 为代表的工作。它具备一些显著区分于其他排序模型的特点:其一是相比于 Cross Encoder,ColBERT 仍采用双编码器策略,将查询和文档分别采用独立的编码器编码,因此查询的 Token 和文档的 Token 在编码时互不影响,这种分离使得文档编码可以离线处理,查询时仅针对 Query 编码,因此处理的速度大大高于 Cross Encoder;其二是相比于双编码器,ColBERT 输出的是多向量而非单向量,这是从 Transformer 的最后输出层直接获得的,而双编码器则通过一个 Pooling 层把多个向量转成一个向量输出,因此丢失了部分语义。在排序计算时,ColBERT 引入了延迟交互计算相似度函数,并将其命名为最大相似性(MaxSim),计算方法如下:对于每个查询 Token 的向量都要与所有文档 Token 对应的向量进行相似度计算,并跟踪每个查询 Token 的最大得分。查询和文档的总分就是这些最大余弦分数的总和。例如对于一个有 32 个 Token 向量的查询(最大查询长度为 32)和一个有 128 个 Token 的文档,需要执行 32*128 次相似性操作,如下图所示。因此相比之下, Cross Encoder 可以称作早期交互模型 (Early Interaction Model)。

下图从性能和排序质量上,分别对以上排序模型进行对比,并且也包含了全文搜索。图中的 Dense Encoder 既为双编码器,代表普通的向量搜索,它既可以做 Retriever,也可以做 Reranker。 由于 ColBERT 的延迟交互机制,它既满足了对排序过程中查询和文档之间复杂交互的捕获,也能实现较快的排序性能,相同数据规模下, ColBERT 的效率可达 Cross Encoder 的 100 倍以上,兼顾了性能与效果,因此 ColBERT 是一种非常有前景的排序模型。

尽管如此,在使用上,ColBERT 仍然面临 2 个问题:

  1. 尽管采用了 MaxSim 延迟交互相似度函数,使得效率大大高于 Cross Encoder,但相比普通向量搜索,计算开销仍然很大:因为查询和文档之间的相似度,是多向量计算,因此 MaxSim 的开销是普通向量相似度计算的 M * N 倍 (M 为查询的 Token 数, N 为 文档的 Token 数)。除此之外,原始的 ColBERT 在排序质量上相比 Cross Encoder 略有差距,针对这些,ColBERT 作者在 2021 年推出了 ColBERT v2 (参考文献 [5]),通过 Cross Encoder 和模型蒸馏,改进了生成的 embedding 质量,并且采用压缩技术,对生成的文档向量进行量化,从而改善 MaxSim 的计算性能。基于 ColBERT v2 包装的项目 RAGatouille (参考文献 [6])成为高质量 RAG 问答的解决方案。然而,ColBERT v2 只是一个算法库,端到端的让它在企业级 RAG 系统使用,仍然是一件困难的事情。
  2. 由于 ColBERT 是预训练模型,而训练数据来自于搜索引擎的查询和返回结果,这些文本数据并不大,例如查询 Token 数 32 , 文档 Token 数 128 是典型的长度限制。因此将 ColBERT 用于真实数据时, 超过限制的长度会被截断,这对于长文档检索并不友好。

基于以上原因, Infinity 在 0.2 版本中提供了 Tensor 数据类型,并基于此原生地提供端到端的 ColBERT 方案。
首先,Tensor 作为一种数据类型,ColBERT 编码输出的多向量,可以直接用一个 Tensor 来存放,因此 Tensor 之间的相似度就可以直接得出 MaxSim 打分。针对 MaxSim 计算,Infinity 给出了 2 种方案, 一种是 binary 量化,它可以让原始 Tensor 的空间只需原始尺寸的 1/32 , 但并不改变 MaxSim 计算的相对排序结果。这种方案主要用于 Reranker,因为需要根据前一阶段排序的结果取出对应的 Tensor 。 另一种是 Tensor 索引, Infinity 采用 [EMVB]技术(参考文献 [7])实现了 [Tensor Index]。EMVB 可以看作是 ColBERT v2 的改进,它主要通过量化和预过滤技术,并在关键操作上引入 SIMD 指令来加速实现。Tensor 索引可以用来服务 Retriever 而非 Reranker,因此结合 Infinity 的多路召回能力,用户可以进行如下各种召回选择:例如可以选择直接用 Tensor 提供语义搜索,从而实现比向量搜索更高的排序质量,也可以组合 Tensor 和全文搜索,用来做高质量的 RAG 所必备的 2 路召回,甚至可以组合向量搜索和 Tensor ,前者用来在大规模数据上粗筛,然后用 ColBERT 来快速精排,等等。Infinity 提供了足够强大的能力可以满足对于各种搜索召回的需求。

res = table_obj.output(['*']).match_tensor('t', [[0.0, -10.0, 0.0, 0.7], [9.2, 45.6, -55.8, 3.5]], 'float', 'maxsim').match_text('title, body', 'hello world', 'topn=10').fusion('weighted_sum', 'weights=0.8, 0.2').to_pl()

其次,针对超过 Token 限制的长文本,Infinity 引入了 Tensor Array 类型:

一篇超过 ColBERT 限制的文档,会被切分成多个段落,分别编码生成 Tensor 后,都跟原始文档保存在一行。计算 MaxSim 的时候,查询跟这些段落分别计算,然后取最大值作为整个文档的打分。
从 0.2 release 开始, Infinity 提供了内置的 Tensor 数据类型,并解锁了端到端的 ColBERT 应用,这使得这种以延迟交互模型为代表的排序模型,可以在较大规模数据上直接提供高质量的排序结果,对于提升 RAG 的检索质量具有非常重要的意义。

有了这么多召回手段,我们需要在真实数据集上进行相应的评测,以验证这些手段的效果。下边是 Infinity 在 MLDR 数据集上进行的评测结果,这也是 MTEB 默认采用的数据集之一。MTEB 是评估 Embedding 模型质量最权威的 Benchmark,目前排行榜上排名前列的模型基本都是基于 Cross Encoder 的编码器。

从图中看到,混合 BM25 全文搜索,可以比单纯向量搜索有显著的提升。而采用全文搜索 + 向量搜索 + 稀疏向量,就是 Blended RAG[参考文献 3],确实可以比单路搜索,以及两路混合搜索,有更好的查询质量。在 3 路混合搜索的基础上,进一步添加 ColBERT 做 Reranker,可以有进一步大的提升。同采用外部的 Reranker (例如 MTEB 排名前列的那些编码器)相比,采用 Hybrid search + ColBERT Reranker,它可以在数据库内部完成重排序,有着更高的效率,因此混合搜索可以进一步扩大 Top K 的范围(例如扩大到 Top 1000)之后再重排序,从而既保证最终召回质量还不影响性能,因此是一种性价比很高的高召回混合搜索方案。下图是各种召回方式添加 ColBERT Reranker 之后的提升效果总揽。

需要说明的是,在不同数据集上,相同的召回手段可能得到不同的返回结果,但有一点是确定的,就是混合搜索的手段越多,返回质量越好。此外,上边的评测并没有涵盖用 Tensor Index 做 Ranker 组合,这是因为在具体实验中,我们发现用 Tensor 做 Reranker 的性价比要高很多,这会在我们后边的文章中详细阐述。因此推荐的最佳混合搜索方案是 Blended RAG + ColBERT Reranker。
Infinity 0.2 release,不仅提供了行业最全的混合搜索能力,还提供最快的混合搜索能力。下文来描述 Infinity 如何做到这一点。
Infinity 是一款在存储引擎和执行引擎层面都精细设计的数据库。 如下是 Infinity 的执行引擎工作流程,可以看到,在完成针对 API 的查询绑定后,接下来执行计划会被编译成一个流水线执行计划。这种机制,常见于一些现代数据仓库,所不同的是,数据仓库的流水线执行,通常服务于并行执行,而 Infinity 的流水线,则同时服务查询的并行和并发执行,需要保证了高并发执行时查询算子的最佳调度策略和 CPU 亲和性,避免了无效上下文切换导致的开销。这种设计,使得查询的端到端开销非常小,完整的查询延迟并不会比运行单独的算法库增加多少。

上图的右边是一个多路召回的查询样例,图中包含 2 个数据 segment 上的向量搜索执行算子,2 个算子并行执行,以及一个向量搜索的 Top K 合并算子负责合并来自 2 个 segment 的向量搜索结果;还有一个全文搜索算子,两路召回最后是一个 Fusion 融合算子,这些算子在内存中形成一个 DAG 图,由查询执行器负责运行期调度。
存储引擎方面,Infinity 建立了完整的以列存为基础的索引体系,对于多路召回的每一路,都有相对应的索引负责高性能检索,这也使得 Infinity 添加新的类型支持变得非常方便。因此,Infinity 可以看做是一个以列存为基础的全索引数据库,这跟近期 OpenAI 收购的 Rockset 有着相似的特性,而在索引的类型上,Infinity 则提供更加丰富的选择。

下边来看 Infinity 的索引实现。
跟许多向量数据库一样,默认情况下 Infinity 也采用了 HNSW 作为向量索引的实现。但 Infinity 的 HNSW 进行了一系列深入优化,具体来讲,就是对每个需要建立索引的向量进行局部自适应量化——通过对每个向量进行缩放和量化操作来提升搜索性能,使得相似性计算速度极快,有效带宽降低,同时减少内存占用,却几乎不影响准确性,因此实质上是这一种压缩技术。
具体的,Infinity 对每个向量采用了两级量化:其中一级量化是针对每个向量和全部向量的均值之间的差值进行量化编码。一级量化主要在 HNSW 图遍历期间使用,通过将向量压缩到较少的规模,从而有效减少实际消耗的内存带宽,提高搜索性能。二级量化负责对前述差值后的残差进行量化编码,它主要用于最后的相似度比对,提高查询精度。局部量化技术因为只针对每个向量进行量化,并不改变任何向量之间的最近邻关系,因此具备随机内存访问模式,所以特别适合基于图索引的相似度搜索。在 Infinity 中,HNSW 索引只基于一级量化的结果来构建,所以查询性能和内存占用都大大优于传统的 HNSW 索引。除了局部量化技术之外,Infinity 采用大量 SIMD 针对距离做加速计算,得益于这些设计,Infinity 的向量搜索性能超出同类许多,下图是 Infinity 和其他向量数据库的 benchmark 对比:

针对全文索引,Infinity 也是采取了全新实现的方案,而没有引入一些流行的全文索引库如 Tantivy,Lucene 等等。这是因为全文索引只是 Infinity 的一个组件,它需要紧密地跟存储引擎和执行引擎高效率协同工作。这体现在几个方面:

  1. 全文索引需要支持实时数据插入。
  2. 全文索引包含倒排索引和前向索引,而前向索引的能力,跟数据库的功能是重叠的,因此简单地整合,必然导致不必要的冗余。
  3. 全文索引还需要跟其他索引返回的结果一起做融合排序,这需要搜索的逻辑跟执行引擎紧密配合。

除却以上因素,Infinity 是一款专用于 RAG 的数据库,对于 RAG 来说,它需要根据用户的提问搜索到答案,由于用户的提问可能会比较长,因此在默认情况下,查询的关键词之间不能提供 “AND” 语义而应提供 “OR” 语义,否则很容易导致零召回。然而,“OR”语义对性能是极大地损害,因为任何一个关键词命中的结果都会被打分,并送到最终的结果排序,所以全文索引需要采用动态查询剪枝技术,减少不必要的打分和排序。
例如近十年来学术界最佳的动态查询剪枝方案,是以 WAND,MaxScore 等为代表的系列技术。尽管全文搜索是一个相对成熟的领域,然而在当下,也只有 Lucene,Tantivy 等少数全文索引库具备生产级的算法实现。Infinity 实现了完整的 Block Max WAND 和 Block Max MaxScore 技术,两种查询动态剪枝策略适应的场景略有不同,在默认情况下,Infinity 选择采用 Block Max WAND (参考文献 [9])来作为首选剪枝策略。
WAND 是 Weak AND 的缩写,它针对全文搜索最常见的打分手段 BM25 进行查询时动态剪枝,通过计算每个关键词贡献的上限来估计最终 Top K 结果的上限,并以此为阀值来决定在倒排索引的上如何快速跳过不必要的文档 ID,从而得到提速的效果。每个关键词贡献的上限,根据该关键词的的 IDF(在多少文档中出现) 和最大 TF(在文档中出现的最大词频) 来确定。

上图是 Infinity 和 Elasticsearch 的全文搜索性能对比,测试方法如下:

  1. 索引数据集为 wikipedia 33M,数据集大小 32GB。
  2. 从数据集中根据词频生成词表,按照 IDF 词频分布百分比分别随机选取关键词生成查询。查询长度从 3 个 Term 到 19 个 Term,生成的查询文件在这里https://github.com/infiniflow/benchmark/tree/main/enwiki_queries。Infinity 和 Elasticsearch 均采用默认 Top-K Union 的语义(OR)进行查询。
  3. Infinity 和 Elasticsearch 均给予一定预热时间,使得索引数据尽可能缓存在操作系统的 pagecache 中。

可以看到,不论是长查询,还是短查询, Infinity 相比 Elasticsearch 均具备压倒性优势,并且在测试过程中 Infinity 的内存消耗仅有 Elasticsearch 的 1/2。因此,提供 RAG 所必备的混合搜索能力(全文搜索 + 向量搜索),此前用户的唯一选择是 Elasticsearch(包括 Opensearch),而现在不仅仅多了 Infinity 这个选项,而且在性能上也远远超过了这些选择。
针对稀疏向量索引,Infinity 采用了跟全文搜索类似的设计,都采用倒排索引 + 查询动态剪枝的策略,所不同的是,稀疏向量首先按照区块组织成前向索引,倒排索引只用来存放跟固定区块有关的信息,查询时用来从一个区块跳转到另一个区块,而具体的相似度计算,则通过前向索引来进行。因此,稀疏向量索引并没有包含一个标准的倒排索引,而是基于 Block 的倒排索引跟前向索引的混合方案。该具体算法来源于 SIGIR 2024 的 Best Paper Runner Up 论文(参考文献 9)。
下图是 Infinity 跟知名向量数据库 Qdrant 在稀疏向量索引上的性能评测:

由此可见,在稠密向量、稀疏向量、全文搜索三种召回手段上, Infinity 的性能均达到了极致,再加上强大的多路召回能力,以及各种的 Reranker 尤其是基于张量的 Reranker,可以说 Infinity 不仅仅是目前最快的 RAG 专用数据库,也是最强大的 RAG 数据库选择。
参考文献

  1. SPLADE v2: Sparse Lexical and Expansion Model for Information Retrieval, [https://arxiv.org/abs/2109.10086], 2021
  2. Bge m3-embedding: Multi-lingual, multi-functionality, multi-granularity text embeddings through self-knowledge distillation, [https://arxiv.org/abs/2402.03216] , 2024
  3. Blended RAG: Improving RAG (Retriever-Augmented Generation) Accuracy with Semantic Search and Hybrid Query-Based Retrievers, [https://arxiv.org/abs/2404.07220] , 2024
  4. Colbert: Efficient and effective passage search via contextualized late interaction over bert, SIGIR 2020.
  5. Colbertv2: Effective and efficient retrieval via lightweight late interaction, arXiv:2112.01488, 2021.
  6. RAGatouille [https://github.com/bclavie/RAGatouille]
  7. Efficient Multi-vector Dense Retrieval with Bit Vectors, ECIR 2024.
  8. Ding, Shuai and Suel, Torsten. Faster top-k document retrieval using block-max indexes. SIGIR 2011
  9. Mallia, Antonio and Suel, Torsten and Tonellotto, Nicola, Faster learned sparse retrieval with block-max pruning. SIGIR 2024

相关文章:

多维度信息捕捉:利用向量、稀疏向量、全文搜索及张量实现RAG的极致性能

开源 AI 原生数据库 Infinity 0.2 release 正式发布,提供了 2 种新数据类型:稀疏向量Sparse Vector 和 张量Tensor,在此前的全文搜索和向量搜索之外, Infinity 提供了更多的召回手段,如下图所示,用户可以采…...

vscode使用remote ssh插件连接服务器的问题

本人今天发现自己的vscode使用remote ssh连接不上服务器了,表现是:始终在初始化 解决方法: 参考链接:vscode remote-ssh 连接失败的基本原理和优雅的解决方案 原因 vscode 的 SSH 之所以能够拥有比传统 SSH 更加强大的功能&a…...

基础版-图书管理系统

现在我们用面向对象编程,首先我们要明确这个图书管理系统的对象有哪些? 图书管理需要管理图书(对象1),在哪管理图书呢?书架(对象2)上 然后由谁来管呢?有两类人&#xf…...

【单片机 C语言】单片机学习过程中常见C库函数(学习笔记)

memset() ​C 标准库 - <string.h> string .h 头文件定义了一个变量类型、一个宏和各种操作字符数组的函数。 <string.h> 是 C 标准库中的一个头文件&#xff0c;提供了一组用于处理字符串和内存块的函数。这些函数涵盖了字符串复制、连接、比较、搜索和内存操作…...

神经网络优化 - 小批量梯度下降之批量大小的选择

上一博文学习了小批量梯度下降在神经网络优化中的应用&#xff1a; 神经网络优化 - 小批量梯度下降-CSDN博客 在小批量梯度下降法中&#xff0c;批量大小(Batch Size)对网络优化的影响也非常大&#xff0c;本文我们来学习如何选择小批量梯度下降的批量大小。 一、批量大小的…...

Novartis诺华制药社招入职综合能力测评真题SHL题库考什么?

一、综合能力测试 诺华制药的入职测评中&#xff0c;综合能力测试是重要的一部分&#xff0c;主要考察应聘者的问题解决能力、数值计算能力和逻辑推理能力。测试总时长为46分钟&#xff0c;实际作答时间为36分钟&#xff0c;共24题。题型丰富多样&#xff0c;包括图形变换题、分…...

文件的物理结构和逻辑结构的区分

文件的物理结构和逻辑结构是文件系统中两个重要的概念&#xff0c;它们分别描述了文件在存储设备上的实际存储方式以及用户在编程或操作文件时所看到的抽象组织形式。理解这两者的区别和联系对于深入掌握文件系统的设计和实现至关重要。 ​一、文件的逻辑结构 ​定义 文件的逻…...

C语言学习记录(16)文件操作7

前面学的东西感觉都跟写代码有关系&#xff0c;怎么突然就开始说文件了&#xff0c;有什么用呢&#xff1f; 其实&#xff0c;文件是另一种数据存储的方式&#xff0c;学会使用文件就可以让我们的数据持久的保存。 一、文件是什么 就算没有学过相关的知识&#xff0c;在这么…...

Coze平台​ 创建AI智能体的详细步骤指南

一、创建智能体的基础流程​ ​注册与登录​ 访问Coze官网&#xff08;www.coze.cn&#xff09;&#xff0c;使用邮箱或手机号注册账号并登录。 ​创建智能体​ 在控制台点击左侧“”按钮&#xff0c;选择“创建智能体”&#xff0c;输入名称&#xff08;如“职场鼓励师”&…...

《作用域大冒险:从闭包到内存泄漏的终极探索》

“爱自有天意&#xff0c;天有道自不会让有情人分离” 大家好&#xff0c;关于闭包问题其实实际上是js作用域的问题&#xff0c;那么js有几种作用域呢&#xff1f; 作用域类型关键字/场景作用域范围示例全局作用域var&#xff08;无声明&#xff09;整个程序var x 10;函数作用…...

android Stagefright框架

作为Android音视频开发人员&#xff0c;学习Stagefright框架需要结合理论、源码分析和实践验证。以下是系统化的学习路径&#xff1a; 1. 基础准备 熟悉Android多媒体体系 掌握MediaPlayer、MediaCodec、MediaExtractor等核心API的用法。 理解Android的OpenMAX IL&#xff08…...

Shell脚本-变量的分类

在Shell脚本编程中&#xff0c;变量是存储数据的基本单位。它们可以用来保存字符串、数字甚至是命令的输出结果。正确地定义和使用变量能够极大地提高脚本的灵活性与可维护性。本文将详细介绍Shell脚本中变量的不同分类及其应用场景&#xff0c;帮助你编写更高效、简洁的Shell脚…...

<C#>.NET WebAPI 的 FromBody ,FromForm ,FromServices等详细解释

在 .NET 8 Web API 中&#xff0c;[FromBody]、[FromForm]、[FromHeader]、[FromKeyedServices]、[FromQuery]、[FromRoute] 和 [FromServices] 这些都是用于绑定控制器动作方法参数的特性&#xff0c;下面为你详细解释这些特性。 1. [FromBody] 作用&#xff1a;从 HTTP 请求…...

让数据应用更简单:Streamlit与Gradio的比较与联系

在数据科学与机器学习的快速发展中&#xff0c;如何快速构建可视化应用成为了许多工程师和数据科学家的一个重要需求。Streamlit和Gradio是两款备受欢迎的开源库&#xff0c;它们各自提供了便捷的方式来构建基于Web的应用。虽然二者在功能上有许多相似之处&#xff0c;但它们的…...

LlamaIndex 生成的本地索引文件和文件夹详解

LlamaIndex 生成的本地索引文件和文件夹详解 LlamaIndex 在生成本地索引时会创建一个 storage 文件夹&#xff0c;并在其中生成多个 JSON 文件。以下是每个文件的详细解释&#xff1a; 1. storage 文件夹结构 1.1 docstore.json 功能&#xff1a;存储文档内容及其相关信息。…...

AndroidRom定制删除Settings某些菜单选项

AndroidRom定制删除Settings某些菜单选项 1.前言. 最近在Rom开发中需要隐藏设置中的某些菜单&#xff0c;launcher3中的定制开发&#xff0c;这个属于很基本的定制需求&#xff0c;和隐藏google搜素栏一样简单&#xff0c;这里我就不展开了&#xff0c;直接上代码. 2.隐藏网络…...

Mysql相关知识2:Mysql隔离级别、MVCC、锁

文章目录 MySQL的隔离级别可重复读的实现原理Mysql锁按锁的粒度分类按锁的使用方式分类按锁的状态分类 MySQL的隔离级别 在 MySQL 中&#xff0c;隔离级别定义了事务之间相互隔离的程度&#xff0c;用于控制一个事务对数据的修改在何时以及如何被其他事务可见。MySQL 支持四种…...

Python爬虫实战:获取海口最近2周天气数据,为出行做参考

一、引言 天气状况对人们的出行计划影响重大。获取准确的天气信息并进行分析,能助力用户更好地规划出行。天气网虽提供丰富的天气数据,但因网站存在反爬机制,直接获取数据存在一定难度。本研究借助 Python 的 Scrapy 框架,结合多种技术手段,实现对海口最近两周天气数据的…...

并发设计模式之双缓冲系统

双缓冲的本质是 ​​通过空间换时间​​&#xff0c;通过冗余的缓冲区解决生产者和消费者的速度差异问题&#xff0c;同时提升系统的并发性和稳定性。 双缓冲的核心优势 优势具体表现解耦生产与消费生产者和消费者可以独立工作&#xff0c;无需直接同步。提高并发性生产者和消…...

linux sysfs的使用

在Linux内核驱动开发中&#xff0c;device_create_file 和 device_remove_file 用于动态创建/删除设备的 sysfs 属性文件&#xff0c;常用于暴露设备信息或控制参数。以下是完整示例及详细说明&#xff1a; 1. 头文件引入 #include <linux/module.h> #include <linux/…...

【数据结构和算法】3. 排序算法

本文根据 数据结构和算法入门 视频记录 文章目录 1. 排序算法2. 插入排序 Insertion Sort2.1 概念2.2 具体步骤2.3 Java 实现2.4 复杂度分析 3. 快排 QuickSort3.1 概念3.2 具体步骤3.3 Java实现3.4 复杂度分析 4. 归并排序 MergeSort4.1 概念4.2 递归具体步骤4.3 Java实现4.4…...

LintCode第192题-通配符匹配

描述 给定一个字符串 s 和一个字符模式 p &#xff0c;实现一个支持 ? 和 * 的通配符匹配。匹配规则如下&#xff1a; ? 可以匹配任何单个字符。* 可以匹配任意字符串&#xff08;包括空字符串&#xff09;。 两个串完全匹配才算匹配成功。 样例 样例1 输入: "aa&q…...

redis常用的五种数据类型

redis常用的五种数据类型 文档 redis单机安装redis数据类型-位图bitmap 说明 官网操作命令指南页面&#xff1a;https://redis.io/docs/latest/commands/?nameget&groupstring 常用命令 keys *&#xff1a;查看所有键exists k1 k2&#xff1a;键存在个数type k1&…...

Linux 进程与线程间通信方式及应用分析

Linux 进程与线程间通信方式及应用分析 文章目录 Linux 进程与线程间通信方式及应用分析 1. 管道&#xff08;Pipe&#xff09;1.1 匿名管道&#xff08;Anonymous Pipe&#xff09;示例代码&#xff1a;结果&#xff1a; 1.2 命名管道&#xff08;FIFO&#xff09;示例代码&am…...

AI日报 - 2024年04月22日

&#x1f31f; 今日概览(60秒速览) ▎&#x1f916; 模型进展 | Google发布Gemini 2.5 Flash&#xff0c;强调低延迟与成本效益&#xff1b;Kling AI 2.0展示多轴运动视频生成&#xff1b;研究揭示SLM在知识图谱上优于LLM&#xff0c;RLHF在推理提升上存局限。 ▎&#x1f4bc;…...

FreeRTos学习记录--2.内存管理

后续的章节涉及这些内核对象&#xff1a;task、queue、semaphores和event group等。为了让FreeRTOS更容易使用&#xff0c;这些内核对象一般都是动态分配&#xff1a;用到时分配&#xff0c;不使用时释放。使用内存的动态管理功能&#xff0c;简化了程序设计&#xff1a;不再需…...

HAL库(STM32CubeMX)——高级ADC学习、HRTIM(STM32G474RBT6)

系列文章目录 文章目录 系列文章目录前言存在的问题HRTIMcubemx配置前言 对cubemx的ADC的设置进行补充 ADCs_Common_Settings Mode:ADC 模式 Independent mod 独立 ADC 模式,当使用一个 ADC 时是独立模式,使用两个 ADC 时是双模式,在双模式下还有很多细分模式可选 ADC_Se…...

单例模式(线程安全)

1.什么是单例模式 单例模式&#xff08;Singleton Pattern&#xff09;是一种创建型设计模式&#xff0c;旨在确保一个类只有一个实例&#xff0c;并提供一个全局访问点来访问该实例。这种模式涉及到一个单一的类&#xff0c;该类负责创建自己的对象&#xff0c;同时确保只有单…...

FreeRTos学习记录--1.工程创建与源码概述

1.工程创建与源码概述 1.1 工程创建 使用STM32CubeMX&#xff0c;可以手工添加任务、队列、信号量、互斥锁、定时器等等。但是本课程不想严重依赖STM32CubeMX&#xff0c;所以不会使用STM32CubeMX来添加这些对象&#xff0c;而是手写代码来使用这些对象。 使用STM32CubeMX时&…...

基于大模型的血栓性外痔全流程风险预测与治疗管理研究报告

目录 一、引言 1.1 研究背景与目的 1.2 研究意义 二、血栓性外痔概述 2.1 定义与发病机制 2.2 临床表现与诊断方法 2.3 现有治疗手段综述 三、大模型在血栓性外痔预测中的应用原理 3.1 大模型技术简介 3.2 模型构建与训练数据来源 3.3 模型预测血栓性外痔的工作流程…...