基于ChatGPT的视频智能摘要实战

news2024/12/23 0:28:05

随着在 YouTube 上提交的大量新视频,很容易感到挑战并努力跟上我想看的一切。 我可以与我每天将视频添加到“稍后观看”列表中的经历联系起来,只是为了让列表变得越来越长,实际上并没有稍后再看。 现在,像 ChatGPT 或 LLaMA 这样的大型语言模型为这个长期问题提供了一个潜在的解决方案。

在这里插入图片描述

推荐:用NSDT设计器 快速搭建可编程3D场景。

通过将数小时的视频内容转换为几行准确的摘要文本,视频摘要器可以快速为我们提供视频的要点,这样我们就不必花费大量时间来完整观看它。 在我创建这个网络应用程序之后,我最常使用的场景是参考它的摘要来决定某个视频是否值得观看,尤其是那些辅导、脱口秀或演示视频。

你可以通过多种方式使用强大的语言模型来完成此视频摘要。

  • 一种选择是使用或设计 ChatGPT 插件,它可以将令人难以置信的 AI 连接到实时 YouTube 网站。 但是,只有少数商业开发人员可以访问 ChatGPT 插件,因此这对包括我在内的所有人来说可能不是最可行的途径。
  • 另一种选择是下载视频的抄本(字幕)并将其附加到提示中,然后要求语言模型通过发送提示来总结抄本文本。 然而,这种方法有一个很大的缺点——你不能总结一个包含超过 4096 个标记的视频,这对于一个普通的谈话节目来说通常是 7 分钟左右。
  • 一个更有前途的选择是使用上下文学习技术对转录本进行向量化,并使用向量向语言模型提示“摘要”查询。 这种方法可以生成准确的答案,指示转录文本的摘要,并且不限制视频长度。

如果你有兴趣开发自己的上下文学习应用程序,我之前关于构建聊天机器人以学习和聊天文档的文章提供了一个很好的起点。 通过一些细微的修改,我们可以应用相同的方法来创建我们自己的视频摘要器。 在本文中,我将逐步指导你完成开发过程,以便你了解并复制自己的视频摘要器。

1、功能框图

在这个Video Summarizer应用程序中,我们以llama-index为基础,开发了一个Streamlit web应用程序,为用户提供视频URL的输入以及屏幕截图、文字记录和摘要内容的显示。 使用 llamaIndex 工具包,我们不必担心 OpenAI 中的 API 调用,因为对嵌入使用的复杂性或提示大小限制的担忧很容易被其内部数据结构和 LLM 任务管理所覆盖。
在这里插入图片描述

你有没有想过为什么我在让 LLM 生成摘要时设计了几个查询而不是一个用于转录文本处理的查询? 答案在于情境学习过程。 当文档被送入 LLM 时,它会根据其大小分成块或节点。 然后将这些块转换为嵌入并存储为向量。

当提示用户查询时,模型将搜索向量存储以找到最相关的块并根据这些特定块生成答案。 例如,如果你在大型文档(如 20 分钟的视频转录本)上查询“文章摘要”,模型可能只会生成最后 5 分钟的摘要,因为最后一块与上下文最相关 的“总结”。

为了说明这个概念,请看下面的图表:
在这里插入图片描述

通过设计多个查询,我们可以促使 LLM 生成更全面的摘要,涵盖整个文档。 我将在本文后面更深入地组织多个查询。

从第2章到第5章,我将重点介绍本项目中使用到的所有模块的基础知识和典型用法介绍。 如果你愿意在没有这些技术背景的情况下立即开始编写整个 Video Summarizer 应用程序,建议你转到第 6 章。

2、Youtube 视频转录文本

总结 YouTube 视频的第一步是下载转录文本。 有一个名为 youtube-transcript-api 的开源 Python 库可以完美满足我们的要求。

使用如下命令安装模块后,

!pip install youtube-transcript-api
可以使用以下代码轻松下载 JSON 格式的转录文本:

from youtube_transcript_api import YouTubeTranscriptApi
from youtube_transcript_api.formatters import JSONFormatter

