HyDE:改善大模型的信息检索的方法

HyDE

HyDE介绍

HyDE,全称为Hypothetical Document Embeddings,是一种用于改进信息检索的方法。它通过生成可用于回答用户输入问题的假设文档,来对齐查询和文档的语义空间。这些文档是由大型语言模型(LLM)根据它们自身学习到的知识生成的,然后这些文档被向量化,用于从索引中检索文档。HyDe的工作过程是从使用LLM基于查询生成假设文档开始的,在完成了假设文档的生成后将生成的假设文档输入编码器,将其映射到密集向量空间中。计算生成文档的向量的平均值,该向量保存来自用户的查询和所需答案模式的信息,使用向量从文档库中检索答案,以提高检索的准确性和召回率。

HyDE(Hypothetical Document Embeddings)的优越性主要体现在以下几个方面:

  • 无需人工标注数据:HyDE能够在没有人工标注数据的情况下进行zero-shot稠密检索,这使得它在没有足够训练数据的场景下也能发挥作用。
  • 提高语义对齐:HyDE通过生成假设文档来对齐查询和文档的语义空间,这有助于改善查询和检索文档之间的语义匹配,尤其是在原始查询较短或措辞不准确时。
  • 提升检索效果:HyDE通过生成的假设文档来增强检索结果的相关性,这可以提高检索的准确性和召回率。
  • 适应性强:HyDE能够适应不同的查询类型,包括那些需要高级概念抽象推理的查询,通过生成假设文档来改善检索结果。
  • 易于集成:HyDE可以与现有的检索系统和大型语言模型(LLM)集成,无需对现有系统进行大规模修改即可提升性能。
  • 改善特定查询的召回效果:对于某些特定的查询,HyDE通过生成包含关键信息的假设文档,能够显著提升召回效果,尤其是当原始查询难以直接匹配到相关文档时。
  • 无监督学习:HyDE不需要训练任何模型,它使用的生成模型和对比编码器都保持不变,这减少了对训练数据的依赖。
  • 提升向量检索的解释性:HyDE通过生成假设文档,可以提高向量检索的可解释性,使得检索结果更容易被理解和分析。

这些优越性使得HyDE成为一种强大的工具,可以显著提升信息检索系统的性能,尤其是在需要处理复杂查询或缺乏标注数据的情况下。任何一种技术方案有优点就会有缺点,HyDE的缺点如下:

  • 生成文档的准确性:生成的假设文档可能包含错误的细节,这会影响检索结果的相关性。虽然HyDE使用无监督编码来过滤错误细节,但生成文档的准确性仍然是一个挑战。
  • 计算和存储成本:HyDE涉及生成文档和向量化处理,这可能导致较高的计算和存储成本,尤其是在处理大规模文档库时。
  • 索引时间:生成假设文档并进行编码可能需要一定的时间,这可能会影响检索系统的响应速度。
  • 结果解释性:虽然HyDE提高了检索的语义对齐,但生成的假设文档可能难以解释,这可能会降低检索结果的可解释性。
  • 特定查询的限制:HyDE可能在某些特定类型的查询上表现更好,而在其他类型的查询上可能效果不佳,这取决于生成的假设文档与实际文档的相关性。
  • 对训练数据的依赖:尽管HyDE是一种无监督学习方法,但它的性能仍然可能受到语言模型训练数据质量和数量的影响。
  • 可能的偏差:大型语言模型可能存在偏差,这可能会通过生成的假设文档传递到检索结果中,导致偏差或不公平的检索结果。
  • 技术复杂性:HyDE的实现可能相对复杂,需要专业知识来集成和优化,这可能限制了其在某些应用场景中的使用。
  • 对特定领域知识的适应性:HyDE可能需要针对特定领域进行调整,以生成更准确的假设文档,这可能需要额外的领域知识或定制化的工作。

HyDE的代码实现

在这里插入图片描述

HyDE既有显著提升信息检索系统的性能的优点,也有一些潜在的缺点,但是HyDE仍然是一种有前景的技术,仍然在信息检索领域发挥重要作用。LlamaIndex就提供了HyDE的实现方式,具体如下代码。
首先引入依赖

from llama_index.core import (
    SimpleDirectoryReader,
    VectorStoreIndex,
    StorageContext,
    Settings,
    get_response_synthesizer)
from llama_index.core.query_engine import RetrieverQueryEngine, TransformQueryEngine
from llama_index.core.node_parser import SentenceSplitter
from llama_index.core.schema import TextNode, MetadataMode
from llama_index.vector_stores.qdrant import QdrantVectorStore
from llama_index.embeddings.ollama import OllamaEmbedding
from llama_index.llms.ollama import Ollama
from llama_index.core.retrievers import VectorIndexRetriever
from llama_index.core.indices.query.query_transform import HyDEQueryTransform
import qdrant_client
import logging

初始化变量

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# load the local data directory and chunk the data for further processing
docs = SimpleDirectoryReader(input_dir="data", required_exts=[".pdf"]).load_data(show_progress=True)
text_parser = SentenceSplitter(chunk_size=512, chunk_overlap=100)

text_chunks = []
doc_ids = []
nodes = []

创建向量存储

# Create a local Qdrant vector store
logger.info("initializing the vector store related objects")
client = qdrant_client.QdrantClient(host="localhost", port=6333)
vector_store = QdrantVectorStore(client=client, collection_name="research_papers")

初始化llm和embeddingmodle

# local vector embeddings model
logger.info("initializing the OllamaEmbedding")
embed_model = OllamaEmbedding(model_name='mxbai-embed-large', base_url='http://localhost:11434')
logger.info("initializing the global settings")
Settings.embed_model = embed_model
Settings.llm = Ollama(model="llama3", base_url='http://localhost:11434')
Settings.transformations = [text_parser]

完成HyDE的调用

logger.info("enumerating docs")
for doc_idx, doc in enumerate(docs):
    curr_text_chunks = text_parser.split_text(doc.text)
    text_chunks.extend(curr_text_chunks)
    doc_ids.extend([doc_idx] * len(curr_text_chunks))

logger.info("enumerating text_chunks")
for idx, text_chunk in enumerate(text_chunks):
    node = TextNode(text=text_chunk)
    src_doc = docs[doc_ids[idx]]
    node.metadata = src_doc.metadata
    nodes.append(node)

logger.info("enumerating nodes")
for node in nodes:
    node_embedding = embed_model.get_text_embedding(
        node.get_content(metadata_mode=MetadataMode.ALL)
    )
    node.embedding = node_embedding

logger.info("initializing the storage context")
storage_context = StorageContext.from_defaults(vector_store=vector_store)
logger.info("indexing the nodes in VectorStoreIndex")
index = VectorStoreIndex(
    nodes=nodes,
    storage_context=storage_context,
    transformations=Settings.transformations,
)

logger.info("initializing the VectorIndexRetriever with top_k as 5")
vector_retriever = VectorIndexRetriever(index=index, similarity_top_k=5)
response_synthesizer = get_response_synthesizer()
logger.info("creating the RetrieverQueryEngine instance")
vector_query_engine = RetrieverQueryEngine(
    retriever=vector_retriever,
    response_synthesizer=response_synthesizer,
)
logger.info("creating the HyDEQueryTransform instance")
hyde = HyDEQueryTransform(include_original=True)
hyde_query_engine = TransformQueryEngine(vector_query_engine, hyde)

logger.info("retrieving the response to the query")
response = hyde_query_engine.query(
    str_or_query_bundle="what are all the data sets used in the experiment and told in the paper")
print(response)

client.close()
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

质问

开心就好

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值