modelscope可控细节的长文档摘要

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 = 0output = []  # list to hold the final combined chunksoutput_indices = []  # list to hold the indices of the final combined chunkscandidate = ([] if header is None else [header])  # list to hold the current combined chunk candidatecandidate_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_overflowand len(tokenize(chunk_delimiter.join(candidate + ["..."]))) <= max_tokens):candidate.append("...")dropped_chunk_count += 1continue  # this case would break downstream assumptions# estimate token count with the current chunk addedextended_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 candidateif extended_candidate_token_count > max_tokens:output.append(chunk_delimiter.join(candidate))output_indices.append(candidate_indices)candidate = chunk_with_header  # re-initialize candidatecandidate_indices = [chunk_i]# otherwise keep extending the candidateelse:candidate.append(chunk)candidate_indices.append(chunk_i)# add the remaining candidate to output if it's not emptyif (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 correctlyassert 0 <= detail <= 1# interpolate the number of chunks based to get specified level of detailmax_chunks = len(chunk_on_delimiter(text, minimum_chunk_size, chunk_delimiter))min_chunks = 1num_chunks = int(min_chunks + detail * (max_chunks - min_chunks))# adjust chunk_size based on interpolated number of chunksdocument_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 messagesystem_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 summarizationaccumulated_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 contextuser_message_content = chunk# Constructing messages based on whether recursive summarization is appliedmessages = [{"role": "system", "content": system_message_content},{"role": "user", "content": user_message_content}]# Assuming this function gets the completion and works as expectedresponse = get_chat_completion(messages, model=model)accumulated_summaries.append(response)# Compile final summary from partial summariesfinal_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.mzph.cn/diannao/40824.shtml

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

相关文章

6个步骤实现Postman接口压力测试(建议收藏)

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 点击文末小卡片 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 这里讲是postman做接口并发测试&#xff0c;基础用法不做赘述 1、第一步接口可以通的情况下点击…

Proteus-51单片机-DS18B20多点测温

DS18B20多点测温 一、Proteus仿真演示 每个DS18B20都有一个唯一的64位序列号,这使得在同一总线上可以挂载多个传感器,无需额外的地址分配。主机(通常为单片机)通过特定的时序控制,可以依次读取各个DS18B20的温度数据,实现分布式测温。 二、代码特点 三、开发环境介绍 本…

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

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

shark云原生-日志体系-filebeat高级配置(适用于生产)

文章目录 1. filebeat.inputs 静态日志收集器2. filebeat.autodiscover 自动发现2.1. autodiscover 和 inputs2.2. 如何配置1.2.1. Providers 提供者1.2.2. Providers kubernetes templates1.2.3. 基于提示&#xff08;hints&#xff09;的自动发现支持的 **hints**的完整列表&…

windows搭建mqtt服务器,并配置DTU收集传感器数据

1.下载并安装emqx服务器 参考&#xff1a;Windows系统下本地MQTT服务器搭建&#xff08;保姆级教程&#xff09;_mqtt windows-CSDN博客 这里我下载的是emqx-5.3.0-windows-amd64.zip版本 下载好之后&#xff0c;放到服务器的路径&#xff0c;我这里放的地方是&#xff1a;C…

脑启发设计:人工智能的进化之路

编者按&#xff1a;你可以用左手&#xff08;不常用的那只手&#xff09;的小指与食指拿起一件物品么&#xff1f; 试完你是不是发现自己竟然可以毫不费力地用自己不常用的手中&#xff0c;两根使用频率相对较低的手指&#xff0c;做一个不常做的动作。这就是人类大脑不可思议…

py黑帽子学习笔记_burp

配置burp kali虚机默认装好了社区版burp和java&#xff0c;其他os需要手动装 burp是用java&#xff0c;还得下载一个jython包&#xff0c;供burp用 配apt国内源&#xff0c;然后apt install jython --download-only&#xff0c;会只下载包而不安装&#xff0c;下载的目录搜一…

9.x86游戏实战-汇编指令mov

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 本次游戏没法给 内容参考于&#xff1a;微尘网络安全 工具下载&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1rEEJnt85npn7N38Ai0_F2Q?pwd6tw3 提…

STM32智能农业监控系统教程

