大模型生成PPT大纲优化方案:基于 nVidia NIM 平台的递归结构化生成

大模型生成PPT大纲优化方案:基于 nVidia NIM 平台的递归结构化生成

待解决的问题

生成PPT大纲是一种大模型在办公场景下应用的常见需求。

然而:

  • 目前直接让大模型生成大纲往往是非结构化的,输出格式多样,难以统一和规范,这使得大纲后续的分析与利用变得复杂。
  • 生成过程中的层级深度和每层的颗粒度无法灵活控制,导致生成内容有时过于简单,有时又过于复杂,缺乏可控性。
  • 由于大模型是基于自回归的,在生成细粒度大纲时首层大纲并没有生成完,和人类规划大纲自顶向下的方法不同,导致大纲的层级之间往往存在模糊和重叠,无法有效传达不同层次的重点内容。

为了解决上述问题,本文提出了一种递归结构化生成的方法,通过分层递归控制大模型生成大纲的过程,不仅能使大纲结构清晰,而且可以灵活控制各层的深度和颗粒度。这样生成的大纲不仅层次分明,内容也更加贴合实际应用需求,避免了层级模糊和内容重叠的现象。

本项目基于NVIDIA NIM平台,使用 LLaMA 3.1 70B 作为基座模型。NVIDIA NIM 平台提供了强大的自然语言处理等人工智能能力,能够方便、高效地调用各种预训练模型,甚至进行定制化的推理。

在这里插入图片描述

核心方案

该项目的核心是递归生成PPT大纲,逐层递进,确保大纲的层次清晰、内容具体,避免生成结果的模糊和重叠问题。核心流程如下:

  1. 第一层生成:首先,通过模型生成第一层的PPT大纲内容,确保初始大纲框架具有明确的层次。
  2. 递归生成:在生成初始层之后,递归生成每个子级的内容,逐层递进。每一级的生成都是基于上一层的大纲内容进行细化和补充,保证了层次结构的清晰和逻辑性。
  3. 递归终止条件:当生成到达指定的层级时,递归终止,输出完整的结构化大纲。

具体的 prompt 将在下一节讲解。

第一层大纲生成 (generate_first_level_outlines)

这个函数负责生成大纲的第一层内容,基于用户输入的主题调用大模型生成初始的大纲框架。

def generate_first_level_outlines(idea):
    first_level_template = FIRST_LEVEL_PROMPT.format(
        few_shot=FIRST_LEVEL_EXAMPLE,
        idea=idea,
    )
    response = client.chat.completions.create(
        model="meta/llama-3.1-70b-instruct",
        messages=[{"role": "user", "content": first_level_template}],
        temperature=0.7,
        max_tokens=1024,
    )
    return extract_outlines(response.choices[0].message.content.strip())

注意,调用模型后,通过extract_outlines函数对生成的结果进行处理,去掉不必要的空白行,得到大纲的第一层结构化内容。extract_outlines函数具体详见下一节。

递归生成下一级大纲 (generate_next_level_outline)

当生成了第一层的大纲后,系统需要递归生成各个子级内容。generate_next_level_outline函数根据上一层的大纲内容,生成当前层的细化内容。

模型生成后,如果当前层级达到了目标层(target_layer),则返回当前层的大纲内容。否则,函数将继续递归调用自己,为每个子项生成更深层的大纲内容,直到达到目标层。

def generate_next_level_outline(
    idea: str,
    current_level: int,
    previous_outline: str,
    previous_list: list[str],
    target_layer: int,
):
    formatted_previous_list = ', '.join(previous_list)
    next_level_template = NEXT_LEVEL_PROMPT.format(
        few_shot=NEXT_LEVEL_EXAMPLE,
        idea=idea,
        formatted_previous_list=formatted_previous_list,
        previous_outline=previous_outline,
        current_level=current_level,
    )
    response = client.chat.completions.create(
        model="meta/llama-3.1-70b-instruct",
        messages=[{"role": "user", "content": next_level_template}],
        temperature=0.7,
        max_tokens=1024,
    )

    outlines = extract_outlines(response.choices[0].message.content.strip())

    if target_layer == current_level:
        return outlines
    else: 
        return {
            text: generate_next_level_outline(
                idea, current_level + 1, text, outlines, target_layer
            ) for text in outlines
        }

