Press "Enter" to skip to content

创建用于YouTube视频摘要的AI助手的完整指南-第1部分

使用OpenAI的Whisper模型转录YouTube视频

图像由Playground.ai生成的

本文是一系列三篇博客文章中的第一篇,逐步解释了如何构建AI助手来总结YouTube视频的过程。我们从详细的说明开始,介绍如何使用OpenAI的声音转文本模型Whisper来捕获YouTube视频的转录。在下一篇文章中,我们将介绍使用Langchain进行文本摘要的基本原理,并详细介绍如何基于Falcon-7b-instruct,一个开源的经过指令调优的LLM,实现摘要管道的详细说明。在最后一篇文章中,我们将看到如何使用Gradio和Hugging Face Spaces演示解决方案原型。在这些文章中,我们评估了每个步骤实现的不同架构选择。

介绍

想象一下:你正在寻找包含你热衷的特定主题信息的视频。一个快速的YouTube搜索会让你的屏幕上充满了迷人的缩略图和引人入胜的视频标题。大多数人会本能地开始浏览,寻找那个最吸引人的点击宝藏。然而,你有多少次在浏览视频时希望它包含对你迫切问题的答案?如果你像我一样,这种情况经常发生,并且这种体验不仅浪费时间,而且非常令人恼火!

受到这种频繁的挫败感的激发,我踏上了创建自己的个人AI助手的旅程。这个智能伴侣会审查视频内容,并高效地总结其主要思想和论点,最终为我节省时间和理智!

在创建这个工具时,我使用了Falcon大型语言模型。这里有一个有趣的类比:就像猎鹰优雅地在高空飞翔,同时拥有对任何感兴趣的对象进行放大的能力一样,我们用Falcon提供的工具让用户以总览的方式查看内容,轻松地通过全面的完整转录进行深入探索!:)

你可能会问:“但已经有在线服务来实现这个功能了,对吗?”你完全正确!然而:

  1. 它们通常有使用率限制,可能会导致额外的费用。
  2. 我发现自己希望对生成的摘要有更多的控制权,没有办法根据我的特定需求设置参数。
  3. 正如谚语所说,“快乐在于旅程!”

所以,我自己动手开发了一个应用程序,它以YouTube视频的URL作为输入,并提供简洁的摘要。很酷,对吧?

作者托管在Hugging Face Spaces上的应用程序用户界面快照

解决方案蓝图

引擎盖下的动力组件执行以下任务:

  1. 如果有可能,从YouTube获取转录。否则,使用声音转文本模型(OpenAI的Whisper)Hugging Face上进行转录。
  2. 使用Langchain针对遵循指令的大型语言模型(Falcon-7b-instruct)Hugging Face上,采用映射-约简的方法对转录进行摘要。
  3. 使用Gradio提供一个美观的用户界面,让用户与模型无缝交互,生成并与视频本身一起查看和审查摘要。
解决方案架构的高层视图

在实施每一步时,我尝试了各种不同的架构方案。例如,我以两种方式实施了每一步:在本地推理 vs 在云端推理。或者,当涉及到应用的托管时,我尝试了在本地托管 vs 在云端托管在Hugging Face Spaces上。

如果其中任何一点引起了你的好奇心,请跟随我一起学习和交流吧。

在进入下一节之前,我建议你快速看一下托管在Hugging Face Spaces上的原型。随意试试,并在评论中告诉我你的第一印象。

第一步:获取YouTube视频的转录文本

在我们能够对视频进行摘要之前,我们需要将其转录为文本格式。虽然许多YouTube视频都有转录,但你可能会遇到一些没有转录的视频。如果有转录存在,我们只需使用youtube_transcript_apipytube简单地下载转录:

from youtube_transcript_api import YouTubeTranscriptApi
import pytube
# 从YouTube获取转录
def get_yt_transcript(url):
    text = ''
    vid_id = pytube.extract.video_id(url)
    temp = YouTubeTranscriptApi.get_transcript(vid_id)
    for t in temp:
        text+=t['text']+' '
    return text

