Skip to content
Announcements6 min read

Potato 2.7.1: la transcripción ya existe

Potato 2.7.1 lee directamente 21 formatos de transcripción y subtítulos, los carga desde archivos adyacentes junto a tu material y trae un conversor que convierte una carpeta de salida de ASR en un archivo de datos listo para anotar.

Potato Team

Casi nadie llega a una herramienta de anotación con audio en crudo y nada más. Llega con una transcripción. Alguien pasó Whisper por una carpeta de entrevistas. Alguien se bajó los subtítulos de cien charlas de congreso. Alguien heredó un corpus de TextGrids de un proyecto de trabajo de campo que acabó en 2019.

Y entonces la herramienta le pide que escriba un script de conversión.

Potato 2.7.1 va de quitar ese paso. Lee directamente 21 formatos de transcripción y subtítulos, los carga desde archivos que están junto a tu material en lugar de exigir que todo se pegue dentro de un archivo de datos, e incluye un conversor para el caso en que sí quieras acabar con un único archivo de datos.

Potato 2.7.1: entran 21 formatos de transcripción, sale un solo modelo de turnosPotato 2.7.1

Entran 21 formatos, sale un solo modelo

Antes eran 6. La lista completa está en la página de Formatos de transcripción, pero a grandes rasgos: nueve tipos de salida de ASR (Whisper JSON, WhisperX y otros JSON diarizados, whisper.cpp, Whisper TSV, AWS Transcribe, Deepgram, AssemblyAI, Rev.ai, SPoRC), seis formatos de subtítulos y rótulos (SubRip, WebVTT, SubStation Alpha, TTML y DFXP, YouTube json3, YouTube srv1/srv2/srv3), tres del mundo del alineamiento forzado (NIST CTM, Praat TextGrid, ELAN EAF) y tres formas genéricas para datos que vienen de cualquier otro sitio.

Los formatos de alineamiento son la incorporación que más nos gusta. La exportación a EAF y TextGrid ya existía, así que las anotaciones por capas hacen ahora el viaje de ida y vuelta: metes una alineación existente, la corriges en Potato y la devuelves a ELAN o Praat.

La detección va por la forma de los datos y no por la extensión del archivo, lo que significa que un archivo WebVTT llamado captions.txt se sigue analizando como WebVTT, y que la misma transcripción funciona incrustada o leída desde disco sin cambiar la configuración.

Los tiempos por palabra y la confianza por segmento se conservan siempre que la fuente los proporcione. Los formatos que son de por sí a nivel de palabra, como CTM, Deepgram y AssemblyAI, se agrupan en turnos por cambio de hablante más un umbral de pausa.

Una transcripción mostrada como burbujas de hablante de colores, con botones de reproducción por turno y una pregunta de etiquetado en líneaEntre el formato que entre, esto es lo que sale

Archivos adyacentes

Tu herramienta de ASR ya escribió los archivos con una disposición razonable: el material aquí, la transcripción al lado. No había ninguna buena razón para obligarte a aplanar eso en un bloque de datos, así que ahora puedes apuntar directamente ahí:

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

Las rutas se resuelven relativas a task_dir y pasan por la misma validación contra el recorrido de directorios que cualquier otra ruta configurada. Si tus datos contienen realmente transcripciones incrustadas de una línea que dan la casualidad de parecer nombres de archivo, transcript_is_path: false desactiva la heurística.

La ventaja práctica es que tus transcripciones siguen siendo archivos. Puedes hacerles un diff, regenerarlas y pasárselas a otra persona, en lugar de tener una copia fosilizada dentro de un array JSON.

Un conversor para el otro caso

A veces sí quieres un único archivo de datos. potato transcripts recorre una carpeta con un glob, empareja cada transcripción con su material por el nombre base, deriva los identificadores de elemento de los nombres de archivo y escribe el resultado:

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

--dry-run no escribe nada y te cuenta qué ha encontrado, que además es lo primero que hay que ejecutar cuando una transcripción se muestra como un único bloque indiferenciado:

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 archivo que aparece como plain text casi siempre es un .txt de Whisper que se coló entre la salida .json. El .txt no tiene ningún tiempo, y no hay forma de recuperarlos sin volver a ejecutar el modelo. Ese único hecho explica la mayoría de los avisos de «¿por qué se ve mal mi transcripción?» que nos llegan.

--emit-config imprime un config.yaml a juego junto al archivo de datos.

Un solo vocabulario para cuatro esquemas

audio_dialogue, speech_transcript, voice_interaction y tiered_annotation analizaban cada uno los datos de transcripción a su manera y aceptaban subconjuntos distintos de formatos, sin ninguna razón que nadie supiera explicar. Ahora comparten un mismo normalizador, así que lo que acepta uno lo aceptan los cuatro.

Las configuraciones existentes no se ven afectadas. Cada esquema conserva su análisis antiguo como respaldo, y toda forma de transcripción que funcionaba antes sigue funcionando byte a byte.

tiered_annotation gana además el prerrellenado opcional a partir de la transcripción. Apunta transcript_field a tu transcripción y una capa llega ya rellena, de modo que los anotadores corrigen una alineación existente en lugar de volver a segmentar el habla desde cero:

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

Los intervalos sembrados no se guardan hasta que un anotador los edita de verdad, así que una semilla intacta nunca se atribuye por error a trabajo humano.

Lo que Potato sigue sin hacer

No transcribe, y no diariza. El ASR va antes. Potato lee lo que produjo tu cadena de procesamiento.

Esto sale a relucir porque Potato ejecuta un modelo Whisper local, para el modo Think-Aloud, que graba a los anotadores hablando mientras trabajan. Eso es una función de captura dirigida a tus anotadores, no a tu corpus. Otra cosa distinta, la misma palabra.

La confianza a nivel de palabra se analiza y se conserva en el modelo de datos siempre que la fuente la proporcione, pero por ahora no hay interfaz para verla.

Y algunos formatos no tienen ningún analizador: SAMI, MicroDVD, SubViewer, Transcriber .trs, EXMARaLDA, CHAT/CHILDES, RTTM por sí solo y la salida nativa de Montreal Forced Aligner o de Gentle. Conviértelos antes. Publicamos esa lista porque una lista de formatos admitidos de la que no se excluye nada no vale gran cosa.

Documentación

Actualizar

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

No hace falta cambiar ninguna configuración. Toda forma de transcripción que Potato aceptaba antes, la sigue aceptando.