背景

OpenAIがwhisperという音声認識&文字起こししてくれるアプリケーションを公開しました。

openai/whisper: Robust Speech Recognition via Large-Scale Weak Supervision

無料だし、なかなかいい感じという噂を聞いて試してみました。

環境はDockerで作る

Dockerで環境を構築しました。

CPUでも動くようですが、文字起こしのスピードが遅いとの記事を読みました。なので、GPUを使用する構成にしています。使用しているのは、GTX 1650のグラフィックメモリが4GBのものです。

ベースイメージのPyTorch(パイトーチって読むの?)は以下のNVIDIAページを参考にしました。

PyTorch Release Notes :: NVIDIA Deep Learning Frameworks Documentation

最終的なDockerファイルは以下です。

FROM nvcr.io/nvidia/pytorch:22.12-py3

WORKDIR /workspace

ENV TZ=Asia/Tokyo
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

RUN apt-get update && apt-get install -y \
    build-essential \
    gcc \
    git \
    ffmpeg \
    && rm -rf /var/lib/apt/lists/*

RUN pip install --upgrade pip

RUN pip install git+https://github.com/openai/whisper.git 

Dockerイメージのbuildでつまづいたところ

Dockerイメージをbuildすると、以下のメッセージでbuildが停止するという事象がありました。ユーザ側の入力を求められるようなのですが、入力しても先に進まないのです。

Configuring tzdata
------------------

Please select the geographic area in which you live. Subsequent configuration
questions will narrow this down by presenting a list of cities, representing
the time zones in which they are located.

  1. Africa      4. Australia  7. Atlantic  10. Pacific  13. Etc
  2. America     5. Arctic     8. Europe    11. SystemV
  3. Antarctica  6. Asia       9. Indian    12. US

以下の記事を参考にして、対応しました。

Fix: tzdata hangs during Docker image build | by Grigor Khachatryan | Medium

具体的には、Dockerファイルに以下のtimezone設定を追加しました。

ENV TZ=Asia/Tokyo
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

Dockerのbuild、run、whisperを使う

実際に使用したコマンドです。

使いやすいようにwhisper_gpuというタグをつけてbuild。

docker build . -t whisper_gpu

runします。落とし上げが面倒なので--rmオプションは必須です。また、execでアタッチしたいので、コンテナは--name whisper_gpuで名前指定しています。

docker run --rm --gpus all -it -d -v $(pwd):/workspace/ --name whisper_gpu whisper_gpu

docker execでコンテナに入ります。

docker exec -it whisper_gpu bash

以下のコマンドで音声ファイルを文字起こし。--modelで学習量を指定しますが、何も書かないとデフォルトのsmallが指定されます。

ちなみに、ffmpegを入れているので音声ファイルは*.m4aもちゃんと読み取ってくれます。

whisper test.m4a --language ja

なお、以下のように--model largeを指定すると2.87Gの学習をメモリに展開するようで、torch.cuda.OutOfMemoryError: CUDA out of memory.というメッセージが出力されて終了します。ビデオカードのメモリが不足しているんだと予想して諦めてます。ちなみに、mediumでも同じメッセージで動きませんでした。

whisper test.m4a --language ja --model large
 18%|██████▉                               | 536M/2.87G [00:47<03:26, 12.2MiB/s]

 Traceback (most recent call last):
  File "/opt/conda/bin/whisper", line 8, in <module>
    sys.exit(cli())
  File "/opt/conda/lib/python3.10/site-packages/whisper/transcribe.py", line 304, in cli
    model = load_model(model_name, device=device, download_root=model_dir)
  File "/opt/conda/lib/python3.10/site-packages/whisper/__init__.py", line 116, in load_model
    return model.to(device)
  File "/opt/conda/lib/python3.10/site-packages/torch/nn/modules/module.py", line 989, in to
    return self._apply(convert)
  File "/opt/conda/lib/python3.10/site-packages/torch/nn/modules/module.py", line 641, in _apply
    module._apply(fn)
  File "/opt/conda/lib/python3.10/site-packages/torch/nn/modules/module.py", line 641, in _apply
    module._apply(fn)
  File "/opt/conda/lib/python3.10/site-packages/torch/nn/modules/module.py", line 641, in _apply
    module._apply(fn)
  [Previous line repeated 2 more times]
  File "/opt/conda/lib/python3.10/site-packages/torch/nn/modules/module.py", line 664, in _apply
    param_applied = fn(param)
  File "/opt/conda/lib/python3.10/site-packages/torch/nn/modules/module.py", line 987, in convert
    return t.to(device, dtype if t.is_floating_point() or t.is_complex() else None, non_blocking)
torch.cuda.OutOfMemoryError: CUDA out of memory. Tried to allocate 26.00 MiB (GPU 0; 3.82 GiB total capacity; 2.94 GiB already allocated; 19.19 MiB free; 3.20 GiB reserved in total by PyTorch) If reserved memory is >> allocated memory try setting max_split_size_mb to avoid fragmentation.  See documentation for Memory Management and PYTORCH_CUDA_ALLOC_CONF

GPUの文字起こし時間

GPUを使用すると、30分の音声ファイルを文字起こしするのに約10分ぐらいです。

速い!この速度なら、十分かなと思います。

GPUが動いているのを感じる

文字起こししている最中はGPUが元気に動きます。ゲームをやらずに、動画のエンコードぐらいしか使っていない自分にはこんなにGPUが動いているのを初めて見ました。

nvidia-smiすると、温度も上昇しているし、ファンが「ウィーン」と音を立てて回りだすのがわかります。

Pythonが2.5GBぐらいのGPUのメモリを使用しているのがわかります。

+-----------------------------------------------------------------------------+
| NVIDIA-SMI 520.61.05    Driver Version: 520.61.05    CUDA Version: 11.8     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|                               |                      |               MIG M. |
|===============================+======================+======================|
|   0  NVIDIA GeForce ...  On   | 00000000:01:00.0 Off |                  N/A |
| 54%   65C    P2    64W /  75W |   2540MiB /  4096MiB |     96%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
                                                                              
+-----------------------------------------------------------------------------+
| Processes:                                                                  |
|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
|        ID   ID                                                   Usage      |
|=============================================================================|
|    0   N/A  N/A      2902      G   /usr/lib/xorg/Xorg                 15MiB |
|    0   N/A  N/A    117856      C   /usr/bin/python                  2520MiB |
+-----------------------------------------------------------------------------+

比較のため、通常の穏やかなnvidia-smi。FANは54%。

+-----------------------------------------------------------------------------+
| NVIDIA-SMI 520.61.05    Driver Version: 520.61.05    CUDA Version: 11.8     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|                               |                      |               MIG M. |
|===============================+======================+======================|
|   0  NVIDIA GeForce ...  On   | 00000000:01:00.0 Off |                  N/A |
| 30%   34C    P8     4W /  75W |     17MiB /  4096MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
                                                                              
+-----------------------------------------------------------------------------+
| Processes:                                                                  |
|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
|        ID   ID                                                   Usage      |
|=============================================================================|
|    0   N/A  N/A      2902      G   /usr/lib/xorg/Xorg                 15MiB |
+-----------------------------------------------------------------------------+

参考にした記事

OpenAI Whisper のコマンドオプション - Qiita

OpenAIの音声認識モデル Whisperの解説 / Fine Tuning 方法

WhisperのREADME