Как стать автором
Обновить

Распознавание речи, генерация субтитров и изучение языков при помощи Whisper

Время на прочтение 12 мин
Количество просмотров 32K
Всего голосов 32: ↑30 и ↓2 +28
Комментарии 27

Комментарии 27

Спасибо за статью! На каком железе проводилась транскрибация?

На 3090ti. Можно запустить и в колабе, а модели поменьше и на CPU.

А сколько памяти требует? И как быстро парсит на твоем GPU?

За ссылки по диаризации и дообучения отдельное спасибо. Заценим.

Я запускал в докере на VDS base версию, занимает вообще ерунду. Парсит долго, дольше чем в коллабе.

Могу в личку дать доступ к swagger-у к вебинтерфейсу, там прямо можно аплоадить файлики.

Спасибо, пока хочется просто узнать, сколько памяти занимает. То же планирую использовать эту модельку

Large около 10 гигов занимает при инференсе. По скорости было x1.8-1.9 от realtime.

А можно ли использовать Whisper для домашних проектов, при наличии шустрого железа?

Аналог Alexa/Google/Алиса, но в упрощенном офлайновом режиме, без доступа в Inet.
Также учитывая заявленную transcription speed, насколько реально использовать Whisper для замены Dragon Naturally Speaking? (использую с 2004 года)

Почему нет. Распознавать команды должно быть проще, так что, возможно, и младшие модели для этого сгодятся.
По поводу Dragon. Насколько я понял, это потоковое распознавание (вы диктуете и, слово за словом, получаете транскрипцию), whisper так не умеет. Нужно, чтобы vad обрезал фрагмент с фразой и подавал ее на вход.

Эх, когда уже можно будет на компьютере средней руки локально добавлять сабы с живым переводом, например, с японского к произвольным аудио источникам, будь то воспроизводящееся видео или звонок в Zoom-е. Ещё бы и под Линуксом при этом...

Как использовать эти команды в питоновском коде? Получается только через командую строку

В репозитории есть примеры как работать через модуль. Но проще из кода запустить утилиту:

import subprocess


args = ['whisper', '--language', 'ru', '--device', 'cuda', '--model', 'large', '-o', './texts', '--', f'./audio.mp3']
res = subprocess.run(args)

Вышел вариант Whisper, не требующий GPU - https://twitter.com/jd7h/status/1601535920875966464

cd /tmp
brew install gh
gh repo clone ggerganov/whisper.cpp
cd whisper.cpp
bash ./models/download-ggml-model.sh base
bash ./models/download-ggml-model.sh medium
make

Скачаем с Ютуба ролик в качестве примера для распознавания русской речи. Для этого берём короткий ролик Шульман на пару минут, id = f0RCGMCphUM , и выцепляем из него аудиодорожку в формате WAV:

brew install yt-dlp ffmpeg
yt-dlp -x --audio-format wav -o test.wav -- f0RCGMCphUM

Конвертируем аудиофайл в формат 16 bit WAV:

ffmpeg -i test.wav -ar 16000 -ac 1 -c:a pcm_s16le test_16bit.wav

Запускаем распознавание полученного файла test_16bit.wav (используем модель medium, если охота - можно base, она попроще)

./main -f test_16bit.wav -l ru -m models/ggml-medium.bin 

Оно задумывается и начинает выплёвывать:

main: processing 'test_16bit.wav' (1990600 samples, 124.4 sec), 4 threads, 1 processors, lang = ru, task = transcribe, timestamps = 1 ...
[00:00:00.000 --> 00:00:03.440]   приправим нашу беседу, цитата Бродского.
[00:00:03.440 --> 00:00:05.440]   Вот что он писал.
[00:00:05.440 --> 00:00:08.400]   Вот смотрите, кот.
[00:00:08.400 --> 00:00:12.720]   Коту совершенно наплевать, существует ли общество память
[00:00:12.720 --> 00:00:15.480]   или отдел идеологии при ЦК.
[00:00:15.480 --> 00:00:19.160]   Также, впрочем, ему безразличный президент США,
[00:00:19.160 --> 00:00:20.520]   его наличие или отсутствие.
[00:00:20.520 --> 00:00:23.800]   А чем я хуже этого кота?
[00:00:23.800 --> 00:00:28.120]   Вот как вы думаете, если бы сделать так,

Можно добавить опцию --print-colors - тогда будет подсвечено, в каких словах нейросетка не уверена. Oпция --max-len N увеличивает длину отдельных строчек до N символов. А --translate сразу переведёт русский текст на английский.

Автоматический перевод, кстати, огонь:

[00:00:00.000 --> 00:00:03.440]   Let's add to our conversation a quote from Brodsky.
[00:00:03.440 --> 00:00:05.360]   Here's what he wrote.
[00:00:05.360 --> 00:00:08.360]   Look, a cat.
[00:00:08.360 --> 00:00:12.720]   A cat doesn't give a damn if there's a memory society
[00:00:12.720 --> 00:00:15.480]   or a branch of the CPSU ideology.
[00:00:15.480 --> 00:00:19.120]   Also, however, he doesn't care about the president, the USA
[00:00:19.120 --> 00:00:20.480]  , his presence or absence.
[00:00:20.480 --> 00:00:23.800]   And what makes me worse than this cat?

У меня старый макбук (Core i7, 16Gb) - даже не начал вентиляторами шуметь. Отжирает где-то четыре гига памяти.

Сколько по времени занимает распознавание минутного аудио на 3020 ti?

Можно по таблице из их репозитория прикинуть, зависит от модели:

А на сколько это лучше встроенной генерации субтитров YouTube?

От языка и от размера модели зависит. Для английского лучше, 98.5% accuracy rate против 60-70% accuracy (which means that 1 in 3 words can be wrong). Но время не очень точно выставляется и бывает сеть галлюцинирует.

Может кто видел колаб в который можно скормить прямую ссылку на ютуб?

А это просто пара команд будет, они тут в статье есть. Скачать mp3 по ID, запустить на нем whisper.

Любопытно, а можно whisper натренировать выдавать IPA, без опоры на язык?

Подскажите, как сделать так, чтобы виспер не разбивал предложения в субтитрах на части? Чтобы вместо так:

3
00:00:09,520 --> 00:00:15,360
Don't do it. End off. And in a head-to-head fight, obviously pacing beats pushing. Pushing gets

4
00:00:15,360 --> 00:00:21,840
disqualified before the bell even rings. But, and you probably knew there was going to be a but,

Было вот так:

3
00:00:09,520 --> 00:00:15,360
Don't do it. End off. And in a head-to-head fight, obviously pacing beats pushing.

4
00:00:15,360 --> 00:00:21,840
Pushing gets disqualified before the bell even rings. But, and you probably knew there was going to be a but,

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

Ребята, я с вами!

Как получить ggml .bin файл из huggingface репки?

# try.py
from transformers import WhisperForConditionalGeneration
import tempfile
import torch

model = WhisperForConditionalGeneration.from_pretrained("openai/whisper-tiny.en")
model.save_pretrained('./my')
torch.save(model.state_dict(), './my/file.pt')
$ python3 try.py
$ python3 models/convert-pt-to-ggml.py ./my/file.pt ~/code/whisper ./my
Traceback (most recent call last):
File "~/code/whisper.cpp/models/convert-pt-to-ggml.py", line 210, in <module>
hparams = checkpoint["dims"]
~~~~~~~~~~^^^^^^^^
KeyError: 'dims'

Так и не смог отгадать эту загадку для whisper.cpp

А качество распознавания русского текста оставляет желать. Очень хотелось попробовать дообученные модели с ресурса huggingface.

Нашёл другой путь - faster-whisper. Там есть утилитка для конвертации whisper-моделей:

$ ct2-transformers-converter --model mitchelldehaven/whisper-medium-ru --output_dir mitchelldehaven/whisper-medium-ru --quantization int8

Перепробовал всё, что нашёл. Печалька:

from faster_whisper import WhisperModel

# artyomboyko/whisper-small-ru-v2 - ошибки, но с пунктуацией
# artyomboyko/whisper-base-fine_tuned-ru - ошибки, но с пунктуацией
# mitchelldehaven/whisper-medium-ru - лучший результат, без пунктуации
# mitchelldehaven/whisper-large-v2-ru - медленно и ошибки, без пунктуации
# lorenzoncina/whisper-small-ru - ошибки, но с пунктуацией
# lorenzoncina/whisper-medium-ru - ошибки, но с пунктуацией
# AlanRobotics/whisper-tiny-ru ??
# gggggggg123/whisper-small-ru-golos ??
# sanchit-gandhi/whisper-small-ru-1k-steps - ошибки, но с пунктуацией
# Kolbaster/whisper-medium-ru ??
# Shirali/whisper-small-ru - ошибки, но с пунктуацией
# erlandekh/whisper-small-russian - ошибки, но с пунктуацией

model_size = "mitchelldehaven/whisper-medium-ru"

model = WhisperModel(model_size, device="cpu", compute_type="int8") # cpu_threads=10, 

segments, info = model.transcribe(
    "audio.wav",
    language="ru",
    beam_size=5,
    # beam_size=1,
    # temperature=0,
    # suppress_tokens=None,
)

print("Detected language '%s' with probability %f" % (info.language, info.language_probability))

for segment in segments:
    print("[%.2fs -> %.2fs] %s" % (segment.start, segment.end, segment.text))

Что ещё можно сделать? Научиться тюнить самому. Прикрутить GOLOS и SILERO.

https://huggingface.co/blog/fine-tune-whisper

Зарегистрируйтесь на Хабре , чтобы оставить комментарий