srt = YouTubeTranscriptApi.get_transcript("{video_id}", languages=['en'])
formatter = JSONFormatter()
json_formatted = formatter.format_transcript(srt)
print(json_formatted)

在 .get_transcript() 方法中,唯一应该强制提供的参数是 11 位视频 ID,你可以在 v= 之后的每个 YouTube 视频的 URL 中找到它,例如:

https://www.youtube.com/watch? v=hJP5GqnTrNo

当视频提供英语以外的其他语言时,可以将它们添加到参数语言中,该参数语言作为包含不同语言的列表。

该库还提供“Formatter”方法来生成具有定义格式的转录数据。 在这种情况下,我们只需要 JSON 格式即可进行进一步的步骤。

通过运行上面的代码,你会看到像这样的一个像样的转录文本:

[
{"text": "So anyone who's been paying attention\nfor the last few months", "start": 4.543, "duration": 3.878}, 
{"text": "has been seeing headlines like this,", "start": 8.463, "duration": 2.086},
{"text": "especially in education.", "start": 10.59, "duration": 2.086},
{"text": "The thesis has been:", "start": 12.717, "duration": 1.919},
...
]

3、OpenAI API 密钥

LlamaIndex 的设计目的是兼容各种 LLM,默认使用 OpenAI 的 GPT 模型进行嵌入和生成操作。 因此,当我们决定实施基于 OpenAI GPT 模型的视频摘要器时,我们应该向程序提供我们的 OpenAI API 密钥。

插入我们的密钥唯一需要做的就是通过环境变量提供它:

import os
os.environ["OPENAI_API_KEY"] = '{your_api_key}'

4、LlamaIndex

LlamaIndex 是一个 Python 库,充当用户私有数据和大型语言模型 (LLM) 之间的接口。 它有几个对开发人员有用的功能,包括连接到各种数据源、处理提示限制、创建语言数据索引、将提示插入数据、将文本拆分为更小的块以及提供查询索引的接口的能力 . 借助 LlamaIndex,开发人员无需实施数据转换即可将现有数据用于 LLM,管理 LLM 与数据的交互方式,并提高 LLM 的性能。

可以在此处查看完整的LlamaIndex文档。

以下是使用 LlamaIndex 的一般步骤:

安装包:

!pip install llama-index

Step1 — 加载文档文件

from llama_index import SimpleDirectoryReader
SimpleDirectoryReader = download_loader("SimpleDirectoryReader")
loader = SimpleDirectoryReader('./data', recursive=True, exclude_hidden=True)
documents = loader.load_data()

SimpleDirectoryReader 是 LlamaIndex 工具集中的文件加载器之一。 它支持在用户提供的文件夹下加载多个文件,在本例中,它是子文件夹“./data/”。 这个神奇的加载器功能可以支持解析各种文件类型,如.pdf、.jpg、.png、.docx等,让您不必自己将文件转换为文本。 在我们的应用程序中,我们只加载一个文本文件 (.json) 来包含视频转录数据。

Step2 — 构建索引

from llama_index import LLMPredictor, GPTSimpleVectorIndex, PromptHelper, ServiceContext
from langchain import ChatOpenAI

# define LLM
llm_predictor = LLMPredictor(llm=ChatOpenAI(temperature=0, model_name="gpt-3.5-turbo", max_tokens=500))

service_context = ServiceContext.from_defaults(llm_predictor=llm_predictor)

index = GPTSimpleVectorIndex.from_documents(
    documents, service_context=service_context
)

在调用此方法时,LlamaIndex 应与你定义的 LLM 交互以构建索引,在本演示的情况下,LlamaIndex 使用 gpt-3.5 聊天模型通过 OpenAI API 调用嵌入方法。

Step3 — 查询索引

通过建立索引,查询非常简单,无需上下文数据,直接输入即可。

response = index.query("Summerize the video transcript")
print(response)

5、Web开发

与我文章中之前的项目一样,我们将继续使用方便的 Streamlit 工具集来构建 Video Summarizer 应用程序。
在这里插入图片描述

