Ingegneria dei sottotitoli

La nostra pipeline sottotitoli funzionava. I dischi veri no.

Tra una pipeline sottotitoli che funziona e una che si può usare c'erano tre difetti: i timestamp PGS, una trascrizione che spezzettavamo noi e otto minuti di CPU al massimo.

Diagramma che confronta i tempi delle cue PGS con le immagini estratte prima e dopo la correzione del tempo di inizio del contenitore

Qualche giorno fa abbiamo scritto come dovrebbe comportarsi un media server con i sottotitoli: tradurre le tracce testuali che esistono già, fare OCR in locale su quelle a immagini di DVD e Blu-ray e, quando nel file non c’è niente di utilizzabile, mettersi ad ascoltare i dialoghi. Tre percorsi, e in fondo a ciascuno una traccia testuale sincronizzata.

L’architettura era giusta. Poi l’abbiamo puntata su materiale vero ed è caduta tre volte, mai nel punto in cui stavamo guardando.

Un disco che ha prodotto 984 sottotitoli e non ne ha accoppiato nessuno

Il primo test era un Blu-ray con solo tracce PGS. Il log diceva frameCount=1371 imageCount=0, il job falliva su un disallineamento delle cue e poi succedeva una cosa peggiore, in silenzio: la selezione automatica scendeva di un gradino e traduceva il tedesco partendo da un sottotitolo francese che Quven stessa aveva generato in precedenza. Due lingue di distanza dall’originale, senza dirlo a nessuno.

Le cause erano tre, impilate una sull’altra: per questo sembrava un unico guasto misterioso.

FFmpeg non riesce a ricavare le dimensioni di uno stream PGS dalla sonda predefinita. Il grafo dei filtri veniva quindi costruito sulle dimensioni del video, e il primo sottotitolo di dimensione corretta veniva rifiutato come cambio di proprietà del frame. Una finestra di analisi più larga risolve questa parte.

Poi le immagini estratte erano vuote. Stavamo prendendo il piano alpha, che per un formato di overlay è la cosa ragionevole da fare, se non fosse che il decoder PGS restituisce frame con palette il cui piano alpha misura zero, mentre i caratteri veri e propri stanno nei piani di colore. Estraevamo con grande precisione il nulla.

La terza è la migliore. Tutte le immagini estratte, tutte le cue note, e nessuna coppia che combaciasse. FFprobe riporta i timestamp grezzi del contenitore, mentre FFmpeg riporta l’output a zero sottraendo l’inizio del contenitore. Su questo disco il contenitore partiva a 79 millisecondi, quindi ogni immagine finiva un tempo di inizio prima della cue a cui apparteneva e la tolleranza di un millisecondo le buttava via tutte. Prima della correzione: 0 su 984. Dopo: 984 su 984.

Lo stesso tempo di inizio spiegava anche uno sfasamento che da settimane attribuivamo al VobSub. Ora il VobSub accoppia 73 cue su 73 per timestamp, invece di ripiegare sull’ordine di posizione.

Un approccio provato e buttato via, nel caso sembrasse allettante: usare il rilevamento di scena per scartare i frame trasparenti che il PGS emette tra un sottotitolo e l’altro. Funziona finché due cue consecutive contengono lo stesso testo, che non conta come cambio di scena, e una delle due sparisce senza far rumore. Una pipeline che fallisce in modo evidente è meglio di una che perde in silenzio una battuta.

Il riconoscitore andava benissimo. Eravamo noi a spezzargli le frasi.

Poi il percorso audio. Un film senza tracce sottotitolo utilizzabili è passato dal riconoscimento vocale locale ed è tornato leggibile, sincronizzato e quasi inguardabile: i dialoghi comparivano più o meno una parola alla volta. 408 delle 1593 cue contenevano una sola parola. 113 duravano esatti 7,00 secondi, che è un numero sospettosamente tondo e il tipo di dettaglio su cui vale la pena fermarsi.

L’indiziato ovvio era il riconoscitore, o i suoi parametri di segmentazione. Per controllare abbiamo lanciato whisper direttamente sullo stesso audio, e restituiva frasi intere: un "Come va?" di dieci secondi e mezzo tornava come un unico blocco. Abbiamo anche testato i parametri che sospettavamo e producevano un output identico byte per byte, quindi è caduta anche quella teoria.

