В статье предлагается рассмотреть работу младших моделей преобразования речи в текст на edge устройстве — raspberry pi 4b. Фраза будет непростая, хоть и короткая — в ней будут элементы и русской, и английской речи. В соревновательный состав войдут представители семейства whisper: whisper, whisper-cpp, whisper-jax и vosk. Будет проведена оценка скорости и точности работы. Также, в качестве бонуса, будет предпринята попытка перевести фразу с таджикского языка на русский с помощью vosk.
Введение.
Сразу необходимо сослаться на статью — Сравнение Vosk и Whisper, чтобы сэкономить время тех, кто уже знает, что такое vosk и whisper.
Однако в упомянутой статье проводилось сравнение только одного пакета (возможно, уже даже framework) — whisper с другим — vosk. Здесь же интересно посмотреть, как vosk и whisper поведут себя в ограниченном пространстве — на одноплатнике raspberry pi4b Raspbian Bullseye aarch64. А также посмотреть на результаты других представителей семейства whisper.
В качестве wav файла для тестов будет использоваться синтезированная речь другим пакетом — piper.
Аудиофрагмент короткий и содержит следующую фразу: «Добро пожаловать в синтез речи. Welcome to our speech synthesis.»
Чтобы уровнять условия данный аудиофрагмент был «стандартизирован» командой:
ffmpeg -i welcome.wav -ar 16000 -ac 1 -c:a pcm_s16le welcome.wav
Все whisperы и vosk устанавливаются без проблем на raspberry pi.
Whisper.
import whisper from time import time ##Добро пожаловать в синтез речи. Welcome to our speech synthesis. model = whisper.load_model("tiny") ts=time() result = model.transcribe("welcome_.wav") print(result["text"]) print(time() -ts) ts=time() result = model.transcribe("welcome_.wav") print(result["text"]) print(time() -ts)
*В коде двойной запуск одного и того же фрагмента. Зачем это нужно, будет продемонстрировано позднее.
На выходе:
«Добро пожаловать с синтизеречи. Веркомтодовый улдов спич синтез«.
С результатом: 20,5 сек.
Whisper неплохо справился с русской частью фразы и даже перевел в стиле одного политика английскую речь.
Интересно, можно ли передать в whisper аудио как объект pickle?
Данный объект был сериализован из датасета huggingface.co/datasets/hf-internal-testing/librispeech_asr_dummy командой:
from datasets import load_dataset; import pickle ds = load_dataset("hf-internal-testing/librispeech_asr_dummy", "clean", split="validation") sample = ds[4]["audio"] with open('audio_dump.obj', 'wb') as fp: pickle.dump(sample, fp)
*на raspberry с 8гб ram это сделать не удалось, т.к. датасет в память не поместился. Поэтому сериализация экземпляра была проведена на более мощной системе.
Фраза из аудио приведена в коде ниже, она полностью на английском и достаточно длинная.
Код, в котором попытаемся скормить whisper audio как объект pickle:
import whisper from time import time import pickle import numpy as np """ LINNELL'S PICTURES ARE A SORT OF UP GUARDS AND AT EM PAINTINGS AND \ MASON'S EXQUISITE IDYLLS ARE AS NATIONAL AS A JINGO POEM MISTER BIRKET \ FOSTER'S LANDSCAPES SMILE AT ONE MUCH IN THE SAME WAY THAT MISTER CARKER \ USED TO FLASH HIS TEETH AND MISTER JOHN COLLIER GIVES HIS SITTER A CHEERFUL \ SLAP ON THE BACK BEFORE HE SAYS LIKE A SHAMPOOER IN A TURKISH BATH NEXT MAN """ with open('audio_dump.obj', 'rb') as fp: sample = pickle.load(fp) model = whisper.load_model("tiny") ts=time() result = model.transcribe(sample) print(result["text"]) print(time() -ts) ts=time() result = model.transcribe(sample) print(result["text"]) print(time() -ts)
К сожалению, данный вариант не работает с whisper. Но он пригодится в дальнейшем.
Whisper-cpp
Также устанавливается на raspberry pi без проблем и обрабатывает audio wav:
cd whisper-cpp ./main -m models/ggml-tiny.en.bin -f samples/welcome.wav
На выходе:
«The group has always seen this region. Welcome to the world of speech synthesis.»
Whisper-cpp не справился с русской часть фразы и допустил небольшие неточности в английской.
Время: 11 сек.
whisper-cpp позволяет немного ускорить время за счет квантования. Не будем рассматривать другие возможности, такие как open-vino и т.п. Только то, что доступно «на месте».
Итак, квантуем и запускаем:
./quantize models/ggml-tiny.en.bin models/ggml-tiny.en-q4_0.bin q4_0 ./main -m models/ggml-tiny.en-q4_0.bin -f samples/welcome.wav
К сожалению, нельзя «ужать» модель до q2 или q1, минимум — q4.
Результат тот же: «The purpose of the scene is raging. Welcome to the world of speech synthesis.»
А вот время сократилось: 6,3 сек.
Русских моделей малого размера у whisper-cpp нет (пока нет ?). base модель также некорректно отображает русскую речь. А вот medium и large варианты хорошо справляются. Но эти модели не для raspberry, даже если их квантовать.
Jax-whisper
Данный пакет построен на достаточно свежей идее jax. Который также, называют «numpy на стероидах». За более подробной информацией можно обратиться к книге «Deep Learning with JAX» Grigory Sapunov.
Наш код для raspberry следующий:
from whisper_jax import FlaxWhisperPipline from time import time #Добро пожаловать в синтез речи. Welcome to our speech synthesis. # instantiate pipeline pipeline = FlaxWhisperPipline("openai/whisper-tiny") ts=time() # JIT compile the forward call - slow, but we only do once text = pipeline("welcome_.wav") print(text) print(time() -ts) ts=time() # used cached function thereafter - super fast!! text = pipeline("welcome_.wav") print(text) print(time() -ts)
Результат: «Добро пожаловать с синтизеречи. Веркомтодовый улток с печь синтез.»
По времени исполнения — интересные вещи.
Первый «прогон» — 25 сек, последующий — 8,8 сек.
Объясняется, как уже упомянуто в коде, jit компиляцией, которая на старте дает такую задержку.
На этом тестирование jax-whisper не заканчивается.
Посмотрим следующий код:
from whisper_jax import FlaxWhisperPipline from time import time import time """ LINNELL'S PICTURES ARE A SORT OF UP GUARDS AND AT EM PAINTINGS AND \ MASON'S EXQUISITE IDYLLS ARE AS NATIONAL AS A JINGO POEM MISTER BIRKET \ FOSTER'S LANDSCAPES SMILE AT ONE MUCH IN THE SAME WAY THAT MISTER CARKER \ USED TO FLASH HIS TEETH AND MISTER JOHN COLLIER GIVES HIS SITTER A CHEERFUL \ SLAP ON THE BACK BEFORE HE SAYS LIKE A SHAMPOOER IN A TURKISH BATH NEXT MAN """ # instantiate pipeline pipeline = FlaxWhisperPipline("openai/whisper-tiny") ts=time() # JIT compile the forward call - slow, but we only do once text = pipeline("welcome_.wav") print(text) print(time() -ts) ts=time() # used cached function thereafter - super fast!! text = pipeline("welcome_.wav") print(text) print(time() -ts)
В этом примере, мы взяли ранее сериализованный аудиофрагмент и поместили его в jax-whisper.
Результат и время следующие (напомним, что это другой аудиофрагмент, взятый из датасета с англ. речью):
{'text': <b>"Lennils, pictures are a sort of upguards and atom paintings, and Mason's exquisite Idols are as national as a jingo poem. Mr. Birkut Foster's landscapes smile at one much in the same way that Mr. Karker used to flash his teeth. And Mr. John Colier gives his sitter a cheerful slap on the back before he says like a shampoo or a Turkish bath. Next man."</b>} 56.28657627105713 {'text': <b>"Lennils, pictures are a sort of upguards and atom paintings, and Mason's exquisite Idols are as national as a jingo poem. Mr. Birkut Foster's landscapes smile at one much in the same way that Mr. Karker used to flash his teeth. And Mr. John Colier gives his sitter a cheerful slap on the back before he says like a shampoo or a Turkish bath. Next man."</b>} 25.147851943969727
Если учесть, что сам аудиофрагмент длительностью 29 сек, результат неплохой, в том числе и по содержанию текста.
Воск
Запустим из cli:
vosk-transcriber --model-name vosk-model-small-ru-0.22 -i welcome.wav
Результат:
«добро пожаловать синтеза речи тогда вы отдых с печь синтаксис»
Время: 4.369 sec
Как видно, с содержанием — каша, однако время исполнения поражает.
К сожалению, следующая в семействе vosk (https://alphacephei.com/vosk/models) модель — 1,8 Гб, по сравнению с текущей — 45Мб, разница существенна.
Английская младшая модель (vosk-model-small-en-us-0.15) справляется, как и следовало ожидать, с иностранной речью, но с русской — нет:
«that up i shall have it seems is it hm welcome to the world of speech synthesis».
В завершение, небольшой эксперимент с vosk и таджикским языком. Попытка перевести пословицы, которые были найдены на просторах сети с готовым переводом:
vosk-transcriber --model-name vosk-model-tg-0.22 -i tadjik.wav
Результат на видео:
то же на rutube
Таким образом, подводя итог, можно заключить:
— Vosk опережает всех остальных при переводе коротких аудио в текст по времени исполнения.
Ему в затылок дышит whisper-cpp, подкрученный при помощи квантизации, далее jax-whisper и в хвосте плетется — whisper.
— в части качества распознавания русской речи, пальму первенства несут (по скромному мнению автора) whisper и vosk. При этом whisper немного опережает соперника.
p.s.
Результаты по 43 сек аудио-фрагменту отрывок из "Демон" Лермонтова М.Ю. : whisper печальный демон. Дух изгнания. Летал над грешной землей и лучших дней в воспоминании приеднемтесь нельзя толпой. Тех дней, когда в жили еще света блесталом, чистый хирувим. Когда бегущая комета, улыбкой ласковой привета, любила поменяться с ним. Когда сквозь вечная туманы, познания жадный, он следил качующая караваны в пространстве брошенных светил. Когда он верил, и любил, счастливый первенец творения. Не знал ни злубы, ни сомнения, и не грозил моего веков бесплодных ряд он и лэм много, много всего при помнит не имел он сила. 77.7968852519989 сек jax-whisper {'text': ' печальный демон. Дух изгнания. Летал над грешной землей и лучших дней в воспоминании при днем теснились от толпой. Тех дней, когда вжили еще света блисталым, чистый хирувим. Когда бигущая комета, улыбкой ласковой привета любила поменяться с ним. Когда сквозь вечная туманы, познания жадный, он следил качющая караваны в пространстве брошенных светил. Когда он верил, и любил, счастливый первенец творения. Не знал ни злубы, ни сомнения, и не грозил моего веков бесплодных ряд он и лямного. Много всего при помнит не имело населы.'} 49.801395416259766 сек vosk печальный демон дух изгнанье летал над грешной земле и лучших дней воспоминанья пред ним теснились а толпой тех дней когда в жилища света блистал он чистые херувим когда бегущая комета улыбкой ласковое привета любила поменяться с ним когда сквозь вечная туманы познания жадный он следил кочующие караваны в пространстве брошенных светил когда он ведь верил и любил счастливой первенец творенья не знал ни злобы ни сомнения и не грозило моего веков бесплодных ряд унылая много многое всего припомнит не имел он силы 13.022 сек
Приложения:
— welcome.wav
— audio_dump.obj
— tadjik.wav
— demon.wav
— видео, демонстрирующее приведенный в статье код — youtube, — rutube.
ссылка на оригинал статьи https://habr.com/ru/articles/846428/
Добавить комментарий