【AI大模型应用开发】【LangChain系列】实战案例6:利用大模型进行文本总结的方法探索,文本Token超限怎么办?

本文涉及的产品
阿里云百炼推荐规格 ADB PostgreSQL,4核16GB 100GB 1个月
简介: 【AI大模型应用开发】【LangChain系列】实战案例6:利用大模型进行文本总结的方法探索,文本Token超限怎么办?
  • 大家好,我是同学小张,日常分享AI知识和实战案例
  • 欢迎 点赞 + 关注 👏,持续学习持续干货输出
  • 一起交流💬,一起进步💪。
  • 微信公众号也可搜【同学小张】 🙏

本站文章一览:


假设有一组文档(PDF、Notion页面、客户问题等),你想要总结内容。可以利用大模型来帮你。今天来系统看下利用大模型来对文本进行总结的方法,以LangChain的使用为例。

参考:https://python.langchain.com/docs/use_cases/summarization

0. 方法概述

在利用大模型总结文本的过程中,最主要的工作是如何将文档内容传递给大模型。目前有两种常见的方法:

  1. Stuff方法:简单地将所有文档“填充”到单个提示中。这种方法的主要优点是简单,但缺点是当文档很长或数量很多时,可能会超出模型的上下文窗口限制,导致信息丢失或模型性能下降。
  2. Map-reduce方法:这种方法分为两步。首先,在“map”步骤中,单独对每个文档进行摘要。然后,在“reduce”步骤中,将这些摘要合并成一个最终摘要。这种方法的主要优点是它可以处理大量或长文档,因为它在合并之前先对它们进行了压缩。但是,这种方法可能需要额外的逻辑来确保在“reduce”步骤中生成的最终摘要是有意义和连贯的。

1. 实操练习

1.1 快速开始

1.1.1 代码示例

from langchain.chains.summarize import load_summarize_chain
from langchain_community.document_loaders import WebBaseLoader
from langchain_openai import ChatOpenAI
loader = WebBaseLoader("https://lilianweng.github.io/posts/2023-06-23-agent/")
docs = loader.load()
llm = ChatOpenAI(temperature=0, model_name="gpt-3.5-turbo-1106")
chain = load_summarize_chain(llm, chain_type="stuff")
result = chain.run(docs)
print(result)

代码示例中,使用了 LangChain 的 load_summarize_chain 来总结文本,chain_type="stuff" 表明采用 Stuff 方式。后面会给大家展示load_summarize_chain的部分实现。

1.1.2 运行一下

运行结果如下:

1.2 Stuff方法

这种方法就是直接将全部文本塞给大模型,让大模型直接总结。

1.2.1 StuffDocumentsChain

在上面的示例代码中,我们使用 load_summarize_chain 时,传入的 chain_type="stuff" ,其实底层用的是 LangChain 中的 StuffDocumentsChain

看下直接 StuffDocumentsChain 的使用示例:

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

Prompt很简单,一眼就能看出其工作原理,它就是将docs全部扔给了大模型,让大模型给出一个简要的总结:

prompt_template = """Write a concise summary of the following:
"{text}"
CONCISE SUMMARY:"""

1.3 Map-Reduce方法

首先使用LLMChain将每个文档映射到一个单独的摘要。然后,使用ReduceDocumentsChain将这些摘要合并为一个全局摘要。

1.3.1 代码示例

1.3.1.1 文本分块
text_splitter = CharacterTextSplitter.from_tiktoken_encoder(
    chunk_size=1000, chunk_overlap=0
)
split_docs = text_splitter.split_documents(docs)
1.3.1.2 对分块文本的总结Chain
# Map
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)

重点看Prompt,给定一个文档列表,根据这个文档列表,识别出主题思想。

来看下其执行的结果(输入分割后的一段文本,输出这段文本的主题思想。每段文本都调用一次大模型,执行一次该操作,所以,注意你的API KEY的次数消耗…):

1.3.1.3 ReduceDocumentsChain

