Skip to main content
Fare una singola chiamata a /audio/speech è facile. Narrare un articolo vero e proprio è il momento in cui emergono i problemi interessanti: l’endpoint accetta al massimo 4096 caratteri per richiesta, ogni voce appartiene a un modello specifico, i formati audio variano da modello a modello, e un testo scritto per essere letto non assomiglia affatto a un testo scritto per essere ascoltato. In questo tutorial affronteremo tutti e quattro gli aspetti. Il risultato è uno script che trasforma un URL in un singolo file audio:
Faremo così:
  1. Scegliere un modello e una voce adatti a una narrazione di forma lunga
  2. Fare una singola richiesta di sintesi e salvare l’audio
  3. Suddividere un articolo lungo in blocchi che rientrano nel limite di caratteri
  4. Unire i blocchi sintetizzati in un unico file senza giunte udibili
  5. Riscrivere l’articolo in qualcosa che valga la pena ascoltare
  6. Combinare i pezzi e poi vedere lo streaming per l’uso interattivo

Setup

Ti servono Python 3.9 o più recente, il pacchetto requests e una chiave API Venice.

1. Scegliere un modello e una voce

Le voci appartengono ai modelli. Inviare una voce di una famiglia a un modello di un’altra è il primo errore più comune, quindi inizia elencando ciò che ciascun modello accetta davvero:
model_spec.voices è l’elenco autorevole delle voci per un modello, e supported_formats ti dice quali valori di response_format accetta. Togli | length dalla query per stampare i nomi delle voci. Useremo tts-xai-v1 con la voce eve. Supporta pcm, che è ciò che rende semplice unire i blocchi nella sezione 4.
La velocità di sintesi varia tra i modelli TTS molto più della qualità dell’output, e il divario è abbastanza ampio da modificare la tua architettura. Cronometra una richiesta realistica su due o tre candidati prima di scegliere. Un blocco che un modello restituisce in pochi secondi può richiedere a un altro diversi minuti.

2. Fare una singola richiesta

Il corpo della risposta è audio grezzo invece che JSON, quindi scrivi i byte direttamente su un file.
Le combinazioni non compatibili vengono rifiutate prima ancora che venga generato audio, e l’errore ti indica cosa avrebbe funzionato:

3. Dividere il testo al limite di 4096 caratteri

Il campo input accetta al massimo 4096 caratteri. Un testo più lungo viene rifiutato del tutto invece di essere troncato in silenzio:
Quindi prima dividiamo l’articolo. Suddividere ai confini delle frasi conta, perché un blocco che termina a metà di una frase produce un’interruzione udibile in corrispondenza della giunzione. Crea narrate.py:
Su uno script di 5362 caratteri questo produce quattro blocchi, ognuno terminante su una frase:
Il valore predefinito di max_chars è 1500 anziché qualcosa vicino al tetto di 4096, ed è una scelta voluta. Il tempo di sintesi cresce con la lunghezza dell’input, quindi blocchi più piccoli tornano prima e, poiché girano in parallelo, completano l’intero lavoro più in fretta. Rendono anche i retry economici quando una richiesta fallisce.

4. Unire i blocchi in un unico file

Concatenare audio codificato come MP3 è inaffidabile, perché ogni blocco porta con sé i propri header dei frame. Richiedere pcm evita del tutto il problema. Il PCM è composto da campioni grezzi senza contenitore, quindi unirli è solo un’aggiunta di byte, e il modulo wave della libreria standard di Python scrive l’header al posto nostro.
Un singolo blocco torna in fretta rispetto a quanto audio contiene:
Quella richiesta ha impiegato circa 13 secondi per produrre 89 secondi di parlato. Eseguire i quattro blocchi in concorrenza è ciò che mantiene ragionevole il totale: la narrazione completa qui sotto ha richiesto 15 secondi di tempo reale. ThreadPoolExecutor.map restituisce i risultati nell’ordine in cui gli input sono stati inviati, quindi i blocchi arrivano nell’ordine di lettura anche se sono stati sintetizzati nello stesso momento.
Il PCM grezzo non porta con sé la sample rate, quindi devi fornirla correttamente al momento di scrivere l’header WAV, ed è specifica per modello. tts-xai-v1 restituisce 24 kHz mentre tts-gradium-v1 restituisce 48 kHz. Sbaglia e la narrazione verrà riprodotta alla velocità e tonalità sbagliata.
Per scoprire la rate di un qualunque modello, chiedi un breve clip in wav e leggi l’header con cui torna:

