Det meste af forsinkelsen i live-oversættelse er ventetid: på streamen, på det næste ord, på sætningen. Den del, du selv kan styre, er latenstilstanden: mindre forsinkelse eller færre revisioner.
En lytter, der læser en live-oversættelse, ser hver linje et par sekunder efter, at taleren sagde den. Forsinkelsen er ikke ét led, men flere, lagt sammen langs en kæde, og de fleste af dem er en form for ventetid. Når man ved, hvilket led der venter på hvad, bliver valget af latenstilstand let, og det fortæller en udvikler, der bygger en læser, hvad der skal vises, og hvornår.
Et nyttigt udgangspunkt før tallene: en menneskelig simultantolk taler typisk to til fire sekunder efter taleren. Tolke kalder det øre-stemme-spændet, og de klarer sprog med verbet til sidst ikke ved at vente på verbet, men ved at forudse det eller ved at dele sætningen op i stykker, der kan stå alene. Et sekund eller to i forsinkelse er ikke en fejl i softwaren; det er nogenlunde det, en meget dygtig tolk gør.
Enhver live-transskription på VocalStack gennemgår de samme trin i samme rækkefølge, og hvert trin venter på det forrige.
Teksten på originalsproget når en læser næsten samtidig med, at den bliver sagt. Oversættelsen følger et sekund eller to senere, og den talte sætning kommer efter sin oversættelse, derfor ankommer et stemmeklip altid til sidst. Kædens første synlige effekt kommer dog længe før nogen stemme: selve teksten bevæger sig.
Det første, folk lægger mærke til i en live-transskription, er at de nyeste ord flytter sig. En frase dukker op, ændrer sig og falder til ro. Det er udkast-trinnet i arbejde, og det findes af en grund, der gælder for enhver talegenkender.
En genkender afgør et ord ud fra det, der følger efter. »I scream« og »ice cream« lyder ens, indtil næste ord kommer, og et afsluttende »s« kan høre til dette ord eller det næste. Indtil der er lyd til højre for et ord, er stavningen et gæt, så de nyeste ord i enhver live-transskription er altid de mest usikre. Et udkast er blot det gæt, vist tidligt i stedet for skjult.
Hvert udkast erstatter hele den levende hale: de ord, der er hørt siden det sidste commit, og som stadig ændrer sig. Et commit er endeligt. Det ændrer sig aldrig, det har tidspunkter på ordniveau, og commits er nummereret uden huller, så en læser kan se, hvis et er gået tabt.
For en udvikler er det den ene regel, realtids-API'et insisterer på: vis hvert commit som et segment, dernæst det seneste udkast efter dem, og ryd udkastet, når et commit ankommer. Hvis man tilføjer udkast i stedet for at erstatte dem, opstår der gentaget, flimrende tekst; commit'et forbruger simpelthen halen. WebSocket-selvstudiet bygger en læser netop på dette.
For en vært er bevægelig tekst prisen for lav forsinkelse. At vise ord, før sætningen er færdig, er det, der får transskriptionen til at føles levende. Oversættelsen har dog ikke råd til det trick, for et ord kan gættes ud fra en halv frase, men en oversættelse kan ikke.
Ordstilling er grunden til, at oversættelsen ikke kan følge med udkastet. Et tysk verbum kan stå til sidst i sit ledsætningsled, og japansk sætter verbet sidst. Enhver oversætter har brug for hele leddet, før den kan gengive det korrekt. Oversættes ord for ord, får lytteren fragmenter, der først giver mening, når leddet slutter. Tolke har ventet på verbet i tysk, længe før software forsøgte det.
VocalStack oversætter derfor sætninger, ikke segmenter. Sætninger er slået til som standard, og når de er slået til, samler serveren commits til en sætning og oversætter hele sætningen. Mens sætningen er åben, er dens oversættelse foreløbig; når den lukkes, bliver oversættelsen endelig. En læser har én post pr. sætning og erstatter den, efterhånden som opdateringer kommer.
Tale venter endnu længere. Kun en lukket sætning bliver læst op, fordi en sætning, der stadig ændrer sig, ville blive genskabt som tale ved hver revision. En lang sætning læses op i stykker, så den første kan afspilles, mens resten laves.
Med sætninger slået fra får hvert commit i stedet sin egen oversættelsesramme. Den vej venter man ikke på noget, men hele sætninger læses langt bedre.
Alle disse ventetider måles fra det øjeblik, lyden når VocalStack. For mange udsendelser var lyden allerede forsinket, da den kom frem.
Når kilden er en stream og ikke en mikrofon, er lyden allerede bagud, før noget transskriberes. Den halter efter live-kanten, det nyeste øjeblik, streamen har udgivet.
En almindelig HTTP-lydstream, den slags de fleste internetradiostationer udsender, ligger typisk et til tre sekunder bagud. Serveren har en burst-buffer: et par sekunders nyligt lyd, sendt på én gang, så en ny lytters afspiller kan starte uden at hakke. Alle lyttere, VocalStack inklusive, starter så langt tilbage. HLS er værre: dens playlister starter en klient tre segmenter bag live-kanten, hvilket i praksis betyder flere sekunder til et halvt minut, afhængigt af segmentlængden. Standard DASH ligger typisk i samme interval som HLS; kun dens low-latency-variant kommer en del under. En stations »live«-stream kan være live på samme måde, som et brev er »aktuelt«.
Tallene er omtrentlige, og de hører til streamen, ikke til transskriptionen: ingen indstilling på VocalStacks side kan hente dem tilbage. Hvis de sekunder betyder noget for et arrangement, så forsyn kilden med lyd fra en mikrofon eller en encoder i stedet for en offentlig stream. Streamforsinkelsen er fast, før VocalStack hører et ord; latenstilstanden er det, du faktisk kan flytte.
Latenstilstanden gør kun ét: den fastlægger balancen mellem forsinkelse og nøjagtighed. Indstillingen ligger under Advanced, når en live-transskription oprettes, og på fanen Speed, mens den kører. Der viser chippen AUTO, SPEED eller ACCURACY (Fast vises som SPEED). Over API'et ændrer session.update den midt i streamen.
Afvejningen er den, navnene antyder. Fast får tekst ud hurtigere, men reviderer mere af den; Accuracy tager lidt længere og reviderer mindre. Et siddende publikum, der læser oversatte undertekster, bemærker sjældent et ekstra sekund, men bemærker ord, der bliver ved med at ændre sig. Accuracy er derfor ofte den mest venlige indstilling, så længe forsinkelsesgrafen forbliver flad. Auto viser, hvad den gør: en linje, som den fremskyndede for at lukke et hul, får et FAST MODE-mærke i værtens transskription med en note om, at nøjagtigheden kan være lavere der.
Uanset tilstand skal transskriptionen være klar før første ord, og at gøre den klar er den ene forsinkelse, kæden kun betaler én gang.
På nogle planer tager en live-transskription et par sekunder om at starte. Hvor lang tid det tager, afhænger af planen: rækken Start-up speed på prissiden går fra en koldstart på op til 15 sekunder på pay as you go til altid varm på Enterprise.
Over API'et viser ventetiden sig som session.loading-rammer, mens sessionen starter, efterfulgt af en session.ready; klienten sender først lyd, når den er kommet. En lytter, der åbner linket i mellemtiden, ser "Live. The first line appears in a moment." Når transskriptionen kører, er denne forsinkelse overstået, og det eneste spørgsmål tilbage er, hvor meget af den resterende forsinkelse du bærer.
Mens en live-transskription kører, viser værtens fane Speed, hvad det hele lægger sammen til: den aktuelle afstand mellem taleren og teksten med mode-chippen ved siden af, og et diagram over afstanden gennem optagelsen med gennemsnit og top. I selve transskriptionen har en linje, der nåede lytterne sent, et mærke med antallet af sekunder mellem, hvornår den blev sagt, og hvornår den ankom.
Et diagram, der holder sig lavt og fladt, betyder, at tilstanden passer til lyden. Et diagram, der stiger, betyder, at pipelinen er ved at halte bagefter. På Accuracy kan det være øjeblikket til at skifte til Auto, som bytter lidt nøjagtighed for hastighed, indtil afstanden er lukket.
Udviklere får i stedet ét tal. Når en realtidssession slutter, indeholder session.done stats.realtimeFactor, altså den transskriberede lyd divideret med den tid, der gik med at transskribere den. En konventionsadvarsel: i talegenkendelseslitteraturen betyder real-time factor normalt det omvendte, behandlingstid over lydtid, hvor lavere er bedre. VocalStack rapporterer den omvendt, så her er højere bedre: en live-session ligger tæt på 1, og under 1 betyder, at lyden kom hurtigere ind, end pipelinen kunne transskribere den.
Ingen af disse sekunder er mystiske. Nogle hører til streamen, nogle til et ord, der venter på det næste, nogle til den sætning, en oversættelse har brug for, og resten til den latenstilstand, du valgte. API-referencen har detaljerne billede for billede, og demoen på forsiden viser kæden i gang.