Summarization with Langchain

IcyFeather233發表於2024-08-21

教程連結 — https://youtu.be/w6wOhSThnoo

摘要是自然語言處理(NLP)的一個關鍵方面,它能夠將大量文字濃縮成簡潔的摘要。LangChain,作為NLP領域中的一個強大工具,提供了三種不同的摘要技術:stuffmap_reducerefine。每種方法都有其獨特的優點和侷限性,使它們適用於不同的情況。本文深入探討了這些技術的細節、它們的優缺點以及理想的應用場景。

教程中使用的完整實現程式碼和資料可在以下儲存庫中找到。

摘要技術

圖片 3

來自langchain

  1. Stuff Chain

stuff鏈特別適用於處理大型文件。它的工作原理是將文件轉換為較小的塊,分別處理每個塊,然後將摘要組合起來生成最終摘要。這種方法適用於管理龐大的檔案,並且可以透過遞迴字元文字分割器的幫助來實現。

優點:

  • 高效處理大型文件。
  • 允許逐塊摘要,適合管理龐大的檔案。

缺點:

  • LLM上下文視窗
from langchain.chains.combine_documents.stuff import StuffDocumentsChain  
from langchain.chains.llm import LLMChain  
from langchain.prompts import PromptTemplate # 定義提示  
prompt_template = """Write a concise summary of the following:  
"{text}"  
CONCISE SUMMARY:"""  
prompt = PromptTemplate.from_template(prompt_template)  
# 定義 LLM 鏈  
llm = ChatOpenAI(temperature=0, model_name="gpt-3.5-turbo-16k")  
llm_chain = LLMChain(llm=llm, prompt=prompt)  
# 定義 StuffDocumentsChain  
stuff_chain = StuffDocumentsChain(llm_chain=llm_chain, document_variable_name="text")  
docs = loader.load()  
print(stuff_chain.run(docs))

Map-Reduce 方法

對映-歸約方法涉及分別對每個文件進行摘要(對映步驟),然後將這些摘要組合成最終摘要(歸約步驟)。這種方法更可擴充套件,並且可以處理更大量的文字。map_reduce技術旨在摘要超出語言模型令牌限制的大型文件。它涉及將文件分成塊,為每個塊生成摘要,然後將這些摘要組合起來建立最終摘要。這種方法對處理大型檔案高效,並且顯著減少了處理時間。

優點:

  • 透過將大型文件分成可管理的塊來有效處理。
  • 透過分別處理塊來減少處理時間。

缺點:

  • 需要額外的步驟來組合單獨的摘要,這可能會增加過程的複雜性。

以下是如何實現對映-歸約方法的示例:

from langchain.chains import MapReduceDocumentsChain, ReduceDocumentsChain  
from langchain_text_splitters import CharacterTextSplitter # 對映  
map_template = """The following is a set of documents  
{docs}  
Based on this list of docs, please identify the main themes   
Helpful Answer:"""  
map_prompt = PromptTemplate.from_template(map_template)  
map_chain = LLMChain(llm=llm, prompt=map_prompt)  
# 歸約  
reduce_template = """The following is set of summaries:  
{docs}  
Take these and distill it into a final, consolidated summary of the main themes.   
Helpful Answer:"""  
reduce_prompt = PromptTemplate.from_template(reduce_template)  
reduce_chain = LLMChain(llm=llm, prompt=reduce_prompt)  
# 透過對映鏈組合文件,然後組合結果  
map_reduce_chain = MapReduceDocumentsChain(  
    llm_chain=map_chain,  
    reduce_documents_chain=reduce_documents_chain,  
    document_variable_name="docs",  
    return_intermediate_steps=False,  
)  
text_splitter = CharacterTextSplitter.from_tiktoken_encoder(chunk_size=1000, chunk_overlap=0)  
split_docs = text_splitter.split_documents(docs)  
print(map_reduce_chain.run(split_docs))

Refine 方法

Refine方法透過迴圈遍歷輸入文件來迭代更新其答案。對於每個文件,它將所有非文件輸入、當前文件和最新的中間答案傳遞給LLM鏈以獲得新答案。這種方法適用於根據新上下文細化摘要。

refine技術是map_reduce技術的簡單替代方案。它涉及為第一個塊生成摘要,將其與第二個塊組合,生成另一個摘要,並繼續這個過程,直到最終摘要完成。這種方法適用於大型文件,但與map_reduce相比,需要的複雜性較小。

優點:

  • map_reduce技術更簡單。
  • 對於大型文件,以較小的複雜性實現了類似的結果。

缺點:

  • 與其它技術相比,功能有限。

以下是如何實現Refine方法的示例:

from langchain.chains.summarize import load_summarize_chain
prompt = """
                  Please provide a summary of the following text.
                  TEXT: {text}
                  SUMMARY:
                  """

question_prompt = PromptTemplate(
    template=question_prompt_template, input_variables=["text"]
)

refine_prompt_template = """
              Write a concise summary of the following text delimited by triple backquotes.
              Return your response in bullet points which covers the key points of the text.
              ```{text}```
              BULLET POINT SUMMARY:
              """

refine_template = PromptTemplate(
    template=refine_prompt_template, input_variables=["text"]

# Load refine chain
chain = load_summarize_chain(
    llm=llm,
    chain_type="refine",
    question_prompt=question_prompt,
    refine_prompt=refine_prompt,
    return_intermediate_steps=True,
    input_key="input_documents",
    output_key="output_text",
)
result = chain({"input_documents": split_docs}, return_only_outputs=True)

選擇合適的技術

摘要技術的選擇取決於當前任務的具體要求。對於大型文件,建議使用map_reducerefine技術,因為它們能夠有效地進行分塊摘要。stuff鏈特別適合於太大而無法一次性處理的文件,為管理龐大的檔案提供了實用的解決方案。

每種方法都有其優勢,適用於不同場景。Stuff方法簡單但可能不適用於處理大量文字。Map-Reduce方法更可擴充套件,可以處理更大的文件,但需要更多的設定。Refine方法適用於基於新上下文迭代細化摘要,使其成為動態摘要任務的良好選擇。

相關文章