当前位置: 首页 > wzjs >正文

html5微网站百度保障平台 客服

html5微网站,百度保障平台 客服,大学生作业代做网站,标志空间 网站一、TL;DR 从0-1使用qwen chat model langchain的链式架构搭建一套rag系统详细介绍了Langchain的工具链的调用流程简单介绍了可能会出现什么问题 二、方法 参考开源链接:https://github.com/Aphasia0515/self_llm/ 2.1 硬件和软件依赖 类型需求备注…

一、TL;DR 

  1. 从0-1使用qwen chat model+ langchain的链式架构搭建一套rag系统
  2. 详细介绍了Langchain的工具链的调用流程
  3. 简单介绍了可能会出现什么问题

二、方法

参考开源链接:https://github.com/Aphasia0515/self_llm/

2.1 硬件和软件依赖

 类型需求备注
硬件      
  1. 显存 >= 24B

实测:

  1. Qwen7B >= 24B
  2. Qwen32B >= 60B 左右
  3. Qwen1B 大概在6B左右(记忆里)
软件
  1. ubuntu20.04
  2. cuda11.8
  3. py3.8
  1. 其实现在大多数的社区镜像基本满足要求,因为Qwen的镜像都是比较新的依赖
  2. 但是训练镜像尤其要注意,我之前就遇到了Qwen和InternVL的训练镜像有冲突的问题

2.2 模型下载和准备

注意:模型下载记得从mirror-huggingface上下载,国内打不开huggingface

模型作用 备注
QwenRag系统的生成器、chat模型
  1. 注意根据自己的显存选择合适的模型
  2. 注意:1B/4B/7B的差异还是比较明显的(从天梯图里可以看到)
 Sentence Transformer 对文本进行向量化

2.3 Rag的文本库准备

这一节就不仔细讲了,将所有你需要的参考文件知识库放在某个指定目录下,本文只做txt和markdown的文档拆分(用于后续的建库)

三、知识库提取和向量化

3.1 得到所有文档的纯本文内容

先遍历2.3节的指定目录,得到所有的markdown和txt文件,并存成list:

import os 
def get_files(dir_path):# args:dir_path,目标文件夹路径file_list = []for filepath, dirnames, filenames in os.walk(dir_path):# os.walk 函数将递归遍历指定文件夹for filename in filenames:# 通过后缀名判断文件类型是否满足要求if filename.endswith(".md"):# 如果满足要求,将其绝对路径加入到结果列表file_list.append(os.path.join(filepath, filename))elif filename.endswith(".txt"):file_list.append(os.path.join(filepath, filename))return file_list

接下来对list里面的内容进行读取和加载,此处使用LangChain提供的FileLoader进行加载

  1. 注意:此处得到的其实还是纯文本loader,而非真正的文本块
from tqdm import tqdm
from langchain.document_loaders import UnstructuredFileLoader
from langchain.document_loaders import UnstructuredMarkdownLoaderdef get_text(dir_path):# args:dir_path,目标文件夹路径# 首先调用上文定义的函数得到目标文件路径列表file_lst = get_files(dir_path)# docs 存放加载之后的纯文本对象docs = []# 遍历所有目标文件for one_file in tqdm(file_lst):file_type = one_file.split('.')[-1]if file_type == 'md':loader = UnstructuredMarkdownLoader(one_file)elif file_type == 'txt':loader = UnstructuredFileLoader(one_file)else:# 如果是不符合条件的文件,直接跳过continuedocs.extend(loader.load())return docs

3.2 对所有的文本进行分块并向量化

LangChain使用多种文本分块工具,示例代码使用的时字符串递归分割器,并选择分块大小时500,块重叠长度是150,分块代码如下所示:

注意:我上一篇博客所说的,分块的大小不同的模型有不同的选择,只有最合适的,没有固定的

from langchain.text_splitter import RecursiveCharacterTextSplittertext_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=150)
split_docs = text_splitter.split_documents(docs)