有了上面分块的总结,下面的步骤就是根据分块总结合并成一条完整的总结。在LangChain中可以使用 ReduceDocumentsChain 类来实现此步骤。

# Reduce
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)
# Run chain
reduce_chain = LLMChain(llm=llm, prompt=reduce_prompt, verbose=True)
# Takes a list of documents, combines them into a single string, and passes this to an LLMChain
combine_documents_chain = StuffDocumentsChain(
    llm_chain=reduce_chain, document_variable_name="docs", verbose=True
)
# Combines and iteratively reduces the mapped documents
reduce_documents_chain = ReduceDocumentsChain(
    # This is final chain that is called.
    combine_documents_chain=combine_documents_chain,
    # If documents exceed context for `StuffDocumentsChain`
    collapse_documents_chain=combine_documents_chain,
    # The maximum number of tokens to group documents into.
    token_max=4000,
    verbose=True
)

从代码中可以看到,ReduceDocumentsChain 设置了4个参数,我们分别来解释下。

  • combine_documents_chain:这是最终执行总结的Chain。它的值为 combine_documents_chain。而 combine_documents_chain 定义为一个 StuffDocumentsChain 类型的Chain,也就是简单地将前面分块总结的内容塞给大模型,让它根据分块总结再汇总总结一次。
  • collapse_documents_chain:这个Chain的作用,是来处理塞给大模型的Token超限的情况。如果文本特别多,分块特别多,那分块总结出来的东西也会非常多。单纯的将分块总结内容合并在一起,还是很有可能超过大模型上下文窗口限制。这个Chain,会按设置的最大Token数将内容再次拆分,然后再利用 StuffDocumentsChain 进行分块总结,直到最终各分块总结合并起来能一次塞给大模型才停止。

这是个递归分割总结的过程,注意Token或者调用次数的消耗,都是钱啊…

  • token_max:最大Token数,超过这个Token数执行上面的collapse_documents_chain
  • verbose:开详细日志

来直观感受下它的运行(合并分块总结内容作为输入,输出最终总结结果):

本例中分块总结文本合并后没有超限,所以没用到 collapse_documents_chain

1.3.1.4 Map-Reduce组合Chain: MapReduceDocumentsChain
# Combining documents by mapping a chain over them, then combining results
map_reduce_chain = MapReduceDocumentsChain(
    # Map chain
    llm_chain=map_chain,
    # Reduce chain
    reduce_documents_chain=reduce_documents_chain,
    # The variable name in the llm_chain to put the documents in
    document_variable_name="docs",
    # Return the results of the map steps in the output
    return_intermediate_steps=False,
    verbose=True
)

1.3.2 运行及结果

print(map_reduce_chain.run(split_docs))

2. 部分源码

(1)ReduceDocumentsChain 中,如果Token超限的处理:collapse_documents_chain,直接一个 while 循环压缩Token数。

(2)load_summarize_chain 的封装,在1.1中我们使用了 chain_type = "stuff",它其实也可以使用 “map_reduce” 或 “refine”。

如果chain_type设置为map_reduce,看它的源码,跟我们1.3节中的代码几乎一样。load_summarize_chain 就是对这几种方法的高层封装!

