ハカセノオト

moon indicating dark mode
sun indicating light mode

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 -mps
Darwin x86_64 i386

rosetta を利用していない場合

$ uname -mps
Darwin 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 example
make

実行

./main -l ja -m models/ggml-large.bin -f input.wav -otxt
  • -otxt: 結果をファイルに出力します (上記例では、input.wav.txt に結果が出力されます)

最後に

  • リアルタイム音声認識の場合、私の環境だと、medium モデルでも話すスピードに追いついていない印象がありました。base にすれば推論速度が上がりますが、精度も下がってしまうので、難しいです。精度が欲しい場合は、録音しておいて、後から large モデルに解析させるのが良さそうです。
  • Mozilla Common Voice にある日本語音声データを入力として試してみましたが、large model で非常に正確に音声認識できていることを確認しました。

hnishi

hnishi のブログ

ソフトウェアエンジニアです。
誰かの役に立つかもしれないと思って、調べたこと、勉強したこと、躓いた箇所などを記事にしています。
問い合わせはこちらからお願いします。