👂

Whisper large-v2 を Whisper API と同等くらいに高速化したいメモ(faster-whisper 推奨)

2023/03/04に公開

Whisper API, 「恋する女子のときめキュンあるある」457 秒の音声データ 30 秒くらいで処理できてしゅごい...

OpenAI では (Azure の) A100 使っているっぽい?

https://www.servethehome.com/chatgpt-hardware-a-look-at-8x-nvidia-a100-systems-powering-the-tool-openai-microsoft-azure-supermicro-inspur-asus-dell-gigabyte/

ので, 3090 ちゃんでも同じくらいで動くはず...!
とりま 3090 で動かすと 90 秒くらいネ. 早くしたい...

音声認識モデル Whisper の推論をほぼ倍速に高速化した話
https://qiita.com/halhorn/items/d2672eee452ba5eb6241

ありがとうございます.

これを参考に高速化してみます.

2023/03/18 追記: faster-whisper で爆速 18.5 秒になりました! あとのほう参照ください.

環境

  • x299 + i9 10940x
  • 3090

テスト音声

https://qiita.com/syoyo/items/4c0c649aa5d8a62a2e04

「恋する女子のときめキュン あるある!」 457 秒

no_grad を使う.

decoder は torch.no_grad の annotation がついていますが, encoder はありません.

with torch.no_grad():
        model.transcribe(
            audio_data,
            verbose=False,
            language='japanese',
            beam_size=1,
            fp16=True,
            without_timestamps=False
        )

no_grad つきだとちょっと早くなりました. メモリ消費量も減ります.

最終的に, fp16 だと GPU メモリ 4.5 GB くらいあれば動きます.

まずは openai-whisper

まずは本家 openai-whisper 使います.

「音声認識モデル Whisper の推論をほぼ倍速に高速化した話」を参考に fp16 化 + no_grad

import sys

import whisper
import torch
import time

load_s = time.time()

audio_data = whisper.load_audio(sys.argv[1])

model = whisper.load_model("large-v2", device="cpu")

_ = model.half()
_ = model.cuda()

for m in model.modules():
    if isinstance(m, whisper.model.LayerNorm):
        m.float()

load_e = time.time()
print("Load time: ", (load_e - load_s))


print("run")

run_s = time.time()

with torch.no_grad():
        model.transcribe(
            audio_data,
            verbose=True,
            language='japanese',
            beam_size=5,
            fp16=True,
            without_timestamps=False
        )

run_e = time.time()
print("infer", (run_e - run_s))

model load 18 秒くらい, 推論時間は

[07:25.000 --> 07:28.000] 自分たちの前で頑張ってくれているんだな
[07:28.000 --> 07:32.000] みたいなことが伝わる内容になっていると思います
[07:32.000 --> 07:34.000] ぜひ見ていただきたいと思います
[07:34.000 --> 07:36.000] 村上でした
infer 69.01157212257385

69 秒でした.
(最後「有村かすみでした」が「村上でした」とうまく認識できていないのはご愛嬌)

beamsearch のサイズを変える.

デフォルトは 5 です.

