Рубрики
Без рубрики

Как измерить задержку распознавания речи

Одним из очевидных заявлений о признании речи является голосовые помощники. Пока есть изобилие … Теги с Python, распознаванием речи, текстом к речи, Google Cloud.

Одним из очевидных заявлений о признании речи является голосовые помощники. В то время как на рынке есть обилие интеллектуальных устройств на рынке, семья Amazon Echo, вероятно, самым известным из них, все еще есть множество случаев, когда вы можете захотеть создать свое собственное решение. Вы должны были бы выбрать из широкого спектра предложений с коммерческим и открытым исходным кодом для признания речи и НЛП по крайней мере. В этой статье я покажу, как измерить задержку распознавания речи, то есть. Определите, насколько быстро он может вернуть транскрипцию, необходимую для вашего приложения, чтобы понять запрос пользователя.

Распознавание речи для голосовых помощников

Как правило, голосовые ассистенты выполняют распознавание потокового речи, то есть они отправляют непрерывный поток цифрового звука на любую речь и текстовое сообщение, которое вы используете. Это позволяет минимизировать время, необходимое для транскрибирования речи, понимают намерение пользователя и, наконец, выполнить запрошенную операцию. Очевидно, что если вы оцениваете разные поставщики или решения с открытым исходным кодом для распознавания речи, вы, вероятно, захотите измерить их задержку, поскольку опыт ваших пользователей в значительной степени зависет от того, насколько мало.

Но как мера задержки, если есть непрерывный поток аудио, а не однозначное время отклика, как в случае API для отдыха?

Измерение латентности по распознаванию речи речи

Аудиопоток происходит в какой-то момент времени 0 (Zero) и звук затем отправляются на обработку в равных кусках, в этом примере 100 мс каждый. Если ваша частота выборки записи составляет 16 кГц, 100 мс звука будут представлены 1600 образцами. Предполагая, что вы хотите, чтобы ваш голосовой ассистент включить интеллектуальную лампу, представление команды в 100 мс кусочки звука будет выглядеть что-то подобное (время на оси X представляет собой произвольную): распознавание речи, вероятно, даст некоторых временных результатов до точки при транскриптуре Соответствует каким-либо определению команды, будь то трубопровод NLP или простое регулярное выражение. Выровнено в той же оси времени, что и аудиопоток, результаты будут выглядеть на изображении ниже. Разница между концом командного произношения и момента, согласованная стенограмма, приходит наша задержка.

Реализация

Давайте поставьте алгоритм для проверки и внедрения его в Python, используя Google Cloud To-to-Text Tequicing API. Сама реализация клиента API – Слегка модифицированное учебное пособие Google Cloud по распознаванию потоковой передачи Итак, я сосредоточусь в основном на расчет логики и задержки обработки звука.

Мы попытаемся транскрибировать аудиофайл, чтобы эксперимент был бы повторяемым, но мы подражаем потоковую передачу в реальном времени. Сначала давайте определим функцию, которая принимает целевое имя файла и шаблон, который мы ожидаем стенограммы, чтобы соответствовать:

def match_command(
        self, filename: str, pattern: str, language_code: str
    ) -> Tuple[str, int]:
        info = sf.info(filename)
        client = StreamingClient(info.samplerate, language_code)
        for transcript in client.recognize(
            self.generate_request_stream(filename, info.samplerate)
        ):
            match = re.match(pattern, transcript)
            if match:
                self.closed = True
                return transcript, current_time_ms() - self.command_end_ts
        return None, None

Здесь мы инициализируем клиент API с частотой дискретизации и кодом языка, кормите генератор аудио-запроса к нему, а затем итерации результатов распознавания. Далее давайте посмотрим на сам генератор запроса.

Эмуляция потоковой передачи в реальном времени

Для начала ни один пользователь не начинает говорить в миллисекунде ее микрофон включен. Итак, насколько это возможно, настолько близко к реальной жизни, мы будем сократить немного тишины в начале. Это будет случайное количество времени между 100 мс (размер чанка) и 2 секунды.