注意,prompt 中会将上一级的内容和当前的层次信息整合,让模型有更充分的信息生成该层的大纲内容。

递归结构化大纲生成 (recursive_outline)

这个函数是整个递归生成过程的核心,通过逐层调用generate_next_level_outline函数,生成每一层的大纲,直到生成目标层的所有内容。

def recursive_outline(idea, target_layer: int):
    first_level = generate_first_level_outlines(idea)
    return {
        text: generate_next_level_outline(
            idea, 2, text, first_level, target_layer
        ) for text in first_level
    }

实现细节

prompt

本项目的 prompt 明确告知模型生成PPT大纲的任务,提供主题信息(idea)和所需层级(layer),确保模型能够聚焦于特定主题,并生成相应层次的内容。此外,通过提供多个生成示例,向模型展示了预期的输出格式和内容结构。通过示例提供了明确的上下文,同时引入了对重复内容的避免,还引入了上一层的内容,帮助模型了解需要避免重复的信息。

BASE_PROMPT = """请你根据主题:“{idea}”生成{layer}层的PPT大纲:\n"""

FIRST_LEVEL_EXAMPLE = """请你根据
技术是一把双刃剑,它既能推动社会向前发展,也可能因不当使用而造成伤害。比如数字鸿沟现象。
生成大纲第1层,一行一个条目,生成在<>中,无需其他解释和内容:
<信息爆炸的时代>
<科技革命与产业变革>
<社会影响日益凸显>
<人类应未雨绸缪,趋利避害>
<发展趋势及前景,结论>

请你根据
为什么我们要好好学习?在快速变化的世界中,持续学习是实现自我价值和社会贡献的关键。
生成大纲第1层,一行一个条目,生成在<>中,无需其他解释和内容:
<引言>
<学习对个人成长的意义>
<学习对社会的责任>
<如何有效学习>

请你根据
在单身的黄金年代我们如何面对爱情:要勇敢地去追求爱情
生成大纲第1层,一行一个条目,生成在<>中,无需其他解释和内容:
<何为单身的黄金时代>
<爱情对人们的意义>
<目前人的生存和处境更加复杂>
<爱情存在肌无力>
<最温暖的东西是人和人之间的感情>
<要勇敢地追求爱情>
"""

FIRST_LEVEL_PROMPT = """{few_shot}
上面是几个生成大纲第一层的例子。请你根据
{idea}
生成大纲第1层,一行一个条目,生成在<>中,无需其他解释和内容:"""

NEXT_LEVEL_EXAMPLE = """请你根据
技术是一把双刃剑,它既能推动社会向前发展,也可能因不当使用而造成伤害。比如数字鸿沟现象。
不要和上一层的 信息爆炸的时代, 科技革命与产业变革, 人类应未雨绸缪,趋利避害, 发展趋势及前景,结论 重复,
生成“社会影响日益凸显”下的大纲第2层内容,一行一个条目,生成在<>中,无需其他解释和内容:
<举例:数字鸿沟现象>
<各种问题普遍存在>
<对人类各方面产生深远影响>

请你根据
在单身的黄金年代我们如何面对爱情:要勇敢地去追求爱情
不要和上一层的 何为单身的黄金时代, 爱情对人们的意义, 目前人的生存和处境更加复杂, 爱情存在肌无力, 最温暖的东西是人和人之间的感情 重复,
生成“要勇敢地追求爱情”下的大纲第2层内容,一行一个条目,生成在<>中,无需其他解释和内容:
<必须树立目标>
<提升心灵的力量>
<走合法的途径去获取>

请你根据
为什么我们要好好学习?在快速变化的世界中,持续学习是实现自我价值和社会贡献的关键。
不要和上一层的 理解自己的权利与义务, 正确价值观和社会责任感 重复,
生成“知识是推动社会发展的关键力量”下的大纲第3层内容,一行一个条目,生成在<>中,无需其他解释和内容:
<科技创新与经济发展>
<社会治理与公共政策>
<文化传承与发展>
"""

