【IR 论文】Query2doc — 使用 LLM 做 Query Expansion 来提高信息检索能力

本文主要是介绍【IR 论文】Query2doc — 使用 LLM 做 Query Expansion 来提高信息检索能力,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

论文:Query2doc: Query Expansion with Large Language Models
⭐⭐⭐⭐⭐
Microsoft Research, EMNLP 2023

文章目录

    • 背景介绍
    • Query2doc 论文速读
    • 实现细节
    • 实验结果和分析
    • 总结分析

背景介绍

信息检索(Information Retrieval,IR)指的是,给定一个 user query,从一个 large corpus 中定位出相关的文档。

目前信息检索有两个主流的范式:

  1. Lexical-based sparse retrieval(基于词汇的稀疏检索):是一类经典的 IR 方法,它依赖于文本的词汇内容和它们的统计特性。这种方法的核心是将文档和查询表示为词汇的集合,然后通过计算这些集合之间的相似度来检索文档。其中最著名的稀疏检索模型是 BM25,它使用词频(term frequency, TF)和逆文档频率(inverse document frequency, IDF)来评估查询词与文档的匹配程度。这类方法简单高效且计算效率搞,但检索效果很大程度上依赖于 query 与 doc 中词汇的匹配程度。
  2. Embedding-based dense retrieval(基于 embedding 的稠密检索):是一种较为现代的信息检索方法。这种方法将文本转为 embedding 向量,这种 embedding 能够捕捉到词汇和短语的语义信息,并通过计算向量之间的距离(如余弦相似度)来检索相关文档。这类方法能够捕捉到词汇之间的语义关系,但更需要更多的计算资源。

尽管经典的 BM25 在很多场景下表现不如基于 embedding 的方法,但 BM25 在跨领域的场景下表现还是很不错的。

Query Expansion 是 IR 领域中的一项关键技术,旨在改善查询与文档之间的匹配度,从而提高检索系统的准确性和相关性。Query Expansion 的基本思想是,通过某些方法对用户原始查询进行扩展,添加额外的词汇或短语,以更好地捕捉用户的检索意图。Query Expansion 的挑战在于选择与用户意图高度相关的词汇,同时避免引入噪声或不相关的信息。有效的 Query Expansion 可以显著提高检索系统的性能,尤其是在处理短查询或模糊查询时。然而,不恰当的扩展可能会降低检索质量,因此 Query Expansion 策略的选择和优化是 IR 中的一个活跃研究方向。

Query2doc 论文速读

论文采用的思路很简单,但效果却很不错。

Query2doc 图示

思路:先把 user query 带上 prompt 问一下 LLM,让 LLM 先生成一个关于这个问题的回复,这里称这个回复为伪文档,然后把伪文档和 user query 拼接在一起,实现了 Query Expansion,将扩展后的 query 再送给 Retriever 实现检索。

这里的 Retriever 可以是之前的任何检索器,可以是 sparse retrieval,也可以是 dense retrieval。

实现细节

下图是一个根据 user query 让 LLM 生成一个伪文档的示例:

LLM 生成示例

其实就是先给一个指令 “Write a passage that answers the given query:”,然后再给他 k 个 few-shot 的 exemplars,从而让他根据 query 生成伪文档回复。

论文选用的 exemplars 的数量 k = 4

现在,我们有了原始 query q q q、LLM 生成的伪文档 d ′ d' d,现在我们需要把它们拼接成扩展后的 query q + q^+ q+,这里的拼接有点小技巧,对于 sparse retrieval 和 dense retrieval 有着不同的拼接方法:

  • 对于 sparse retrieval:由于 q q q 往往比伪文档更加简短,为了平衡两者的权重,这里故意将 q q q 重复几次之后再与 d ′ d' d 进行拼接:

sparse retrieval 的拼接

  • 对于 dense retrieval:这时 query 和 document 都被表示为 embedding vector,这种情况下,不需要通过重复查询词汇来增加其权重,因为检索系统已经能够通过向量表示来捕捉查询和文档之间的语义关系。所以在这里,就直接将两者中间加一个 SEP 直接拼接在一起就好了:

dense retrieval 的拼接

对于 dense retrieval 的场景,最大的困难并不在拼接,而在于训练,由于输入 query 和文档仍旧不是一个分布(两者语义并不相同甚至完全不相同,只是匹配),我们仍然需要针对特定的数据集或检索任务进行训练或微调模型。本论文工作对密集检索模型进行了训练,并展示了如何将新的查询扩展技术与这些模型结合,以提高信息检索系统的整体性能。具体的训练细节可以参考原论文。

实验结果和分析

实验结果数据如下,可以从中看到,使用了 query2doc 的 Query Expansion 技术后,效果都有了不错的提升。

实验结果
除此之外,作者还做出了以下分析:

  • 模型大小的提升对最终的召回效果是有收益的,随着模型变大,生成的文本对预测效果有提升
  • 该方案本身对向量表征模型的训练,也是有明显收益的。
  • 对字面检索而言,原始 query 和大模型生成的回复之间,是互补关系,两者组合才能真正达到提升

作者还使用案例来分析了该方案生效的可能原因:大模型直接生成一个答案,很大程度拉近了检索词和文档之间在语义空间上的相似,因为本质上两者都是回复问题