Il difetto era nostro. Sette secondi è la durata massima di visualizzazione di una cue, e a un certo punto quel limite aveva iniziato a essere usato anche come confine del testo. Ogni blocco più lungo di sette secondi veniva quindi tagliato a ogni parola. Il limite appartiene alla fase dei tempi, non a quella del testo, e adesso vive lì, con dei test che gli impediscono di tornare dove non deve.

C’è dentro una lezione generale che continuiamo a riimparare: prova il componente da solo, prima di dargli la colpa.

Otto minuti con tutti i core al 100%

Il terzo problema non era un bug. Trascrivere un film richiedeva circa otto minuti e teneva tutti e 24 i core della macchina al massimo per tutto il tempo. Tecnicamente un successo. In pratica, un media server che rende il computer inutilizzabile mentre lavora non è una funzione che qualcuno voglia lasciare accesa in sottofondo.

Così il riconoscimento è passato sulla GPU: Metal su macOS, Vulkan su Windows e Linux. Sulla scheda che abbiamo misurato la fase di encode è scesa da 591 millisecondi a 15,7, e un clip di due minuti si è chiuso in 2,26 secondi invece di 6,34. Un film di due ore ora richiede circa due minuti e mezzo invece di otto, e nel frattempo la CPU resta quasi ferma.

La selezione scende una scala — GPU dedicata, GPU integrata, build CPU ottimizzata, build CPU base — così una macchina senza un adattatore utilizzabile trascrive comunque, solo più lentamente. La preferenza per la scheda dedicata va imparata dalla lista degli adattatori, perché l’enumerazione torna nell’ordine dei driver e altrimenti ci ritroveremmo con la prima capitata. E sul percorso CPU adesso lasciamo stare almeno un processore: il computer deve continuare a risponderti.

Il limite onesto: la misura viene da una sola scheda NVIDIA. AMD, Intel e Apple Silicon sono implementate e non verificate finché non le proviamo su hardware vero, e preferiamo scriverlo noi piuttosto che fartelo scoprire.

Che aspetto ha davvero un risultato “buono”

Abbiamo riletto un episodio tradotto per intero, riga per riga, tutte e 740 le cue, a fronte dell’originale. Circa 18 erano sbagliate davvero, di cui forse una dozzina pesanti: grammatica, un modo di dire caduto male, una continuità saltata. È un sottotitolo utilizzabile, e non è un traduttore umano. Preferiamo scrivere il numero piuttosto che raccontarlo come indistinguibile da un lavoro professionale.

Il percorso audio è più interessante. La traduzione in sé è tornata pulita — 1593 cue su 1593, niente vuoti, nessun residuo della lingua di partenza — e lungo la strada il traduttore ha perfino riparato gli errori del riconoscitore, rimettendo a posto parole inventate. Quello che sopravvive è l’altra classe di errore: testo perfettamente grammaticale che semplicemente non è ciò che è stato detto. Su quel percorso il tetto lo fissa il riconoscitore, non il traduttore, e nessun lavoro a valle sistema una frase capita male con troppa sicurezza.

Perché metà di tutto questo è gratis e l’altra metà non può esserlo

Generare un sottotitolo in locale usa il tuo processore, la tua scheda video e la tua corrente. Nessuno ci manda una fattura per questo, quindi è gratis e resta gratis.

La traduzione ha una forma diversa. Il testo esce dalla macchina, e ogni film sono migliaia di cue che passano da un provider a pagamento, su server che affittiamo, dietro una coda di lavori che deve sopravvivere ai riavvii, più le licenze e i mesi di lavoro che l’hanno messa lì. Un singolo film di due ore è un costo reale e contabile, che si ripete ogni volta che qualcuno preme il pulsante.

È l’unico motivo per cui sta nella parte a pagamento. Non per tenere in ostaggio una funzione — la base locale resta completa e gratuita — ma perché proprio questo pezzo ha un conto attaccato, e far finta di no vorrebbe dire solo doverlo limitare di nascosto più avanti. Se vuoi provarla prima che aprano i piani, quella conversazione si fa su Discord.

Per la versione pratica di tutto questo ci sono la guida su come tradurre i sottotitoli con l’AI e quella su come generare i sottotitoli per un film che non ne ha.

Comunità

Commenti

0 commenti

Verrà mostrato pubblicamente con il commento.

Gli invii degli ospiti registrano dati limitati di rete e dispositivo per prevenire abusi. Consulta l’Informativa privacy.

Non ci sono ancora commenti. Inizia la conversazione.

Conferma azione

Riporta a casa la tua libreria.

Gratis per uso domestico e tua da eseguire sul tuo hardware. Si installa in pochi minuti.