5. Preparare un testo che suoni bene

Del Markdown estratto letto ad alta voce parola per parola è quasi inascoltabile. Gli URL ne sono l’esempio più chiaro. Un modello vocale li pronuncia carattere per carattere, quindi https://docs.venice.ai/llms.txt viene fuori come:
h t t p s due punti barra barra docs punto venice punto a i l l m s punto t x t
Titoli, elenchi puntati, tabelle e blocchi di codice provocano versioni più piccole dello stesso problema. Invece di combattere il Markdown con espressioni regolari, possiamo chiedere a un chat model di riscrivere l’articolo come qualcosa pensato per essere detto. Crea article_to_audio.py:
La sostituzione con URL_PATTERN rimane come rete di sicurezza per l’occasionale link che il modello si lascia dietro.

6. Mettere tutto insieme

Il punto di ingresso fa scraping, scrive lo script, lo salva e narra:
Salvare script.txt accanto all’audio vale le due righe in più. Quando una narrazione suona sbagliata, lo script ne mostra quasi sempre il motivo, e puoi correggerla senza pagare una nuova sintesi.
Poco meno di sei minuti di narrazione, prodotti in circa quindici secondi. Ora lo script si apre con prosa vera invece di elementi di navigazione:
Venice è costruita su un principio semplice ma potente. La privacy dell’utente viene prima di tutto. L’intera architettura della piattaforma discende da questo impegno filosofico.
Per controllare una narrazione senza starla ad ascoltare, rimanda l’audio a /audio/transcriptions e confronta la trascrizione con script.txt. Trascrivere gli ultimi venti secondi è un modo rapido per confermare che i blocchi sono stati uniti nell’ordine giusto, e coglie in pochi secondi i blocchi persi e gli URL letti carattere per carattere.

Streaming per l’uso interattivo

La narrazione in batch ottimizza il tempo totale. Un’interfaccia vocale ha la priorità opposta, cioè far uscire il primo audio il più in fretta possibile. Impostando streaming: true il corpo viene restituito frase per frase man mano che viene generato, quindi la riproduzione può iniziare in circa un secondo invece di aspettare la clip completa.
Preferisci pcm a mp3 quando alimenti la Web Audio API di un browser o un dispositivo audio direttamente, perché non richiede alcun passaggio di decodifica.

Opzioni della richiesta che vale la pena conoscere

Errori

Poiché i blocchi sono indipendenti, un fallimento costa sempre e solo uno di essi, e ripetere synthesize per quel blocco è sempre sicuro.

Prossimi passi

Alcune estensioni naturali da qui:
  • Metti in cache l’audio tramite un hash del testo, della voce e del modello, così i paragrafi invariati non vengono mai risintetizzati.
  • Sostituisci con una voce clonata da Voice Cloning in modo che la narrazione usi la tua.
  • Genera il testo sorgente invece di farne lo scraping, usando Risposte con citazioni tramite Web Search.
  • Aggiungi audio di intro o di sottofondo con Musica ed effetti sonori.

Text-to-Speech

Riferimento per l’endpoint speech e i suoi parametri.

Voice Cloning

Narra con una voce personalizzata invece di un preset.

Risposte con citazioni tramite Web Search

Genera il testo che questo strumento narra.

Speech-to-Text

Trascrivi l’audio per verificare una narrazione da capo a fondo.