pre_silence = np.random.choice(
    [*range(chunk_size, samples_per_ms * 2000 + 1, chunk_size)], 1
)[0]
pre_silence_sent = 0
while pre_silence_sent <= pre_silence:
    yield np.zeros(chunk_size, dtype="int16").tobytes()
    pre_silence_sent += chunk_size
    time.sleep(0.1)

Следующим шагом является трансляция самого аудиофайла, все еще эмуляционный в реальном времени, позвонив Time.sleep каждый раз. Я использую отличную библиотеку SoundFile, чтобы открыть файл, заголовки полоски волны и читать образцы. Я также захватываю временную метку того, когда должен быть отправлен последовательный кусок – нам понадобится последний меток времени для расчета задержки в конце.

with sf.SoundFile(filename, mode="r") as wav:
    while wav.tell() < wav.frames:
        sound_for_recognition = wav.read(chunk_size, dtype="int16")
        self.command_end_ts = current_time_ms()

        yield sound_for_recognition.tobytes()
        time.sleep(0.1)

Это на самом деле будет немного неточным способом захватить момент, когда командное произношение завершилось. Последний кусок, скорее всего, будет короче, чем около 100 мс выбирающихся, потому что никто не не агрессирует свою речь к шкале времени 🙂, что означает, что фактическая речь закончилась по крайней мере 100 - Last_Chunk_duration Миллисекунды назад. Давайте учитывать это:

with sf.SoundFile(filename, mode="r") as wav:
    while wav.tell() < wav.frames:
        sound_for_recognition = wav.read(chunk_size, dtype="int16")

        if sound_for_recognition.shape[0] < chunk_size:
            last_chunk_size = sound_for_recognition.shape[0]
            sound_for_recognition = np.concatenate(
                (
                    sound_for_recognition,
                    np.zeros(
                        chunk_size - sound_for_recognition.shape[0],
                        dtype="int16",
                    ),
                )
            )
            self.command_end_ts = (
                current_time_ms()
                - (chunk_size - last_chunk_size) / samples_per_ms
            )
        else:
            self.command_end_ts = current_time_ms()

        yield sound_for_recognition.tobytes()
        time.sleep(0.1)

Теперь, когда мы передали всю нашу запись голосовой команды, мы могли бы просто закончить запрос, однако, что бы заставить речь-текстовую репутацию в промывать гипотезы транскрипции, что приведет к искусственно более низкой задержке. Чтобы смягчить это, мы будем транслировать куски молчания до того момента, когда соответствующая стенограмма будет естественным образом приедет. Речь-текстовый бэкэнд, вероятно, будет использовать обнаружение голосовой активности (VAD), чтобы определить, что речь закончилась, и пришло время промывать результаты распознавания.

while not self.closed:
    yield np.zeros(chunk_size, dtype="int16").tobytes()
    time.sleep(0.1)

Вот и все! Возвращаясь к Match_command Функция содержит цикл прослушивания для результатов – как только приходит сопоставление стенограммы, мы захватываем, что Timestamp, вычитаем временную метку, когда командное произношение завершилось, и это будет наша задержка.

Заключение

В зависимости от вашего местоположения и подключения к Интернету вы можете получить разные результаты, но я получаю задержку около 700 мс для моих справочных файлов, что означает, что если нет действительно сложной и потребляющейся потенциальной обработки, гипотетический голосовой ассистент сможет предоставить ответ Около секунды, которые большинство пользователей считают, чтобы быть довольно быстрыми.

Полный код для этой статьи на Github Отказ На данный момент я предоставил реализацию только для Google Cloud Relect To-Text, но попытаюсь добавить больше поставщиков для сравнения с течением времени.

Обложка Фото Томас Кольновский на Бессмысленно

Оригинал: “https://dev.to/hiisi13/how-to-measure-speech-recognition-latency-3b48”