检索原理
HyDEQueryTransform
是一种用于信息检索系统中的查询转换技术,它基于假设文档嵌入(Hypothetical Document Embeddings,简称HyDE)的概念,旨在通过生成假设文档来改善查询与文档之间的语义对齐,进而提升检索的准确性和相关性。下面将详细介绍 HyDEQueryTransform
的原理及其工作流程。
HyDEQueryTransform 的原理
生成假设文档
HyDEQueryTransform
的核心在于使用大型语言模型(LLM)根据用户的查询生成假设文档。这些假设文档虽然可能不是真实的文档,但它们试图捕捉用户的查询意图,并且通常包含与查询相关的关键词和概念。生成这些假设文档的目的在于创建一组文档,这些文档能够更好地反映用户的查询需求,即使原始查询表述不清晰或包含歧义。
文档向量化
一旦生成了假设文档,下一步就是将这些文档转化为向量形式。这通常涉及到使用预训练的编码器模型对文档进行编码,生成的向量可以用来衡量文档之间的相似度。编码器模型可以是专门为文本编码设计的,比如BERT等预训练模型。
向量聚合
生成的假设文档的向量会被聚合起来,形成一个代表用户查询的向量。聚合的方式可以简单地采用平均值,也可以更加复杂,比如加权平均,其中权重可以根据假设文档与原始查询的相关性来确定。此外,原始查询的向量也可以被纳入聚合过程,以确保生成的查询向量能够保留原始查询的重要特征。
检索与匹配
最后,使用聚合后的查询向量在文档库中进行检索,寻找与之最相似的文档。由于查询向量是基于假设文档生成的,理论上它能够更好地捕捉用户的查询意图,从而提高检索结果的相关性和准确性。
应用示例
在实践中,HyDEQueryTransform
可以与各种信息检索系统集成,以提升其性能。例如,在使用 LlamaIndex
构建的信息检索系统中,可以通过以下步骤应用 HyDEQueryTransform
:
- 加载文档和构建索引:首先,加载需要检索的文档集合,并构建一个向量存储索引。
- 初始化
HyDEQueryTransform
:创建一个HyDEQueryTransform
实例,可以设置参数如是否包含原始查询向量。 - 构建查询引擎:使用
TransformQueryEngine
将HyDEQueryTransform
和原始查询引擎组合起来。 - 执行查询:通过
TransformQueryEngine
发起查询,它会自动使用HyDEQueryTransform
对查询进行转换,然后基于转换后的查询向量检索相关文档。
注意事项
虽然 HyDEQueryTransform
有许多优点,但也存在一些潜在的问题和限制。例如,生成的假设文档可能包含错误的信息,这可能会影响检索结果的质量。此外,该方法的计算开销较大,特别是在处理大规模文档库时,生成假设文档和向量化处理可能会消耗较多资源。因此,在实际应用中,需要根据具体情况权衡利弊,选择合适的参数配置和优化策略。
综上所述,HyDEQueryTransform
是一种有效的查询转换技术,它通过生成假设文档来改善查询与文档之间的语义对齐,从而提高信息检索系统的性能。然而,使用时也需要考虑到其潜在的局限性和计算成本。
该检索技术的优缺点
HyDEQueryTransform
是 LlamaIndex 提供的一种查询转换策略,旨在通过增强原始查询来提高搜索和问答系统的性能。下面将详细介绍 HyDEQueryTransform
的优缺点:
优点
-
查询增强:
HyDEQueryTransform
可以自动扩展用户的原始查询,通过添加同义词、相关概念或其他上下文信息,使得查询更加丰富和具体。这有助于提高搜索结果的相关性和准确性。
-
适应性强:
- 由于其能够根据不同的查询动态地生成增强版的查询,因此可以更好地适应各种类型的查询需求,无论查询是简单还是复杂。
-
提高召回率:
- 增强查询可以捕获更多与原始查询相关的文档或段落,从而提高系统的召回率,确保不会错过任何可能相关的资料。
-
减少用户负担:
- 用户无需精心构造复杂的查询语句,因为查询转换器能够帮助他们找到所需的信息。这对于非专业用户尤其有利。
缺点
-
潜在的误匹配:
- 尽管查询增强通常能带来更好的结果,但在某些情况下也可能引入不相关或错误的关键词,导致搜索结果包含无关的文档或段落,影响精度。
-
增加计算成本:
- 执行查询转换需要额外的计算资源,特别是在对大量文档进行索引和搜索时。这可能会增加系统的响应时间和总体开销。
-
过度泛化风险:
- 在某些场景下,过于积极的查询增强可能导致搜索范围过大,反而降低了搜索的精确度。例如,对于已经非常具体和明确的查询,进一步增强可能并不会带来实质性的改善,甚至可能引入干扰。
-
依赖高质量训练数据:
HyDEQueryTransform
的性能很大程度上取决于其背后的模型训练数据的质量。如果训练数据不够丰富或代表性不足,那么查询转换的效果可能不尽如人意。
-
难以调整和优化:
- 对于开发者来说,调整和优化查询转换策略可能较为困难,因为它涉及到复杂的自然语言处理技术和机器学习算法。没有一定的专业知识和技术背景,很难有效地改进这一部分的功能。
-
可能产生误导:
- 当查询在没有上下文的情况下被误解时,HyDE 可能会产生误导
结论
总的来说,HyDEQueryTransform
是一种有效的查询增强工具,能够显著提升搜索和问答系统的性能。然而,它的应用也需要谨慎考虑,尤其是在对查询质量和计算资源有严格要求的场景中。合理的配置和优化是确保这一技术充分发挥潜力的关键。
LlamaIndex官方地址 https://docs.llamaindex.ai/en/stable/
快速上手
创建一个文件,例如“chainlit_chat”
mkdir chainlit_chat
进入 chainlit_chat
文件夹下,执行命令创建python 虚拟环境空间(需要提前安装好python sdk
。 Chainlit
需要python>=3.8
。,具体操作,由于文章长度问题就不在叙述,自行百度),命令如下:
python -m venv .venv
- 这一步是避免python第三方库冲突,省事版可以跳过
.venv
是创建的虚拟空间文件夹可以自定义
接下来激活你创建虚拟空间,命令如下:
#linux or mac
source .venv/bin/activate
#windows
.venv\Scripts\activate
在项目根目录下创建requirements.txt
,内容如下:
chainlit
llama-index-core
llama-index-llms-dashscope
llama-index-embeddings-dashscope
执行以下命令安装依赖:
pip install -r .\requirements.txt
- 安装后,项目根目录下会多出
.chainlit
和.files
文件夹和chainlit.md
文件
代码创建
只使用通义千问的DashScope
模型服务灵积的接口
在项目根目录下创建.env
环境变量,配置如下:
DASHSCOPE_API_KEY="sk-api_key"
DASHSCOPE_API_KEY
是阿里dashscope的服务的APIkey,代码中使用DashScope的sdk实现,所以不需要配置base_url。默认就是阿里的base_url。- 阿里模型接口地址 https://dashscope.console.aliyun.com/model
在项目根目录下创建app.py文件
代码如下:
import os
import timeimport chainlit as cl
from llama_index.core import (Settings,VectorStoreIndex,SimpleDirectoryReader, load_index_from_storage, StorageContext,
)
from llama_index.core.indices.query.query_transform import HyDEQueryTransform
from llama_index.core.node_parser import SentenceSplitter
from llama_index.core.query_engine import TransformQueryEngine
from llama_index.embeddings.dashscope import DashScopeEmbedding, DashScopeTextEmbeddingModels, \DashScopeTextEmbeddingType
from llama_index.llms.dashscope import DashScope, DashScopeGenerationModelsSettings.llm = DashScope(model_name=DashScopeGenerationModels.QWEN_TURBO, api_key=os.environ["DASHSCOPE_API_KEY"], max_tokens=512
)
Settings.embed_model = DashScopeEmbedding(model_name=DashScopeTextEmbeddingModels.TEXT_EMBEDDING_V2,text_type=DashScopeTextEmbeddingType.TEXT_TYPE_DOCUMENT,
)
Settings.node_parser = SentenceSplitter(chunk_size=512, chunk_overlap=20)
Settings.num_output = 512
Settings.context_window = 6000@cl.cache
def get_vector_store_index():storage_dir = "./storage_hyde"if os.path.exists(storage_dir):storage_context = StorageContext.from_defaults(persist_dir=storage_dir)index = load_index_from_storage(storage_context)else:documents = SimpleDirectoryReader("./data_file").load_data(show_progress=True)index = VectorStoreIndex.from_documents(documents)index.storage_context.persist(persist_dir=storage_dir)return indexvector_store_index = get_vector_store_index()@cl.on_chat_start
async def start():await cl.Message(author="Assistant", content="你好! 我是泰山AI智能助手. 有什么可以帮助你的吗?").send()@cl.on_message
async def main(message: cl.Message):start_time = time.time()query_engine = vector_store_index.as_query_engine(streaming=True, similarity_top_k=5)hyde = HyDEQueryTransform(include_original=True)hyde_query_engine = TransformQueryEngine(query_engine, hyde)msg = cl.Message(content="", author="Assistant")res = await hyde_query_engine.aquery(message.content)async for token in res.response_gen:await msg.stream_token(token)print(f"代码执行时间: {time.time() - start_time} 秒")source_names = []for idx, node_with_score in enumerate(res.source_nodes):node = node_with_score.nodesource_name = f"source_{idx}"source_names.append(source_name)msg.elements.append(cl.Text(content=node.get_text(), name=source_name, display="side"))await msg.stream_token(f"\n\n **数据来源**: {', '.join(source_names)}")await msg.send()
- 代码中的
persist_dir=storage_dir
不设置的默认是./storage
. - 代码中
chunk_size
是将长文档分割的文本块的大小,chunk_overlap
是和上下文本块的重合文本的大小。 - 经测试
hyde
这种检索模式,效果非常好,不仅检索内容匹配度提高,而且自动屏蔽了检索内容中和用户不相关的文本。
代码解读
这段代码实现了一个基于向量存储的问答系统,使用了chainlit
作为前端框架来与用户进行交互,并利用了llama_index
(也称为LlamaIndex)构建索引以及查询。以下是对代码各部分的详细解释:
1. 导入必要的模块和库
os
和time
是Python标准库中的模块,分别用于操作文件系统和获取时间信息。chainlit
是一个用于快速搭建聊天机器人的框架。llama_index
是一个用于构建语义搜索和问答系统的库。- 其他导入的部分包括用于创建和管理向量存储索引、解析文档节点、转换查询、加载模型等类和函数。
2. 设置环境
通过Settings
对象配置了语言模型(LLM)、嵌入模型(Embedding Model)和节点解析器(Node Parser)的具体参数:
- 使用了阿里云的
DashScope
作为语言模型服务,指定了模型名称、API密钥和最大输出令牌数。 - 同样使用
DashScope
提供的文本嵌入服务,指定了模型版本和文本类型。 - 节点解析器用于将文档切分为更小的块(chunks),这里设置了每个块的最大长度和重叠长度。
3. 创建或加载向量存储索引
get_vector_store_index
函数首先检查是否存在已保存的向量存储索引。如果存在,则从磁盘加载;否则,从指定目录读取文档并创建新的索引,然后将其持久化到磁盘上。- 这个索引用于后续的相似度搜索和回答问题。
4. 定义聊天机器人的启动和消息处理逻辑
start
函数定义了当用户开始会话时,机器人发送欢迎消息。main
函数负责处理用户的输入。它接收用户的消息,调用查询引擎生成答案,并流式地发送给用户。同时,它还会显示查询所依赖的数据源。
5. 查询处理流程
- 使用
HyDEQueryTransform
对原始查询进行转换,以提高查询的质量。 TransformQueryEngine
结合了转换器和查询引擎,能够根据转换后的查询来检索最相关的文档片段。- 当接收到用户的查询后,程序记录开始时间,然后通过异步方式调用查询引擎获取响应。每接收到一个新的token,就立即发送给用户,实现流式的响应效果。
- 最后,将查询所依据的数据源信息添加到响应中,并发送给用户。
总结
该代码展示了一个完整的问答系统的工作流程,从文档的加载、索引的创建与加载、用户请求的处理到最终的回答生成。整个过程充分考虑了性能优化,比如通过缓存机制避免重复计算,使用流式响应提升用户体验。此外,还采用了先进的技术手段如向量存储、查询转换等,以提高系统的准确性和效率。
在项目根目录下创建data_file文件夹
将你的文件放到这里,代码中设置的支持,pdf、doc、csv 、txt格式的文件,后续可以根据自己的需求增加更多,langchain带有很多格式文件的加载器,可以自行修改代码。
运行应用程序
要启动 Chainlit
应用程序,请打开终端并导航到包含的目录app.py。然后运行以下命令:
chainlit run app.py -w
- 该
-w
标志告知Chainlit
启用自动重新加载,因此您无需在每次更改应用程序时重新启动服务器。您的聊天机器人 UI 现在应该可以通过http://localhost:8000访问。 - 自定义端口可以追加
--port 80
启动后界面如下:
后续会出关于LlamaIndex
高级检查的技术文章教程,感兴趣的朋友可以持续关注我的动态!!!
相关文章推荐
《Chainlit快速实现AI对话应用的界面定制化教程》
《Chainlit接入FastGpt接口快速实现自定义用户聊天界面》
《使用 Xinference 部署本地模型》
《Fastgpt接入Whisper本地模型实现语音输入》
《Fastgpt部署和接入使用重排模型bge-reranker》
《Fastgpt部署接入 M3E和chatglm2-m3e文本向量模型》
《Fastgpt 无法启动或启动后无法正常使用的讨论(启动失败、用户未注册等问题这里)》
《vllm推理服务兼容openai服务API》
《vLLM模型推理引擎参数大全》
《解决vllm推理框架内在开启多显卡时报错问题》
《Ollama 在本地快速部署大型语言模型,可进行定制并创建属于您自己的模型》