仿NotebookLM播客生成器

谷歌推出了两款创新产品,NotebookLM 和 Illuminate。这在 LinkedIn 等平台上引起了广泛关注。

这两款产品都展示了人工智能在改变内容消费方面的力量,它们创建了两个人讨论某个话题的动态播客。

受此概念的启发,我实现了自己的版本,以完全控制所使用的声音和提示。

在本文中,我将带你了解我构建此动态播客生成器的历程,并解释所涉及的代码和技术。

体验AI生成的播客

在深入探讨构建此动态播客生成器的技术历程之前,我邀请你收听我使用此代码创建的播客。每个播客都将我的一篇文章转化为两位播客主持人 Sascha 和 Marina 之间的精彩对话:多模态文档处理排名

1、NotebookLM 和 Illuminate

Illuminate 和 NotebookLM 极大地影响和启发了本文。

Illuminate 是谷歌开发的一项实验性技术,它利用人工智能根据个人学习偏好调整内容。它可生成以两个 AI 生成的声音对话的音频,讨论所选学术论文的要点,主要针对已发表的计算机科学研究进行优化。

“作为一款实验性产品,以两个 AI 生成的声音对话生成的音频可能并不总是能完美捕捉原始研究论文的细微差别。请注意,可能偶尔会出现错误或不一致,并且我们会不断迭代以改善用户体验。”

NotebookLM 是一款个性化的 AI 研究助手,可帮助用户通过生成摘要、回答问题和促进对复杂材料的更好理解来深入研究主题。

2、创建自己的动态播客

为了复制和自定义此体验,我使用了以下服务:

  • 具有两个新实验声音的 Google 文本转语音 (TTS)。
  • ElevenLabs 用于训练克隆声音。
  • Google Cloud Storage 用于存储生成的播客。
  • Gemini,将文章转化为两个人之间引人入胜的对话。
播客生成器流程

目标:

  • 创建一个动态播客,其中有两位演讲者 Sascha 和 Marina 讨论给定的文章。
  • 完全控制声音和提示。
  • 生成具有情感深度和真实感的自然对话。

3、深入研究代码

3.1 定义系统提示以生成对话

此提示引导 AI 模型生成自然、引人入胜的对话,适合转换为语音。试用一下,如果你发现一些不错的技巧来进一步优化对话,请告诉我。

system_prompt = """you are an experienced podcast host...

- Based on text like an article, you can create an engaging conversation between two people.
- Make the conversation at least 30,000 characters long with a lot of emotion.
- In the response, for me to identify, use Sascha and Marina.
- Sascha is writing the articles, and Marina is the second speaker who asks all the good questions.
- The podcast is called The Machine Learning Engineer.
- Use short sentences that can be easily used with speech synthesis.
- Include excitement during the conversation.
- Do not mention last names.
- Sascha and Marina are doing this podcast together. Avoid sentences like: "Thanks for having me, Marina!"
- Include filler words like "uh" or repeat words to make the conversation more natural.
"""

使用此提示和 Gemini,我们可以将对话创建为交替讨论的列表。使用 Gemini 1.5 Flash 产生了非常好的效果,我们可以利用低使用成本。

generation_config = GenerationConfig(
    max_output_tokens=8192,
    temperature=1,
    top_p=0.95,
    response_mime_type="application/json",
    response_schema={
        "type": "ARRAY",
        "items": {
            "type": "OBJECT",
            "properties": {
                "speaker": {"type": "STRING"},
                "text": {"type": "STRING"}
            }
        }
    },
)

def generate_conversation():
    vertexai.init(project="YOUR_PROJECT_ID", location="us-central1")
    model = GenerativeModel(
        "gemini-1.5-flash-001",
        system_instruction=[system_prompt]
    )
    responses = model.generate_content(
        [article],
        generation_config=generation_config,
        stream=False,
    )
    
    json_response = responses.candidates[0].content.parts[0].text
    json_data = json.loads(json_response)
    formatted_json = json.dumps(json_data, indent=4)
    print(formatted_json)
    return json_data

3.2 将说话者映射到特定声音

如前所述,我正在使用 ElevenLabs 处理我的克隆声音。如果你不想克隆自己的声音,只需通过调整映射即可使用 Google Speech-to-Text 声音。

speaker_voice_map = {
    "Sascha": "ElevenLabs",            # Sascha's voice via ElevenLabs API
    "Marina": "en-US-Journey-O"        # Marina's voice via Google TTS
}

3.3 Google 文本转语音

此函数使用 Google TTS 为指定说话者合成语音并保存音频文件。

def synthesize_speech_google(text, speaker, index):
    synthesis_input = texttospeech.SynthesisInput(text=text)
    voice = texttospeech.VoiceSelectionParams(
        language_code="en-US",
        name=speaker_voice_map[speaker]
    )
    audio_config = texttospeech.AudioConfig(
        audio_encoding=texttospeech.AudioEncoding.LINEAR16
    )
    response = client.synthesize_speech(
        input=synthesis_input, voice=voice, audio_config=audio_config
    )
    filename = f"audio-files/{index}_{speaker}.mp3"
    with open(filename, "wb") as out:
        out.write(response.audio_content)
    print(f'Audio content written to file "{filename}"')

3.4 ElevenLabs 文本转语音

此函数使用 ElevenLabs API 处理我克隆的声音的语音合成。你还可以利用 ElvenLabs 出色的预训练声音。

def synthesize_speech_elevenlabs(text, speaker, index):
    data = {
        "text": text,
        "model_id": "eleven_turbo_v2_5",
        "voice_settings": {
            "stability": 0.5,
            "similarity_boost": 0.75
        }
    }
    response = requests.post(elevenlabs_url, json=data, headers=elevenlabs_headers)
    filename = f"audio-files/{index}_{speaker}.mp3"
    with open(filename, "wb") as out:
        for chunk in response.iter_content(chunk_size=1024):
            if chunk:
                out.write(chunk)
    print(f'Audio content written to file "{filename}"')

3.5 生成播客音频

作为最后一步,我们进行对话并创建单独的音频片段。每个音频片段都是对话每个部分的合成语音。

最后,我们将所有单独的片段合并到最终的完整播客中。

def generate_audio(conversation):
    os.makedirs('audio-files', exist_ok=True)
    for index, part in enumerate(conversation):
        speaker = part['speaker']
        text = part['text']
        synthesize_speech(text, speaker, index)
    audio_folder = "./audio-files"
    output_file = "podcast.mp3"
    merge_audios(audio_folder, output_file)

4、生成播客的成本

给定一篇 1000 字的普通文章,让我们来分析一下成本。

5、结束语

通过利用 Google 的 Text-to-Speech、ElevenLabs 和 Vertex AI 服务,我们创建了一个动态播客生成器,可将书面文章或任何类型的文本或主题转换为引人入胜的音频对话。

该项目展示了将 AI 语言模型与语音合成技术相结合以创建创新内容消费方法的强大功能。无论是出于教育目的还是为了增强可访问性,可能性都是巨大且令人兴奋的。

别忘了我们可以在几分钟内轻松制作出多种语言的播客。这也有助于为代表性不足的语言提供更多内容。

本文的完整代码可在 GitHub 上找到。


原文链接:Building a AI Podcast Generator Inspired by Google’s NotebookLM and Illuminate

汇智网翻译整理,转载请标明出处