[音声認識] wav2vecによるwav fileの認識サンプル

まずenglishのwave fileを用意します。

app.py

# -*- coding: utf-8 -*-
#! /usr/bin/python3

import librosa
import torch
from transformers import Wav2Vec2ForCTC, Wav2Vec2Tokenizer

audio, rate = librosa.load("sample.wav", sr = 16000)

tokenizer = Wav2Vec2Tokenizer.from_pretrained("facebook/wav2vec2-base-960h")
model = Wav2Vec2ForCTC.from_pretrained("facebook/wav2vec2-base-960h")

input_values = tokenizer(audio, return_tensors="pt").input_values

logits = model(input_values).logits

prediction = torch.argmax(logits, dim = -1)

transcription = tokenizer.batch_decode(prediction)[0]

print(transcription)

$ python3 app.py
// 省略
FOUR SCORE AND SEVEN YEARS AGO OUR FATHERS BROUGHT FORTH ON THIS CONTINENT A NEW NATION CONCEIVED IN LIBERTY AND DEDICATED TO THE PROPOSITION THAT ALL MEN ARE CREATED EQUAL

なるほど、これは凄い
tokenizerとmodelを日本語でやりたい

from asrecognition import ASREngine

asr = ASREngine("ja", model_path="jonatasgrosman/wav2vec2-large-xlsr-53-japanese")

audio_paths = ["itou.wav"]
transcriptions = asr.transcribe(audio_paths)

