20
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【CPU上の実行に対応】OpenAI Whisperの高性能推論ver Whisper.cppを試してみた

Last updated at Posted at 2022-11-08

まえがき

OpenAI Whisperの高性能推論verが話題となっていたので試してみました。
C/C++で実装され、CPUの実行に最適化されたものとなっているようです。
特徴としては以下が挙げられていました。

  • 依存性のないプレーンなC/C++による実装
  • x86 アーキテクチャの AVX 組み込み関数のサポート
  • POWER アーキテクチャの VSX 組み込み関数のサポート
  • F16 / F32 の混合精度
  • 低メモリ使用量
  • CPU上で実行
  • Windows / Linux / Mac OS / iOS / Android / WebAssembly / Raspberry Piのプラットフォームに対応

導入

  • ソースコードをローカルへクローンする
$ git clone https://github.com/ggerganov/whisper.cpp.git
  • 使用するモデルをダウンロードする
$ bash ./models/download-ggml-model.sh <Model>
Downloading ggml model small ...
ggml-small.bin                                             
 100%[====================================================================>] 465.01M  2.84MB/s 時間 1m 58s   
Done! Model 'small' saved in 'models/ggml-small.bin'
You can now use it like this:

   ./main -m models/ggml-small.bin -f samples/jfk.wav
  • 対象モデルは以下となります。
Model Disk Mem
tiny 75 MB ~390 MB
tiny.en 75 MB ~390 MB
base 142 MB ~500 MB
base.en 142 MB ~500 MB
small 466 MB ~1.0 GB
small.en 466 MB ~1.0 GB
medium 1.5 GB ~2.6 GB
medium.en 1.5 GB ~2.6 GB
large 2.9 GB ~4.7 GB

OpenAIのWhisperでは、VRAMの使用量について言及されていましたが、Whisper.cppではVRAMの記述はありません。

  • makeコマンドを実行するためインストールされていない場合は、以下をインストールする
$ yum install make -y
$ yum install gcc -y
$ yum install gcc-c++ -y
  • Whisper.cppをクローンしたディレクトリでmakeコマンド実行
$ make
g++ -I. -I./examples -O3 -std=c++11 -pthread -c whisper.cpp -o whisper.o
g++ -I. -I./examples -O3 -std=c++11 -pthread examples/main/main.cpp whisper.o ggml.o -o main 
./main -h

usage: ./main [options] file0.wav file1.wav ...

options:
  -h,       --help           show this help message and exit
  -s SEED,  --seed SEED      RNG seed (default: -1)
  -t N,     --threads N      number of threads to use during computation (default: 4)
  -p N,     --processors N   number of processors to use during computation (default: 1)
  -ot N,    --offset-t N     time offset in milliseconds (default: 0)
  -on N,    --offset-n N     segment index offset (default: 0)
  -d  N,    --duration N     duration of audio to process in milliseconds (default: 0)
  -mc N,    --max-context N  maximum number of text context tokens to store (default: max)
  -ml N,    --max-len N      maximum segment length in characters (default: 0)
  -wt N,    --word-thold N   word timestamp probability threshold (default: 0.010000)
  -v,       --verbose        verbose output
            --translate      translate from source language to english
  -otxt,    --output-txt     output result in a text file
  -ovtt,    --output-vtt     output result in a vtt file
  -osrt,    --output-srt     output result in a srt file
  -owts,    --output-words   output script for generating karaoke video
  -ps,      --print_special  print special tokens
  -pc,      --print_colors   print colors
  -nt,      --no_timestamps  do not print timestamps
  -l LANG,  --language LANG  spoken language (default: en)
  -m FNAME, --model FNAME    model path (default: models/ggml-base.en.bin)
  -f FNAME, --file FNAME     input WAV file path
  • その後、以下コマンドを実行し、Whisper.cppを動かそうとすると以下エラーが表示される。

OpenAIのWhisperはm4aなど他のファイルにも対応していたが、Whisper.cppは16kHzのWAVファイルにのみ対応しているとのこと。
そのため、ffmpegを利用して音声データをWAVファイルに変換する。

$ ./main -m models/ggml-small.bin -f output.wav -l ja -ovtt
./main: WAV file 'audio.wav' must be 16 kHz
  • 以下コマンドを実施しffmpegをインストールする。(CentOS8例)
dnf install https://download.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
dnf localinstall --nogpgcheck https://download1.rpmfusion.org/free/el/rpmfusion-free-release-8.noarch.rpm
dnf install https://rpmfind.net/linux/epel/7/x86_64/Packages/s/SDL2-2.0.14-2.el7.x86_64.rpm
dnf -y install ffmpeg
  • ffmpegにより16kHzのWAVファイルに変換する。