NEXT_LEVEL_PROMPT = """{few_shot}
上面是几个生成大纲具体层的例子。请你根据
{idea}
不要和上一层的 {formatted_previous_list} 重复,
生成“{previous_outline}”下的大纲第{current_level}层内容,一行一个条目,生成在<>中,无需其他解释和内容:
"""

大纲文本提取

简单的提取方法,将模型输出按行分割并去除空白行和格式字符。

def extract_outlines(model_output: str):
    return [
        line.strip().strip('<').strip('>')
        for line in model_output.split('\n')
        if line.strip()
    ]

baseline 对比、全局变量和简易用户界面

简易的 web 用户界面是基于 gradio 构建的。复现时记得更换为自己的NVIDIA_API_KEY

借助Gradio构建用户友好的交互界面,用户只需输入一个主题和层数,本项目会生成两个版本的PPT大纲,一个是直接生成的,一个是递归生成的,并将两者进行对比展示。

大纲生成的基本过程通过调用 nVidia NIM 平台 的接口,将主题与层级信息传入模型生成器,控制输出大纲的层级深度和层次内容。

import gradio as gr
from openai import OpenAI

import json

client = OpenAI(
    base_url="https://integrate.api.nvidia.com/v1",
    api_key=NVIDIA_API_KEY
)

def generate_outline(input_text, layer: int):
    prompt = BASE_PROMPT.format(idea=input_text, layer=layer)
    completion = client.chat.completions.create(
        model="meta/llama-3.1-70b-instruct",
        messages=[{"role": "user", "content": prompt}],
        temperature=0.7,
        max_tokens=1024,
    )
    return completion.choices[0].message.content.strip()


def compare_outlines(input_text, layers):
    direct = generate_outline(input_text, int(layers))
    recursive = recursive_outline(input_text, int(layers))
    return direct, json.dumps(recursive, ensure_ascii=False, indent=8)

iface = gr.Interface(
    fn=compare_outlines,
    inputs=["text", gr.Number()],
    outputs=["text", "text"],
    title="PPT大纲生成对比",
    description="输入一个句子,比较直接生成和递归生成的PPT大纲效果。"
)

iface.launch()

项目效果

运行后,在浏览器中打开项目前端,输入要生成的主题和期望的层数,可以得到普通方法生成和本方法生成的结果。

在这里插入图片描述
如图所示,递归结构化生成的效果不仅结构清晰、方便利用,而且相对于普通方法,生成了正确的层次深度,大纲对于主题的分析更加深入和全面,有更多的信息量和参考价值。

通过采用递归结构化生成的方法,本项目能够有效地解决传统PPT大纲生成中遇到的各种问题,为用户提供更清晰、有条理的内容。希望本项目的实践经验能够为更多相关应用的探索与优化提供启示和借鉴。

完整代码:


import gradio as gr
from openai import OpenAI

from __env import NVIDIA_API_KEY
import json

client = OpenAI(
    base_url="https://integrate.api.nvidia.com/v1",
    api_key=NVIDIA_API_KEY
)

BASE_PROMPT = """请你根据主题:“{idea}”生成{layer}层的PPT大纲:\n"""

FIRST_LEVEL_EXAMPLE = """请你根据
技术是一把双刃剑,它既能推动社会向前发展,也可能因不当使用而造成伤害。比如数字鸿沟现象。
生成大纲第1层,一行一个条目,生成在<>中,无需其他解释和内容:
<信息爆炸的时代>
<科技革命与产业变革>
<社会影响日益凸显>
<人类应未雨绸缪,趋利避害>
<发展趋势及前景,结论>

请你根据
为什么我们要好好学习?在快速变化的世界中,持续学习是实现自我价值和社会贡献的关键。
生成大纲第1层,一行一个条目,生成在<>中,无需其他解释和内容:
<引言>
<学习对个人成长的意义>
<学习对社会的责任>
<如何有效学习>

请你根据
在单身的黄金年代我们如何面对爱情:要勇敢地去追求爱情
生成大纲第1层,一行一个条目,生成在<>中,无需其他解释和内容:
<何为单身的黄金时代>
<爱情对人们的意义>
<目前人的生存和处境更加复杂>
<爱情存在肌无力>
<最温暖的东西是人和人之间的感情>
<要勇敢地追求爱情>
"""

