1.具体思路
LLM分析PDF的话一种是可以通过PDF转文字,让大语言模型进行分析,但是这种方法存在局限性,如果PDF文字内容过多话,就涉及到最大Token的问题,即使是本地部署的大语言模型,也会遇到Token限制,或者是显存溢出问题。
这个时候就可以用到LangChain中的Chroma来构建我们的向量知识库,具体流程如下:
PyPDFLoader(加载PDF文档)–>文本分割–>向量化–>构造向量库
2.实现方法
1.定义我们的文件路径并加载
from langchain.document_loaders import PyPDFLoader, UnstructuredFileLoader
from langchain.embeddings import HuggingFaceEmbeddings
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.vectorstores import Chroma
loader = PyPDFLoader(file_path)
docs = loader.load()
2.文本分割
chunk_size:为分割大小
chunk_overlap: 是为了避免完整的句子被分割导致LLM理解错误
text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=200)
docs = text_splitter.split_documents(docs)
3.向量化并构造向量数据库
我这边使用的Embdding模型是shibing624/text2vec-base-multilingual
embedding = HuggingFaceEmbeddings(model_name=config.EMBEDDING_MODEL_PATH)
# 构造向量库+conversation_id
persist_directory = os.path.join(config.KNOWLEDGE_FILE_PATH, kb_name)
# 创建向量数据库
vectordb = Chroma.from_documents(
documents=docs,
embedding=embedding,
persist_directory=persist_directory
)
print("vectordb:", vectordb._collection.count())
vectordb.persist() # 向量持久话
4.用户提问,检索对应的片段,交给LLM处理回答
我们可以根据用户的Query来进行匹配文章内容,进而构造prompt来进行提问
embedding = HuggingFaceEmbeddings(model_name=config.EMBEDDING_MODEL_PATH)
vectordb = Chroma(persist_directory=persist_directory, embedding_function=embedding)
print(vectordb._collection.count())
logger.info("Load database building finished. %s", time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
# docs = vectordb.similarity_search(query, k=3)
docs = vectordb.similarity_search(query, k=5)
page = list(set([docs.metadata['page'] for docs in docs]))
page.sort()
context = [docs.page_content for docs in docs]
prompt = f"已知PDF内容:\n{context}\n根据已知信息回答问题:\n{query}\n所有的回答都根据已知信息"
GitHub已经开源:
https://github.com/1264204425/PdfReader-LangChian-LLM
代码写的较烂轻喷