whisper-ctranslate2を試す
Whisperのいろいろな実装。
で今はこれが熱いらしい。
ということで触ってみる。
環境
- 自宅サーバ
- Intel Core i9-13900F
- メモリ 96GB
- NVIDIA GeForce RTX 4090 24GB
- Ubuntu 22.04
- Python-3.10.11 (pyenv-virtualenv)
$ nvcc --version
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2022 NVIDIA Corporation
Built on Wed_Sep_21_10:33:58_PDT_2022
Cuda compilation tools, release 11.8, V11.8.89
Build cuda_11.8.r11.8/compiler.31833905_0
やってみた
$ pip install -U whisper-ctranslate2
サンプルとしてYouTubeにある自分の勉強会動画をmp3化したものを使用した。
- 内容は音声インタフェース・会話フローに関する勉強会
- 日本語と英語が混在
- 1時間8分
YouTube動画のmp3化は以下。
音声文字起こし。とりあえずmediumで。
$ whisper-ctranslate2 sample.mp3 --model medium
初回はモデルのダウンロードが行われるので少し時間がかかる。
Detecting language using up to the first 30 seconds. Use `--language` to specify the language
Downloading (…)90c7f7fb/config.json: 100%|█| 2.26k/2.26k [00:00<00:00, 35.9MB/s]
Downloading (…)7f7fb/vocabulary.txt: 100%|████| 460k/460k [00:00<00:00, 992kB/s]
Downloading (…)7f7fb/tokenizer.json: 100%|█| 2.20M/2.20M [00:01<00:00, 1.80MB/s]
Downloading model.bin: 100%|███████████████| 1.53G/1.53G [02:32<00:00, 10.0MB/s]
Detected language 'Japanese' with probability 0.989258
が、文字起こしが始まるとめちゃめちゃ速い!モデルダウンロード後に時間計測してみた。
real 3m45.369s
user 5m35.265s
sys 0m19.273s
large-v2でも試してみた。こちらもモデルダウンロード時間は含めない形で。
real 4m5.638s
user 6m24.424s
sys 0m19.572s
内容は以下。
medium
[00:00.720 --> 00:06.760] はいじゃあ始めますちょっとまだ来られて ない方もいらっしゃるんですけど
[00:06.760 --> 00:11.320] ポイズランチで p 始めます 皆さん見てる
[00:11.320 --> 00:15.920] はーい はい日曜日にお集まりいただきまして
[00:15.920 --> 00:21.040] ありがとうございますえっと今日久しぶりにですね オフラインということで8今日はですね
[00:21.040 --> 00:26.280] スペシャルなゲストを2人 来ていただいておりますということで
[00:26.320 --> 00:30.840] はい8今日ちょっとトピックにもあります けれども8ボイスローの仕様であるレゼン
[00:30.840 --> 00:35.720] リームさんとあと8セルスフォースの 8カムセドルデザインのディレクター
[00:35.720 --> 00:39.840] であるブレックベネスさんに来て いただいてます
[00:39.840 --> 00:44.200] ということで日本に来ていただいて ありがとうございました
[00:44.200 --> 00:47.000] はい で今日はちょっとこのお二人にまた
[00:47.000 --> 00:52.040] 後でいろいろと聞こうという8コーナー がありますのでそこでまたいろいろと
[00:52.240 --> 00:55.960] 聞きたいと思います で今日のアジェンダーなんですけども8ちょっと時間
large-v2
[00:00.000 --> 00:02.840] おだしょー はい じゃあ始めます ちょっとまだ
[00:02.840 --> 00:09.000] 来られてない方もいらっしゃるんです けど ボイスランチでAP始めます
[00:09.000 --> 00:17.720] 皆さん 日曜日にお集まりいただき ましてありがとうございます 今日は
[00:17.720 --> 00:23.360] 久しぶりにオフラインということで 今日はスペシャルなゲストお二人
[00:23.360 --> 00:28.200] 来ていただいておりますということで 今日ちょっとトピックに回ります
[00:28.200 --> 00:32.800] けれども ボイスローのCEOである レデン・リムさんと あとセールス
[00:32.800 --> 00:36.920] フォースのカムセジョナルデザイン のディレクターであるブレイク
[00:36.920 --> 00:41.640] ベネスさんに来ていただいてます ということで 日本に来ていただ
[00:41.640 --> 00:46.800] いてありがとうございました 今日はちょっとこのお二人に
[00:46.800 --> 00:51.240] また後でいろいろと聞こうという コーナーがありますので そこで
[00:51.240 --> 00:55.800] またいろいろと聞きたいと思います 今日のアジェンダなんですけども
mediumだと「えーと」みたいなのが「8」で認識されていたりするのがlarge-v2だと削除されていたりしてやはりlarge-v2のほうがよい。人名などの固有名詞が弱いのは致し方ない。
でデフォルトだとCPU/GPUのところは自動で判別するようになっているっぽいので、うちの場合だとおそらく認識されている(数GB程度しかGPUメモリは使われてないけど)。CPUだけで処理した場合の時間も測ってみる。
明示的にCPUを使用する場合は以下のような感じで。
$ whisper-ctranslate2 sample.mp3 --model medium --device cpu
時間は測ってないけど、GPUを使う場合よりもかなりかかる。
リアルタイム文字起こし
whisper-ctranslate2はリアルタイム文字起こしが可能ということでやってみる。
サーバにUSBマイクを接続した。以下の通り認識されている。
$ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 004: ID 1b3f:2008 Generalplus Technology Inc. Usb Audio Device # これ
Bus 001 Device 003: ID 05e3:0608 Genesys Logic, Inc. Hub
Bus 001 Device 002: ID 1462:7e06 Micro Star International MYSTIC LIGHT
Bus 001 Device 005: ID 05e3:0608 Genesys Logic, Inc. Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
$ cat /proc/asound/modules
(snip)
2 snd_usb_audio
(snip)
$ sudo arecord -l
**** ハードウェアデバイス CAPTURE のリスト ****
カード 0: PCH [HDA Intel PCH], デバイス 0: ALC897 Analog [ALC897 Analog]
import sounddevice as sd
devices = sd.query_devices()
for i, device in enumerate(devices):
サブデバイス: 1/1
サブデバイス #0: subdevice #0
カード 0: PCH [HDA Intel PCH], デバイス 2: ALC897 Alt Analog [ALC897 Alt Analog]
サブデバイス: 1/1
サブデバイス #0: subdevice #0
カード 1: Device [Usb Audio Device], デバイス 0: USB Audio [USB Audio] # これ
サブデバイス: 1/1
サブデバイス #0: subdevice #0
ただpython -m sounddevice
でみると出てこない。
$ python -m sounddevice
0 pulse, ALSA (32 in, 32 out)
* 1 default, ALSA (32 in, 32 out)
いろいろ調べてみたところ、どうもオーディオデバイスにはsudoじゃないとアクセスできなかったみたい。以下を追加して再起動した。
$ sudo usermod -a -G audio $USER
認識した。
$ python -m sounddevice
0 HDA Intel PCH: ALC897 Analog (hw:0,0), ALSA (2 in, 8 out)
1 HDA Intel PCH: ALC897 Alt Analog (hw:0,2), ALSA (2 in, 0 out)
2 Usb Audio Device: USB Audio (hw:1,0), ALSA (1 in, 0 out) # これ
3 HDA NVidia: HDMI 0 (hw:2,3), ALSA (0 in, 8 out)
4 HDA NVidia: HDMI 1 (hw:2,7), ALSA (0 in, 8 out)
5 HDA NVidia: HDMI 2 (hw:2,8), ALSA (0 in, 8 out)
6 HDA NVidia: HDMI 3 (hw:2,9), ALSA (0 in, 8 out)
7 sysdefault, ALSA (128 in, 128 out)
8 front, ALSA (0 in, 8 out)
9 surround21, ALSA (0 in, 128 out)
10 surround40, ALSA (0 in, 8 out)
11 surround41, ALSA (0 in, 128 out)
12 surround50, ALSA (0 in, 128 out)
13 surround51, ALSA (0 in, 8 out)
14 surround71, ALSA (0 in, 8 out)
15 samplerate, ALSA (128 in, 128 out)
16 speexrate, ALSA (128 in, 128 out)
17 pulse, ALSA (32 in, 32 out)
18 upmix, ALSA (8 in, 8 out)
19 vdownmix, ALSA (6 in, 6 out)
20 dmix, ALSA (0 in, 2 out)
* 21 default, ALSA (32 in, 32 out)
で、これを--live_input_device
でデバイスのIDを指定すればいいということだと思っただけど、
$ whisper-ctranslate2 --live_transcribe True --live_input_device 2 --language ja
こうなる。
Live stream device: Usb Audio Device: USB Audio (hw:1,0)
Listening.. (Ctrl+C to Quit)
Expression 'paInvalidSampleRate' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 2048
Expression 'PaAlsaStreamComponent_InitialConfigure( &self->capture, inParams, self->primeBuffers, hwParamsCapture, &realSr )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 2718
Expression 'PaAlsaStream_Configure( stream, inputParameters, outputParameters, sampleRate, framesPerBuffer, &inputLatency, &outputLatency, &hostBufferSizeMode )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 2842
Quitting..
Traceback (most recent call last):
File "/home/kun432/.pyenv/versions/whisper-test/bin/whisper-ctranslate2", line 8, in <module>
sys.exit(main())
File "/home/kun432/.pyenv/versions/3.10.11/envs/whisper-test/lib/python3.10/site-packages/src/whisper_ctranslate2/whisper_ctranslate2.py", line 512, in main
).inference()
File "/home/kun432/.pyenv/versions/3.10.11/envs/whisper-test/lib/python3.10/site-packages/src/whisper_ctranslate2/live.py", line 158, in inference
self.listen()
File "/home/kun432/.pyenv/versions/3.10.11/envs/whisper-test/lib/python3.10/site-packages/src/whisper_ctranslate2/live.py", line 146, in listen
with sd.InputStream(
File "/home/kun432/.pyenv/versions/3.10.11/envs/whisper-test/lib/python3.10/site-packages/sounddevice.py", line 1421, in __init__
_StreamBase.__init__(self, kind='input', wrap_callback='array',
File "/home/kun432/.pyenv/versions/3.10.11/envs/whisper-test/lib/python3.10/site-packages/sounddevice.py", line 898, in __init__
_check(_lib.Pa_OpenStream(self._ptr, iparameters, oparameters,
File "/home/kun432/.pyenv/versions/3.10.11/envs/whisper-test/lib/python3.10/site-packages/sounddevice.py", line 2747, in _check
raise PortAudioError(errormsg, err)
sounddevice.PortAudioError: Error opening InputStream: Invalid sample rate [PaErrorCode -9997]
どうもマイクのサンプリングレートが合わないということの様子。使ってるのはこれ。
デフォルトだと16kHzみたい。一応このマイク自体は対応はしてる。
こんな感じで録音ができることも確認した。
$ arecord --device "plughw:CARD=Device,DEV=0" --channels 1 --format S16_LE --rate 16000 --max-file-time 60 test.wav
で直接該当のファイルを書き換えたりもしてみたのだけど、結論としては以下。
arecord -lの結果を元にALSAの設定ファイルを作成。ここはちょっと自信がない。
pcm.!default {
type asym
capture.pcm "input"
playback.pcm "output"
}
pcm.input {
type plug
slave {
pcm "hw:1,0"
rate 16000
}
}
pcm.output {
type plug
slave {
pcm "hw:0,0"
}
}
これでどうやらUSBマイクがdefaultで認識されるようになるので、--live_input_device
は指定しないでOK。
$ whisper-ctranslate2 --live_transcribe True --language ja
ちゃんと動いてる!
Live stream device: default
Listening.. (Ctrl+C to Quit)
.................................
やっとウィスパーの自動文字起こしができるようになりました。今日はこれで寝ます。おやすみなさい。
Linuxのサウンド周りは難しい・・・けどとりあえずなんとか動いてよかった。
まとめ
- とても高速に動作するし、十分使えるレベル。
- ただしGPUはあった方がよい、スピードがぜんぜん違うので。CPUだと結構遅い。
- Whisperでfine-tuningしたモデルを読み込むこともできるらしい。
- 無音カットを行うオプションもある様子。
かなり良いのではなかろうか。GPUメモリもそんなに食わないのでゲーミングPCと呼ばれてるものなら普通に動かせそう。
fine-tuning難しいよなーと思ってたけど、こんなのがあった。やってみよう。