网站推广方法技校十大吃香专业
网站推广方法,技校十大吃香专业,网站备案安全责任书是谁盖章,网站备案用户名忘了怎么办文章目录 概要内容RAG整体流程#xff08;因为加了点优化看着比较多#xff09;langchain应用#xff08;重要内容#xff09;gradio使用#xff08;web页面显示#xff09;效果整体代码运行前置工作 概要
传统LLM的瓶颈 (The Bottlenecks of Traditional LLMs) 知识固化…文章目录概要内容RAG整体流程因为加了点优化看着比较多langchain应用重要内容gradio使用web页面显示效果整体代码运行前置工作概要传统LLM的瓶颈 (The Bottlenecks of Traditional LLMs)知识固化训练数据截止日期后的事件无法知晓。幻觉问题可能生成看似合理但错误的内容。缺乏特定领域/私有知识无法访问非公开或高度专业化的信息。RAG的核心思想 (The Core Idea of RAG)检索 (Retrieval)根据用户查询从外部知识库中查找最相关的文档片段。增强 (Augmentation)将检索到的上下文信息与原始查询一起输入给LLM。生成 (Generation)LLM基于合并后的输入查询上下文生成最终回答。内容这个内容主要是langchainmodelscopegradio的应用我会把模型调用和langchain重要内容和整体项目分开写。只是把重要内容组合没办法运行所以要完整的在整体项目中。如果要学习知识点看这几个部分就行如果要整体学当然更好整体中主要是有一些辅助函数模型调用优化gradio显示逻辑函数代码有注释除了python语法和简单逻辑主要流程上传相关文档-----输入问题-----RAG检索-----模型调用-----前端显示整体代码在文章结尾RAG整体流程因为加了点优化看着比较多加载文档并切分defload_and_split_pdf(pdf_file_path): :param pdf_file_path:上传文档 :return: 切块后的文档 file_posos.path.splitext(pdf_file_path)[-1].lower()suppotr_pos[.pdf,.txt,.docx,.doc]iffile_posnotinsuppotr_pos:raiseValueError(f不支持的文件类型仅支持{suppotr_pos}当前文件{file_pos})loaderNonetry:iffile_pos.pdf:loaderPyPDFLoader(pdf_file_path)eliffile_pos.txt:loaderTextLoader(pdf_file_path)eliffile_pos.docx:loaderDocx2txtLoader(pdf_file_path)documentsloader.load()ifnotdocuments:raiseValueError(文件为空或无法解析)# 递归分块按语义分割优先级空行段落换行句号空格text_splitterRecursiveCharacterTextSplitter(chunk_sizeconfig.CHUNK_SIZE,chunk_overlapconfig.CHUNK_OVERLAP,separators[\n\n,\n,。, ])doc_splitstext_splitter.split_documents(documents)# 给每个分块添加元数据用于溯源加分亮点fori,docinenumerate(doc_splits):doc.metadata[chunk_id]i doc.metadata[source]os.path.basename(pdf_file_path)doc.metadata[file_type]file_pos[1:]print(f文档处理完成{len(doc_splits)}个文本块)returndoc_splitsexceptExceptionase:raiseValueError(f文档处理失败{str(e)})创建向量库defbuild_vector_db(doc_splits,persist_dir./faiss_db_cpu): :param doc_splits: 切分的文档 :param persist_dir: 本地向量库 :return: 获取向量 embeddingsget_embeddings()faiss_addressos.path.join(config.PERSIST_DIR,index.faiss)if(os.path.exists(faiss_address)):vectordbFAISS.load_local(config.PERSIST_DIR,embeddings,allow_dangerous_deserializationTrue)# 必须为Truevectordb.add_documents(doc_splits)else:# 构建FAISS向量库vectordbFAISS.from_documents(documentsdoc_splits,embeddingembeddings)# 持久化FAISS向量库vectordb.save_local(persist_dir)print(向量库构建完成FAISS纯CPU)returnvectordb数据检索重排提高检索质量用的模型其实原理还是余弦相似度defenhanced_retrieval(vectordb,question): 只需要1就可以完成相关数据检索粗排但是第2步的是精排 :param vectordb: 持久化的向量 :param question: 要问的问题 :return: 整合的数据元数据 # 1. 向量粗排语义匹配retrievervectordb.as_retriever(search_kwargs{k:config.TOP_K})raw_docsretriever.invoke(question)#*********raw_docs结果是字典page_content,metadata************# 2. 重排序提升相关性过滤无关内容rerankerCrossEncoder(config.RERANK_MODEL,devicecpu)# 强制CPU(本人电脑是FW)# 构造重排序输入(问题, 文本)rerank_inputs[(question,doc.page_content)fordocinraw_docs]# 计算相关性分数scoresreranker.predict(rerank_inputs)# 按分数排序取Top3doc_score_pairslist(zip(raw_docs,scores))doc_score_pairs.sort(keylambdax:x[1],reverseTrue)final_docs[pair[0]forpairindoc_score_pairs[:config.TOP_N]]# 拼接上下文溯源信息context_with_sourcefori,docinenumerate(final_docs):sourcedoc.metadata.get(source,未知文档)pagedoc.metadata.get(page,未知页码)context_with_sourcef【参考信息{i1}】\n内容{doc.page_content}\n来源{source}第{page}页\n\nreturncontext_with_source,final_docslangchain应用重要内容学习langchain的核心组件Prompt、RunnableWithMessageHistory历史对话、stream流式输出等等。首先要写个合适的提示词prompt_with_historyChatPromptTemplate.from_template( 你是一个严谨且聪明的知识库问答助手必须严格遵守以下规则 1. 仅使用【参考信息】中的内容回答问题绝不编造任何未提及的信息 2. 如果【参考信息】中没有相关内容就用你自己的理解来回答 3. 回答要简洁、准确最后必须标注信息来源参考信息1/2/3 【历史对话】 {chat_history} 【参考信息】 {context} 【用户问题】 {question} )RunnableWithMessageHistory带历史对话的rag链base_rag_chain(RunnablePassthrough.assign(contextlambdax:x[context])|prompt_with_history|llm|StrOutputParser())# 包装成带会话历史的链rag_chain_with_historyRunnableWithMessageHistory(base_rag_chain,get_session_history,# 绑定当前会话IDinput_messages_keyquestion,#下面3个都是类似起个名字例如名字是question那么输入参数必须是question字典history_messages_keychat_history,output_messages_keyoutput)stream流式输出# 流式调用streamrag_chain_with_history.stream({question:question.strip(),context:context},config{configurable:{session_id:session_id}}#RunnableWithMessageHistory规定 configurable中找参数)gradio使用web页面显示页面defgr_show():#css这个不用管只是调了一下样式withgr.Blocks(titleRAG知识库问答系统,)asdemo:gr.Markdown(# RAG本地知识库问答系统)gr.Markdown(---)withgr.Tab(### 文档管理):# 文档上传Tabwithgr.Tab(文档上传):filesgr.File(label上传文档PDF/Word/TXT,typefilepath,file_countmultiple)build_btngr.Button(构建向量库纯CPU)build_statusgr.Textbox(label构建状态,lines3)db_status1gr.Textbox(label已加载文档,valueget_loaded_files(),lines5,interactiveFalse)config.db_status_components.append(db_status1)# 文档删除Tabwithgr.Tab(删除文档):filenamegr.Textbox(label文档名,placeholder例如数据结构.pdf)delete_doc_btngr.Button(删除该文档,variantprimary)clear_doc_btngr.Button(清空所有文档,variantsecondary)delete_statusgr.Textbox(label删除结果,lines3)db_status2gr.Textbox(label已加载文档,valueget_loaded_files(),lines5,interactiveFalse)config.db_status_components.append(db_status2)# 全局状态当前选中的会话IDcurrent_session_idgr.State(valueconfig.DEFAULT_SESSION_ID)withgr.Tab(### 智能问答):# 布局左侧会话管理文档管理右侧聊天区withgr.Row():# 左侧面板会话管理 文档管理withgr.Column(scale1,min_width250):gr.Markdown(### 会话管理)gr.Markdown(---)withgr.Row():new_session_btngr.Button(新建会话,variantprimary)delete_session_btngr.Button(删除会话,variantsecondary)session_statusgr.Textbox(label会话操作状态,lines1)session_radiogr.Radio(choicesget_session_list(),label历史会话,valueconfig.DEFAULT_SESSION_ID,interactiveTrue,containerTrue,# 保持容器样式elem_idsession-radio)# 右侧面板聊天区withgr.Column(scale4):# 聊天记录chatbotgr.Chatbot(label对话历史流式输出,height600,resizableTrue,avatar_images(None,https://img.icons8.com/fluency/96/000000/robot.png),sanitize_htmlFalse,)# 输入框 按钮withgr.Row():questiongr.Textbox(label输入问题,placeholder例如论文中提出的核心方法是什么,scale8)answer_btngr.Button(发送,variantprimary,scale1)clear_chat_btngr.Button(清空当前会话,variantsecondary)效果整体代码运行前置工作先去魔搭平台注册其他的大模型平台也行这个每天有免费API调用次数拿到这个api_key去替换代码文件中config里面的api_key2. 因为是免费的所以模型调用质量不太行一定选择API-inference选择模型替换config里面的LLM_CANDIDATES就行3. 数据检索的模型我用的都是体积最小的模型只是为了演示可以下载体积比较大的向量编码模型和重排模型替换一下config里面的EMBEDDING_MODEL和RERANK_MODEL。https://gitee.com/yyrainy/rag