def _load_map_reduce_chain(
    llm: BaseLanguageModel,
    map_prompt: BasePromptTemplate = map_reduce_prompt.PROMPT,
    combine_prompt: BasePromptTemplate = map_reduce_prompt.PROMPT,
    combine_document_variable_name: str = "text",
    map_reduce_document_variable_name: str = "text",
    collapse_prompt: Optional[BasePromptTemplate] = None,
    reduce_llm: Optional[BaseLanguageModel] = None,
    collapse_llm: Optional[BaseLanguageModel] = None,
    verbose: Optional[bool] = None,
    token_max: int = 3000,
    callbacks: Callbacks = None,
    *,
    collapse_max_retries: Optional[int] = None,
    **kwargs: Any,
) -> MapReduceDocumentsChain:
    map_chain = LLMChain(
        llm=llm, prompt=map_prompt, verbose=verbose, callbacks=callbacks
    )
    _reduce_llm = reduce_llm or llm
    reduce_chain = LLMChain(
        llm=_reduce_llm, prompt=combine_prompt, verbose=verbose, callbacks=callbacks
    )
    # TODO: document prompt
    combine_documents_chain = StuffDocumentsChain(
        llm_chain=reduce_chain,
        document_variable_name=combine_document_variable_name,
        verbose=verbose,
        callbacks=callbacks,
    )
    if collapse_prompt is None:
        collapse_chain = None
        if collapse_llm is not None:
            raise ValueError(
                "collapse_llm provided, but collapse_prompt was not: please "
                "provide one or stop providing collapse_llm."
            )
    else:
        _collapse_llm = collapse_llm or llm
        collapse_chain = StuffDocumentsChain(
            llm_chain=LLMChain(
                llm=_collapse_llm,
                prompt=collapse_prompt,
                verbose=verbose,
                callbacks=callbacks,
            ),
            document_variable_name=combine_document_variable_name,
        )
    reduce_documents_chain = ReduceDocumentsChain(
        combine_documents_chain=combine_documents_chain,
        collapse_documents_chain=collapse_chain,
        token_max=token_max,
        verbose=verbose,
        callbacks=callbacks,
        collapse_max_retries=collapse_max_retries,
    )
    return MapReduceDocumentsChain(
        llm_chain=map_chain,
        reduce_documents_chain=reduce_documents_chain,
        document_variable_name=map_reduce_document_variable_name,
        verbose=verbose,
        callbacks=callbacks,
        **kwargs,
    )

3. 总结

本文我们学习和实践了利用 LangChain 进行文本总结的两种方法,知道了其实现原理,所以,我们应该不用 LangChain的这些封装也可以自己实现一套文档总结流程。

其实,LangChain 还有其它的文档总结的Chain,例如 RefineDocumentsChain 和 AnalyzeDocumentsChain,大体原理与本文介绍的两种方式都差不多,主要是封装的差异,感兴趣的也可以去试试。

如果觉得本文对你有帮助,麻烦点个赞和关注呗 ~~~


  • 大家好,我是 同学小张,日常分享AI知识和实战案例
  • 欢迎 点赞 + 关注 👏,持续学习持续干货输出
  • 一起交流💬,一起进步💪。
  • 微信公众号也可搜【同学小张】 🙏

本站文章一览:

相关实践学习
阿里云百炼xAnalyticDB PostgreSQL构建AIGC应用
通过该实验体验在阿里云百炼中构建企业专属知识库构建及应用全流程。同时体验使用ADB-PG向量检索引擎提供专属安全存储,保障企业数据隐私安全。
AnalyticDB PostgreSQL 企业智能数据中台:一站式管理数据服务资产
企业在数据仓库之上可构建丰富的数据服务用以支持数据应用及业务场景;ADB PG推出全新企业智能数据平台,用以帮助用户一站式的管理企业数据服务资产,包括创建, 管理,探索, 监控等; 助力企业在现有平台之上快速构建起数据服务资产体系
相关文章
|
6天前
|
机器学习/深度学习 数据采集 人工智能
探索AI技术在文本生成中的应用与挑战
【9月更文挑战第26天】本文深入探讨了AI技术在文本生成领域的应用,并分析了其面临的挑战。通过介绍AI文本生成的基本原理、应用场景以及未来发展趋势,帮助读者全面了解该技术的潜力和局限性。同时,文章还提供了代码示例,展示了如何使用Python和相关库实现简单的文本生成模型。
29 9
|
25天前
|
人工智能 测试技术 API
AI计算机视觉笔记二十 九:yolov10竹签模型,自动数竹签
本文介绍了如何在AutoDL平台上搭建YOLOv10环境并进行竹签检测与计数。首先从官网下载YOLOv10源码并创建虚拟环境,安装依赖库。接着通过官方模型测试环境是否正常工作。然后下载自定义数据集并配置`mycoco128.yaml`文件,使用`yolo detect train`命令或Python代码进行训练。最后,通过命令行或API调用测试训练结果,并展示竹签计数功能。如需转载,请注明原文出处。
|
18天前
|
机器学习/深度学习 人工智能 UED
OpenAI o1模型:AI通用复杂推理的新篇章
OpenAI发布了其最新的AI模型——o1,这款模型以其独特的复杂推理能力和全新的训练方式,引起了业界的广泛关注。今天,我们就来深入剖析o1模型的特点、背后的原理,以及一些有趣的八卦信息。
210 73
|
23天前
|
机器学习/深度学习 人工智能 编解码
深入探索AI文生语音技术的奥秘:从文本输入到逼真语音输出的全链条语音合成过程解析
【9月更文挑战第2天】深入探索AI文生语音技术的奥秘:从文本输入到逼真语音输出的全链条语音合成过程解析
 深入探索AI文生语音技术的奥秘:从文本输入到逼真语音输出的全链条语音合成过程解析
