Whisper で日本語のリアルタイム文字起こし
February 05, 2023
今回は、最近 ChatGPT でも話題になっている OpenAI が発表した自動音声認識(ASR)システムである Whisper を C/C++ で動かせるようにした whisper.cpp をご紹介します。
先日、会社で whisper 論文の内容を発表した 際にデモをしたので、その際の作業の覚え書きの意味合いもあります。
whisper.cpp は以下のようなケースで、利用が適するツールです。
- 最近の文字書き起こしディープラーニングモデルを使って、音声データから文字起こししたい
- オープンソースのツールを使いたい
- できるだけ高速なものが良い
- WASM や Raspberry Pi(ラズパイ)のようなマイコンで動かしたい
whisper と同じように whisper.cpp も MIT ライセンスです。
Whisper とは
本記事で、詳細な説明は省きますが、ざっくり下記のような特徴があります。
- ウェブから収集した68万時間に及ぶ多言語・マルチタスク教師付きデータで学習させた自動音声認識(ASR)システム
- 大規模で多様なデータセットを使用することで、アクセント、背景雑音、専門用語に対する耐性が向上
- 多言語での書き起こしや、多言語から英語への翻訳も可能
- 有用なアプリケーションの構築や、ロバストな音声処理に関するさらなる研究のための基礎として、モデルと推論コードをオープンソースで公開
- 音声認識において人間レベルの頑健性 (robustness) と精度に迫る
- 日本語にも対応し、英語に対する性能と同程度
詳細は こちら (会社でやった論文輪読の発表資料) を参照下さい。
手順
手順は repository の README を見るだけですが、本記事では、Apple Silicon Mac 上でリアルタイム音声認識を動かすための手順にフォーカスして説明します。
rosseta で動かしているために、うまく make できない問題
Apple Silicon Mac (arm64 cpu) でやった時にいくつか気をつけた方が良いポイントを記しておきます。
rosetta (x86_64 向けのアプリを動かすためのエミュレータ) を使っている場合、コンパイルされた whisper.cpp 実行ファイルのパフォーマンスが著しく悪くなるため、rosetta はオフにしてコンパイルしましょう。
参考: https://github.com/ggerganov/whisper.cpp/issues/66
rosetta 環境にいるかどうかは、下記のように確認できます。
rosetta 環境の場合
$ uname -mpsDarwin x86_64 i386
rosetta を利用していない場合
$ uname -mpsDarwin arm64 arm
rosseta を使わないように terminal アプリを設定する方法は、下記の記事が参考になります。
参考: M1 MacでARMとIntelのターミナルを切り替えて使う (Homebrew 3以降の場合) - Qiita
要点としては、
- finder でターミナル (or iTerm) を右クリック
- 情報を見る
- 「Rosetta を使用して開く」を uncheck
リアルタイム音声認識
以下で、ス トリーム処理に必要なライブラリ (sdl2) をインストールします。
# install sdl2 (Mac OS)$ brew install sdl2
以下のようにモデルファイル (models/ggml-base.bin) をダウンロードするためのスクリプトを動かします。
日本語の音声認識をするためには、multi-language モデルを利用する必要があります (英語オンリーの base.en のように .en が付いていないモデル)。
# download a model if you don't have one$ bash ./models/download-ggml-model.sh base
リアルタイム音声認識の実行ファイルをコンパイルします。
# run the real-time audio transcription$ make stream
以下のように実行することで、日本語の音声認識を開始することができます。
$ ./stream -l ja -t 4 -m models/ggml-small.bin -f output.txt
./stream
: コンパイル (make stream
) により作成される実行ファイル-l
: 言語を指定 (上記例では日本語ja
を指定)-m
: モデルを指定 (上記例ではsmall
を指定)-f
: 音声認識の結果を出力するファイルを指定-t
: 使用するスレッド数
終了する際は ctrl + c
です。
参考: https://github.com/ggerganov/whisper.cpp/issues/10#issuecomment-1264665959
モデルサイズが大きいほど認識精度が高いですが、推論速度が遅くなってしまい、話者が話すスピードに追いつかないため結果も正確ではなくなってしまいます。 従って、実行環境に合わせてリアルタイム音声認識に最適なモデルとスレッド数を選択、調整する必要があります。
ベンチマークの実行
利用している実行環境における性能を計測することができます。
ビルド
$ make bench
ベンチマークの実行
$ ./bench -t 4 -m models/ggml-small.bin
-t
: 使用するスレッド数
結果の encode time
を見ることで、推論に要する時間の計測結果がわかります。
様々な実行環境におけるベンチマーク結果は、以下の github issue で共有されています。
Benchmark results: https://github.com/ggerganov/whisper.cpp/issues/89
音声ファイルから音声認識
リアルタイム音声認識ではない、通常のファイルから解析する場合の手順も記載しておきます。
入力ファイルの準備
入力とする音声ファイルは、現状 16 bit の wav ファイルのみ対応しているため、ffmpeg で下記のように変換します。
以下の例では、m4a から変換しています。
$ ffmpeg -i input.m4a -ar 16000 -ac 1 -c:a pcm_s16le input.wav
ビルド
# build the main examplemake
実行
./main -l ja -m models/ggml-large.bin -f input.wav -otxt
-otxt
: 結果をファイルに出力します (上記例では、input.wav.txt
に結果が出力されます)
最後に
- リアルタイム音声認識の場合、私の環境だと、medium モデルでも話すスピードに追いついていない印象がありました。base にすれば推論速度が上がりますが、精度も下がってしまうので、難しいです。精度が欲しい場合は、録音しておいて、後から large モデルに解析させるのが良さそうです。
- Mozilla Common Voice にある日本語音声データを入力として試してみましたが、large model で非常に正確に音声認識できていることを確認しました。