$ python3 app.py
/home/vagrant/.local/lib/python3.8/site-packages/transformers/configuration_utils.py:340: UserWarning: Passing `gradient_checkpointing` to a config initialization is deprecated and will be removed in v5 Transformers. Using `model.gradient_checkpointing_enable()` instead, or if you are using the `Trainer` API, pass `gradient_checkpointing=True` in your `TrainingArguments`.
warnings.warn(
Killed

うむ、うまくいかないが近づいている様な気がする
vagrantだとうまくいかないので、vpsでやることにした

micによるliveだと、こちらで出来ますね
https://github.com/oliverguhr/wav2vec2-live

[音声認識] wav2vecを使いたい

最近のトレンドはtransformarを用いた自然言語処理とのことで、wav2vecを使いたい

### ライブラリのinstall
$ pip3 install transformers datasets librosa

main.py

# -*- coding: utf-8 -*-
#! /usr/bin/python3

import librosa
import matplotlib.pyplot as plt
from IPython.display import display, Audio
import librosa.display
import numpy as np 

import torch
from transformers import Wav2Vec2Processor, Wav2Vec2ForCTC
from datasets import load_dataset
import soundfile as sf

processor = Wav2Vec2Processor.from_pretrained("facebook/wav2vec2-base-960h")
model = Wav2Vec2ForCTC.from_pretrained("facebook/wav2vec2-base-960h")

def map_to_array(batch):
	speech, sr_db = sf.read(batch["file"])
	batch["speech"] = speech
	batch['sr_db'] = sr_db
	return batch

ds = load_dataset("patrickvonplaten/librispeech_asr_dummy","clean",split="validation")
ds = ds.map(map_to_array)

librosa.display.waveplot(np.array(ds['speech'][0]), sr=ds['sr_db'][0])
plt.savefig('01')
display(Audio(np.array(ds['speech'][0]), rate=ds['sr_db'][0]))

input_values = processor(ds["speech"][0], return_tensors="pt").input_values
logits = model(input_values).logits
predicted_ids = torch.argmax(logits, dim=-1)

transcription = processor.decode(predicted_ids[0])

print(transcription)

$ python3 main.py
// 省略
A MAN SAID TO THE UNIVERSE SIR I EXIST

なんだこれええええええええええええええええええ
音声をvector graphicにしてるのはわかるが、、、

[RaspberryPI4] DeepSpeechをmicで動かす

### ラズパイのUBSマイクの設定
$ sudo vim /etc/modprobe.d/alsa-base.conf

options snd slots=snd_usb_audio,snd_bcm2835
options snd_usb_audio index=0
options snd_bcm2835 index=1
$ sudo vim ~/.profile
一番最後の行に追加
export ALSADEV=”plughw:0,0″

$ sudo apt-get install alsa-utils sox libsox-fmt-all
$ sudo sh -c “echo snd-pcm >> /etc/modules”

ラズパイ再起動

### マイクから音声認識
$ source dev/deepspeech-train-venv/bin/activate
$ cd deepspeech
$ git clone https://github.com/mozilla/DeepSpeech-examples
$ cd DeepSpeech-examples/DeepSpeech-examples
$ pip install -r requirements.txt
$ sudo apt install portaudio19-dev
$ pip3 install halo webrtcvad –upgrade
$ python3 DeepSpeech-examples/mic_vad_streaming/mic_vad_streaming.py -m deepspeech-0.7.1-models.tflite -s deepspeech-0.7.1-models.scorer

こんな感じになる
Listening (ctrl-C to exit)…
Recognized:
Recognized:
Recognized:
Recognized: you
Recognized:
Recognized: night

きたあああああああああああああああああああああ
さあ サーバーサイドやろう
とりあえず満足

https://github.com/mozilla/DeepSpeech-examples/blob/r0.9/mic_vad_streaming/mic_vad_streaming.py
line188行目でtextをrecognized:としているので、ここでテキストとして保存すれば良い

        else:
            if spinner: spinner.stop()
            logging.debug("end utterence")
            if ARGS.savewav:
                vad_audio.write_wav(os.path.join(ARGS.savewav, datetime.now().strftime("savewav_%Y-%m-%d_%H-%M-%S_%f.wav")), wav_data)
                wav_data = bytearray()
            text = stream_context.finishStream()
            print("Recognized: %s" % text)
            stream_context = model.createStream()

[RaspberryPI4]DeepSpeechを動かしたい

まずラズパイ4とモニターを秋葉原で購入して起動
キーボードから日本語入力ができるように設定

$ mkdir dev
$ cd dev
$ python3 -m venv deepspeech-train-venv
$ source dev/deepspeech-train-venv/bin/activate
$ mkdir deepspeech
$ cd deepspeech
$ pip install deepspeech

$ curl -LO https://github.com/mozilla/STT/releases/download/v0.7.1/deepspeech-0.7.1-models.tflite
$ curl -LO https://github.com/mozilla/STT/releases/download/v0.7.1/deepspeech-0.7.1-models.pbmm
$ curl -LO https://github.com/mozilla/STT/releases/download/v0.7.1/deepspeech-0.7.1-models.scorer

$ curl -LO https://github.com/mozilla/STT/releases/download/v0.7.1/audio-0.7.1.tar.gz
$ tar xvf audio-0.7.1.tar.gz

$ deepspeech –model deepspeech-0.7.*-models.tflite –scorer deepspeech-0.7.*-models.scorer –audio audio/2830-3980-0043.wav
Loading model from file deepspeech-0.7.1-models.tflite
TensorFlow: v2.3.0-6-g23ad988
DeepSpeech: v0.9.3-0-gf2e9c85
Loaded model in 0.00285s.
Loading scorer from files deepspeech-0.7.1-models.scorer
Loaded scorer in 0.00296s.
Running inference.
experience proves this
Inference took 1.546s for 1.975s audio file.

venvを使わないと以下のようなエラーになるので注意が必要
The script deepspeech is installed in ‘/home/pi/.local/bin’ which is not on PATH.
Consider adding this directory to PATH or, if you prefer to suppress this warning, use –no-warn-script-location.

OK 続いてdeeepspeechをmicでやりたい

[音声認識] Juliusで独自辞書を作成

辞書ファイルを作成するには、「語彙」「音素」「構文」が必要

語彙: Juliusに認識させたい単語を定義
音素: 語彙の読みを定義
構文: 認識する文章の構成を定義

### 読みファイルの作成
/julius/dict/greeting.yomi
L 平仮名で作成

おはよう	おはよう
ございます ございます
こんにちは こんにちわ
こんばんは こんばんわ

### 音素ファイルの作成
$ iconv -f utf8 -t eucjp dict/greeting.yomi | gramtools/yomi2voca/yomi2voca.pl | iconv -f eucjp -t utf8 > dict/greeting.phone

perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
LANGUAGE = (unset),
LC_ALL = (unset),
LANG = “ja_JP.UTF-8”
are supported and installed on your system.
perl: warning: Falling back to the standard locale (“C”).

どうやらjuliusはeucではなくutf8になってるらしい

$ iconv dict/greeting.yomi | gramtools/yomi2voca/yomi2voca.pl > dict/greeting.phone

/julius/dict/greeting.phone

おはよう	o h a y o u
ございます	g o z a i m a s u
こんにちは	k o N n i ch i w a
こんばんは	k o N b a N w a

### 構文ファイルの作成
greeting.grammar
L NS_Bが文書の開始、NS_Eが文章の終了 2行目以降がGREETで認識される読みの文字列

S : NS_B GREET NS_E
GREET : OHAYOU
GREET : OHAYOU GOZAIMASU
GREET : KONNICHIWA
GREET : KONBANWA

### 語彙ファイルの作成
各音素に対して、構文で割り振った読みと、開始終了を表すNS_B、NS_Eを設定

% OHAYOU
おはよう	o h a y o u
% GOZAIMASU
ございます	g o z a i m a s u
% KONNICHIWA
こんにちは	k o N n i ch i w a
% KONBANWA
こんばんは	k o N b a N w a
% NS_B
s		silB
% NS_E
/s	silE

辞書ファイルを作成する
$ cp -b gramtools/mkdfa/mkfa-1.44-flex/mkfa gramtools/mkdfa/mkfa
$ cp -b gramtools/dfa_minimize/dfa_minimize gramtools/mkdfa/dfa_minimize
$ cp -b gramtools/dfa_determinize/dfa_determinize gramtools/mkdfa/dfa_determinize

$ gramtools/mkdfa/mkdfa.pl dict/greeting
// 省略
now reversing dict/greeting.dfa into NFA “dict/greeting.dfa.forward_nfa”
executing [gramtools/mkdfa/dfa_determinize dict/greeting.dfa.forward_nfa -o dict/greeting.dfa.forward_beforeminimize]
6 categories, 6 nodes, 7 arcs
-> determinized: 5 nodes, 7 arcs
executing [gramtools/mkdfa/dfa_minimize dict/greeting.dfa.forward_beforeminimize -o dict/greeting.dfa.forward]
6 categories, 5 nodes, 7 arcs
-> minimized: 5 nodes, 7 arcs

generated: dict/greeting.dfa dict/greeting.term dict/greeting.dict dict/greeting.dfa.forward

### 辞書を指定
$ julius/julius -C ../ja_model/am-gmm.jconf -nostrip -gram dict/greeting -input mic

なるほど、辞書の作り方はOK
次はGoやな

[音声認識] RaspberryPI 4(model B)でJuliusを動かす

音声認識をwavファイルではなく、ラズパイでやります。

### 前準備
– ラズパイ4 model B (秋葉原で電源、microSDなどセットで1万くらい)
– モニター、キーボード, マウス(メルカリでセットで3500円くらい)
– USBマイク(amazonで300円くらい)
※初期設定でwifiの設定とキーボードをJapaneseにする必要がある

$ mkdir julius
$ cd julius
$ wget https://github.com/julius-speech/julius/archive/v4.4.2.1.tar.gz
$ tar xvzf v4.4.2.1.tar.gz
$ cd julius-4.4.2.1
$ sudo apt-get install libasound2-dev libesd0-dev libsndfile1
※libsndfile1-devはRaspberryPI 4ではinstallできなかった
$ ./configure –with-mictype=alsa
$ make
$ sudo make install

$ cd ../
$ mkdir julius-kit
$ cd julius-kit
$ wget https://osdn.net/dl/julius/dictation-kit-v4.4.zip
$ unzip dictation-kit-v4.4.zip

$ sudo vim /etc/modprobe.d/alsa-base.conf

options snd slots=snd_usb_audio,snd_bcm2835
options snd_usb_audio index=0
options snd_bcm2835 index=1

$ sudo vim ~/.profile
一番最後の行に追加

export ALSADEV="plughw:0,0"

$ sudo apt-get install alsa-utils sox libsox-fmt-all
$ sudo sh -c “echo snd-pcm >> /etc/modules”

ラズパイ再起動

$ cd ~/julius/julius-kit/dicration-kit-v4.4/
$ julius -C main.jconf -C am-gmm.jconf -demo

AWSにjsonを送信したい
-> S3に保存すれば良いのかな
そこさえできれば、ほぼ基本的な挙動は完成

[音声認識] DeepSpeechで中国語の音声認識を行う

まず中国語の音声ファイルを用意します

続いてDeepspeechの中国語モデルをDLします。
deepspeech-0.9.3-models-zh-CN.pbmm
deepspeech-0.9.3-models-zh-CN.scorer

実行は、Englishと同様
$ source deepspeech-venv/bin/activate
$ deepspeech –model deepspeech-0.9.3-models-zh-CN.pbmm –scorer deepspeech-0.9.3-models-zh-CN.scorer –audio audio/zh_test.wav
Loading model from file deepspeech-0.9.3-models-zh-CN.pbmm
TensorFlow: v2.3.0-6-g23ad988
DeepSpeech: v0.9.3-0-gf2e9c85
2021-09-04 02:47:32.705419: I tensorflow/core/platform/cpu_feature_guard.cc:142] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN)to use the following CPU instructions in performance-critical operations: AVX2
To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
Loaded model in 0.0436s.
Loading scorer from files deepspeech-0.9.3-models-zh-CN.scorer
Loaded scorer in 0.00114s.
Running inference.
同的祖母是一位佛教徒但他从二没有在未向前年国佛经有一天他前我是菜里杨聪认我在我一八年气派来结果动的管领流泪总合了他说乔丽多难受到这一个密绝大这么起就有机
Inference took 12.015s for 25.003s audio file.

ほう、何でもできるような気がしてきた。
まあ設計次第かな。

[音声認識] DeepSpeechでvideoのAutoSub(srtファイル)作成

– AutoSub is a CLI application to generate subtile file for any video using DeepSpeech.

### install
$ git clone https://github.com/abhirooptalasila/AutoSub
$ cd AutoSub

### virtual env
$ python3 -m venv sub
$ source sub/bin/activate
$ pip3 install -r requirements.txt
requirementsの中身は以下の通りです。

cycler==0.10.0
numpy
deepspeech==0.9.3
joblib==0.16.0
kiwisolver==1.2.0
pydub==0.23.1
pyparsing==2.4.7
python-dateutil==2.8.1
scikit-learn
scipy==1.4.1
six==1.15.0
tqdm==4.44.1

$ deactivate

### download model & scorer
$ wget https://github.com/mozilla/DeepSpeech/releases/download/v0.9.3/deepspeech-0.9.3-models.pbmm
$ wget https://github.com/mozilla/DeepSpeech/releases/download/v0.9.3/deepspeech-0.9.3-models.scorer
$ mkdir audio output

$ sudo apt-get install ffmpeg
$ ffmpeg -version
ffmpeg version 4.2.4-1ubuntu0.1

今回はyoutubeの動画を使います

これを mp4に変換します。

$ python3 autosub/main.py –file hello.mp4
※main.pyで、modelとscorerのファイルを取得しているため、–model /home/AutoSub/deepspeech-0.9.3-models.pbmm –scorer /home/AutoSub/deepspeech-0.9.3-models.scorerは不要です。

for x in os.listdir():
        if x.endswith(".pbmm"):
            print("Model: ", os.path.join(os.getcwd(), x))
            ds_model = os.path.join(os.getcwd(), x)
        if x.endswith(".scorer"):
            print("Scorer: ", os.path.join(os.getcwd(), x))
            ds_scorer = os.path.join(os.getcwd(), x)

output/hello.srt

1
00:00:06,70 --> 00:00:15,60
a low and low and level how are you have low low and low how are you

2
00:00:16,10 --> 00:00:30,20
i do i am great i wonder for a good i grant it wonder for

3
00:00:32,45 --> 00:00:41,30
now at low halloway hallo hallo hallo how are you

4
00:00:41,90 --> 00:00:43,40
tired

5
00:00:43,55 --> 00:00:50,35
i am angry i'm not so good i'm tired

6
00:00:50,55 --> 00:00:55,95
i'm hungry and not so good

7
00:00:58,10 --> 00:01:07,15
love hollow hollow how are you have to have loved halloo are you

8
00:01:07,30 --> 00:01:16,65
how how low how do how are you allow a love as now how are you

これ、日本語でやりたい & リアルタイム出力したい

[音声認識] Juliusのdictation-kit(日本語のGMM-HMMモデル)で検収

まず.wavファイルの音源を用意します。

「お疲れ様でした」という女性の声が入っています。

これをJuliusで音声認識します。
日本語のモデルはDictation-kitを使います。
https://github.com/julius-speech/dictation-kit
-> Githubのdictation-kitはトータルサイズが2Gで重いのでwgetでダウンロードしてunzipする方を使いたいと思います。

※dictation-kitをgit cloneする時
git-lfsを使うよう指示されます。
$ sudo yum install git-lfs
$ git lfs clone https://github.com/julius-speech/dictation-kit.git
no space left on device
$ df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 2.0G 0 2.0G 0% /dev
tmpfs 2.0G 0 2.0G 0% /dev/shm
tmpfs 2.0G 520K 2.0G 1% /run
tmpfs 2.0G 0 2.0G 0% /sys/fs/cgroup
/dev/sda1 25G 25G 0 100% /
tmpfs 395M 0 395M 0% /run/user/1000
vagrant 234G 186G 49G 80% /vagrant
tmpfs 395M 0 395M 0% /run/user/0
これだと、直ぐにリソースが一杯になってしまい、使い切っていたのでframework系のファイル群を削除します😅

