modelscope可控细节的长文档摘要

news2024/11/24 1:57:34

modelscope可控细节的长文档摘要尝试
本文的想法来自今年OpenAI cookbook的一篇实践:summarizing_long_documents,目标是演示如何以可控的细节程度总结大型文档。

如果我们想让大语言模型总结一份长文档(例如 10k 或更多tokens),但是直接输入大语言模型往往会得到一个相对较短的摘要,该摘要与文档的长度并不成比例。例如,20k tokens的文档的摘要不会是 10k tokens的文档摘要的两倍长。本文通过将文档分为几部分来解决这个问题,然后分段生成摘要。在对大语言模型进行多次查询后,可以重建完整的摘要。通过控制文本块的数量及其大小,我们最终可以控制输出中的细节级别。

本文使用的工具和模型如下:

大语言模型:Qwen2的GGUF格式模型

工具1:Ollama,将大语言模型GGUF部署成OpenAI格式的API

工具2:transformers,使用transformers的新功能,直接加载GGUF格式模型的tokenizer,用于文档长度查询和分段。

最佳实践

运行Qwen2模型(详见《魔搭社区GGUF模型怎么玩!看这篇就够了》)

复制模型路径,创建名为“ModelFile”的meta文件,内容如下:

FROM /mnt/workspace/qwen2-7b-instruct-q5_k_m.gguf

# set the temperature to 0.7 [higher is more creative, lower is more coherent]
PARAMETER temperature 0.7
PARAMETER top_p 0.8
PARAMETER repeat_penalty 1.05
TEMPLATE """{{ if and .First .System }}<|im_start|>system
{{ .System }}<|im_end|>
{{ end }}<|im_start|>user
{{ .Prompt }}<|im_end|>
<|im_start|>assistant
{{ .Response }}"""
# set the system message
SYSTEM """
You are a helpful assistant.
"""

使用ollama create命令创建自定义模型并运行