分块完后,使用2.2节的下载好的模型(sentence Transformer)此时进一步进行向量化,LangChain 提供了直接引入 HuggingFace 开源社区中的模型进行向量化的接口::

注意:这个是直接加载本地路径

from langchain.embeddings.huggingface import HuggingFaceEmbeddingsembeddings = HuggingFaceEmbeddings(model_name="/root/autodl-tmp/embedding_model")

加载玩模型后,使用 Chroma 作为向量数据库,基于上文分块后的文档以及加载的开源向量化模型,将语料加载到指定路径下的向量数据库:

from langchain.vectorstores import Chroma# 定义持久化路径
persist_directory = 'data_base/vector_db/chroma'
# 加载数据库
vectordb = Chroma.from_documents(documents=split_docs,embedding=embeddings,persist_directory=persist_directory  # 允许我们将persist_directory目录保存到磁盘上
)
# 将加载的向量数据库持久化到磁盘上
vectordb.persist()

运行上述脚本,就得到一个本地构建已持久化的向量数据库,后续直接导入该数据库即可,无需重复构建

四、接入LLM-Chat Model

注意:本步骤接入任何llm模型其实都是可以的,主要还是看这个检索框架的整体实现。

4.1 QwenLM接入LangChain

本地部署Qwen llm模型,然后将QwenLM接入到Langchain框架里面,完成自定义 LLM 类之后,可以以完全一致的方式调用 LangChain 的接口,而无需考虑底层模型调用的不一致。

  1. 从 LangChain.llms.base.LLM 类继承一个子类,并重写构造函数与 _call 函数
from langchain.llms.base import LLM
from typing import Any, List, Optional
from langchain.callbacks.manager import CallbackManagerForLLMRun
from transformers import AutoTokenizer, AutoModelForCausalLM, GenerationConfigclass QwenLM(LLM):# 基于本地 Qwen 自定义 LLM 类tokenizer : AutoTokenizer = Nonemodel: AutoModelForCausalLM = Nonedef __init__(self, model_path :str):# model_path: Qwen 模型路径# 从本地初始化模型super().__init__()print("正在从本地加载模型...")model_dir = '/root/autodl-tmp/qwen/Qwen-7B-Chat'self.tokenizer = AutoTokenizer.from_pretrained(model_dir, trust_remote_code=True)self.model = AutoModelForCausalLM.from_pretrained(model_dir, device_map="auto", trust_remote_code=True).eval()# Specify hyperparameters for generationself.model.generation_config = GenerationConfig.from_pretrained(model_dir, trust_remote_code=True) # 可指定不同的生成长度、top_p等相关超参print("完成本地模型的加载")def _call(self, prompt : str, stop: Optional[List[str]] = None,run_manager: Optional[CallbackManagerForLLMRun] = None,**kwargs: Any):# 重写调用函数response, history = self.model.chat(self.tokenizer, prompt , history=[])return response@propertydef _llm_type(self) -> str:return "QwenLM"

上述代码在构造函数里直接加载了qwen模型,如果有其他的llm model也可以一并加载进去, _call 函数是 LLM 类的核心函数,LangChain 会调用该函数来调用 LLM来使用qwen的chat能力。

开源仓库里面将上述代码封装为 LLM.py,后续将直接从该文件中引入自定义的 LLM 类,直接使用from LLM import QwenLM。

五、构建检索问答链

LangChain 通过提供检索问答链对象来实现对于 RAG 全流程的封装

  1. 我们可以调用一个 LangChain 提供的 RetrievalQA 对象,通过初始化时填入已构建的数据库和自定义 LLM 作为参数,来简便地完成检索增强问答的全流程,LangChain 会自动完成基于用户提问进行检索、获取相关文档、拼接为合适的 Prompt 并交给 LLM 问答的全部流程。

5.1 导入向量数据库

from langchain.vectorstores import Chroma
from langchain.embeddings.huggingface import HuggingFaceEmbeddings
import os# 定义 Embeddings
embeddings = HuggingFaceEmbeddings(model_name="/root/autodl-tmp/embedding_model")# 向量数据库持久化路径
persist_directory = 'data_base/vector_db/chroma'# 加载数据库
vectordb = Chroma(persist_directory=persist_directory, embedding_function=embeddings
)