$ wget https://osdn.net/dl/julius/dictation-kit-4.5.zip
$ unzip ./dictation-kit-4.5.zip
$ cd dictation-kit-4.5

### 日本語のGMM-HMMモデルでJuliusを起動
am-dnn.jconf
L inputがmicになっているので、fileに変更します。

-input file

$ ../julius/julius/julius -C main.jconf -C am-gmm.jconf -nostrip -input rawfile
enter filename->test.wav
——
### read waveform input
enter filename->test2.wav
Stat: adin_file: input speechfile: test2.wav
STAT: 53499 samples (3.34 sec.)
STAT: ### speech analysis (waveform -> MFCC)
### Recognition: 1st pass (LR beam)
……………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………..pass1_best: 別れ た 真似 し た 。
pass1_best_wordseq: 別れ+動詞 た+助動詞 真似+名詞 し+動詞 た+助動詞
pass1_best_phonemeseq: silB | w a k a r e | t a | m a n e | sh i | t a | silE
pass1_best_score: -7376.977051
### Recognition: 2nd pass (RL heuristic best-first)
STAT: 00 _default: 7136 generated, 1958 pushed, 182 nodes popped in 332
sentence1: 伴天連 様 でし た 。
wseq1: 伴天連+名詞 様+接尾辞 でし+助動詞 た+助動詞
phseq1: silB | b a t e r e N | s a m a | d e sh i | t a | silE
cmscore1: 0.477 0.083 0.314 0.446 0.411 1.000
score1: -7376.384766

——

おいおいオイ、「別れ た 真似 し た 。」になってるやんか。
いい加減にしろや✊ どうなってんねんコレ。

まあ、日本語モデルはdeepspeechとかには無いからjuliusでアプリ作るけどさ。

[音声認識] DeepSpeechでTranscriberを実装する

PyAudio has two modes: blocking, where data has to read from the stream; and non-blocking, where a callback function is passed to PyAudio for feeding the audio data stream.
DeepSpeech streaming APIを使う
audio機能を使うには、pyaudioをインストールする必要がある

$ sudo apt-get install portaudio19-dev
$ pip3 install pyaudio

# -*- coding: utf-8 -*-
#! /usr/bin/python3

import deepspeech
import wave
import numpy as np
import os
import pyaudio

model_file_path = 'deepspeech-0.9.3-models.pbmm'
model = deepspeech.Model(model_file_path)

context = model.createStream()

text_so_far = ''

def process_audio(in_data, frame_count, time_info, status):
	global text_so_far
	data16 = np.frombuffer(in_data, dtype=np.int16)
	model.feedAudioContent(context, data16)
	text = model.intermediateDecode(context)
	if text != text_so_far:
		print('Interim text = {}'.format(text))
		text_so_far = text
	return (in_data, pyaudio.paContinue)

audio = pyaudio.PyAudio()
stream = audio.open(
	format=pyaudio.paInt16,
	channels=1,
	rate=16000,
	input=True,
	frames_per_buffer=1024,
	stream_callback=process_audio
)
print('Please start speaking, when done press Ctr-c ...')
stream.start_stream()

try:
	while stream.is_active():
		time.sleep(0.1)
except KeyboardInterrupt:
	stream.stop_stream()
	stream.close()
	audio.terminate()
	print('Finished recording.')

	text = model.finishStream(context)
	print('Final text = {}'.format(text))

$ python3 transcribe.py
Traceback (most recent call last):
File “transcribe.py”, line 28, in
stream = audio.open(
File “/home/vagrant/deepspeech-venv/lib/python3.8/site-packages/pyaudio.py”, line 750, in open
stream = Stream(self, *args, **kwargs)
File “/home/vagrant/deepspeech-venv/lib/python3.8/site-packages/pyaudio.py”, line 441, in __init__
self._stream = pa.open(**arguments)
OSError: [Errno -9996] Invalid input device (no default output device)

vagrantだとテストできないな。。

>>> import pyaudio
>>> pa = pyaudio.PyAudio()
>>> pa.get_default_input_device_info()
OSError: No Default Input Device Available

結局ラズパイ環境を準備しないとダメか。。
DeepSpeechがかなり使えることはわかった。