FIRST_LEVEL_PROMPT = """{few_shot}
上面是几个生成大纲第一层的例子。请你根据
{idea}
生成大纲第1层,一行一个条目,生成在<>中,无需其他解释和内容:"""

NEXT_LEVEL_EXAMPLE = """请你根据
技术是一把双刃剑,它既能推动社会向前发展,也可能因不当使用而造成伤害。比如数字鸿沟现象。
不要和上一层的 信息爆炸的时代, 科技革命与产业变革, 人类应未雨绸缪,趋利避害, 发展趋势及前景,结论 重复,
生成“社会影响日益凸显”下的大纲第2层内容,一行一个条目,生成在<>中,无需其他解释和内容:
<举例:数字鸿沟现象>
<各种问题普遍存在>
<对人类各方面产生深远影响>

请你根据
在单身的黄金年代我们如何面对爱情:要勇敢地去追求爱情
不要和上一层的 何为单身的黄金时代, 爱情对人们的意义, 目前人的生存和处境更加复杂, 爱情存在肌无力, 最温暖的东西是人和人之间的感情 重复,
生成“要勇敢地追求爱情”下的大纲第2层内容,一行一个条目,生成在<>中,无需其他解释和内容:
<必须树立目标>
<提升心灵的力量>
<走合法的途径去获取>

请你根据
为什么我们要好好学习?在快速变化的世界中,持续学习是实现自我价值和社会贡献的关键。
不要和上一层的 理解自己的权利与义务, 正确价值观和社会责任感 重复,
生成“知识是推动社会发展的关键力量”下的大纲第3层内容,一行一个条目,生成在<>中,无需其他解释和内容:
<科技创新与经济发展>
<社会治理与公共政策>
<文化传承与发展>
"""

NEXT_LEVEL_PROMPT = """{few_shot}
上面是几个生成大纲具体层的例子。请你根据
{idea}
不要和上一层的 {formatted_previous_list} 重复,
生成“{previous_outline}”下的大纲第{current_level}层内容,一行一个条目,生成在<>中,无需其他解释和内容:
"""


def generate_outline(input_text, layer: int):
    prompt = BASE_PROMPT.format(idea=input_text, layer=layer)
    completion = client.chat.completions.create(
        model="meta/llama-3.1-70b-instruct",
        messages=[{"role": "user", "content": prompt}],
        temperature=0.7,
        max_tokens=1024,
    )
    return completion.choices[0].message.content.strip()


def extract_outlines(model_output: str):
    # 简单的提取方法,将模型输出按行分割并去除空白行
    return [
        line.strip().strip('<').strip('>')
        for line in model_output.split('\n')
        if line.strip()
    ]


def generate_first_level_outlines(idea):
    first_level_template = FIRST_LEVEL_PROMPT.format(
        few_shot=FIRST_LEVEL_EXAMPLE,
        idea=idea,
    )
    response = client.chat.completions.create(
        model="meta/llama-3.1-70b-instruct",
        messages=[{"role": "user", "content": first_level_template}],
        temperature=0.7,
        max_tokens=1024,
    )
    return extract_outlines(response.choices[0].message.content.strip())


def generate_next_level_outline(
    idea: str,
    current_level: int,
    previous_outline: str,
    previous_list: list[str],
    target_layer: int,
):

    formatted_previous_list = ', '.join(previous_list)
    next_level_template = NEXT_LEVEL_PROMPT.format(
        few_shot=NEXT_LEVEL_EXAMPLE,
        idea=idea,
        formatted_previous_list=formatted_previous_list,
        previous_outline=previous_outline,
        current_level=current_level,
    )
    response = client.chat.completions.create(
        model="meta/llama-3.1-70b-instruct",
        messages=[{"role": "user", "content": next_level_template}],
        temperature=0.7,
        max_tokens=1024,
    )

    outlines = extract_outlines(response.choices[0].message.content.strip())

    if target_layer == current_level:
        return outlines
    else: 
        return {
            text: generate_next_level_outline(
                idea, current_level + 1, text, outlines, target_layer
            ) for text in outlines
        }


def recursive_outline(idea, target_layer: int):

    first_level = generate_first_level_outlines(idea)

    return {
        text: generate_next_level_outline(
            idea, 2, text, first_level, target_layer
        ) for text in first_level
    }