Streamlit 是一个开源的 Python 库,有助于创建交互式 Web 应用程序。 它的主要目的是供数据科学家和机器学习工程师用来与他人分享他们的工作。 借助 Streamlit,开发人员可以使用最少的代码创建应用程序,并且可以使用单个命令轻松地将它们部署到 Web。

它提供了多种可用于创建交互式应用程序的小部件。 这些小部件包括按钮、文本框、滑块和图表。 可以从其官方文档中找到所有小部件的用法。

Web 应用程序的典型 Streamlit 代码可以像下面这样简单:

!pip install streamlit
import streamlit as st

st.write("""
# My First App
Hello *world!*
""")

然后只需键入以下命令即可在线运行该网站:

!python -m streamlit run demo.py

如果运行成功,会打印出用户可以访问的URL:

You can now view your Streamlit app in your browser.
Network URL: http://xxx.xxx.xxx.xxx:8501
External URL: http://xxx.xxx.xxx.xxx:8501

6、完整的 Video Summarizer 应用程序

要实现总结 YouTube 视频的整个工作流程,用户体验非常简单。

第 1 步 — 用户输入 YouTube 视频的 URL。
在这里插入图片描述

在这一步中,我们通过 Streamlit st.text_input() 方法创建一个 text_input 小部件,以接收用户输入的视频 URL。

第 2 步 — 应用程序下载视频的屏幕截图和文字记录文件,并将它们显示在侧边栏中。
在这里插入图片描述

在这一步中,在成功从 URL 解析视频 ID 后,我们使用 html2image 库创建一个侧边栏区域来显示屏幕截图(另存为 ./youtube.png)并显示转录文本(另存为 ./data/transcript。 json )通过使用 LlamaIndex 的 SimpleDirectoryReader() 方法。 我们还从 Streamlit 小部件中实现了一个进度条,以指示剩余时间,因为当视频需要很长时间时,摘要过程会花费更多时间。

第 3 步 — 应用程序生成整个视频的摘要,每 5 分钟的视频有一个详细描述
在这里插入图片描述

在此步骤中,如前所述,我们不希望语言模型通过仅搜索摘要作业的相关块来遗漏整个视频中的重要信息。 为避免这种情况,我们创建了一个循环,每 5 分钟查询一次摘要视频部分。 这确保带有向量的提示的标记不超过 4096 个标记的最大限制,防止拆分成块。 需要注意的是,5 分钟间隔只是一个粗略的估计。 我们创建一个 st.expander() 小部件来包含 5 分钟部分的摘要,并创建一个 st.success() 小部件来通过查询显示最终摘要以总结部分摘要。

我用来总结 5 分钟窗口的提示是:

Summarize this article from ”{start_text}\” to ”{end_text}, limited in 100 words, start with ”This section of video”

start_text 和 end_text 是文本字段中引用转录 JSON 中起始字段的内容

请找到完整的演示代码供你参考:

!python -m pip install openai streamlit llama-index langchain youtube-transcript-api html2image
import os
os.environ["OPENAI_API_KEY"] = '{your_api_key}'

import streamlit as st
from llama_index import download_loader
from llama_index import GPTSimpleVectorIndex
from llama_index import LLMPredictor, GPTSimpleVectorIndex, PromptHelper, ServiceContext
from langchain import OpenAI
from langchain.chat_models import ChatOpenAI

from youtube_transcript_api import YouTubeTranscriptApi
from youtube_transcript_api.formatters import JSONFormatter
import json
import datetime
from html2image import Html2Image

doc_path = './data/'
transcript_file = './data/transcript.json'
index_file = 'index.json'
youtube_img = 'youtube.png'
youtube_link = ''

if 'video_id' not in st.session_state:
    st.session_state.video_id = ''

def send_click():
    st.session_state.video_id = youtube_link.split("v=")[1][:11]

index = None
st.title("Yeyu's Video Summarizer")

sidebar_placeholder = st.sidebar.container()
youtube_link = st.text_input("Youtube link:")
st.button("Summarize!", on_click=send_click)