但是,由于 LLM 存在幻觉问题,其生成的答案可能并不准确,如果 LLM 生成的关键信息出现错误的话,那么这个错误很可能会导致最终检索结果的错误。

总之,该方案简单易行,有好处也有坏处,还是需要根据具体的场景来使用。

总结分析

这里参考 微软新文query2doc:用大模型做query检索拓展 的总结

Query2doc 的思路很简单,但其背后做的实验和分析很有价值,在现实应用中也很有意义,所以单独把这篇文章进行了分享。然而在现实中,仍旧有很多细节问题还需要进一步考虑,我还没完全想好,不过应该是逃不开的:

  • 现实场景下的召回相似度应该如何计算,尤其是向量相似度,这里需要很多的数据支撑。
  • 召回后的下一步,仍旧依赖相对完善的精排模块,也需要考虑类似的匹配机制,否则即使召回层有了召回,排序层面也会被排到后面去。
  • 大模型本身的幻觉问题,会对召回带来很大的影响,该问题对召回还是有影响的,需要考虑如何尽可能剔除或者缓解。
  • 性能问题,依赖大模型是能够有所提升,但是多一次的大模型的请求,无疑让整体耗时有了很大的影响。(这点在论文中也有提及)

这篇关于【IR 论文】Query2doc — 使用 LLM 做 Query Expansion 来提高信息检索能力的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/930334

相关文章

Java中流式并行操作parallelStream的原理和使用方法

《Java中流式并行操作parallelStream的原理和使用方法》本文详细介绍了Java中的并行流(parallelStream)的原理、正确使用方法以及在实际业务中的应用案例,并指出在使用并行流... 目录Java中流式并行操作parallelStream0. 问题的产生1. 什么是parallelS

Linux join命令的使用及说明

《Linuxjoin命令的使用及说明》`join`命令用于在Linux中按字段将两个文件进行连接,类似于SQL的JOIN,它需要两个文件按用于匹配的字段排序,并且第一个文件的换行符必须是LF,`jo... 目录一. 基本语法二. 数据准备三. 指定文件的连接key四.-a输出指定文件的所有行五.-o指定输出

Linux jq命令的使用解读

《Linuxjq命令的使用解读》jq是一个强大的命令行工具,用于处理JSON数据,它可以用来查看、过滤、修改、格式化JSON数据,通过使用各种选项和过滤器,可以实现复杂的JSON处理任务... 目录一. 简介二. 选项2.1.2.2-c2.3-r2.4-R三. 字段提取3.1 普通字段3.2 数组字段四.

Linux kill正在执行的后台任务 kill进程组使用详解

《Linuxkill正在执行的后台任务kill进程组使用详解》文章介绍了两个脚本的功能和区别,以及执行这些脚本时遇到的进程管理问题,通过查看进程树、使用`kill`命令和`lsof`命令,分析了子... 目录零. 用到的命令一. 待执行的脚本二. 执行含子进程的脚本,并kill2.1 进程查看2.2 遇到的

详解SpringBoot+Ehcache使用示例

《详解SpringBoot+Ehcache使用示例》本文介绍了SpringBoot中配置Ehcache、自定义get/set方式,并实际使用缓存的过程,文中通过示例代码介绍的非常详细,对大家的学习或者... 目录摘要概念内存与磁盘持久化存储:配置灵活性:编码示例引入依赖:配置ehcache.XML文件:配置

Java 虚拟线程的创建与使用深度解析

《Java虚拟线程的创建与使用深度解析》虚拟线程是Java19中以预览特性形式引入,Java21起正式发布的轻量级线程,本文给大家介绍Java虚拟线程的创建与使用,感兴趣的朋友一起看看吧... 目录一、虚拟线程简介1.1 什么是虚拟线程?1.2 为什么需要虚拟线程?二、虚拟线程与平台线程对比代码对比示例:三

k8s按需创建PV和使用PVC详解

《k8s按需创建PV和使用PVC详解》Kubernetes中,PV和PVC用于管理持久存储,StorageClass实现动态PV分配,PVC声明存储需求并绑定PV,通过kubectl验证状态,注意回收... 目录1.按需创建 PV(使用 StorageClass)创建 StorageClass2.创建 PV

Redis 基本数据类型和使用详解

《Redis基本数据类型和使用详解》String是Redis最基本的数据类型,一个键对应一个值,它的功能十分强大,可以存储字符串、整数、浮点数等多种数据格式,本文给大家介绍Redis基本数据类型和... 目录一、Redis 入门介绍二、Redis 的五大基本数据类型2.1 String 类型2.2 Hash

Redis中Hash从使用过程到原理说明

《Redis中Hash从使用过程到原理说明》RedisHash结构用于存储字段-值对,适合对象数据,支持HSET、HGET等命令,采用ziplist或hashtable编码,通过渐进式rehash优化... 目录一、开篇:Hash就像超市的货架二、Hash的基本使用1. 常用命令示例2. Java操作示例三

Linux创建服务使用systemctl管理详解

《Linux创建服务使用systemctl管理详解》文章指导在Linux中创建systemd服务,设置文件权限为所有者读写、其他只读,重新加载配置,启动服务并检查状态,确保服务正常运行,关键步骤包括权... 目录创建服务 /usr/lib/systemd/system/设置服务文件权限:所有者读写js,其他