Skip to content
Announcements6 min read

Potato 2.7.1: la trascrizione esiste già

Potato 2.7.1 legge direttamente 21 formati di trascrizione e sottotitoli, li carica da file affiancati ai tuoi media e include un convertitore che trasforma una cartella di output di riconoscimento vocale in un file di dati pronto per l'annotazione.

Potato Team

Quasi nessuno arriva a uno strumento di annotazione con dell'audio grezzo e nient'altro. Arriva con una trascrizione. Qualcuno ha fatto girare Whisper su una cartella di interviste. Qualcuno ha scaricato i sottotitoli di cento talk di conferenza. Qualcuno si è ritrovato in eredità un corpus di TextGrid da un progetto sul campo finito nel 2019.

E poi lo strumento gli chiede di scrivere uno script di conversione.

Potato 2.7.1 serve a togliere quel passaggio. Legge direttamente 21 formati di trascrizione e sottotitoli, li carica da file che stanno accanto ai tuoi media invece di pretendere che tutto venga incollato dentro un file di dati, e include un convertitore per il caso in cui alla fine un file di dati unico lo vuoi davvero.

Potato 2.7.1: 21 formati di trascrizione in ingresso, un solo modello di turni in uscitaPotato 2.7.1

21 formati in ingresso, un modello in uscita

Da 6 che erano. L'elenco completo sta nella pagina Formati di trascrizione, ma grosso modo: nove tipi di output di riconoscimento vocale (Whisper JSON, WhisperX e altri JSON diarizzati, whisper.cpp, Whisper TSV, AWS Transcribe, Deepgram, AssemblyAI, Rev.ai, SPoRC), sei formati di sottotitoli e didascalie (SubRip, WebVTT, SubStation Alpha, TTML e DFXP, YouTube json3, YouTube srv1/srv2/srv3), tre dal mondo dell'allineamento forzato (NIST CTM, Praat TextGrid, ELAN EAF) e tre forme generiche per i dati che arrivano da tutt'altra parte.

I formati di allineamento sono l'aggiunta di cui siamo più contenti. L'esportazione verso EAF e TextGrid c'era già, quindi ora le annotazioni a livelli fanno andata e ritorno: porti dentro un allineamento esistente, lo correggi in Potato e lo rimandi a ELAN o Praat.

Il riconoscimento avviene sulla forma dei dati e non sull'estensione del file, il che significa che un file WebVTT chiamato captions.txt viene comunque interpretato come WebVTT, e che la stessa trascrizione funziona incorporata nel file di dati oppure letta da disco senza cambiare la configurazione.

I tempi per parola e la confidenza per segmento vengono conservati dove la sorgente li fornisce. I formati nativamente a livello di parola, come CTM, Deepgram e AssemblyAI, vengono raggruppati in turni al cambio di parlante più una soglia di pausa.

Una trascrizione mostrata come fumetti colorati per parlante, con un pulsante di riproduzione su ogni turno e una domanda di etichettatura in lineaQualunque formato sia entrato, questo è quello che esce

File affiancati

Il tuo strumento di riconoscimento vocale ha già scritto i file in una disposizione sensata: il media qui, la trascrizione accanto. Non c'era un buon motivo per costringerti ad appiattire tutto in un blob di dati, quindi ora puoi puntarci direttamente:

json
{"id": "int_001", "conversation": {"audio": "media/int_001.mp3",
                                   "transcript": "media/int_001.srt"}}

I percorsi si risolvono rispetto a task_dir e passano dalla stessa validazione contro il directory traversal di ogni altro percorso configurato. Se i tuoi dati contengono davvero trascrizioni incorporate su una riga che sembrano nomi di file, transcript_is_path: false disattiva l'euristica.

Il vantaggio pratico è che le tue trascrizioni restano file. Puoi farne il diff, rigenerarle e passarle a qualcun altro, invece di avere una copia fossilizzata dentro un array JSON.

Un convertitore per l'altro caso

A volte un file di dati unico lo vuoi davvero. potato transcripts scorre una cartella, abbina ogni trascrizione al suo media per nome base, ricava gli identificatori degli elementi dai nomi dei file e scrive il risultato:

bash
potato transcripts ./whisper_out --media-dir ./audio -o data/interviews.json

--dry-run non scrive niente e ti dice cosa ha trovato, ed è anche la prima cosa da eseguire quando una trascrizione appare come un unico blocco indifferenziato:

text
Scanned 3 file(s):
  interview_01.json      Whisper JSON      42 turns    891.4s  undiarized
  interview_02.json      WhisperX JSON     51 turns   1120.8s  2 speaker(s): SPEAKER_00, SPEAKER_01
  interview_03.json      Whisper JSON      38 turns    754.2s  undiarized

3 item(s), 131 turn(s).

Un file che risulta plain text è quasi sempre un .txt di Whisper finito in mezzo all'output .json. Il .txt non ha alcun tempo, e non lo recuperi senza rieseguire il modello. Questo singolo fatto spiega la maggior parte delle segnalazioni del tipo «perché la mia trascrizione viene fuori sbagliata?» che ci arrivano.

--emit-config stampa un config.yaml corrispondente accanto al file di dati.

Un solo vocabolario per quattro schemi

audio_dialogue, speech_transcript, voice_interaction e tiered_annotation interpretavano ciascuno i dati di trascrizione a modo suo e accettavano sottoinsiemi diversi di formati, per motivi che nessuno sapeva spiegare. Ora condividono un unico normalizzatore, quindi quello che accetta uno lo accettano tutti e quattro.

Le configurazioni esistenti non cambiano. Ogni schema mantiene la vecchia interpretazione come ripiego, e ogni forma di trascrizione che funzionava prima funziona ancora byte per byte.

tiered_annotation guadagna anche la precompilazione facoltativa dalla trascrizione. Punta transcript_field alla tua trascrizione e un livello arriva già popolato, così gli annotatori correggono un allineamento esistente invece di risegmentare il parlato da zero:

yaml
  - annotation_type: tiered_annotation
    name: tiers
    source_field: audio_url
    media_type: audio
    tiers:
      - name: utterance
        labels:
          - name: speech
            color: "#7c3aed"

Gli intervalli precompilati non vengono salvati finché un annotatore non li modifica davvero, così una precompilazione mai toccata non viene attribuita per errore a lavoro umano.

Che cosa Potato continua a non fare

Non trascrive e non diarizza. Il riconoscimento vocale gira a monte. Potato legge quello che la tua pipeline ha prodotto.

La cosa salta fuori perché Potato esegue davvero un modello Whisper locale, per la modalità Think-Aloud, che registra gli annotatori mentre parlano lavorando. È una funzione di cattura rivolta ai tuoi annotatori, non al tuo corpus. Cose diverse, stessa parola.

La confidenza a livello di parola viene letta e conservata nel modello dati dove la sorgente la fornisce, ma non esiste ancora un'interfaccia per visualizzarla.

E per alcuni formati non esiste alcun parser: SAMI, MicroDVD, SubViewer, Transcriber .trs, EXMARaLDA, CHAT/CHILDES, RTTM da solo e gli output nativi di Montreal Forced Aligner o Gentle. Quelli vanno convertiti prima. Pubblichiamo quell'elenco perché un elenco di formati supportati da cui non è escluso niente non vale granché.

Documentazione

Aggiornamento

bash
pip install --upgrade potato-annotation==2.7.1

Non devi cambiare nessuna configurazione. Ogni forma di trascrizione che Potato accettava prima, continua ad accettarla.