if st.session_state.video_id != '':

    progress_bar = st.progress(5, text=f"Summarizing...")

    srt = YouTubeTranscriptApi.get_transcript(st.session_state.video_id, languages=['en'])
    formatter = JSONFormatter()
    json_formatted = formatter.format_transcript(srt)
    with open(transcript_file, 'w') as f: 
        f.write(json_formatted)

    hti = Html2Image()
    hti.screenshot(url=f"https://www.youtube.com/watch?v={st.session_state.video_id}", save_as=youtube_img)
    
    SimpleDirectoryReader = download_loader("SimpleDirectoryReader")

    loader = SimpleDirectoryReader(doc_path, recursive=True, exclude_hidden=True)
    documents = loader.load_data()

    sidebar_placeholder.header('Current Processing Video')
    sidebar_placeholder.image(youtube_img)
    sidebar_placeholder.write(documents[0].get_text()[:10000]+'...')

    # define LLM
    llm_predictor = LLMPredictor(llm=ChatOpenAI(temperature=0, model_name="gpt-3.5-turbo", max_tokens=500))
    service_context = ServiceContext.from_defaults(llm_predictor=llm_predictor)
    index = GPTSimpleVectorIndex.from_documents(
        documents, service_context=service_context
    )
    index.save_to_disk(index_file)

    section_texts = ''
    section_start_s = 0

    with open(transcript_file, 'r') as f:
        transcript = json.load(f)    
    
    start_text = transcript[0]["text"]

    progress_steps = int(transcript[-1]["start"]/300+2)
    progress_period = int(100/progress_steps)
    progress_timeleft = str(datetime.timedelta(seconds=20*progress_steps))
    percent_complete = 5
    progress_bar.progress(percent_complete, text=f"Summarizing...{progress_timeleft} left")

    section_response = ''

    for d in transcript:
    
        if d["start"] <= (section_start_s + 300) and transcript.index(d) != len(transcript) - 1:
            section_texts += ' ' + d["text"]

        else:
            end_text = d["text"]

            prompt = f"summarize this article from \"{start_text}\" to \"{end_text}\", limited in 100 words, start with \"This section of video\""
            #print(prompt)
            response = index.query(prompt)
            start_time = str(datetime.timedelta(seconds=section_start_s))
            end_time = str(datetime.timedelta(seconds=int(d['start']))

            section_start_s += 300
            start_text = d["text"]
            section_texts = ''
    
            section_response += f"**{start_time} - {end_time}:**\n\r{response}\n\r"      

            percent_complete += progress_period
            progress_steps -= 1
            progress_timeleft = str(datetime.timedelta(seconds=20*progress_steps))
            progress_bar.progress(percent_complete, text=f"Summarizing...{progress_timeleft} left")

    prompt = "Summarize this article of a video, start with \"This Video\", the article is: " + section_response
    #print(prompt)
    response = index.query(prompt)
    
    progress_bar.progress(100, text="Completed!")
    st.subheader("Summary:")
    st.success(response, icon= "🤖")

    with st.expander("Section Details: "):
        st.write(section_response)

    st.session_state.video_id = ''
    st.stop()

将代码保存到 Python 文件“demo.py”,创建一个 ./data/ 文件夹,然后运行命令:

!python -m streamlit run demo.py

Video Summarizer 现已准备就绪,能够简单而有效地执行其任务。

注意——请从一段短视频开始测试,因为长视频会花费你大量的 OpenAI API 使用费。 在继续之前,还请检查视频是否启用文本转录。


原文链接:基于LLM的视频摘要开发 — BimAnt

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

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

相关文章

常见信号质量问题、危害及其解决方法-信号完整性-过冲、噪声、回勾、边沿缓慢

概述 在电路设计中&#xff0c;“信号”始终是工程师无法绕开的一个知识点。不管是在设计之初&#xff0c;还是在测试环节中&#xff0c;信号质量问题都值得关注。在本文中&#xff0c;主要介绍信号相关的四类问题&#xff1a;信号过冲、毛刺&#xff08;噪声&#xff09;、回…

springboot第18集:SpringMVC我的春天

mybatis-spring http://mybatis.org/spring/zh/index.html mybatis-ehcache http://mybatis.org/ehcache-cache/ MVC是一种常用的软件设计规范&#xff0c;它将一个应用程序分为三个不同的部分&#xff1a;模型(Model)、视图(View)、控制器(Controller)。这三个部分相互协作&am…

计算机毕业论文内容参考|基于三维建模和卷积神经网络的人脸转正的技术设计

文章目录 导文文章重点摘要前言绪论课题背景国内外现状与趋势课题内容相关技术与方法介绍技术分析技术设计人脸转正方法卷积神经网络的训练和优化数据预处理技术实现总结与展望本文总结导文 基于java开发汽车销售系统资料 文章重点 摘要 在实际应用中,人脸图像往往具有旋转、…

基于线特征的图像配准

一、线特征提取 1.1 模板检测 使用模板在一幅图像上移动&#xff0c;他会对特定方向上的&#xff08;一个像素宽&#xff09;线响应强烈。下面是常见检测模板&#xff1a; 1.2 边缘检测 边缘检测的基本思想是使用如下两个准则之一找到图像中快速变换的位置&#xff1a; 1.…

Flutter框架:从入门到实战,构建跨平台移动应用的全流程解析

第一章&#xff1a;Flutter框架介绍 Flutter框架是由Google推出的一款跨平台移动应用开发框架。相比其他跨平台框架&#xff0c;Flutter具有更高的性能和更好的用户体验。本章将介绍Flutter框架的概念、特点以及与其他跨平台框架的比较&#xff0c;以及Flutter开发环境的搭建和…

MathGPT是什么,MathGPT与ChatGPT的区别是什么,MathGPT十大应用场景

MathGPT是一种基于自然语言处理技术的数学语言模型&#xff0c;其目的是通过自动化生成数学公式、证明和解题步骤等来辅助数学学习和研究。 与ChatGPT相比&#xff0c;MathGPT主要关注数学领域而非通用性的自然语言理解&#xff0c;因此其训练语料库和预测任务都与数学有关&…

Ubuntu20.04安装Vtk9.2.6+PCL1.12.1(成功无报错)

成功不报错的原因&#xff1a;VTK和PCL版本需要对应正确.. 错误可参考&#xff1a;Ubuntu20.04 编译 pcl1.8可能出现的问题 安装参考1&#xff1a;ubuntu20.04下安装pcl_ubuntu安装pcl_Yuannau_jk的博客-CSDN博客 安装参考2&#xff1a;Ubuntu20.04 安装pcl详细教程_ubuntu20…

构造函数,析构函数,拷贝构造函数与运算符重载简图总结,赋值运算符重载与前置++后置++的重载参数区分

构造函数简图 析构函数简图 拷贝构造函数简图 运算符重载简图 赋值运算符重载与拷贝构造函数的区别 即为赋值运算符这涉及到两个已经存在的实例化对象之间的复制拷贝。这个与拷贝构造函数是完全不一样的&#xff0c;拷贝构造函数它的本质上就是一个构造函数&#xff0c;主要是用…

C++ 类和对象下

文章目录 重载operator<< 输出自定义类型const对象 无法调用 非const成员函数非const函数的缺陷 初始化列表&#xff1a;对象的成员定义的位置为什么会要用到初始化列表&#xff1f;自定义类型成员如何初始列表初始化灵活的初始化列表声明次序内置类型_size不给缺省值&am…

win10系统电脑硬盘里的文件不显示,到底出了什么问题呢?有什么解决方法呢?

演示机型&#xff1a;技嘉 H310M HD22.0 系统版本&#xff1a;Windows 10 专业版 软件版本&#xff1a;云骑士数据恢复软件3.21.0.92 Win10系统是我们经常使用的操作系统之一&#xff0c;但这也意味着我们可能会遇到一些问题。其中一个比较常见的问题是硬盘中的文件不显示。在这…

国内又款智能AI聊天软件-科大讯飞星火模型

介绍 介绍 中国科大讯飞星火GPT聊天软件是一款基于自然语言处理技术的人工智能聊天机器人。它利用了大量的文本数据&#xff0c;通过深度学习模型进行训练&#xff0c;从而实现与用户的智能对话。讯飞星火GPT聊天软件能够理解用户输入的问题或指令&#xff0c;并根据预设的回答…

MySQL 主从复制涉及到了几个线程?

目录 前言一、主从同步原理二、主从同步分析 前言 说到主从&#xff0c;我相信大家在 MySQL 这一节面试经常被问到MySQL 的主从复制原理&#xff0c;而且大家背得滚瓜烂熟。但是在主从复制的过程中&#xff0c;是如何进程数据同步的&#xff0c;又涉及到了哪些线程呢&#xff…

卖一辆亏5.8万美元!福特的困扰

随着电动化进入关键的「抢量」周期&#xff0c;加上年初掀起的降价潮&#xff0c;对于还无法适应转型节奏的传统汽车制造商来说&#xff0c;现在是一个艰难的时刻。 本月初&#xff0c;福特首席执行官Jim Farley表示&#xff0c;电动汽车市场的降价是"令人担忧的趋势"…

js垃圾回收机制各阶段问题以及解决方案

很多文章的三色标记法&#xff0c;增量标记法&#xff0c;新生代老生代&#xff0c;引用计数法&#xff0c;标记回收法。很容易给最开始学习垃圾回收算法的朋友搞混。文章适合有一部分基础&#xff0c;但是要把算法搞混的朋友们。这篇文章带大家梳理一下本人的思路&#xff0c;…

ASEMI代理ADV7125JSTZ330原装ADI车规级ADV7125JSTZ330

编辑&#xff1a;ll ASEMI代理ADV7125JSTZ330原装ADI车规级ADV7125JSTZ330 型号&#xff1a;ADV7125JSTZ330 品牌&#xff1a;ADI/亚德诺 封装&#xff1a;LQFP-48 批号&#xff1a;2023 引脚数量&#xff1a;48 工作温度&#xff1a;-40C~85C 安装类型&#xff1a;表面…

深夜12点,果断卸载Access,3分钟启用国产Access,源自WPS

Access的“忠实粉丝”&#xff0c;你我皆可能是一员 历经20多年迭代的微软Access&#xff0c;因简单易用&#xff0c;在全球吸引了一大批的“忠实粉丝”&#xff0c;你我可能就是其中的一员。 基于Windows操作系统的集成开发的大环境&#xff0c;Access的灵活性和实用性大大提…

QUIC在京东直播的应用与实践 | 京东云技术团队

作者&#xff1a;京东零售 周凯 一. 前言与背景 国内的互联网直播技术从2005年前后兴起&#xff0c;彼时最具代表性的直播产品是由PPLive创始人姚欣在华中科技大学就读期间发起的校园直播项目PPLive。当时的直播技术用的还是基于windows系统自带的mediaplayer内置的COM组件开…

小程序uniapp利用canvas生成海报并可以保存至相册

✨uniapp实现生成海报并保存至相册组件&#xff0c;u-popup可以根据自己所使用的组件进行替换 这里主要讲的是JS部分&#xff0c;css和元素相关的就不展开赘述了&#xff0c;下方先给大伙看看效果图&#xff0c;图的下方有代码讲解&#xff0c;最下方有完整代码&#xff0c;如…

Echarts 热力图的详细配置过程

文章目录 一&#xff0c;配置过程二&#xff0c;具体实例 一&#xff0c;配置过程 引入Echarts库和热力图插件 <script src"https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js"></script> <script src"https://cdn.jsdelivr.net/npm/…

Java多线程入门到精通学习大全?了解线程池和线程常用集合的基本原理、代码示例!(第六篇:线程池和集合的学习)

设计和实现多线程应用程序需要了解线程池、线程常用集合等相关知识。下面我们将分别介绍线程池、线程常用集合的原理、使用场景、代码示例、注意事项和总结。 1. 线程池 线程池是一种线程调度机制&#xff0c;它可以管理多个线程&#xff0c;并且可以重复使用这些线程来处理多…