ollama create myqwen2 --file ./ModelFile
ollama run myqwen2```

安装依赖&读取需要总结的文档

import os
from typing import List, Tuple, Optional
from openai import OpenAI
from transformers import AutoTokenizer
from tqdm import tqdm
# load doc
with open("data/artificial_intelligence_wikipedia.txt", "r") as file:
    artificial_intelligence_wikipedia_text = file.read()

加载encoding并检查文档长度

HuggingFace的transformers 支持加载GGUF单文件格式,以便为 gguf 模型提供进一步的训练/微调功能,然后再将这些模型转换回生态系统gguf中使用ggml,GGUF文件通常包含配置属性,tokenizer,以及其他的属性,以及要加载到模型的所有tensor,参考文档:https://huggingface.co/docs/transformers/gguf

目前支持的模型架构为:llama,mistral,qwen2

# load encoding and check the length of dataset
encoding = AutoTokenizer.from_pretrained("/mnt/workspace/cherry/",gguf_file="qwen2-7b-instruct-q5_k_m.gguf")
len(encoding.encode(artificial_intelligence_wikipedia_text))

调用LLM的OpenAI格式的API

client = OpenAI(
    base_url = 'http://127.0.0.1:11434/v1',
    api_key='ollama', # required, but unused
)

def get_chat_completion(messages, model='myqwen2'):
    response = client.chat.completions.create(
        model=model,
        messages=messages,
        temperature=0,
    )
    return response.choices[0].message.content

文档拆解

我们定义了一些函数,将大文档分成较小的部分。

def tokenize(text: str) -> List[str]:    
    return encoding.encode(text)
# This function chunks a text into smaller pieces based on a maximum token count and a delimiter.
def chunk_on_delimiter(input_string: str,
                       max_tokens: int, delimiter: str) -> List[str]:
    chunks = input_string.split(delimiter)
    combined_chunks, _, dropped_chunk_count = combine_chunks_with_no_minimum(
        chunks, max_tokens, chunk_delimiter=delimiter, add_ellipsis_for_overflow=True
    )
    if dropped_chunk_count > 0:
        print(f"warning: {dropped_chunk_count} chunks were dropped due to overflow")
    combined_chunks = [f"{chunk}{delimiter}" for chunk in combined_chunks]
    return combined_chunks


# This function combines text chunks into larger blocks without exceeding a specified token count. It returns the combined text blocks, their original indices, and the count of chunks dropped due to overflow.
def combine_chunks_with_no_minimum(
        chunks: List[str],
        max_tokens: int,
        chunk_delimiter="\n\n",
        header: Optional[str] = None,
        add_ellipsis_for_overflow=False,
) -> Tuple[List[str], List[int]]:
    dropped_chunk_count = 0
    output = []  # list to hold the final combined chunks
    output_indices = []  # list to hold the indices of the final combined chunks
    candidate = (
        [] if header is None else [header]
    )  # list to hold the current combined chunk candidate
    candidate_indices = []
    for chunk_i, chunk in enumerate(chunks):
        chunk_with_header = [chunk] if header is None else [header, chunk]
        if len(tokenize(chunk_delimiter.join(chunk_with_header))) > max_tokens:
            print(f"warning: chunk overflow")
            if (
                    add_ellipsis_for_overflow
                    and len(tokenize(chunk_delimiter.join(candidate + ["..."]))) <= max_tokens
            ):
                candidate.append("...")
                dropped_chunk_count += 1
            continue  # this case would break downstream assumptions
        # estimate token count with the current chunk added
        extended_candidate_token_count = len(tokenize(chunk_delimiter.join(candidate + [chunk])))
        # If the token count exceeds max_tokens, add the current candidate to output and start a new candidate
        if extended_candidate_token_count > max_tokens:
            output.append(chunk_delimiter.join(candidate))
            output_indices.append(candidate_indices)
            candidate = chunk_with_header  # re-initialize candidate
            candidate_indices = [chunk_i]
        # otherwise keep extending the candidate
        else:
            candidate.append(chunk)
            candidate_indices.append(chunk_i)
    # add the remaining candidate to output if it's not empty
    if (header is not None and len(candidate) > 1) or (header is None and len(candidate) > 0):
        output.append(chunk_delimiter.join(candidate))
        output_indices.append(candidate_indices)
    return output, output_indices, dropped_chunk_count

摘要函数

现在我们可以定义一个实用程序来以可控的细节级别总结文本(注意参数detail)。

该函数首先根据可控参数在最小和最大块数之间进行插值来确定块数detail。然后,它将文本拆分成块并对每个块进行总结。

<span>def summarize(text: str,</span>

现在,我们可以使用此实用程序生成具有不同详细程度的摘要。通过detail从 0 增加到 1,我们可以逐渐获得更长的底层文档摘要。参数值越高,detail摘要越详细,因为实用程序首先将文档拆分为更多块。然后对每个块进行汇总,最终摘要是所有块摘要的串联。

def summarize(text: str,
              detail: float = 0,
              model: str = 'myqwen2',
              additional_instructions: Optional[str] = None,
              minimum_chunk_size: Optional[int] = 500,
              chunk_delimiter: str = "\n",
              summarize_recursively=False,
              verbose=False):
    """
    Summarizes a given text by splitting it into chunks, each of which is summarized individually. 
    The level of detail in the summary can be adjusted, and the process can optionally be made recursive.

    Parameters:
    - text (str): The text to be summarized.
    - detail (float, optional): A value between 0 and 1 indicating the desired level of detail in the summary.
      0 leads to a higher level summary, and 1 results in a more detailed summary. Defaults to 0.
    - model (str, optional): The model to use for generating summaries. Defaults to 'gpt-3.5-turbo'.
    - additional_instructions (Optional[str], optional): Additional instructions to provide to the model for customizing summaries.
    - minimum_chunk_size (Optional[int], optional): The minimum size for text chunks. Defaults to 500.
    - chunk_delimiter (str, optional): The delimiter used to split the text into chunks. Defaults to ".".
    - summarize_recursively (bool, optional): If True, summaries are generated recursively, using previous summaries for context.
    - verbose (bool, optional): If True, prints detailed information about the chunking process.

    Returns:
    - str: The final compiled summary of the text.

    The function first determines the number of chunks by interpolating between a minimum and a maximum chunk count based on the `detail` parameter. 
    It then splits the text into chunks and summarizes each chunk. If `summarize_recursively` is True, each summary is based on the previous summaries, 
    adding more context to the summarization process. The function returns a compiled summary of all chunks.
    """

    # check detail is set correctly
    assert 0 <= detail <= 1
    # interpolate the number of chunks based to get specified level of detail
    max_chunks = len(chunk_on_delimiter(text, minimum_chunk_size, chunk_delimiter))
    min_chunks = 1
    num_chunks = int(min_chunks + detail * (max_chunks - min_chunks))

    # adjust chunk_size based on interpolated number of chunks
    document_length = len(tokenize(text))
    chunk_size = max(minimum_chunk_size, document_length // num_chunks)
    text_chunks = chunk_on_delimiter(text, chunk_size, chunk_delimiter)
    if verbose:
        print(f"Splitting the text into {len(text_chunks)} chunks to be summarized.")
        print(f"Chunk lengths are {[len(tokenize(x)) for x in text_chunks]}")

    # set system message
    system_message_content = "Rewrite this text in summarized form."
    if additional_instructions is not None:
        system_message_content += f"\n\n{additional_instructions}"

    accumulated_summaries = []
    for chunk in tqdm(text_chunks):
        if summarize_recursively and accumulated_summaries:
            # Creating a structured prompt for recursive summarization
            accumulated_summaries_string = '\n\n'.join(accumulated_summaries)
            user_message_content = f"Previous summaries:\n\n{accumulated_summaries_string}\n\nText to summarize next:\n\n{chunk}"
        else:
            # Directly passing the chunk for summarization without recursive context
            user_message_content = chunk

        # Constructing messages based on whether recursive summarization is applied
        messages = [
            {"role": "system", "content": system_message_content},
            {"role": "user", "content": user_message_content}
        ]

        # Assuming this function gets the completion and works as expected
        response = get_chat_completion(messages, model=model)
        accumulated_summaries.append(response)

    # Compile final summary from partial summaries
    final_summary = '\n\n'.join(accumulated_summaries)

    return final_summary
summary_with_detail_0 = summarize(artificial_intelligence_wikipedia_text, detail=0, verbose=True)

summary_with_detail_pt25 = summarize(artificial_intelligence_wikipedia_text, detail=0.25, verbose=True)

在这里插入图片描述

此实用程序还允许传递附加指令。

summary_with_additional_instructions = summarize(artificial_intelligence_wikipedia_text, detail=0.1,
                                                 additional_instructions="Write in point form and focus on numerical data.")
print(summary_with_additional_instructions)

最后,请注意,该实用程序允许递归汇总,其中每个摘要都基于先前的摘要,从而为汇总过程添加更多上下文。可以通过将参数设置summarize_recursively为 True 来启用此功能。这在计算上更昂贵,但可以提高组合摘要的一致性和连贯性。

recursive_summary = summarize(artificial_intelligence_wikipedia_text, detail=0.1, summarize_recursively=True)
print(recursive_summary)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1894000.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

WIN32核心编程 - 进程操作(一) 进程基础 - 创建进程 - 进程句柄

公开视频 -> 链接点击跳转公开课程博客首页 -> 链接点击跳转博客主页 目录 进程基础 进程的定义与概念 进程的组成 创建进程 可执行文件 CreateProces 执行流程 GetStartupInfo 进程终止 进程句柄 创建进程 打开进程 进程提权 内核模拟 回溯对象 自身进…

iOS App 测试环境升级,遇到的问题以及解决方法

iOS App 测试环境升级&#xff0c;遇到的问题以及解决方法 Mac 实体机升级到 Sonima 14.5 Xcode 升级到 15.3 问题1&#xff1a; Xcode 编译 WebDriverAgent 失败 尝试下载 最新版本的WDA 源码编译&#xff0c;可以编译成功。 问题2&#xff1a;具体坐标直接点击的代码都会报错…

简洁纯文字类的Typecho主题wenso

主题介绍 文章说说类博客网站源码&#xff0c;页面清新简洁。适合文章说说美文博客网站建站使用&#xff0c;响应式手机版本。 本来是dedecms的模板&#xff0c;也比较简单&#xff0c;适合用来搭建一个文学类的&#xff0c;纯文字的网站&#xff0c;简单的改成了typecho&…

nccl 04 nvidia 官方小程序

1&#xff0c;代码重新编辑 为了地毯式地检查结果的正确性&#xff0c;这里修改了代码 主要步骤为 step1: data_p指向的空间中&#xff0c;分别生成随机数&#xff1b; step2: 分别拷贝到gpu的sendbuff的显存中&#xff1b; step3: 通过nccl_all_reduce sum&#xff1b;…

职场办公受欢迎的电脑桌面便签,手机电脑同步的备忘录

在快节奏的职场生活中&#xff0c;有效的时间管理和信息记录变得尤为重要。为了帮助大家更好地应对工作挑战&#xff0c;好用的电脑桌面便签和手机电脑同步的备忘录&#xff0c;好用便签应运而生&#xff0c;成为了当前职场办公中的得力助手。 好用便签是一款备受青睐的电脑桌…

香橙派AIpro实测:YOLOv8便捷检测,算法速度与运行速度结合

香橙派AIpro实测&#xff1a;YOLOv8便捷检测&#xff0c;算法速度与运行速度结合 文章目录 香橙派AIpro实测&#xff1a;YOLOv8便捷检测&#xff0c;算法速度与运行速度结合一、引言二、香橙派AIpro简介三、YOLOv8检测效果3.1 目标检测算法介绍3.1.1 YOLO家族3.1.2 YOLOv8算法理…

Node.js 入门

目录 定义 什么是前端工程化&#xff1f; Node.js 为何能执行 JS&#xff1f; Node.js 安装 使用 Node.js fs 模块 - 读写文件 path 模块 - 路径处理 案例 - 压缩前端 html URL 中的端口号 常见的服务程序 http 模块-创建 Web 服务 浏览时钟&#xff08;案例&#x…

2024最新中级会计职称考试全科题库资料。

1.根据消费税法律制度的规定&#xff0c;下列各项中&#xff0c;属于消费税征税范围的是&#xff08;&#xff09;。 A.汽车轮胎 B.食用酒精 C.铂金首饰 D.体育上用的发令纸 答案&#xff1a;C 解析&#xff1a;选项ABD均不属于消费税的征税范围。 2.甲企业&#xff08;…

2024亚太杯中文赛B题全保姆教程

B题 洪水灾害的数据分析与预测 问题 1. 请分析附件 train.csv 中的数据&#xff0c;分析并可视化上述 20 个指标中&#xff0c;哪 些指标与洪水的发生有着密切的关联&#xff1f;哪些指标与洪水发生的相关性不大&#xff1f;并 分析可能的原因&#xff0c;然后针对洪水的提前预…

基于Arduino平台开源小车的初步使用体验

创作原因&#xff1a;偶然有机会接触到基于Arduino平台的开源智能小车&#xff0c;初步使用后与大家分享。因使用时间不常&#xff0c;可以纯当个乐子看看&#xff0c;感谢大家的阅读&#xff01; 图&#xff1a;一款基于Arduino平台的开源小车 一、开发环境 Misly&#xff1…

两个Activity之间切换时UI部分重叠

书籍 《第一行代码 Android》第三版 开发 环境 Android Studio Jellyfish | 2023.3.1 setContentView android studio自动生成的SecondActivity.kt中自动生成的代码中已经绑定了second_layout.xml的布局资源&#xff0c;通过代码&#xff1a;setContentView(R.layout.secon…

tkinter给按钮设置背景图片

tkinter给按钮设置背景图片 效果代码 效果 代码 import tkinter as tk from PIL import Image, ImageTk# 创建主窗口 root tk.Tk() root.title("按钮背景图片示例")# 加载图片 image Image.open("new.png") photo ImageTk.PhotoImage(image)# 创建按钮…

比Proxmox VE更易用的免费虚拟化平台

之前虚拟化一直玩Proxmox VE&#xff0c;最近发现一个更易用的虚拟化软件CSYun&#xff0c;他与Proxmox VE类似&#xff0c;都是一个服务器虚拟化平台。它不像VMware ESXi那么复杂&#xff0c;对于个人使用者和中小企业是一个比较好的选择。 这个软件所在的网址为&#xff1a;…

Nuxt3 的生命周期和钩子函数(十)

title: Nuxt3 的生命周期和钩子函数&#xff08;十&#xff09; date: 2024/6/30 updated: 2024/6/30 author: cmdragon excerpt: 摘要&#xff1a;本文详细介绍了Nuxt3框架中的五个webpack钩子函数&#xff1a;webpack:configResolved用于在webpack配置解析后读取和修改配置…

PCL从理解到应用【02】PCL环境安装 | PCL测试| Linux系统

前言 本文介绍在Ubuntu18.04系统中&#xff0c;如何安装PCL。 源码安装方式&#xff1a;pcl版本1.91&#xff0c;vtk版本8.2.0&#xff0c;Ubuntu版本18.04。 安装好后&#xff0c;可以看到pcl的库&#xff0c;在/usr/lib/中&#xff1b; 通过编写C代码&#xff0c;直接调用…

2.8亿东亚五国建筑数据分享

数据是GIS的血液&#xff01; 我们现在为你分享东亚5国的2.8亿条建筑轮廓数据&#xff0c;该数据包括中国、日本、朝鲜、韩国和蒙古5个东亚国家完整、高质量的建筑物轮廓数据&#xff0c;你可以在文末查看领取方法。 数据介绍 虽然开源的全球的建筑数据已经有微软的建筑数据…

​埃文科技受邀出席2024 “数据要素×”生态大会​

2024“数据要素”生态大会&#xff08;以下简称“大会”&#xff09;于2024年6月30日在河南省郑州市举办。大会在国家数据局、河南省人民政府等单位的指导下&#xff0c;由中国经济体制改革研究会、中国电子信息产业集团有限公司、郑州市人民政府等共同主办。大会主题为“加快数…

C++字体库开发之字体回退三

代码片段 class FontCoverage { public: using SP std::shared_ptr<FontCoverage>; virtual ~FontCoverage() default; virtual void set(int index, FontTypes::CoverageLevel level) 0; virtual FontTypes::Coverag…

架构 | 数据归档

INDEX 1 通用思路2 快速归档3 归档整体流程&#xff08;完整归档 & 快速归档&#xff09;4 准备阶段4.1 确认归档表4.2 思路&#xff1a;确认归档数据范围 & 归档方案待选&#xff08;重点&#xff09;4.3 归档方式选择 & 业务场景覆盖4.4 确认归档数据范围 & …

Spring源码十:BeanPostProcess

上一篇Spring源码九&#xff1a;BeanFactoryPostProcessor&#xff0c;我们看到ApplicationContext容器通过refresh方法中的postProcessBeanFactory方法和BeanFactoryPostProcessor类提供预留扩展点&#xff0c;他可以在Spring容器的层面对BeanFactroy或其他属性进行修改&#…