|
13天前
|
存储 人工智能 算法
阿里云AI基础设施升级亮相,模型算力利用率提升超20%
阿里云AI基础设施升级亮相,模型算力利用率提升超20%
105 18
|
3天前
|
机器学习/深度学习 消息中间件 搜索推荐
【数据飞轮】驱动业务增长的高效引擎 —从数据仓库到数据中台的技术进化与实战
在数据驱动时代,企业逐渐从数据仓库过渡到数据中台,并进一步发展为数据飞轮。本文详细介绍了这一演进路径,涵盖数据仓库的基础存储与查询、数据中台的集成与实时决策,以及数据飞轮的自动化增长机制。通过代码示例展示如何在实际业务中运用数据技术,实现数据的最大价值,推动业务持续优化与增长。
14 4
|
20天前
|
人工智能 自动驾驶 云计算
【通义】AI视界|谷歌大模型被盯上!欧盟最高隐私监管机构对PaLM2模型展开调查~
本文汇总了近24小时内科技领域的五大要闻:欧盟对谷歌PaLM2模型启动隐私合规调查;甲骨文推出Zettascale云计算集群,集成大量NVIDIA GPU强化计算力;红杉资本偏好AI应用投资而非模型构建;夸克新推智能助手CueMe,支持长达2万字内容生成;沃尔沃与NVIDIA合作,未来车型将采用后者先进芯片提升自动驾驶功能。以上内容由通义自动生成。
|
21天前
|
机器学习/深度学习 人工智能 自然语言处理
探索AI在文本生成中的应用与挑战
【9月更文挑战第11天】本文将深入探讨人工智能在文本生成领域的应用及其面临的挑战。我们将通过实际案例分析,了解当前技术如何影响内容创作,并讨论未来可能的发展方向。文章旨在为读者提供一个关于AI文本生成技术的全面视角,包括其优势、局限及潜在影响。
|
22天前
|
机器学习/深度学习 人工智能 供应链
【通义】AI视界|OpenAI的“草莓”模型预计两周内上线!像人类一样思考!
本文介绍了近期科技领域的五大亮点:OpenAI即将推出的新一代AI模型“草莓”,具备高级推理能力;亚马逊测试AI技术加速有声读物生产,通过语音克隆提高效率;Kimi API新增联网搜索功能,拓宽信息来源;顺丰发布物流行业专用大语言模型“丰语”,提升工作效率;钉钉推出“AI班级群”功能,改善家校沟通体验。更多详情,请访问[通义官网]。
|
24天前
|
机器学习/深度学习 人工智能 自然语言处理
探索AI在文本情感分析中的应用
【8月更文挑战第40天】本文将深入探讨人工智能在文本情感分析领域的强大应用。我们将从基础概念出发,逐步深入到技术实现,最终通过一个Python代码示例具体展示如何使用自然语言处理库进行情感分析。文章旨在为读者提供一个清晰的指南,了解并实践如何利用AI技术解读和评估文本中的情感色彩。
下一篇
无影云桌面