Heim >Backend-Entwicklung >Python-Tutorial >So erstellen Sie Ihr eigenes Google NotebookLM

So erstellen Sie Ihr eigenes Google NotebookLM

Patricia Arquette
Patricia ArquetteOriginal
2024-12-03 08:13:10477Durchsuche

Mit der zunehmenden Beliebtheit des Konsums von Audioinhalten ist die Möglichkeit, Ihre Dokumente oder schriftlichen Inhalte in realistische Audioformate umzuwandeln, in letzter Zeit im Trend.

Während Googles NotebookLM in diesem Bereich Aufmerksamkeit erregt hat, wollte ich den Aufbau eines ähnlichen Systems mithilfe moderner Cloud-Dienste erkunden. In diesem Artikel erkläre ich Ihnen, wie ich ein skalierbares, cloudnatives System erstellt habe, das mithilfe von FastAPI, Firebase, Google Cloud Pub/Sub und dem Text-to-Speech-Dienst von Azure Dokumente in hochwertige Podcasts umwandelt.

Hier ist ein Schaufenster, auf das Sie sich für die Ergebnisse dieses Systems beziehen können: MyPodify Showcase

Die Herausforderung

Das Konvertieren von Dokumenten in Podcasts ist nicht so einfach wie das Ausführen von Text durch eine Text-to-Speech-Engine. Es erfordert sorgfältige Verarbeitung, Verständnis natürlicher Sprache und die Fähigkeit, verschiedene Dokumentformate zu verarbeiten und gleichzeitig ein reibungsloses Benutzererlebnis zu gewährleisten. Das System muss:

  • Mehrere Dokumentformate effizient verarbeiten
  • Erzeugen Sie natürlich klingendes Audio mit mehreren Stimmen
  • Erledigen Sie die Verarbeitung umfangreicher Dokumente, ohne die Benutzererfahrung zu beeinträchtigen
  • Stellen Sie Benutzern Statusaktualisierungen in Echtzeit bereit
  • Achten Sie auf hohe Verfügbarkeit und Skalierbarkeit

Architektur Deep Dive

Lassen Sie uns die Schlüsselkomponenten aufschlüsseln und verstehen, wie sie zusammenarbeiten:

How to Build your very own Google

1. FastAPI-Backend

FastAPI dient als unser Backend-Framework und wurde aus mehreren überzeugenden Gründen ausgewählt:

  • Asynchrone Unterstützung: Die asynchronen Funktionen von FastAPI basieren auf Starlette und ermöglichen eine effiziente Bearbeitung gleichzeitiger Anfragen
  • Automatische OpenAPI-Dokumentation: Erzeugt sofort einsatzbereite interaktive API-Dokumentation
  • Typsicherheit: Nutzt Pythons Typhinweise für die Laufzeitvalidierung
  • Hohe Leistung: In Bezug auf die Geschwindigkeit vergleichbar mit Node.js und Go

Hier ist ein detaillierter Blick auf unseren Upload-Endpunkt:

@app.post('/upload')
async def upload_files(
    token: Annotated[ParsedToken, Depends(verify_firebase_token)],
    project_name: str,
    description: str,
    website_link: str,
    host_count: int,
    files: Optional[List[UploadFile]] = File(None)
):
    # Validate token
    user_id = token['uid']

    # Generate unique identifiers
    project_id = str(uuid.uuid4())
    podcast_id = str(uuid.uuid4())

    # Process and store files
    file_urls = await process_uploads(files, user_id, project_id)

    # Create Firestore document
    await create_project_document(user_id, project_id, {
        'status': 'pending',
        'created_at': datetime.now(),
        'project_name': project_name,
        'description': description,
        'file_urls': file_urls
    })

    # Trigger async processing
    await publish_to_pubsub(user_id, project_id, podcast_id, file_urls)

    return {'project_id': project_id, 'status': 'processing'}

2. Firebase-Integration

Firebase bietet zwei wichtige Dienste für unsere Anwendung:

Firebase-Speicher

  • Verwaltet sichere Datei-Uploads mit automatischer Skalierung
  • Bietet eine CDN-gestützte Verteilung für generierte Audiodateien
  • Unterstützt fortsetzbare Uploads für große Dateien

Feuerladen

  • Echtzeitdatenbank zur Projektstatusverfolgung
  • Dokumentbasierte Struktur, perfekt für Projektmetadaten
  • Automatische Skalierung ohne manuelles Sharding

So implementieren wir Statusaktualisierungen in Echtzeit:

async def update_status(user_id: str, project_id: str, status: str, metadata: dict = None):
    doc_ref = db.collection('projects').document(f'{user_id}/{project_id}')

    update_data = {
        'status': status,
        'updated_at': datetime.now()
    }

    if metadata:
        update_data.update(metadata)

    await doc_ref.update(update_data)