注意:向量数据库里面存储的是分块的文档和对应的向量,是embedding和index的关系

5.2 实例化自定义的QwenLM对象

from LLM import QwenLM
llm = QwenLM(model_path = "/root/autodl-tmp/qwen")
llm.predict("你是谁")

5.3 构建Prompt Template

prompt Template的作用是通过将用户input、rag检索得到的知识片段组合成input:

  1. 是一个带变量的字符串
  2. 在检索之后,LangChain 会将检索到的相关文档片段填入到 Template 的变量中,从而实现带知识的 Prompt 构建。
from langchain.prompts import PromptTemplate# 我们所构造的 Prompt 模板
template = """使用以下上下文来回答最后的问题。如果你不知道答案,就说你不知道,不要试图编造答案。尽量使答案简明扼要。总是在回答的最后说“谢谢你的提问!”。
{context}
问题: {question}
有用的回答:"""# 调用 LangChain 的方法来实例化一个 Template 对象,该对象包含了 context 和 question 两个变量,在实际调用时,这两个变量会被检索到的文档片段和用户提问填充
QA_CHAIN_PROMPT = PromptTemplate(input_variables=["context","question"],template=template)

5.4 直接检索问答

最后,可以调用 LangChain 提供的检索问答链构造函数,基于我们的自定义 LLM、Prompt Template 和向量知识库来构建一个基于 Qwen 的检索问答链:

question = "什么是QwenLM"
result = qa_chain({"query": question})
print("检索问答链回答 question 的结果:")
print(result["result"])# 仅 LLM 回答效果
result_2 = llm(question)
print("大模型回答 question 的结果:")
print(result_2)

可以看到,使用检索问答链生成的答案更接近知识库里的内容。

六、部署WebDemo

七、可优化的点

上述用的是开源代码,如果实际工程中可以从哪里优化呢?

  1. 检索的文本是大文本或者超大文本(>2K文本):
    1. summary,对大文本进行 map-reduce summary
    2. k-means(BRV steps)
  2. 检索内容太多不准该怎么办?
  3. 等等 明天再写把
http://www.dtcms.com/wzjs/346491.html

相关文章:

  • 模板网站和插件有哪些搜索引擎大全入口
  • 作词做曲网站刚刚传来最新消息
  • 家居企业网站建设平台百度我的订单app
  • 做网站技术人员seo基础知识培训视频
  • 如何做网站收录seo实战论坛
  • 网站开发7个基本流程图河北网站优化公司
  • 个人网站开发论文外链工具软件
  • 公司网站建设 上海手机地图app下载安装
  • 上城区商城网站建设深圳百度推广公司
  • 产地证在什么网站做网站设计是做什么的
  • 企业网站制作模板收录优美图片
  • 长安网站建设详细教程自动推广软件免费
  • 建个人网站怎么赚钱吗线上推广方案怎么做
  • godaddy如何创建网站网站建站方式有哪些
  • 常州公司网站模板建站软文客
  • 大连网站建设培训班陕西网络推广公司
  • 苏州网站建设公司电话媒介星软文平台
  • 软文写作平台怎样进行seo
  • c2b做的好的网站网络服务中心
  • 旅行网站首页模板关键词优化软件哪家好
  • 做gif动图的网站犯法吗上海免费关键词排名优化
  • 福建省建设执业注册与管理中心网站seo和sem是什么意思啊
  • 网站开发建设企业网上的推广
  • 房地产做网站不外包seo公司
  • 怎么做网站 知乎百度官方网页
  • 设计页面导航seo内部优化方案
  • 阿里妈妈个人网站怎么做的知名网页设计公司
  • 重庆医院网站建设seo流量的提升的软件
  • 沧州市网站建设seo综合排名优化
  • wordpress 订阅者外贸谷歌seo