目录 引言环境准备智能农业监控系统基础代码实现&#xff1a;实现智能农业监控系统 4.1 数据采集模块 4.2 数据处理与分析 4.3 控制系统实现 4.4 用户界面与数据可视化应用场景&#xff1a;农业监控与优化问题解决方案与优化收尾与总结 1. 引言 智能农业监控系统利用STM32嵌…

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;直接调用…

华为路由器静态路由配置(eNSP模拟实验)

实验目标 如图下所示&#xff0c;让PC1ping通PC2 具体操作 配置PC设备ip 先配置PC1的ip、掩码、网关。PC2也做这样的配置 配置路由器ip 配置G0/0/0的ip信息 #进入系统 <Huawei>system-view #进入GigabitEthernet0/0/0接口 [Huawei]int G0/0/0 #设置接口的ip和掩码 […

【UE5.3】笔记7 控制Pawn移动

使用A、D键控制角色左右移动 打开我们的BP_Player蓝图类&#xff0c;选择事件图表&#xff0c;添加我们的控制事件 右键&#xff0c;搜索A keyboard&#xff0c;选择A,如下图&#xff0c;D也是 添加扭矩力 首先我们要把我们的player上的模拟物理选项打开&#xff0c;这样我们…

JavaFx基础知识

1.Stage 舞台 如此这样的一个框框&#xff0c;舞台只是这个框框&#xff0c;并不管里面的内容 public void start(Stage primaryStage) throws Exception {primaryStage.setScene(new Scene(new Group()));primaryStage.getIcons().add(new Image("/icon/img.png"))…

【不锈钢酸退作业区退火炉用高温辐射计快速安装】

项目名称 不锈钢酸退作业区退火炉用高温辐射计快速安装 改造实施项目简介项目提出前状况:不锈钢生产过程中,各种型号的不锈钢带钢在退火工艺中对带钢温度的准确性要求很高,带钢温度的检测直接影响带钢的产品质量,不锈钢带钢温度测量依靠的是高温辐射计,其测量的准确性、稳…

【Python机器学习】算法链与管道——通用的管道接口

Pipeline类补单可以用于预处理和分类&#xff0c;实际上还可以将任意数量的估计器连接在一起。例如&#xff0c;我们可以构建一个包含特征提取、特征选择、缩放和分类的管道&#xff0c;总共有4个步骤。同样的&#xff0c;最后一步可以用聚类或回归代替。 对于管道中估计器的唯…

vue2使用use注册自定义指令实现权限控制

版本环境 vue的版本是^2.6.12&#xff0c;将会使用到Vue.use()、Vue.directive() 适用环境 页面某些按钮&#xff0c;需要受到当前登录用户的“角色”“权限”的影响&#xff0c;通过store获取角色role和权限permission&#xff0c;通过自定义指令的方式&#xff0c;控制某一…

antd DatePicker日期选择框限制最多选择一年

实现效果 实现逻辑 import React, { useState } from react;const ParentComponent () > {const [dates, setDates] useState(null);const disabledDate (current) > {if (!dates) {return false;}const tooLate dates[0] && current.diff(dates[0], days) &…

Appium自动化测试框架1

电脑的浏览器 手机的浏览器 手机上的app 原生的应用 纯java 手机上的app apk 移动网页应用 纯HTML CSS 手机的浏览器上 电脑的浏览器上 混合应用 java html css python代码 Appium python库 Appium 手机 都是代表本机 0.0.0.0 127.0.0.1 localhost 如何启动app 启动参…

土壤养分化验仪:农业生态与可持续发展

随着现代农业技术的不断进步&#xff0c;土壤养分化验仪在农业生产中扮演着越来越重要的角色。这款高科技设备以其高精度、高效率的特点&#xff0c;为农业生态与可持续发展提供了强有力的支撑。 一、农田土壤监测与管理 农田是土壤养分化验仪最主要的应用场所。通过对农田土壤…

【AI】DeepStream(14):图像分割deepstream-segmentation-test示例演示

【AI】AI学习目录汇总 1、简介 deepstream-segmentation-test示例演示了图像的语义分割。两个配置文件,分别加载U-Net和Res-UNet两种分割模型 unet_output_graph.uffunetres18_v4_pruned0.65_800_data.uffU-Net是一个在生物医学图像分割领域广泛应用的卷积神经网络(CNN),…