这段代码只是从URL中获取YouTube视频ID,并使用YouTubeTranscriptApi获取转录对象。转录对象是一个包含转录文本、开始时间和在视频上显示的持续时间的字典列表。这里我们只需要文本属性。

但是如果YouTube没有视频的转录呢?现在事情变得更有趣了……

使用Whisper转录

为此,我使用了著名的Whisper模型,这是来自OpenAI的开源语音转文字模型。目前,只要它能满足我们的需求,我们不需要过多关注模型的内部工作原理。虽然有很多在线资源可供参考,如果评论中有兴趣,我会在单独的博客文章中介绍它们。

在使用Whisper模型之前,我们需要将视频的音频下载到本地目录中,只需几行代码即可完成:

from pytube import YouTube
yt = YouTube(str(url))
audio = yt.streams.filter(only_audio = True).first()
out_file = audio.download(filename="audio.wav",output_path="./docs/youtube/")

现在,我们可以直接使用Whisper接受音频文件作为输入并进行转录了。我们首先创建一个从HuggingFace下载模型的Transformers Pipeline对象:

import transformers
whisper_asr = transformers.pipeline(
    "automatic-speech-recognition", model="openai/whisper-large", device_map= 'auto',)

Whisper有各种不同的大小,从小型(拥有3900万个参数)到大型(拥有15.5亿个参数)。我使用了whisper-large,以获得最高质量的结果。一旦加载并开始评分,在峰值时,它占用了我16GB GPU内存的12GB,这还可以接受。但是如果适用于你的用例,你可以选择使用更小的版本。

然后,我们需要设置模型的配置参数,包括语言和任务:

whisper_asr.model.config.forced_decoder_ids = (
    whisper_asr.tokenizer.get_decoder_prompt_ids(
        language="en",
        task="transcribe"
    ))

在这种情况下,我将流水线限制为只转录英文视频。但是,你也可以使用相同的模型转录其他几十种语言。为此,你需要在配置转录流水线之前确定视频的语言。我将这留给有兴趣的读者作为练习。

最后,我们为推断调用模型:

temp = whisper_asr(out_file,chunk_length_s=20)text = temp ['text']

但是chunk_length_s参数是什么意思?Whisper模型被设计用于分析最大长度为30秒的音频文件。因此,在将文件提供给模型之前,需要将其分割成块。 chunk_length_s参数控制这些块的长度。

将其整合到一起,代码如下:

from pytube import YouTubeimport transformersimport torch# transcribes the videodef transcribe_yt_vid(url):    # download YouTube video's audio    save_dir="./docs/youtube/"    yt = YouTube(str(url))    audio = yt.streams.filter(only_audio = True).first()    out_file = audio.download(filename="audio.wav",                              output_path = save_dir)    # defining an automatic-speech-recognition pipeline using `openai/whisper-large`    whisper_asr = transformers.pipeline(        "automatic-speech-recognition",        model="openai/whisper-large",        device_map= 'auto',    )    # setting model config parameters    whisper_asr.model.config.forced_decoder_ids = (        whisper_asr.tokenizer.get_decoder_prompt_ids(            language="en",            task="transcribe"        )    )    # invoking the Whisper model    temp = whisper_asr(out_file,chunk_length_s=20)    text = temp['text']       # we can do this at the end to release GPU memory    del(whisper_asr)    torch.cuda.empty_cache()       return text

好了,太棒了!但是等等!如果我在本地没有足够的计算能力,想要将推断请求发送到云端怎么办?

使用HuggingFace Hub API进行推断

好消息是,HuggingFace通过HuggingFace Hub API支持在云端进行推断。

以下是使用方法:

from HuggingFace_hub import InferenceClient# Initialize client for the Whisper modelclient = InferenceClient(model="openai/whisper-large", token="xxxxxxxxxxx")

