基于llamaindex构建的RAG应用程序
该项目为基于金融大模型的RAG问答系统,使用基于飞桨框架训练后的本地模型和向量检索来提高答复的准确性。
主要用于金融领域的客户支持,提供基于上下文的专业回答。
一、文件使用说明:
1、如需加载文档,请将文件放入以下存储路径:./data
2、如需查看文档索引生成的结果,可查看生成的向量数据库存储路径:./index
4、环境搭建:./models/requirements.txt
5、基于外规场景下精调后的金融大模型:checkpoint
6、嵌入式模型:bge-large-zh-1.5
二、如需要使用基础RAG,请使用以下文件:
1、向量检索:base_index.py
2、向量+关键词检索:vector_keyword.py
3、向量+BM25检索:vector_BM25.py
4、向量+BM25+MTCS+动态文档检索:vector_BM25_mtcs_auto.py
三、向量+BM25+MTCS+动态文档检索代码结构:
一、模型加载和自定义LLM类
本地模型加载:
加载模型:通过paddlenlp的AutoTokenizer和AutoModelForCausalLM从指定路径加载本地模型和tokenizer。
模型切换到评估模式:model.eval()确保模型处于评估模式,避免训练中的不必要操作。
自定义LLM类 OurLLM:
complete 方法:用于生成模型的回答。它首先定义了一个银行业务相关的prompt模板,并将用户问题和上下文插入模板中,生成格式化后的提示。然后通过tokenizer将文本转化为模型输入,利用model.generate()方法生成模型的输出文本,最后将生成的文本解码并返回。
stream_complete 方法:此方法未实现,可能是为未来的流式生成设计的。
设置自定义LLM:
Settings.llm = OurLLM():将自定义的LLM类应用到系统的设置中,替换默认的LLM。
二、嵌入模型和文档索引
加载嵌入模型:使用HuggingFaceEmbedding加载本地嵌入模型,并设置在Settings.embed_model中。
文档加载与索引:
文本加载:通过SimpleDirectoryReader从指定路径加载文本文件,构建文档对象。
索引构建:使用VectorStoreIndex.from_documents创建基于文档的向量索引,并将其持久化到指定目录中。
索引加载:从持久化存储中加载索引,并转换成检索器。
BM25检索:自定义了SimpleBM25Retriever类,修改了BM25Retriever的tokenizer,使用jieba分词来支持中文检索。创建了bm25_retriever和vector_retriever两个检索器,并组合成一个QueryFusionRetriever,通过加权检索结果来增强查询效果。
三、MCTS(蒙特卡洛树搜索)
TreeNode 类:
该类表示树中的节点,保存了当前节点的文本块、父节点、子节点以及访问次数、总效用等信息。
expand方法用来生成新节点,将多个候选块组合生成新的子节点,并保证成本不超出预算。
MCTS类:
search 方法:这是MCTS的核心搜索函数,通过多次迭代,选择、扩展、模拟和反向传播来搜索最佳的节点组合。
select 方法:选择一个节点进行扩展,使用UCB1公式(即基于效用和访问次数的公式)来平衡探索与开发。
simulate 方法:模拟一个节点的响应并评估其效用,基于生成的文本和上下文计算响应的质量。
backpropagate 方法:将模拟的效用反向传播到树的父节点,用于更新树的状态。
四、聊天引擎的循环与优化
聊天循环:
chat_loop_with_query_engine函数实现了一个用户交互的循环,用户输入问题后,系统将通过检索器(retriever)检索相关文档。
检索结果被传递给MCTS算法,选择出最佳的文本块组合并生成回复。
生成的回复通过query_engine.query进行查询,并计算其相关性得分,选择最佳的回复。
结果处理和评估:
在生成回复之前,首先使用MCTS优化选出最相关的文本块组合,通过generate_and_score方法生成响应,并计算得分。
得分较高的文本被认为是最佳回复,并最终输出给用户。
五、辅助函数与相似度计算
extract_embeddings:提取输入文本的嵌入向量。它使用model对输入文本进行编码,并返回句子的嵌入表示。
相似度计算:
calculate_similarity:通过余弦相似度计算两个文本的相似度。
evaluate_response:综合文本的长度、相似度和多样性评分来评估生成的回答的质量。
calculate_relevance_score:计算文档节点与用户查询的相关性得分,通常是通过嵌入向量的相似度计算。
六、线程池与并发
ThreadPoolExecutor:
在chat_loop_with_query_engine中,使用ThreadPoolExecutor并发地生成和评分多个文本块组合,进一步提升系统的效率。
注意事项:paddlenlp和paddlepaddle请从源代码进行安装
相关链接:
paddlenlp:https://github.com/PaddlePaddle/PaddleNLP
paddlepaddle:https://www.paddlepaddle.org.cn/
llamaindex:https://github.com/run-llama/llama_index
paddle版本
paddle2onnx1.2.11
paddlefsl1.1.0
paddlenlp3.0.0b2.post20241115
paddlepaddle-gpu3.0.0b1
llamaindex版本
llama-index 0.11.3
llama-index-agent-openai 0.3.4
llama-index-cli 0.3.1
llama-index-core 0.11.21
llama-index-embeddings-huggingface 0.3.1
llama-index-embeddings-openai 0.2.5
llama-index-indices-managed-llama-cloud 0.4.0
llama-index-legacy 0.9.48.post3
llama-index-llms-openai 0.2.16
llama-index-multi-modal-llms-openai 0.2.3
llama-index-program-openai 0.2.0
llama-index-question-gen-openai 0.2.0
llama-index-readers-file 0.2.2
llama-index-readers-llama-parse 0.3.0
llama-index-retrievers-bm25 0.4.0
提示:
1、需修改llamaindex中的llama_index/llama-index-core/llama_index/core/chat_engine/condense_plus_context.py文件中的窗口大小
chat_history = chat_history or []
memory = memory or ChatMemoryBuffer.from_defaults(
chat_history=chat_history, token_limit=llm.metadata.context_window - 100
)
2、如需对模型进行精调,请参考https://github.com/PaddlePaddle/PaddleNLP/tree/develop/llm