large-v2 だと 2 くらいでもまあまあいける感じでした
Whisper API は 2 くらいそうでした.
(少なくともローカルで large-v2 を fp16/fp32 + beamsearch 5 で処理したときとは結果が違う

beamsearch 2 にします!

[07:23.000 --> 07:25.000] 日頃女性がこういうふうにして
[07:25.000 --> 07:28.000] 自分たちの前で頑張ってくれているんだな
[07:28.000 --> 07:31.000] みたいなことが伝わる内容になっていると思います
[07:31.000 --> 07:33.000] ぜひ見ていただきたいと思います
[07:33.000 --> 07:58.000] 有村かすみでした
infer 55.838754653930664

56 秒.

timesamp なし

with torch.no_grad():
        model.transcribe(
            audio_data,
            verbose=True,
            language='japanese',
            beam_size=2,
            fp16=True,
            without_timestamps=True
        )
[00:00.000 --> 00:30.000] 恋する女子のときめきゅんあるあるこっちかな?いや、こっちかな?もう違う?よし、完璧!ともくんにコメントしてる人がいるん?ハートついてる!お待たせ!ごめんね今日天気いいねうん、天気いいね
[00:30.000 --> 01:00.000] お腹すいたなお腹すいたまだかな?美味しそう!ちょっと写真撮ってもいい?こうかな?撮れた?これってチュロスじゃない?そうだよすっごい好きなんだよね好きなんだ!じゃあこれは?好き綺麗系と可愛い系どっちが好き?
[01:00.000 --> 01:30.000] 綺麗系なんだじゃあ髪型だったらロングかショートかボブどれが好き?ロングなんだ!下ろしてる方がいい?それともアレンジしてる方がいい?どっちがいい?どっちも好きだよどっちも好きなんだちょっといい?何?もしかして告白?私も好き!やっぱり!まつげついてるよえ?どこ?ここここ?
[01:30.000 --> 02:00.000] ほらありがとうあのさうん?やっぱ何でもない何それまた二人で会いたいねうんまた二人で会いたいねまたねうん気をつけてうん
[02:00.000 --> 02:30.000] また二人で会いたいな来週映画見に行かない?
[02:30.000 --> 03:00.000] 映画ってことは隣だよね手とか繋げちゃうかもな変身しなきゃよし好き行かなきゃ
[03:00.000 --> 03:30.000] 今回はいろんなトキメキのあるあるを撮らせてもらったんですけどその中で自分は今年で26歳になるので26歳の等身大の女性が演じるとしたらどういう風に表現するかっていうのを考えたりとかあとはSNSにまつわる
[03:30.000 --> 04:00.000] トキメキあるあるがあったりとかしてあっそうなんだ今今そういうことがあるんだっていう風に自分自身も発見だったりとかうんなんか世の中のキュンポイントっていうのをちょっと勉強させてもらいながらやってましたえっとこれはピンクゴールドの時計で女性らしいなと思うしあとここのデザインの部分が大きめになってるので
[04:00.000 --> 04:30.000] 時計の針も見やすいし文字盤についてるダイヤとかもシンプルで女性はすごく使いやすいなと思います女性は今結構時計をファッションの一部としても使ってる方が多いですしなんか本当に時計は時計として使っていたものがそうやってどんどんどんどん新しくなんかあの新しいアイテムとしても活用されてて
[04:30.000 --> 05:00.000] その中の女性にはそのトキメクトキをこう一緒に刻んでもらえたらいいなと思います
[05:00.000 --> 05:30.000] 25歳は分からないっていうことが口癖だったように思います分からないっていうのは表現の仕方だったりとか自分のやってることが合ってるのかどうかとかそういうことがちょっと迷うじゃないけど
[05:30.000 --> 06:00.000] そういうふうに思うことが多かった1年だったなと思います26歳はお芝居もそうだしいろんなことに身を委ねられたらいいなと思ってます久しぶりに会う先輩や自分の役者仲間たちと話すことが
[06:00.000 --> 06:30.000] 変わってきたなっていうのを感じると大人になったのかなというふうに思います前にあの先輩の俳優さんと共演させてもらったんですけど6年前ぐらいに一度共演させてもらっていてその時は話す内容もそんなに深くないことばっかりで何を話していいか分からなかったんですけどでも今自分もいろんな経験をさせてもらって話せる内容が変わってきて
[06:30.000 --> 07:00.000] そういうふうに思った時にすごいキャッチボールできていたことが嬉しくて感激しました
[07:00.000 --> 07:30.000] 皆さんには共感していただけるところがたくさんあるんじゃないかなと思っていますまた男性の方々にも女性が待ち合わせの前に入念に準備をしているところだったりとかデート中は実はすごくドキドキしていることがあったりもするのでそういったところもぜひ見ていただいて日頃女性がこういうふうにして自分たちの前で頑張ってくれているんだなみたいなことが伝わる内容になっています
[07:30.000 --> 08:00.000] ぜひ見ていただきたいと思います有村かすみでした
infer 38.11665344238281

38 秒台になりました!
timestamp 処理が時間かかっていただけかも...
(CPU とやりとりでてくるしね)

verbose なし

infer 37.54277753829956

37 秒

beamsearch 1 だと 34 秒になりました.
この当たりで, 概ね Whisper API の処理時間と同じかんじですかね.

TorchScript

音声認識モデル Whisper の推論をほぼ倍速に高速化した話
https://qiita.com/halhorn/items/d2672eee452ba5eb6241

にあるように, TorchScript 化します!

import sys

import efficient_whisper as whisper
import torch
import time

load_s = time.time()

audio_data = whisper.load_audio(sys.argv[1])

model = whisper.load_model("large-v2", device="cpu")
model.encoder = torch.jit.script(model.encoder)
model.decoder = torch.jit.script(model.decoder)

_ = model.half()
_ = model.cuda()

load_e = time.time()
print("Load time: ", (load_e - load_s))


print("run")

run_s = time.time()

with torch.no_grad():
        model.transcribe(
            audio_data,
            verbose=False,
            language='japanese',
            beam_size=2,
            fp16=True,
            without_timestamps=True
        )

run_e = time.time()
print("infer", (run_e - run_s))
infer 45.02641558647156

逆に遅くなってしまいました... 🤔

まとめ

  • no_grad + fp16 で動かす
  • timestamp いらなければ無しにすると速い
  • beamsearch 2 か 1

これで概ね 3090 で Whisper API と同等の速度になりました. OpenAI 内部での独自高速化トリックは使ってなさそうですね.

さらなる高みを目指して

faster-whisper

https://github.com/guillaumekln/faster-whisper

とりまこれできまり!

[390.00s -> 420.00s] そういうふうに思った時にすごいキャッチボールできていたことが嬉しくて感激しました
[420.00s -> 450.00s] 皆さんには共感していただけるところがたくさんあるんじゃないかなと思っていますまた男性の方々にも女性が待ち合わせの
前に入念に準備をしているところだったりとかデート中は実はすごくドキドキしていることがあったりもするのでそういったところもぜひ見ていただいて日頃女性がこういうふうにして自分たちの前で頑張ってくれているんだなみたいなことが伝わる内容になっています
[450.00s -> 457.61s] ぜひ見ていただきたいと思います有村かすみでした
infer  18.68753719329834  secs

timestamp なし + beamsize 2 で 18.5 秒!

[440.00s -> 442.00s] そういったところもぜひ見ていただいて
[442.00s -> 444.00s] 日頃女性がこういうふうにして
[445.00s -> 447.00s] 自分たちの前で頑張ってくれているんだな
[448.00s -> 450.00s] みたいなことが伝わる内容になっていると思います
[451.00s -> 453.00s] ぜひ見ていただきたいと思います
[454.00s -> 455.00s] 有村香澄でした
infer  25.790561199188232  secs

ちな timestamp ありだと 25.8 秒でした.

temperature とか, 処理単位時間を調整

処理の単位時間はデフォでは 30 秒です.
chat みたいな用途では 10 秒くらいに短縮するのでもよいでしょう.
いろいろパラメータ調整試してくださいネ.

int8 を使う

int8 で動かす.
Lovelace 系(e.g. 4090)だと int8 性能二倍なので(fp8 も?), ワンチャン 2 倍あるかも

AITemplate を使う

https://github.com/facebookincubator/AITemplate

1.4 倍高速化は狙えるので, たぶん 30 秒はきりそう!
(似たようなので faster-whisper CTranslate2 では 2 倍くらい速くなったので, AITemplate でも 2 倍高速になるかも)

PyTorch 2 を使う

AITemplate っぽい機能がついたような?

encoder, decoder を別 GPU で行う.

2 GPUs ある場合は encoder, decoder 分けて高速化ねらえます.

https://github.com/openai/whisper/discussions/360

レイテンシー(応答速度)を上げたい

音声で ChatGPT とか LLM で対話システム組みたい場合は応答速度速いのがほしいですよね.

ただ現状の large のアーキテクチャ(モデルサイズ)では, 処理量多いため, whisper large ではちょっと難しいかも.

レイテンシ縮めるのは faster-whisper + 処理単位時間 10 秒とかである程度いけるかも
(10 秒入力に対して 2~3 秒で応答)

日本語限定でよければ, ReazonSpeech の日本語コーパスで, Whisper medium サイズくらいの model 構成で学習したらよりリアルタイムワンチャンあるかも?
(medium だと RTX 3090 あたりであれば結構リアルタイムいけそう)

Discussion