只需要传递一个令牌参数,该令牌可以免费从HuggingFace获得。

但是,我遇到了一个问题!推断API对结果进行了截断,我无法从在线资源中找到是否这是预期行为,还是可能是使用免费服务的限制。无论哪种情况,解决方法是在将音频片段通过推断API发送之前将音频分割成块。可以使用librosa将音频文件加载为numpy数组,然后使用长度不会被API截断的块长度(比如20秒)将其分割成块,最后将每个块保存到文件,然后发送给API进行推断:

import librosaimport soundfile as sfx, sr = librosa.load(out_file, sr=None)t=20 # 音频片段长度(秒)# 这将x作为numpy数组音频文件,sr作为原始采样率# 由于API调用截断响应,音频需要拆分成20秒的块    text = ''for i in range(0, (len(x)//(t * sr)) +1):    y = x[t * sr * i: t * sr *(i+1)]    split_path = save_dir+"audio_split.wav"    sf.write(split_path, y, sr)    text += client.automatic_speech_recognition(split_path)

通过这种解决方法,我能够在API上转录较长的视频。但要注意的是,免费订阅会限制推断速率。这意味着如果短时间内多次调用API,可能会出错。好消息是,限制每小时重置一次,所以您不必等太长时间,就可以再次测试代码。但这也意味着您可能无法将此解决方法用于太长的视频!

最终的结果可能如下所示:

from pytube import YouTubefrom huggingface_hub import InferenceClient# transcribes the video using the Hugging Face Hub APIdef transcribe_yt_vid_api(url):    # download YouTube video's audio    yt = YouTube(str(url))    audio = yt.streams.filter(only_audio = True).first()    out_file = audio.download(filename="audio.wav",                              output_path = save_dir)       # Initialize client for the Whisper model    client = InferenceClient(model="openai/whisper-large",                       token=os.environ["HUGGINGFACEHUB_API_TOKEN"])    import librosa    import soundfile as sf    text = ''    t=20 # audio chunk length in seconds    x, sr = librosa.load(out_file, sr=None)    # This gives x as audio file in numpy array and sr as original sampling rate    # The audio needs to be split in 20 second chunks since the API call truncates the response    for i in range(0, (len(x)//(t * sr)) +1):        y = x[t * sr * i: t * sr *(i+1)]        split_path = save_dir+"audio_split.wav"        sf.write(split_path, y, sr)        text += client.automatic_speech_recognition(split_path)    return text

将所有内容放在一起

现在将这两种方法放在一个函数中,我们可以这样做:

def transcribe_youtube_video(url, force_transcribe=False, use_api=False):       yt = YouTube(str(url))    text = ''    # 从YouTube获取字幕(如果有)    try:        text = get_yt_transcript(url)    except:        print('字幕不可用,正在进行转录...')        pass       # 如果YouTube没有提供字幕,或者您想强制进行转录的话,进行视频转录    if text == '' or force_transcribe:        if use_api:            text = transcribe_yt_vid_api(url)        else:            text = transcribe_yt_vid(url)       return yt.title, text

结论

让我们回顾一下我们在本文中讨论过的内容。我们创建了三个不同的函数,用于获取YouTube视频的转录:第一个直接从YouTube下载,第二个在本地使用OpenAI的Whisper模型转录,第三个通过Hugging Face Hub API进行转录。值得注意的是,在生产环境中部署会更加复杂。根据推理吞吐量和所需资源的数量,模型可能会被推送到一个端点。Hugging Face提供了推理端点服务,在专用和自动伸缩的基础设施上部署模型。关于这个问题,我们将在另一个时间进行讨论。

在下一篇文章中,我将向您介绍使用LangchainFalcon-7b-instructHuggingFace上获取转录并进行摘要的步骤。

Leave a Reply

Your email address will not be published. Required fields are marked *