Press "Enter" to skip to content

构建功能强大的聊天助手,无需OpenAI密钥,适用于PDF和文章

介绍

自然语言处理领域正在迅速扩张,特别是随着大型语言模型的诞生,它们彻底改变了这个领域并使其对每个人都可访问。在本文中,我们将探索并实现一些NLP技术,创建一个功能强大的聊天助手,可以根据给定的文章(或PDF)使用开源库回答您的问题,而无需OpenAI API密钥。

构建功能强大的聊天助手,无需OpenAI密钥,适用于PDF和文章 四海 第1张

本文作为数据科学博文马拉松的一部分发表。

工作流程

应用程序的工作流程如下所示:

构建功能强大的聊天助手,无需OpenAI密钥,适用于PDF和文章 四海 第2张

用户提供一个PDF文件或文章的URL,提出一个问题,应用程序将根据提供的来源尝试回答问题。

我们将使用PYPDF2库(对于PDF文件)或BeautifulSoup库(对于文章URL)提取内容。然后,我们将使用langchain库的CharacterTextSplitter将其分成块。

对于每个块,我们使用all-MiniLM-L6-v2模型计算其对应的词嵌入向量,将句子和段落映射到384维的稠密向量空间(词嵌入只是将单词/句子表示为向量的技术),并且相同的技术应用于用户的问题。

这些向量作为输入传递给由<sentence_transformers 提供的语义搜索函数,该函数是用于最先进的句子、文本和图像嵌入的Python框架。</sentence_transformers 

该函数将返回可能包含答案的文本块,然后问答模型将基于语义搜索和用户问题的输出生成最终答案。

注意

  • 所有提到的模型都可以通过API访问,只需使用HTTP请求即可。
  • 代码将使用Python编写。
  • FAQ-QN是一个关键词,表示您应该查看常见问题解答部分,特别是第N个问题,以获取更多详情。

实现

在本节中,我将只关注实现部分,详细信息将在常见问题解答部分提供。

依赖项

我们首先下载依赖项,然后导入它们。

pip install -r requirements.txt

import torch
import numpy as np
from sentence_transformers import util
from langchain.text_splitter import CharacterTextSplitter
from bs4 import BeautifulSoup
import requests
  • torch:在处理张量(Pytorch库)时非常有用。
  • requests:用于发送HTTP请求。

内容提取

对于PDF

try:
    pdf = PdfReader(path_pdf_file)
    result = ''
    for i in range(len(pdf.pages)):
        result += pdf.pages[i].extract_text()
except:
    print('PDF文件不存在')
    exit(0)

对于文章,我们尝试找到html标签(如h1、p、li、h2等)之间的内容(这些标签在VoAGI等网站上效果很好,其他网站可能不同)

try:
    request = requests.get(URL_LINK)
    request = BeautifulSoup(request.text, 'html.parser')
    request = request.find_all(['h1', 'p', 'li', 'h2'])
except:
    print('URL链接无效')
    exit(0)
result = [element.text for element in request]
result = ''.join(result)

分割成块

每个块将包含1000个标记,其中有200个标记重叠,以保持块之间的相关性并防止断开。(FAQ-Q2)

text_splitter = CharacterTextSplitter(
        separator="\n",
        chunk_size=1000,
        chunk_overlap=200,
        length_function=len
)
chunks = text_splitter.split_text(result)

词嵌入

您可以从huggingface下载模型all-MiniLM-L6-v2,或者您可以通过HTTP请求直接访问它,因为它作为一个API可用。 (FAQ-Q1)

注意:要访问huggingface的API,您必须注册(免费)以获得访问令牌。

hf_token='在这里输入您的huggingface访问令牌'
api_url= """https://api-inference.huggingface.co/pipeline/feature-extraction/sentence-transformers/all-MiniLM-L6-v2"""
headers = {"Authorization": f"Bearer {hf_token}"}

def query(texts):
  response = requests.post(api_url, headers=headers, json={"inputs": texts, "options":{"wait_for_model":True}})
  return response.json()

user_question = '在这里放置您的问题'
question = query([user_question])
query_embeddings = torch.FloatTensor(question)
output=query(chunks)
output=torch.from_numpy(np.array(output)).to(torch.float)

查询函数返回一个384维稠密向量,将其转换为‘torch.Float’和FloatTensor是为了语义搜索功能而必需的。

最终的结果将包含2个文本块,可能包含答案(我设置top_k=2,以提高从QA模型获取正确答案的概率)。(FAQ-Q4)

result=util.semantic_search(query_embeddings, output,top_k=2)
final=[chunks[result[0][i]['corpus_id']] for i in range(len(result[0]))]

问答模型

由于您拥有上下文(文本块)和问题,您可以使用任何您想要的模型(您可以快速浏览huggingface QA模型以获取了解)。我选择了AI21studio的问答模型,您可以免费注册以获得访问令牌。

AI21_api_key = 'AI21studio api密钥'
url = "https://api.ai21.com/studio/v1/answer"
payload = {
    "context":' '.join(final),
    "question":user_question
}
headers = {
    "accept": "application/json",
    "content-type": "application/json",
    "Authorization": f"Bearer {AI21_api_key}"
}
response = requests.post(url, json=payload, headers=headers)

if response.json()['answerInContext']:
    print(response.json()['answer'])
else:
    print('在文档中找不到答案⚠️,请重新提出您的问题。')

该模型可以验证答案是否与上下文相关(在使用大型语言模型时,可能会出现LLM回答的与提供的上下文无关的问题)。(FAQ-Q3)****

结论

您可以将这个项目扩展到各种来源的输入(PowerPoint文件、YouTube视频/音频、幻灯片、有声读物),成本相对较低,因此请随意根据您的用例进行调整。此外,您可以为该应用程序创建一个简单的用户界面并进行托管。

正如我所做的那样,将Streamlit作为界面(GitHub存储库可以在这里找到,请别忘了点亮星星按钮。

在本文中,我们为您的PDF文件/文章构建了一个功能强大的聊天助手。

  • 我们使用了网络抓取技术从来源中提取文本。
  • 文本被拆分成多个块。
  • 我们为每个块和用户问题计算了词嵌入向量。
  • 我们应用了语义搜索功能来检测最相关的文本块。
  • 最终答案由问答模型提供。

感谢您的时间和关注。如果需要进一步的帮助:

领英: SAMY GHEBACHE

电子邮件: [email protected]

常见问题

本文中显示的媒体不属于Analytics Vidhya所有,是根据作者的自由裁量使用的。

Leave a Reply

Your email address will not be published. Required fields are marked *