ffmpeg -i audio.m4a -ar 16000 -ac 1 -c:a pcm_s16le output.wav
ffmpeg version 4.2.8 Copyright (c) 2000-2022 the FFmpeg developers
  built with gcc 8 (GCC)
  configuration: --prefix=/usr --bindir=/usr/bin --datadir=/usr/share/ffmpeg --docdir=/usr/share/doc/ffmpeg --incdir=/usr/include/ffmpeg --libdir=/usr/lib64 --mandir=/usr/share/man --arch=x86_64 --optflags='-O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection' --extra-ldflags='-Wl,-z,relro -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld ' --extra-cflags=' ' --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libvo-amrwbenc --enable-version3 --enable-bzlib --disable-crystalhd --enable-fontconfig --enable-frei0r --enable-gcrypt --enable-gnutls --enable-ladspa --enable-libaom --enable-libdav1d --enable-libass --enable-libbluray --enable-libcdio --enable-libdrm --enable-libjack --enable-libfreetype --enable-libfribidi --enable-libgsm --enable-libmp3lame --enable-nvenc --enable-openal --enable-opencl --enable-opengl --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-librsvg --enable-libsrt --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libvorbis --enable-libv4l2 --enable-libvidstab --enable-libvmaf --enable-version3 --enable-vapoursynth --enable-libvpx --enable-libx264 --enable-libx265 --enable-libxvid --enable-libzimg --enable-libzvbi --enable-avfilter --enable-avresample --enable-libmodplug --enable-postproc --enable-pthreads --disable-static --enable-shared --enable-gpl --disable-debug --disable-stripping --shlibdir=/usr/lib64 --enable-libmfx --enable-runtime-cpudetect
  libavutil      56. 31.100 / 56. 31.100
  libavcodec     58. 54.100 / 58. 54.100
  libavformat    58. 29.100 / 58. 29.100
  libavdevice    58.  8.100 / 58.  8.100
  libavfilter     7. 57.100 /  7. 57.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  5.100 /  5.  5.100
  libswresample   3.  5.100 /  3.  5.100
  libpostproc    55.  5.100 / 55.  5.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'audio.m4a':
  Metadata:
    major_brand     : M4A 
    minor_version   : 0
    compatible_brands: M4A mp42isom
  Duration: 00:00:25.22, start: 0.000000, bitrate: 127 kb/s
    Stream #0:0(und): Audio: aac (LC) (mp4a / 0x6134706D), 32000 Hz, mono, fltp, 126 kb/s (default)
Stream mapping:
  Stream #0:0 -> #0:0 (aac (native) -> pcm_s16le (native))
Press [q] to stop, [?] for help
Output #0, wav, to 'output.wav':
  Metadata:
    major_brand     : M4A 
    minor_version   : 0
    compatible_brands: M4A mp42isom
    ISFT            : Lavf58.29.100
    Stream #0:0(und): Audio: pcm_s16le ([1][0][0][0] / 0x0001), 16000 Hz, mono, s16, 256 kb/s (default)
    Metadata:
      encoder         : Lavc58.54.100 pcm_s16le
size=     788kB time=00:00:25.21 bitrate= 256.0kbits/s speed=1.22e+03x    
video:0kB audio:788kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.009666%

実行

オプション 内容
-m 利用モデル
-f インプットとなるWAVファイルのパス
-l 言語を指定する
-ovtt 結果をvttファイルで出力する
./main -m models/ggml-small.bin -f output.wav -l ja -ovtt
whisper_model_load: loading model from 'models/ggml-small.bin'
whisper_model_load: n_vocab       = 51865
whisper_model_load: n_audio_ctx   = 1500
whisper_model_load: n_audio_state = 768
whisper_model_load: n_audio_head  = 12
whisper_model_load: n_audio_layer = 12
whisper_model_load: n_text_ctx    = 448
whisper_model_load: n_text_state  = 768
whisper_model_load: n_text_head   = 12
whisper_model_load: n_text_layer  = 12
whisper_model_load: n_mels        = 80
whisper_model_load: f16           = 1
whisper_model_load: type          = 3
whisper_model_load: mem_required  = 1044.00 MB
whisper_model_load: adding 1608 extra tokens
whisper_model_load: ggml ctx size = 464.56 MB
whisper_model_load: memory size =    68.48 MB
whisper_model_load: model size  =   464.44 MB

system_info: n_threads = 4 / 4 | AVX2 = 1 | AVX512 = 0 | NEON = 0 | FP16_VA = 0 | WASM_SIMD = 0 | BLAS = 0 | 

main: processing 'output.wav' (403456 samples, 25.2 sec), 4 threads, 1 processors, lang = ja, task = transcribe, timestamps = 1 ...

実行結果

CPU、メモリを増設して検証してみました。(1時間分の音声データ)

増設前

  • Intel(R) Xeon(R) CPU E5-2667 4コア
  • RAM 8GB

この状態で実行したとき、処理完了まで33分かかりました。

増設後

  • Intel(R) Xeon(R) CPU E5-2667 8コア
  • RAM 16GB

この状態で実行したとき、処理完了まで26分かかりました。

総評

スケールアップをすることで、1時間当たりの音声データでVRAM非搭載サーバ上からの実行により7分の削減ができ、CPUの性能にwhisper.cppの動作が依存していると言えます。
また、OpenAI純正のWhisperで同環境で実行した際は、GPUを搭載していないため動作にかなりの時間がかかりましたので、GPU非搭載サーバ上で動作させる場合は、Whisper.cppの利用を推奨します。

参考

20
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?