3. Google Cloud Pub/Sub

Pub/Sub dient als unser Messaging-Rückgrat und ermöglicht Folgendes:

  • Entkoppelte Architektur für bessere Skalierbarkeit
  • Mindestens einmalige Liefergarantie
  • Automatische Nachrichtenspeicherung und -wiedergabe
  • Warteschlangen für unzustellbare Nachrichten für fehlgeschlagene Nachrichten

Beispiel für eine Nachrichtenstruktur:

@app.post('/upload')
async def upload_files(
    token: Annotated[ParsedToken, Depends(verify_firebase_token)],
    project_name: str,
    description: str,
    website_link: str,
    host_count: int,
    files: Optional[List[UploadFile]] = File(None)
):
    # Validate token
    user_id = token['uid']

    # Generate unique identifiers
    project_id = str(uuid.uuid4())
    podcast_id = str(uuid.uuid4())

    # Process and store files
    file_urls = await process_uploads(files, user_id, project_id)

    # Create Firestore document
    await create_project_document(user_id, project_id, {
        'status': 'pending',
        'created_at': datetime.now(),
        'project_name': project_name,
        'description': description,
        'file_urls': file_urls
    })

    # Trigger async processing
    await publish_to_pubsub(user_id, project_id, podcast_id, file_urls)

    return {'project_id': project_id, 'status': 'processing'}

4. Sprachgenerierung mit Azure Speech Service

Der Kern unserer Audiogenerierung nutzt das Cognitive Services Speech SDK von Azure. Schauen wir uns an, wie wir eine natürlich klingende Sprachsynthese implementieren:

async def update_status(user_id: str, project_id: str, status: str, metadata: dict = None):
    doc_ref = db.collection('projects').document(f'{user_id}/{project_id}')

    update_data = {
        'status': status,
        'updated_at': datetime.now()
    }

    if metadata:
        update_data.update(metadata)

    await doc_ref.update(update_data)

Eine der einzigartigen Funktionen unseres Systems ist die Möglichkeit, mithilfe von KI mehrsprachige Podcasts zu generieren. So handhaben wir die Skripterstellung für verschiedene Hosts:

{
    'user_id': 'uid_123',
    'project_id': 'proj_456',
    'podcast_id': 'pod_789',
    'file_urls': ['gs://bucket/file1.pdf'],
    'description': 'Technical blog post about cloud architecture',
    'host_count': 2,
    'action': 'CREATE_PROJECT'
}

Für die Sprachsynthese ordnen wir verschiedene Sprecher bestimmten Azure-Stimmen zu:

import azure.cognitiveservices.speech as speechsdk
from pathlib import Path

class SpeechGenerator:
    def __init__(self):
        self.speech_config = speechsdk.SpeechConfig(
            subscription=os.getenv("AZURE_SPEECH_KEY"),
            region=os.getenv("AZURE_SPEECH_REGION")
        )

    async def create_speech_segment(self, text, voice, output_file):
        try:
            self.speech_config.speech_synthesis_voice_name = voice
            synthesizer = speechsdk.SpeechSynthesizer(
                speech_config=self.speech_config,
                audio_config=None
            )

            # Generate speech from text
            result = synthesizer.speak_text_async(text).get()

            if result.reason == speechsdk.ResultReason.SynthesizingAudioCompleted:
                with open(output_file, "wb") as audio_file:
                    audio_file.write(result.audio_data)
                return True

            return False

        except Exception as e:
            logger.error(f"Speech synthesis failed: {str(e)}")
            return False

5. Hintergrundverarbeitungsarbeiter

Die Worker-Komponente übernimmt das schwere Heben:

  1. Dokumentenanalyse

    • Text aus verschiedenen Dokumentformaten extrahieren
    • Dokumentstruktur und -inhalt analysieren
    • Identifizieren Sie wichtige Themen und Abschnitte
  2. Inhaltsverarbeitung

    • Erzeugen Sie einen natürlichen Gesprächsfluss
    • Inhalte in Sprechersegmente aufteilen
    • Schaffe Übergänge zwischen Themen
  3. Audioerzeugung

    • Konvertieren Sie Text mit den neuronalen Stimmen von Azure in Sprache
    • Verwaltung mehrerer Sprecherstimmen
    • Audio-Nachbearbeitung anwenden

Hier ist eine vereinfachte Ansicht unserer Worker-Logik:

async def generate_podcast_script(outline: str, analysis: str, host_count: int):
    # System instructions for different podcast formats
    system_instructions = TWO_HOST_SYSTEM_PROMPT if host_count > 1 else ONE_HOST_SYSTEM_PROMPT

    # Example of how we structure the AI conversation
    if host_count > 1:
        script_format = """
        **Alex**: "Hello and welcome to MyPodify! I'm your host Alex, joined by..."
        **Jane**: "Hi everyone! I'm Jane, and today we're diving into {topic}..."
        """
    else:
        script_format = """
        **Alex**: "Welcome to MyPodify! Today we're exploring {topic}..."
        """

    # Generate the complete script using AI
    script = await generate_content_from_openai(
        content=f"{outline}\n\nContent Details:{analysis}",
        system_instructions=system_instructions,
        purpose="Podcast Script"
    )

    return script

Fehlerbehandlung und Zuverlässigkeit

Das System implementiert eine umfassende Fehlerbehandlung:

  1. Wiederholungslogik

    • Exponentielles Backoff für fehlgeschlagene API-Aufrufe
    • Konfiguration der maximalen Wiederholungsversuche
    • Warteschlange für unzustellbare Nachrichten für fehlgeschlagene Nachrichten
  2. Statusverfolgung

    • Detaillierte Fehlermeldungen im Firestore gespeichert
    • Statusaktualisierungen für Benutzer in Echtzeit
    • Fehleraggregation für die Überwachung
  3. Ressourcenbereinigung

    • Automatisches temporäres Löschen von Dateien
    • Upload-Bereinigung fehlgeschlagen
    • Erkennung verwaister Ressourcen

Skalierung und Leistungsoptimierungen

Um die Produktionslast zu bewältigen, haben wir mehrere Optimierungen implementiert:

  1. Worker-Skalierung

    • Horizontale Skalierung basierend auf der Warteschlangenlänge
    • Ressourcenbasierte Autoskalierung
    • Regionale Bereitstellung für geringere Latenz
  2. Speicheroptimierung

    • Inhaltsdeduplizierung
    • Komprimierter Audiospeicher
    • CDN-Integration für die Lieferung
  3. Verarbeitungsoptimierung

    • Stapelverarbeitung für ähnliche Dokumente
    • Caching für wiederholte Inhalte
    • Parallele Verarbeitung, soweit möglich

Überwachung und Beobachtbarkeit

Das System umfasst eine umfassende Überwachung:

@app.post('/upload')
async def upload_files(
    token: Annotated[ParsedToken, Depends(verify_firebase_token)],
    project_name: str,
    description: str,
    website_link: str,
    host_count: int,
    files: Optional[List[UploadFile]] = File(None)
):
    # Validate token
    user_id = token['uid']

    # Generate unique identifiers
    project_id = str(uuid.uuid4())
    podcast_id = str(uuid.uuid4())

    # Process and store files
    file_urls = await process_uploads(files, user_id, project_id)

    # Create Firestore document
    await create_project_document(user_id, project_id, {
        'status': 'pending',
        'created_at': datetime.now(),
        'project_name': project_name,
        'description': description,
        'file_urls': file_urls
    })

    # Trigger async processing
    await publish_to_pubsub(user_id, project_id, podcast_id, file_urls)

    return {'project_id': project_id, 'status': 'processing'}

Zukünftige Verbesserungen

Während das aktuelle System gut funktioniert, gibt es mehrere spannende Möglichkeiten für zukünftige Verbesserungen:

  1. Verbesserte Audioverarbeitung

    • Integration von Hintergrundmusik
    • Erweiterte Audioeffekte
    • Individuelles Stimmtraining
  2. Inhaltsverbesserung

    • Automatische Kapitelmarkierungen
    • Interaktive Transkripte
    • Mehrsprachige Unterstützung
  3. Plattformintegration

    • Direkte Veröffentlichung auf der Podcast-Plattform
    • RSS-Feed-Generierung
    • Social-Media-Sharing

Der Aufbau eines Dokument-zu-Podcast-Konverters war eine aufregende Reise in die moderne Cloud-Architektur. Die Kombination aus FastAPI, Firebase, Google Cloud Pub/Sub und den Text-to-Speech-Diensten von Azure bietet eine solide Grundlage für die Handhabung komplexer Dokumentverarbeitung in großem Maßstab.

Die ereignisgesteuerte Architektur stellt sicher, dass das System unter Last reaktionsfähig bleibt, während der Einsatz verwalteter Dienste den Betriebsaufwand reduziert. Unabhängig davon, ob Sie ein ähnliches System aufbauen oder einfach nur Cloud-native Architekturen erkunden, hoffe ich, dass dieser ausführliche Einblick wertvolle Einblicke in die Entwicklung skalierbarer, produktionsbereiter Anwendungen geliefert hat.


Möchten Sie mehr über Cloud-Architektur und moderne Anwendungsentwicklung erfahren? Folgen Sie mir für weitere technische und praktische Tutorials.

Das obige ist der detaillierte Inhalt vonSo erstellen Sie Ihr eigenes Google NotebookLM. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn