赞
踩
基于chatGLM3,应用langchain模式外挂知识库进行问答训练。
主要思路:将外挂知识库文本制成文本向量库,与提问文本做相似度比对,选出高相似度信息进行回答。
一 环境平台配置
可参考网上教程,注册阿里云,免费获取3个月的GPU资源。
二 langchain本地部署
1. 知识库文本加载&文本切割
- //文本加载库
- from langchain.document_loaders import DirectoryLoader
-
- //文本切割库
- from langchain.text_splitter import CharacterTextSplitter
-
- //directory中用文本路径替换
- def load_documents(directory = "books"):
- loader = DirectoryLoader(directory)
- documents = loader.load()
- # for d in documents:
- # print(d)
- text_spliter = CharacterTextSplitter(chunk_size = 256, chunk_overlap = 1) //切分的文本长度为256,交叠部分为1,根据GPU资源大小,可以增大该参数,使训练更加精准
- split_docs = text_spliter.split_documents(documents)
- # print(split_docs[:2])
- return split_docs
-
-
2 文本词嵌入
国内需下载相关模型进行本地化调用,可使用模型清单包括:ernie-3.0-nano-zh、ernie-3.0-mediu-zh、text2vec-large-chinese、sbert-bert-chinese-nli、text2vec-base-chinese、
- //词嵌入模型列表
- # embedding
- embedding_model_dict = {
-
- "ernie-tiny": "nghuyong/ernie-3.0-nano-zh", //国内禁用,可修改成本地路径
- "ernie-medium": "/mnt/workspace/ChatGLM3/openai_api_demo/ernie-3.0-medium-zh",
- "text2vec": "/mnt/workspace/ChatGLM3/text2vec-large-chinese",
- "text2vec2": "uer/sbert-base-chinese-nli",
- "text2vec3": "/mnt/workspace/ChatGLM3/text2vec-base-chinese"
- }
-
-
-
- def load_embedding_mode(model_name = "ernie-tiny"):
- encode_kwargs = {"normalize_embeddings":False}
- model_kwargs = {"device":"cuda:0"}
- return HuggingFaceEmbeddings(
- model_name = embedding_model_dict[model_name]
- model_kwargs = model_kwargs,
- encode_kwargs = encode_kwargs,
- cache_folder = "/mnt/workspace/ChatGLM3"
- )
-
- embeddings = load_embedding_mode('text2vec')
3 向量数据库构建
可选用chroma或FAISSS,此处以chroma为例。同样方式可使用faiss,且建议使用FAISS,chroma容易产生embedding dimensity错误。
- from langchain.vectorstores import Chroma
-
- def store_chroma(docs, embeddings,persist_directory = 'VectorStore'):
- db = Chroma.from_documents(docs, embeddings, persist_directory = persist_directory)
- db.persist()
- return db
-
4. 模型加载
- MODEL_PATH = os.environ.get('MODEL_PATH', '/mnt/workspace/ChatGLM3/chatglm3-6b')
-
-
- model_config = AutoConfig.from_pretrained(
- MODEL_PATH,
- trust_remote_code=True
- )
- tokenizer = AutoTokenizer.from_pretrained(MODEL_PATH, trust_remote_code=True)
- model = AutoModel.from_pretrained(MODEL_PATH, trust_remote_code=True, device='cuda').half().quantize(4).cuda()
- model = model.eval()
5 使用词向量相似度进行答案检索
(1)通过相似度比对,可找到相似的K个文本,再次作为大模型的输入进行答案检索。且可输入固定格式的prompt,以便提高模型识别率。
(2)通过history参数的设置,可稳定较为关键固定的答案,提升模型回答的准确率。比如:某些规则。
- hist = [
- {'role': 'user','content':"基于下面给出的资料,回答问题。如果资料不足,回答不了,就回复不知道,下面是资料。\n小王子来自哪里\n1.小王子来自B612星星"},
- {'role': 'user','content':"基于下面给出的资料,回答问题。如果资料不足,回答不了,就回复不知道,下面是资料。\n狐狸告诉小王子的秘密是什么\n1.狐狸告诉小王子的秘密是:只有用心才能看得清,重要的东西,用眼睛是看不见的"},
- {'role': 'user','content':"基于下面给出的资料,回答问题。如果资料不足,回答不了,就回复不知道,下面是资料。\n小王子是谁\n1.小王子是一个虚构的人物,出自法国作家安托万·德·圣埃克苏佩里的作品《小王子》"}
- ]
-
-
- while True:
- query = input('Human:')
- similar_docs = db.similarity_search(query,include_metadata = True,k = 3)
- prompt = f'基于下面给出的资料,回答问题。基于下面给出的资料,回答问题。如果资料不足,回答不了,就回复不知道,下面是资料。\n'
- for idx, doc in enumerate(similar_docs):
- prompt += f'{idx+1}. {doc.page_content}\n'
- prompt += f'下面是问题:{query}'
- # print(prompt)
-
- response, history = model.chat(tokenizer, prompt, history=hist)
- print(response)
- print('\n')
- print(f'history:{history}')
- print('\n')
二 API方式调用
通过API方式,可支持多个模块并行调用,提高模型使用效能
1. API启动:demo中有个API接口,可直接进行启动。但此处建议将之前的词向量库替换成FAISS,否则embedding维度会报错。
2. 模型接口能力调用
- from langchain.chains import RetrievalQA
- from langchain.llms import ChatGLM
-
- //API接口调用
- llm = ChatGLM(
- endpoint = 'http://127.0.0.1:8000/v1/chat/completions',
- max_token = 80000,
- top_p =0.9
- )
-
- //
- retriever = db.as_retriever()
- qa = RetrievalQA.from_chain_type(
- llm = llm,
- chain_type = 'stuff',
- retriever = retriever
- )
-
- def chat(question,history):
- response = qa.run(question)
- return(response)
-
- //使用gradio界面化
- demo = gr.ChatInterface(chat)
- demo.launch(inbrowser = True)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。