様々なAI関連のサービスが増えたが、情報漏洩などのセキュリティリスクの問題から会社の稟議が通らないなど、サービスを使用できない事もある。しかしHugging Faceには既に様々なモデルやデータセットが公開されているため、ローカルで動作する自分用のツールを開発する事もそれ程難しくはないはずだ。元々は日本語話者同士の会議の議事録を取る事を目的としていて、マイク音声とデスクトップ音声の両方をFFmpegを用いてオーディオファイルに出力できるようになった。今回は、そのオーディオファイルから文字を起こせるかを試す事にする。
まずオーディオデータを作成する。オーディオデータの元のデータは、適当に拾ってきた動画ファイル(mp4)とする。この動画ファイルを、ffmpegを使って音声のみのwavファイルに変換する。
ffmpeg -i DUMMY.mp4 -ac 1 -ar 16000 output.wav
変換に成功すると output.wav
が作成される。この output.wav
を読み込ませる。
Pythonを起動し、=soundfile= モジュールを使ってオーディオファイルを読み込む。これはオーディオファイルのファイルパスを引数に受け取り、音声データをnumpy.ndarrayに変換したものと、サンプルレートを返す。
import soundfile
speech, rate = soundfile.read("output.wav")
プロセッサを読み込む。
import transformers
processor = transformers.Speech2Text2Processor.from_pretrained("facebook/s2t-wav2vec2-large-en-de")
このプロセッサを用いて入力可能なデータに変換する。このプロセッサはサンプリングレートを16000で学習させたらしく、 sampling_rate=16000
を指定する必要がある。因みに英語からドイツ語用らしい。微妙に間違えた。
inputs = processor(speech, sampling_rate=16000, return_tensors="pt")
メモリが足りないと、ここで死ぬ。メモリ16GBの型落ちMac Book Proだと、OOM KillerによってPythonプロセスを強制的に停止させられた。
Process Python killed: 9
よく考えると、オーディオファイルのデータが大きすぎる。20分ぐらいある音声ファイルの全体を食わせている。それはメモリ足りないかも。小さく区切ってデータを食わしてみる。
どの程度で区切ればいいか分からないため、とりあえず先頭から10秒で区切ってみる。
data = speech[0:10*16000]
inputs = processor(data, sampling_rate=16000, return_tensors="pt")
モデルを読み込む。
model = transformers.SpeechEncoderDecoderModel.from_pretrained("facebook/s2t-wav2vec2-large-en-de")
入力用のデータをモデルに食わせて、結果を取得する。
generated_ids = model.generate(inputs=inputs["input_values"], attention_mask=inputs["attention_mask"])
結果をデコードする。
decoded_text = processor.batch_decode(generated_ids)[0]
print(decoded_text)
これらのコードを main.py
に記述し実行する。
python main.py
</s> Ich werde darüber sprechen, was ich in Kanu, Mexiko, sehen würde. </s>
いくつかワーニング等が出力されるかもしれないが、一応結果が取得できる所まで確認できた。