LangChain实战案例:利用大模型进行文本总结的方法探索,文本Token超限怎么办?

本站文章一览:

在这里插入图片描述


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

参考:python.langchain.com/docs/use_ca…

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的次数消耗…):

image.png

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:开详细日志

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

image.png

本例中分块总结文本合并后没有超限,所以没用到 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大模型资料包括市面上AI大模型各大白皮书、AGI大模型系统学习路线、AI大模型视频教程、实战学习,等录播视频免费分享出来,需要的小伙伴可以扫取。

现在社会上大模型越来越普及了,已经有很多人都想往这里面扎,但是却找不到适合的方法去学习。

作为一名资深码农,初入大模型时也吃了很多亏,踩了无数坑。现在我想把我的经验和知识分享给你们,帮助你们学习AI大模型,能够解决你们学习中的困难。

下面这些都是我当初辛苦整理和花钱购买的资料,现在我已将重要的AI大模型资料包括市面上AI大模型各大白皮书、AGI大模型系统学习路线、AI大模型视频教程、实战学习,等录播视频免费分享出来,需要的小伙伴可以扫取。

一、AGI大模型系统学习路线

很多人学习大模型的时候没有方向,东学一点西学一点,像只无头苍蝇乱撞,我下面分享的这个学习路线希望能够帮助到你们学习AI大模型。

在这里插入图片描述

二、AI大模型视频教程

在这里插入图片描述

三、AI大模型各大学习书籍!

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

四、AI大模型各大场景实战案例

在这里插入图片描述

五、AI大模型面试题库
在这里插入图片描述

👉学会后的收获:👈
基于大模型全栈工程实现(前端、后端、产品经理、设计、数据分析等),通过这门课可获得不同能力;

能够利用大模型解决相关实际项目需求: 大数据时代,越来越多的企业和机构需要处理海量数据,利用大模型技术可以更好地处理这些数据,提高数据分析和决策的准确性。因此,掌握大模型应用开发技能,可以让程序员更好地应对实际项目需求;

• 基于大模型和企业数据AI应用开发,实现大模型理论、掌握GPU算力、硬件、LangChain开发框架和项目实战技能, 学会Fine-tuning垂直训练大模型(数据准备、数据蒸馏、大模型部署)一站式掌握;

能够完成时下热门大模型垂直领域模型训练能力,提高程序员的编码能力: 大模型应用开发需要掌握机器学习算法、深度学习框架等技术,这些技术的掌握可以提高程序员的编码能力和分析能力,让程序员更加熟练地编写高质量的代码。

👉 福利来袭优快云大礼包:《2025最全AI大模型学习资源包》免费分享,安全可点 👈

五、结束语

学习AI大模型是当前科技发展的趋势,它不仅能够为我们提供更多的机会和挑战,还能够让我们更好地理解和应用人工智能技术。通过学习AI大模型,我们可以深入了解深度学习、神经网络等核心概念,并将其应用于自然语言处理、计算机视觉、语音识别等领域。同时,掌握AI大模型还能够为我们的职业发展增添竞争力,成为未来技术领域的领导者。

再者,学习AI大模型也能为我们自己创造更多的价值,提供更多的岗位以及副业创收,让自己的生活更上一层楼。

因此,学习AI大模型是一项有前景且值得投入的时间和精力的重要选择。

<think>好的,我现在需要回答用户关于大模型token的使用与定义的问题。首先,我得回顾一下用户提供的引用内容,确保回答准确并正确引用。 用户引用了三个来源: 1. 引用[1]提到词汇表的大小和质量影响模型性能,需要覆盖常见词汇,避免过多稀有词。 2. 引用[2]说明token是处理文本的最小单位,控制成本和效果的关键。 3. 引用[3]指出token数量限制可能导致输入超限或输出冗长的问题。 首先,我应该从token的定义开始解释,结合引用[2],强调它是处理文本的基本单位。然后,需要讨论词汇表的作用,如引用[1]所述,说明词汇表如何影响模型表现。接下来,要涉及token的使用,包括输入输出的处理,比如分词过程,这里可能需要举例,比如英文和中文的不同处理方式。然后,成本和性能的影响部分需要引用[2]和[3],提到输入长度限制和生成成本的问题。最后,应用中的注意事项可以结合引用[3]中的输入超限问题,给出实际建议。 在组织内容时,要保持结构清晰,分点说明。可能需要分为定义、词汇表、使用流程、成本与性能、注意事项等部分。同时,确保每个引用都自然地插入到相关段落末尾,比如在讨论词汇表时引用[1],在定义token时引用[2],在输入输出限制时引用[3]。 还需要检查是否符合用户的要求:使用中文,数学公式用$...$,独立公式用$$...$$,不过当前问题可能不涉及数学公式,但如果有的话需要正确应用。此外,生成相关问题,可能需要涉及token的定义、分词技术、优化方法应用影响等。 最后,确保回答真实可靠,引用正确,结构符合用户提供的示例,比如先详细回答,然后列出相关问题。</think>### 大模型Token的定义与使用 #### 1. **Token的定义** **Token**是大语言模型处理文本的最小单位,类似于自然语言中的“词”或“子词”。例如,英文单词"unhappy"可能被拆分为"un"和"happy"两个token,而中文的“自然语言处理”可能被分为“自然”、“语言”、“处理”三个tokenToken的设计直接影响模型对文本的理解能力和计算效率[^2]。 #### 2. **词汇表(Tokenization Vocabulary)** 词汇表是模型处理文本的核心工具,包含所有可能的token。其设计需满足以下条件: - **覆盖性**:包含常见词汇和符号(如标点、数字)。 - **效率性**:避免过多稀有token(如生僻字),以减少计算复杂度。 - **灵活性**:支持子词拆分(如BPE算法)以处理未登录词[^1]。 #### 3. **Token的使用流程** - **输入阶段**:文本通过分词器(Tokenizer)转换为token序列。例如: ```python # 示例:Hugging Face分词器 from transformers import AutoTokenizer tokenizer = AutoTokenizer.from_pretrained("gpt-3") tokens = tokenizer.encode("你好,世界!") # 输出如 [101, 2345, 102] ``` - **模型处理**:每个token被映射为向量(嵌入表示),参与模型计算。 - **输出阶段**:模型生成的token序列被转换回文本。 #### 4. **Token与成本、性能的关系** - **上下文窗口限制**:模型对输入token数量有上限(如GPT-3.5的4096 token)。超出限制会导致截断或报错[^3]。 - **计算成本**:生成文本的成本通常按token数量计费。 - **生成质量**:过长的输出可能包含冗余信息,需通过参数(如`max_new_tokens`)控制。 #### 5. **应用中的注意事项** - **输入优化**:压缩冗余文本,优先保留关键信息。 - **输出控制**:设置合理的生成长度阈值(如`temperature=0.7`)。 - **分词差异**:不同模型的分词规则可能影响结果(如中英文混合文本需特殊处理)。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值