def compare_outlines(input_text, layers):
    direct = generate_outline(input_text, int(layers))
    recursive = recursive_outline(input_text, int(layers))
    return direct, json.dumps(recursive, ensure_ascii=False, indent=8)


iface = gr.Interface(
    fn=compare_outlines,
    inputs=["text", gr.Number()],
    outputs=["text", "text"],
    title="PPT大纲生成对比",
    description="输入一个句子,比较直接生成和递归生成的PPT大纲效果。"
)

iface.launch()

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据结构-5.1.树的定义和基本术语

一.树的基本概念&#xff1a; 1.根结点&#xff1a;最顶层的结点&#xff0c;有且仅有一个&#xff0c;没有前驱&#xff1b; 2.叶子结点&#xff1a;不能再有子结点&#xff0c;没有后继&#xff1b; 3.结点&#xff1a;用于存数据&#xff1b; 4.也有前驱和后继的说法&…

制造企业MES管理系统的应用策略与实施路径

在智能制造浪潮的席卷之下&#xff0c;MES管理系统作为连接生产计划与车间操作的核心桥梁&#xff0c;其战略地位愈发显著。本文旨在深入剖析MES管理系统在智能制造转型中的核心价值、实施策略及实践路径&#xff0c;为制造企业探索智能化生产之路提供实践指导与灵感启发。 MES…

JavaScript函数基础(通俗易懂篇)

10.函数 10.1 函数的基础知识 为什么会有函数&#xff1f; 在写代码的时候&#xff0c;有一些常用的代码需要书写很多次&#xff0c;如果直接复制粘贴的话&#xff0c;会造成大量的代码冗余&#xff1b; 函数可以封装一段重复的javascript代码&#xff0c;它只需要声明一次&a…

github 搭建个人导航网

最近搭建了个 个人的导航网&#xff0c;具体内容见下图&#xff0c;欢迎大家访问吖&#xff0c;点击访问 具体实现是使用 vue3 编写&#xff0c;白嫖 github 的 page 部署 首先在 github上创建一个仓库&#xff1a;name.github.io # name是你 github 的名字 然后在本地创建一…

◇【论文_20181020 v6】广义优势估计器 (generalized advantage estimator, GAE)

https://arxiv.org/abs/1506.02438 ICLR 2016 加州伯克利 电子工程与计算机科学系 High-Dimensional Continuous Control Using Generalized Advantage Estimation 文章目录 摘要1 引言2 预备知识3 优势函数估计4 解释为 奖励设计reward shaping5 价值函数估计6 实验6.1 策略优…

九、Drf序列化器

九、序列化器 9.1序列化 从数据库取QuerySet或数据对象转换成JSON 9.1.1序列化器的简易使用 #新建一张部门表 class Depart(models.Model):titlemodels.CharField(verbose_name部门,max_length32)ordermodels.IntegerField(verbose_name顺序)countmodels.IntegerField(verb…

C语言_内存函数

内存函数是 C 标准库中的一组函数&#xff0c;用于管理和操作内存。使用时需要包含头文件<string.h>。 1. memcpy的使用和模拟实现 函数形式如下&#xff1a; void* memcpy(void* destination, const void* source, size_tnum);函数解析和注意事项&#xff1a; memcp…

LinuxO(1)调度算法

概念 在Linux中&#xff0c;O(1)调度算法是一种进程调度算法。O(1)表示算法的时间复杂度是常数级别的&#xff0c;与系统中的进程数量无关。 运行队列结构 他采用了两个运行队列&#xff0c;一个活动队列和一个过期队列。活动队列中的进程是有资格获取CPU时间片的进程&#x…

AWS EC2 部署Echarts大屏展示项目

前言 Echarts简介 ECharts是一个由JavaScript开发的开源可视化库。它能使数据生动、直观、互动、高度个性化数据可视化图表。ECharts适用大部分浏览器&#xff0c;如IE6 、Chrome、Firefox、Safari等&#xff0c;同时支持PC和移动设备。 开源&#xff1a;ECharts是一个开源项目…

【JavaEE】——文件IO

