介绍
自然语言处理领域正在迅速扩张,特别是随着大型语言模型的诞生,它们彻底改变了这个领域并使其对每个人都可访问。在本文中,我们将探索并实现一些NLP技术,创建一个功能强大的聊天助手,可以根据给定的文章(或PDF)使用开源库回答您的问题,而无需OpenAI API密钥。
本文作为数据科学博文马拉松的一部分发表。
工作流程
应用程序的工作流程如下所示:
用户提供一个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所有,是根据作者的自由裁量使用的。