網路應用程式開發中,常需整合外部資源或處理不同格式的資料。本文示範如何結合網頁內容擷取、大語言模型和 Streamlit 框架,建構一個兼具網站摘要、問答以及 PDF 檔案問答功能的系統。系統核心流程包含使用 requests 取得網頁 HTML 內容,BeautifulSoup 解析並提取段落,以及過濾合併段落以控制文字長度。利用 Hugging Face 的 API,系統可以對處理後的文字進行摘要和問答。此外,系統也支援使用者上傳 PDF 檔案,透過 PyPDF2 讀取檔案內容,並同樣利用大語言模型和相似度搜尋技術,實作 PDF 檔案的問答功能。Streamlit 則提供簡潔易用的介面,讓使用者能輕鬆與系統互動。
網站摘要與問答系統的開發與實作
系統概述
本系統旨在開發一個根據網站內容的摘要與問答功能,透過整合自然語言處理(NLP)技術與機器學習模型,實作對網站內容的自動化摘要與根據內容的問答。
開發流程
網頁內容擷取
- 使用
requests函式庫傳送 GET 請求至指定 URL,取得網頁的 HTML 內容。 url = "https://shivamsolanki.net/posts/Tuning-LLMs/" response = requests.get(url) html_content = response.text
- 使用
HTML 解析與段落提取
- 利用
BeautifulSoup對 HTML 內容進行解析,提取所有<p>標籤內的文字內容。 soup = BeautifulSoup(html_content, "html.parser") paragraphs = soup.find_all("p")
- 利用
段落過濾與合併
- 對提取的段落進行過濾,篩選出長度大於或等於 100 個字元的段落。
- 將篩選後的段落合併成一個字串,總長度不超過 2000 個字元。
passages = [p.get_text(strip=True) for p in paragraphs if len(p.get_text(strip=True)) >= 100] combined_passage = "" for passage in passages: if len(combined_passage) + len(passage) <= 2000: combined_passage += passage + " " else: break
使用 Streamlit 建立使用者介面
程式碼實作
import streamlit as st
import requests
from bs4 import BeautifulSoup
import json
# HuggingFace Inference API endpoint
QA_ENDPOINT = "https://api-inference.huggingface.co/models/bigscience/bloom"
SUMMARIZATION_ENDPOINT = "https://api-inference.huggingface.co/models/tiiuae/falcon-7b-instruct"
def extract_combined_passage(url, min_paragraph_length, max_combined_length):
# #### 內容解密:
# 此函式用於從指定 URL 中提取合併後的段落內容。
# 1. 傳送 GET 請求取得網頁 HTML 內容。
# 2. 使用 BeautifulSoup 解析 HTML 並提取段落。
# 3. 篩選並合併段落,總長度不超過 max_combined_length。
response = requests.get(url)
html_content = response.text
soup = BeautifulSoup(html_content, "html.parser")
paragraphs = soup.find_all("p")
passages = [p.get_text(strip=True) for p in paragraphs if len(p.get_text(strip=True)) >= min_paragraph_length]
combined_passage = ""
for passage in passages:
if len(combined_passage) + len(passage) <= max_combined_length:
combined_passage += passage + " "
else:
break
return combined_passage
def generate_summary(url):
# #### 內容解密:
# 此函式用於生成指定 URL 內容的摘要。
# 1. 呼叫 extract_combined_passage 取得合併後的段落內容。
# 2. 使用 HuggingFace 的摘要模型生成摘要。
headers = {"Authorization": "Bearer XXXXXXXX"}
combined_passage = extract_combined_passage(url, 100, 2000)
model_input = f"Summarize the following article. Article: {combined_passage}"
json_data = {
"inputs": model_input,
"parameters": {'temperature': 0.5, 'max_new_tokens': 100, 'return_full_text': False}
}
response = requests.post(SUMMARIZATION_ENDPOINT, headers=headers, json=json_data)
json_response = json.loads(response.content.decode("utf-8"))
summary = json_response[0]['generated_text']
return summary
def answer_question(url, question):
# #### 內容解密:
# 此函式用於根據指定 URL 的內容回答問題。
# 1. 呼叫 extract_combined_passage 取得合併後的段落內容。
# 2. 使用 HuggingFace 的問答模型生成答案。
headers = {"Authorization": "Bearer XXXXXXXX"}
combined_passage = extract_combined_passage(url, 100, 2000)
model_input = f"Answer the question based on the context below. Context: {combined_passage} Question: {question}"
json_data = {
"inputs": model_input,
"parameters": {'temperature': 0.5, 'max_new_tokens': 100, 'return_full_text': False}
}
response = requests.post(QA_ENDPOINT, headers=headers, json=json_data)
answer = response.json()[0]["generated_text"]
return answer
def main():
st.title("網站摘要與問答系統")
url = st.text_input("輸入網站 URL:")
question = st.text_input("輸入問題:")
if st.button("生成摘要與答案"):
if url:
text = extract_combined_passage(url, 100, 2000)
summary = generate_summary(url)
answer = answer_question(url, question)
st.subheader("摘要:")
st.write(summary)
st.subheader("答案:")
st.write(answer)
else:
st.warning("請輸入有效的 URL。")
if __name__ == "__main__":
main()
系統功能與特點
- 自動從指定網站提取內容並生成摘要。
- 根據提取的內容回答使用者提出的問題。
- 使用 Streamlit 提供友好的使用者介面。
- 結合 HuggingFace 的 NLP 模型實作摘要與問答功能。
使用大語言模型建構網站摘要與問答系統
本章節將探討如何利用大語言模型(LLMs)開發一個能夠摘要網站內容並回答相關問題的應用程式。我們將使用Streamlit框架來建立使用者介面,並結合Hugging Face的API來實作文字摘要和問答功能。
系統架構與流程
首先,我們定義了一些全域常數,包括Hugging Face API的端點地址以及文字摘要和問答所需的最小和最大長度引數。
# 定義Hugging Face API端點
QA_ENDPOINT = "https://api-inference.huggingface.co/models/..."
SUMMARIZATION_ENDPOINT = "https://api-inference.huggingface.co/models/tiiuae/falcon-7b-instruct"
# 設定最小和最大長度引數
min_length = 100
max_length = 2000
內容解密:
QA_ENDPOINT和SUMMARIZATION_ENDPOINT分別是Hugging Face提供的問答和摘要模型的API端點。min_length和max_length用於控制從網站提取的文欄位落的長度範圍。
網站內容擷取功能
接下來,我們定義了一個名為extract_combined_passage的函式,用於從指定的URL中擷取網站內容。
def extract_combined_passage(url, min_paragraph_length, max_combined_length):
# 傳送GET請求以取得HTML內容
response = requests.get(url)
html_content = response.text
# 使用BeautifulSoup解析HTML內容
soup = BeautifulSoup(html_content, "html.parser")
# 尋找所有段落標籤並提取文字內容
paragraphs = soup.find_all("p")
passages = [p.get_text(strip=True) for p in paragraphs if len(p.get_text(strip=True)) >= min_paragraph_length]
# 合併段落直到達到指定的最大長度
combined_passage = ""
for passage in passages:
if len(combined_passage) + len(passage) <= max_combined_length:
combined_passage += passage + " "
else:
break
return combined_passage
內容解密:
- 此函式首先傳送GET請求取得指定URL的HTML內容。
- 使用BeautifulSoup解析HTML並提取所有段落標籤中的文字內容。
- 過濾掉長度小於
min_paragraph_length的段落。 - 合併剩餘的段落直到總長度達到
max_combined_length。
主程式與使用者介面
在主程式中,我們設定了Streamlit的使用者介面,包括標題、網址輸入欄位、問題輸入欄位以及觸發摘要和問答的按鈕。
def main():
st.title("網站摘要與問答系統")
# 取得使用者輸入
url = st.text_input("輸入網站網址:")
question = st.text_input("輸入問題:")
if st.button("摘要並回答"):
if url:
# 從網站擷取內容
text = extract_combined_passage(url, min_length, max_length)
# 生成摘要
summary = generate_summary(url)
# 回答問題
answer = answer_question(url, question)
# 顯示結果
st.subheader("摘要:")
st.write(summary)
st.subheader("答案:")
st.write(answer)
else:
st.warning("請輸入有效的網址。")
內容解密:
- 使用Streamlit建立了一個簡單的使用者介面。
- 使用者可以輸入網址和問題,並點選按鈕觸發後續處理。
- 程式會根據輸入的網址擷取內容,生成摘要,並回答問題。
摘要與問答功能實作
我們定義了兩個函式,分別用於生成摘要和回答問題,這兩個函式都利用了Hugging Face的API。
def generate_summary(url):
# 設定Hugging Face API請求
headers = {"Authorization": "Bearer XXXXXXXX"}
combined_passage = extract_combined_passage(url, min_length, max_length)
model_input = f"摘要以下文章。文章:{combined_passage}"
json_data = {
"inputs": model_input,
"parameters": {'temperature': 0.5, 'max_new_tokens': 100, 'return_full_text': False}
}
# 傳送請求到Hugging Face Inference API
response = requests.post(SUMMARIZATION_ENDPOINT, headers=headers, json=json_data)
json_response = json.loads(response.content.decode("utf-8"))
summary = json_response[0]['generated_text']
return summary
def answer_question(url, question):
# 設定Hugging Face API請求
headers = {"Authorization": "Bearer XXXXXXXX"}
combined_passage = extract_combined_passage(url, min_length, max_length)
model_input = f"根據以下內容回答問題。內容:{combined_passage} 問題:{question}"
json_data = {
"inputs": model_input,
"parameters": {'temperature': 0.5, 'max_new_tokens': 100, 'return_full_text': False}
}
# 傳送請求到Hugging Face Inference API
response = requests.post(QA_ENDPOINT, headers=headers, json=json_data)
answer = response.json()[0]["generated_text"]
return answer
內容解密:
- 這兩個函式都首先擷取網站內容,然後建構合適的輸入給Hugging Face模型。
generate_summary函式生成指定文章的摘要。answer_question函式根據提供的內容回答指定的問題。
利用大語言模型開發互動式PDF問答系統
透過大語言模型(LLMs),我們可以開發一個應用程式,讓使用者能夠直接向PDF檔案提問並獲得根據檔案內容的答案。該應用程式利用強大的語言模型處理PDF文字,提取關鍵訊息,並對使用者的查詢提供簡潔的答案。此外,我們還可以採用摘要技術生成PDF檔案的摘要,使我們能夠快速掌握其主要內容和關鍵要點。
PDF問答系統的優勢
利用LLMs開發的PDF問答系統,可以大幅簡化我們的資訊檢索流程,節省時間,並更有效地取得寶貴的見解。無論是用於研究目的、學習,還是從冗長的報告中提取關鍵訊息,這種方法都能幫助我們快速有效地解鎖PDF檔案中所包含的知識。
建構PDF問答應用程式
讓我們來建立一個簡單的根據Streamlit框架的PDF問答應用程式示範。
from dotenv import load_dotenv
import streamlit as st
from PyPDF2 import PdfReader
from langchain.text_splitter import CharacterTextSplitter
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores import FAISS
from langchain.chains.question_answering import load_qa_chain
from langchain.llms import OpenAI
from langchain.callbacks import get_openai_callback
import os
def main():
# 載入環境變數
load_dotenv()
os.environ["OPENAI_API_KEY"] = "XXXXXX"
# 設定Streamlit應用程式
st.set_page_config(page_title="PDF-Chatbot")
st.header("詢問有關您的PDF的任何問題")
# 上傳PDF檔案
pdf = st.file_uploader("上傳您的PDF", type="pdf")
# 從PDF中提取文字
if pdf is not None:
pdf_reader = PdfReader(pdf)
text = ""
for page in pdf_reader.pages:
text += page.extract_text()
# 將文字分割成區塊
text_splitter = CharacterTextSplitter(
separator="\n",
chunk_size=1000,
chunk_overlap=200,
length_function=len
)
chunks = text_splitter.split_text(text)
# 為文字區塊建立嵌入表示
embeddings = OpenAIEmbeddings()
knowledge_base = FAISS.from_texts(chunks, embeddings)
# 提示使用者詢問有關PDF的問題
user_question = st.text_input("詢問有關您的PDF的問題:")
if user_question:
# 執行相似度搜尋以找到相關的文字區塊
docs = knowledge_base.similarity_search(user_question)
# 初始化LLM模型和問答鏈
llm = OpenAI()
chain = load_qa_chain(llm, chain_type="stuff")
# 使用問答鏈取得答案
with get_openai_callback() as cb:
response = chain.run(input_documents=docs, question=user_question)
print(cb)
# 向使用者顯示回應
st.write(response)
if __name__ == '__main__':
main()
內容解密:
- 載入必要的函式庫和模組:首先,我們載入了實作應用程式功能所需的各個函式庫,包括用於載入環境變數的
dotenv、用於建立應用程式介面的streamlit,以及來自langchain函式庫的各種用於文字處理和問答的模組。 main()函式的實作:在main()函式中,我們首先載入環境變數並設定OpenAI API金鑰。然後,我們組態Streamlit應用程式,設定頁面標題並顯示標頭。- 上傳和處理PDF檔案:使用者被提示上傳PDF檔案。我們使用
PdfReader從PyPDF2讀取上傳的PDF檔案的內容,並將文字從每一頁提取並連線成一個單一的文字字串。 - 將文字分割成區塊:使用
CharacterTextSplitter從langchain將提取的文字分割成較小的區塊,以便更有效地處理文字。 - 建立文字區塊的嵌入表示:我們使用
OpenAIEmbeddings類別從langchain為文字區塊建立詞嵌入表示,這些嵌入表示捕捉了文字的語義含義,並使得高效的相似度搜尋成為可能。 - 執行相似度搜尋和問答:當使用者輸入問題時,我們在文字區塊上執行相似度搜尋,以找到與問題最相關的區塊。然後,我們初始化LLM模型並載入問答鏈,使用該鏈根據給定的上下文回答問題。
程式碼逐步解析
匯入必要模組:程式開始時匯入了多個必要的Python模組和函式庫,包括環境變數管理、PDF讀取、文字分割、嵌入表示建立、向量儲存、問答鏈等。
定義主函式:定義了名為
main()的主函式,該函式包含了整個應用程式的主要邏輯。載入環境變數和設定OpenAI API金鑰:在
main()函式內,首先載入了環境變數並手動設定了OpenAI API金鑰。組態Streamlit應用程式介面:使用Streamlit的功能設定了應用程式的頁面標題和顯示了一個標頭,邀請使用者詢問有關其上傳PDF的問題。
實作PDF上傳功能:提供了一個檔案上傳元件,允許使用者上傳PDF檔案。
提取上傳PDF的文字內容:一旦使用者上傳了PDF檔案,程式就讀取該檔案,提取每一頁的文字,並將它們合併成一個單一的字串。
將長文字分割成小區塊:由於大語言模型對輸入長度有限制,因此需要將提取的長文字分割成較小的區塊。這是透過使用特定的文字分割器完成的,可以根據需要調整區塊大小和重疊部分。
建立文字嵌入表示:將分割好的文字區塊轉換成嵌入表示,這是一種可以捕捉文字語義資訊的向量形式。這一步對於後續的相似度搜尋至關重要。
提供使用者輸入問題的介面:允許使用者輸入他們想詢問的問題。
執行相似度搜尋:當使用者提交問題後,系統會在之前建立的知識函式庫(即文字區塊的嵌入表示)中進行相似度搜尋,以找出與問題最相關的文字片段。
使用LLM模型回答問題:根據檢索出的相關文字片段,利用大語言模型生成對使用者問題的回答。
顯示答案給使用者:最後,將生成的答案顯示給使用者,完成整個問答流程。
內容解密:
- 該程式碼實作了一個根據Streamlit的互動式網頁應用,使用者可上傳PDF檔案並對其內容進行提問。
- 程式使用了大語言模型(LLM)和相關技術(如文字嵌入表示、相似度搜尋)來理解和回答使用者的問題。
- 透過將PDF內容分割、嵌入和檢索,系統能夠提供精準的答案給使用者。