阿华代码&#xff0c;不是逆风&#xff0c;就是我疯 你们的点赞收藏是我前进最大的动力&#xff01;&#xff01; 希望本文内容能够帮助到你&#xff01;&#xff01; 目录 一&#xff1a;认识文件 1&#xff1a;文件的概念 2&#xff1a;文件的结构 3&#xff1a;文件路径…

矩阵求解复数(aniwoth求解串扰)

所以这种求解串扰的格式是因为&#xff0c;有串扰的共轭项在方程组中 复数共轭项的作用&#xff0c;但是这是二次方程&#xff0c;

【深度学习】yolov8n模型的剪枝操作记录

原始 剪枝微调后 可以看到模型大小了&#xff0c; 测试结果显示再cpu 上加速5%-10% from ultralytics import YOLOimport time # Load a pretrained YOLO11n model count_num 500 def test1():model YOLO("/home/justin/Desktop/code/v8_prun/runs/detect/train3/weig…

算法知识点————贪心

贪心&#xff1a;只考虑局部最优解&#xff0c;不考虑全部最优解。有时候得不到最优解。 DP&#xff1a;考虑全局最优解。DP的特点&#xff1a;无后效性&#xff08;正在求解的时候不关心前面的解是怎么求的&#xff09;&#xff1b; 二者都是在求最优解的&#xff0c;都有最优…

微服务实战——ElasticSearch(保存)

商品上架——ElasticSearch&#xff08;保存&#xff09; 0.商城架构图 1.商品Mapping 分析&#xff1a;商品上架在 es 中是存 sku 还是 spu &#xff1f; 检索的时候输入名字&#xff0c;是需要按照 sku 的 title 进行全文检索的检索使用商品规格&#xff0c;规格是 spu 的…

No package nodejs available.No package npm available.

安装nodejs时出现的报错 这个错误的原因是当前的 yum 源没有包含 Node.js 和 npm 的安装包。 解决方法 使用 NodeSource 仓库 curl -fsSL https://rpm.nodesource.com/setup_14.x | bash -运行 yum install 安装 Node.js 和 npm&#xff1a; yum install -y nodejs使用 E…

深入了解Oracle OCP认证,开启数据库专业之旅

使用Oracle数据库的公司内部&#xff0c;经常有员工们在讨论OCP认证(Oracle Certified Professional&#xff0c;Oracle认证专家)&#xff0c;这是甲骨文Oracle公司提供的一种专业认证&#xff0c;认证用于使用者在Oracle技术领域的专业知识和技能。 在这里&#xff0c;有一点…

华为、华三、锐捷网络设备的常用命令整理

华为&#xff08;Huawei&#xff09;、华三&#xff08;H3C&#xff09;、锐捷&#xff08;Ruijie&#xff09;常用网络设备命令&#xff1a; 华为&#xff08;Huawei&#xff09; 查看设备的信息&#xff0c;可执行“display version”命令。 查看当下的配置&#xff0c;则…

动手学深度学习9.3. 深度循环神经网络-笔记练习(PyTorch)

本节课程地址&#xff1a;58 深层循环神经网络【动手学深度学习v2】_哔哩哔哩_bilibili 本节教材地址&#xff1a;9.3. 深度循环神经网络 — 动手学深度学习 2.0.0 documentation (d2l.ai) 本节开源代码&#xff1a;...>d2l-zh>pytorch>chapter_multilayer-perceptr…

计算机毕业设计Tensorflow交通标志识别检测 车流量预测 车速检测 自动驾驶 机器学习 深度学习 人工智能 PyTorch 大数据毕设

《Tensorflow交通标志识别检测》开题报告 一、研究背景及意义 随着智能交通系统和无人驾驶技术的快速发展&#xff0c;交通标志识别系统成为智能驾驶系统的重要组成部分。传统的交通标志识别方法主要依赖于人工检查和识别&#xff0c;存在效率低下、易受主观因素影响等问题。…

聚观早报 | 苹果重磅更新;OpenAI推出ChatGPT Canvas

聚观早报每日整理最值得关注的行业重点事件&#xff0c;帮助大家及时了解最新行业动态&#xff0c;每日读报&#xff0c;就读聚观365资讯简报。 整理丨Cutie 10月1日消息 苹果重磅更新 OpenAI推出ChatGPT Canvas Meta发布Movie Gen iQOO 13影像规格曝光 华为HarmonyOS N…