Модель для Vosk

Начал осваивать библиотку Vosk по offline распознаванию речи и столкнулся со следующей проблемой: при запуске кода ниже выходит ошибка. Соответствующая модель установлена и находится в директории самого проекта. Часа два сижу, не понимаю, в чём проблема. Как это исправить?

Ошибка:

LOG(VoskAPI: ReadDataFiles():model.cc: 196) Decoding params beam = 10 max - active = 3000 lattice - beam = 2
LOG(VoskAPI: ReadDataFiles():model.cc: 199) Silence phones 1:2:3:4:5:6:7:8:9:10
LOG(VoskAPI: RemoveOrphanNodes():nnet - nnet.cc: 948) Removed 0 orphan nodes.
LOG(VoskAPI: RemoveOrphanComponents():nnet - nnet.cc: 847) Removing 0 orphan components.
LOG(VoskAPI: CompileLooped():nnet - compile - looped.cc: 345) Spent 0.153587 seconds in looped compilation.
LOG(VoskAPI: ReadDataFiles():model.cc: 223) Loading i - vector extractor from C:\lm8p\LM8P dead version\models\vosk - model - small - ru - 0.15 / ivector / final.ie
LOG(VoskAPI: ComputeDerivedVars():ivector - extractor.cc: 183) Computing derived variables for iVector extractor
LOG(VoskAPI: ComputeDerivedVars():ivector - extractor.cc: 204) Done.
LOG(VoskAPI: ReadDataFiles():model.cc: 258) Loading HCL and G from C:\lm8p\LM8P deadversion\models\vosk - model - small - ru - 0.15 / graph / HCLr.fst C:\lm8p\LM8P dead version\models\vosk - model - small - ru - 0.15 / graph / Gr.fst
LOG(VoskAPI: ReadDataFiles():model.cc: 282) Loading winfo C:\lm8p\LM8P deadversion\models\vosk - model - small - ru - 0.15 / graph / phones / word_boundary.int
ERROR(VoskAPI: MaybeCreateResampler():online - feature.cc: 99) Sampling frequency mismatch, expected 16000, got 8000
Perhaps you want to use the options - -allow_ {upsample, downsample}
terminate called after throwing an instance of 'kaldi::KaldiFatalError'
what(): kaldi::KaldiFatalError

Код:

from vosk import Model, KaldiRecognizer
import pyaudio

model = Model(r"C:\lm8p\LM8P dead version\models\vosk-model-small-ru-0.15")  # полный путь к модели
rec = KaldiRecognizer(model, 8000)
p = pyaudio.PyAudio()
stream = p.open(
    format=pyaudio.paInt16,
    channels=1,
    rate=8000,
    input=True,
    frames_per_buffer=8000
)
stream.start_stream()

while True:
    data = stream.read(4000)
    if len(data) == 0:
        break

    print(rec.Result() if rec.AcceptWaveform(data) else rec.PartialResult())

print(rec.FinalResult())

Ответы (1 шт):

Автор решения: XurRound

Не знаю, как работать с pyaudio, сам только начал разбираться. Но через sounddevice всё делается очень просто.

import sounddevice as sd
import vosk, queue, json

q = queue.Queue()

devices = sd.query_devices()
print("Select device id: \n", devices)

dev_id = 0 # default

try:
    dev_id = int(input())
except ValueError:
    print("Using default value: 0")

samplerate = int(sd.query_devices(dev_id, 'input')['default_samplerate'])

try:
    model = vosk.Model("model")
    with sd.RawInputStream(samplerate=samplerate, blocksize=8000, device=dev_id, dtype='int16', channels=1, callback=(lambda i, f, t, s: q.put(bytes(i)))):
        rec = vosk.KaldiRecognizer(model, samplerate)
        while True:
            data = q.get()
            if rec.AcceptWaveform(data):
                data = json.loads(rec.Result())["text"]
                print("Recognized: " + data)
            else:
                data = json.loads(rec.PartialResult())["partial"]
                if data != "":
                    print(data)
except KeyboardInterrupt:
    print('\nDone')

У вас ошибка в том, что заданный samplerate (8000) не соответствует, тому, с которым работает устройство (16000): Sampling frequency mismatch, expected 16000, got 8000. Можно попробовать просто заменить samplerate с 8000 на 16000:

rec = KaldiRecognizer(model, 16000)
stream = p.open(
    format=pyaudio.paInt16,
    channels=1,
    rate=16000,
    input=True,
    frames_per_buffer=8000
)
→ Ссылка