赞
踩
这里面涉及到的技术点有:
langchain 把这些技术都整合到一起,让我们可以方便的搭建自己的应用。
网上有很多demo ,最简单的是用llama-index,openai,gradio 进行搭建
llama-index 是基于文件的向量数据库,gradio 是web 服务器,实现了基本的ui页面,还可以提供域名服务。句向量和大模型用的openai.
这种demo 需要一台服务器,能连上openai. langchain 的安装有也些bug. 现在还是0.5的版本。 我在window2012 上安装,用miniconda, 和 visual studio,langchain 中有些c++的代码编译需要
这种应用搭demo 还可以的,但是在生产环境是不可行
下面我基于demo 进行了改进
标题 | demo | 改进 |
---|---|---|
句向量 | openai embedding | HuggingFace ‘m3e-base’ |
大模型 | openai gpt-3.5-turbo | gpt-3.5-turbo |
向量数据库 | llama_index | Annoy |
import os from langchain.embeddings.openai import OpenAIEmbeddings from langchain.vectorstores import Annoy from langchain.text_splitter import CharacterTextSplitter from langchain import OpenAI, VectorDBQA from langchain.chat_models import ChatOpenAI from langchain.document_loaders import DirectoryLoader from langchain.chains import RetrievalQA from langchain.indexes import VectorstoreIndexCreator import time from langchain import PromptTemplate from langchain.embeddings import HuggingFaceEmbeddings,HuggingFaceInstructEmbeddings # openAI的Key os.environ["OPENAI_API_KEY"] = 'xxxx' def create_index(path): loader = DirectoryLoader('D:/download/', glob='**/*.docx') documents = loader.load() text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0) split_docs = text_splitter.split_documents(documents) embeddings = HuggingFaceEmbeddings(model_name='moka-ai/m3e-base') vector_store_path = r"./storage4" docsearch = Annoy.from_documents(documents=split_docs, embedding=embeddings, persist_directory=vector_store_path) docsearch.save_local(vector_store_path) def search(txt): embeddings = HuggingFaceEmbeddings(model_name='moka-ai/m3e-base') vector_store_path = r"./storage4" docsearch = Annoy.load_local(vector_store_path,embeddings=embeddings) start = time.time() prompt_template = """请注意:请谨慎评估query与提示的Context信息的相关性,只根据本段输入文字信息的内容进行回答,如果query与提供的材料无关,请回答"对不起,我不知道",另外也不要回答无关答案: Context: {context} Question: {question} Answer:""" PROMPT = PromptTemplate(template=prompt_template, input_variables=["context", "question"]) # qa = VectorDBQA.from_chain_type(llm=ChatOpenAI(temperature=0, model_name="gpt-3.5-turbo-16k"), chain_type="stuff", vectorstore=docsearch, return_source_documents=True) # result = qa({"query": txt}) qa = RetrievalQA.from_chain_type(llm=ChatOpenAI(temperature=0, model_name="gpt-3.5-turbo"), chain_type="stuff", retriever=docsearch.as_retriever(search_kwargs={"k": 8}), chain_type_kwargs={"prompt": PROMPT}) result = qa.run(txt) print(result) print(time.time() - start) if __name__=="__main__": create_index('') search('xxx')
文档的切分
文档切分对句向量的生成有很大影响。最理想的效果把相拟的段落切到一起,想实现这样的效果需要对文档内容比较了解,进而切分。
使用默认的 langchain CharacterTextSplitter chunk_size = 1000,这种切分的效果不是很好。它的分割符是 \n\n,先按chunk 切,再按分割符切。这样会把段落切错。
大模型的选型
使用openai gpt-3.5-turbo 它是有字数限制,4096个字符,top K选出的答案多了,它都答不上来。可以换用 gpt-3.5-turbo-16k, 它有16k个字符,大大的满足冲破答的需要。
换用国产大模型,如chatGLM, 它有6B 的小模型,单张GPU上就可以跑。这样也不用国外服务器。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。