Большая часть задержки в живом переводе — это ожидание: потока, следующего слова, предложения. Единственное, что вы можете контролировать, — режим задержки: меньше задержки или меньше правок.
Слушатель, который читает живой перевод, видит каждую строку через несколько секунд после того, как докладчик её произнёс. Этот промежуток складывается не из одной задержки, а из нескольких, идущих друг за другом по цепочке, и большинство из них — это ожидание. Понимание того, какое ожидание за что отвечает, делает выбор режима задержки простым и подсказывает разработчику читалки, что выводить и когда.
Полезный ориентир перед цифрами: профессиональный синхронный переводчик обычно говорит на два–четыре секунды позади оратора. Переводчики называют этот промежуток ear-voice span, «интервал между ухом и голосом». Языки, где глагол стоит в конце предложения, они преодолевают не ожиданием глагола, а его предвосхищением или разбиением фразы на части, которые могут стоять самостоятельно. Одна-две секунды задержки — не дефект программного обеспечения; это примерно то, что делает очень хороший человек.
Каждая живая транскрибация в VocalStack проходит одни и те же этапы в одном и том же порядке, и каждый этап ждёт предыдущего.
Текст на языке оригинала доходит до читателя почти сразу, как его произносят. Перевод отстаёт на секунду-другую, а произнесённое предложение звучит после своего перевода, поэтому аудиоклип всегда приходит последним. Первый видимый эффект цепочки, однако, появляется задолго до голоса: сам текст начинает двигаться.
Первое, что замечают люди в живой расшифровке, — самые новые слова движутся. Фраза появляется, меняется и устаивается. Так работает стадия черновика, и она существует по причине, которая справедлива для любого распознавания речи.
Распознаватель определяет слово, глядя на то, что идёт после него. «I scream» и «ice cream» звучат одинаково, пока не прозвучит следующее слово; конечное «s» может относиться к этому слову или к следующему. Пока справа от слова нет звука, его написание — догадка, поэтому самые новые слова в любой живой расшифровке всегда самые неуверенные. Черновик — это просто такая догадка, показанная заранее, а не скрытая.
Каждый черновик полностью заменяет живой хвост: слова, услышанные после последней фиксации и всё ещё меняющиеся. Фиксация окончательна. Она не меняется, несёт тайминги на уровне слов, а фиксации нумеруются без пропусков, чтобы читатель мог заметить, если какую-то он пропустил.
Для разработчика это единственное правило, которого требует realtime API: выводить каждый зафиксированный сегмент, затем после них последний черновик, а когда приходит фиксация, очищать черновик. Если добавлять черновики вместо того, чтобы их заменять, текст дублируется и мерцает; фиксация просто поглощает хвост. Учебник по WebSocket строит читалку именно на этом принципе.
Для ведущего движущийся текст — цена низкой задержки. Показ слов до того, как фраза закончена, и делает расшифровку живой. Но перевод не может позволить себе этот приём: слово можно угадать по половине фразы, а перевод — нельзя.
Порядок слов — причина, по которой перевод не может идти в ногу с черновиком. Немецкий глагол может стоять в конце клаузы, а в японском глагол всегда последний. Любому переводчику нужна вся клауза, чтобы передать её верно. Перевод по словам отдаёт слушателю обрывки, которые ему приходится держать в памяти до конца клаузы. Немецкий язык заставлял переводчиков ждать глагола задолго до того, как за дело взялись программы.
Поэтому VocalStack переводит предложения, а не сегменты. Предложения включены по умолчанию: при этом сервер собирает фиксации в предложение и переводит его целиком. Пока предложение открыто, его перевод предварительный; когда оно закрывается, перевод становится окончательным. Читатель держит одну запись на предложение и заменяет её по мере поступления обновлений.
Озвучка ждёт ещё дольше. Озвучивается только закрытое предложение, потому что предложение, которое ещё меняется, пришлось бы синтезировать заново при каждой правке. Длинное предложение озвучивается по частям, так что первая часть может звучать, пока делаются остальные.
Если предложения выключены, каждая фиксация получает собственный кадр перевода. Этот путь ничего не ждёт, но целые предложения читаются заметно лучше.
Все эти ожидания отсчитываются от момента, когда звук попадает в VocalStack. Для многих трансляций звук к этому моменту уже опаздывал.
Когда источник — поток, а не микрофон, звук отстаёт ещё до того, как его начали транскрибировать. Он отстаёт от живого края, то есть от самого свежего момента, который поток успел опубликовать.
Простой HTTP-аудиопоток, какие публикуют большинство интернет-радиостанций, обычно отстаёт на одну-три секунды. Сервер ведёт буфер предзагрузки: несколько секунд недавнего звука, отправляемых сразу, чтобы плеер нового слушателя мог стартовать без заиканий. Каждый слушатель, включая VocalStack, подключается на такое же расстояние назад. HLS хуже: его плейлисты начинают клиента в трёх сегментах от живого края, а на практике это от нескольких секунд до полуминуты в зависимости от длины сегмента. Стандартный DASH обычно попадает в тот же диапазон, что и HLS; только его низколатентный вариант уходит заметно ниже. «Прямой» эфир станции может быть прямым примерно в том же смысле, в каком актуально письмо.
Эти цифры приблизительные, и относятся они к потоку, а не к транскрибации: никакая настройка на стороне VocalStack не вернёт эти секунды назад. Если они важны для мероприятия, подавайте звук на вход со стороны микрофона или энкодера, а не с публичного потока. Задержка потока фиксируется до того, как VocalStack услышит первое слово; сдвинуть можно только режим задержки.
Режим задержки делает одно: задаёт баланс между задержкой и точностью. Настройка находится в разделе Advanced при создании живой транскрибации, а на вкладке Speed — во время работы. Там чип показывает AUTO, SPEED или ACCURACY (Fast отображается как SPEED). Через API session.update меняет режим прямо во время потока.
Компромисс такой, как подсказывают названия. Fast выводит текст быстрее, но переписывает его чаще; Accuracy занимает чуть больше времени и переписывает реже. Сидящая аудитория, которая читает субтитры перевода, редко замечает лишнюю секунду, но замечает слова, которые продолжают меняться. Поэтому Accuracy часто оказывается более щадящей настройкой, если график задержки ровный. Auto раскрывает себя: строка, которую он ускорил, чтобы закрыть разрыв, получает значок FAST MODE в расшифровке у ведущего с примечанием, что точность там может быть ниже.
Какой бы ни был режим, транскрибация должна быть готова до первого слова, и подготовка — единственная задержка, которую цепочка платит только один раз.
На некоторых тарифах живая транскрибация запускается несколько секунд. Сколько именно, зависит от тарифа: строка Start-up speed на странице цен показывает, что холодный старт занимает до 15 секунд на оплате по факту использования и ничего не ждёт на Enterprise, где сервис всегда прогрет.
Через API ожидание видно как кадры session.loading во время запуска сессии, затем session.ready; клиент отправляет звук только после этого. Слушатель, который открывает ссылку в это время, видит «Live. The first line appears in a moment.» Когда транскрибация уже идёт, эта задержка позади, и остаётся только вопрос, какую часть оставшейся задержки вы несёте.
Пока живая транскрибация идёт, вкладка Speed у ведущего показывает, чему всё это в сумме равно: текущий разрыв между докладчиком и текстом, рядом с чипом режима, и график этого разрыва по всей записи со средним и пиковым значениями. В самой расшифровке строка, которая дошла до слушателей с опозданием, несёт значок с числом секунд между моментом, когда её произнесли, и моментом, когда она пришла.
Низкий ровный график означает, что режим подходит аудио. Растущий график — признак того, что конвейер отстаёт. В режиме Accuracy может наступить момент перейти на Auto, который жертвует частью точности ради скорости, пока разрыв не закроется.
Разработчики получают одно число. Когда realtime-сессия заканчивается, session.done несёт stats.realtimeFactor: транскрибированное аудио, делённое на время, потраченное на его транскрибацию. Одно предупреждение о соглашении: в литературе по распознаванию речи real-time factor обычно означает обратное, то есть время обработки к длительности аудио, где меньше значит лучше. VocalStack считает наоборот, так что здесь больше значит лучше: живая сессия стоит около 1, а значение ниже 1 означает, что аудио пришло быстрее, чем конвейер успевает его транскрибировать.
Ни одна из этих секунд не загадочна. Одни принадлежат потоку, другие — слову, которое ждёт следующего, третьи — предложению, которое нужно переводу, а остальные — режиму задержки, который вы выбрали. В справочнике API подробно разобран каждый кадр, а демо на главной странице показывает цепочку в действии.