漢なら xcmyz's FastSpeech https://github.com/xcmyz/FastSpeech を CPU で推論(text-to-speech)したいですよね! やりましょう!
できました.
自前 fork に推論専用(matplotlib でプロット部分を消しただけですが) branch infer
もあります.
セットアップ
conda で Python3.7 環境を作り,
pytorch 1.3.1 CPU 版をインストールするとします.
pip で FastSpeech 動かすように install します.
$ pip install librosa inflect unidecode
# (optional) 本来推論したいだけであれば不要であるもの
$ pip install matplotlib soundfile
あとは FastSpeech の README にあるように, pretrained model を配置して synthesis.py すれば音声がよろしく生成されます.
GPU 版と CPU 版とで結果を聴き比べてみましたが, 特段差分はなさそうでした(本当は生成された音声の波形の diff をとるとよいところですが).
速度について
I'am happy to see you again
を Threadripper 1950X で生成すると, fastspeech(transformer)で 0.1 秒, griffin-lim 変換で 0.9 秒くらいでした. waveglow は 9 秒くらい(つまり fastspeech + waveglow で 9.1 秒くらい). 比較用の Tacotron2 + waveglow は 12 秒くらいでした.
CPU 版は thread 実行されているため, コア数に比例します. たとえば i9-9900K(8 コア)では 20 秒くらいかかりました.
ちなみに Ryzen9 3950X でも試しましたが, 処理時間は Threadripper 1950X とほぼ同じでした. 2020 年 1 月 17 日時点では, 1950X は中古で 3~4 万円くらいで買えるので, CPU で FastSpeech 推論する場合は 1950X がコスパがよさそうです.
CUDA(2080 Ti)では, だいたい 1950X に比べ 8~10 倍くらい高速でした(waveglow 処理 tacotron2 + waveglow が 1~2 秒くらい). ただ, fastspeech 部分は CPU よりも 2~3 倍くらい遅くなりました. カーネル起動などのコストですかね.
とりあえずお手軽にそこそこいい感じの品質で TTS で音声生成したいとか, サーバーで TTS 処理したいとか, いろいろな環境で動かしたい(サーバーレス実行したいとか, macOS で動かしたい(今後 macOS で CUDA 対応は打ち切られますし)とか)を考えると, CPU で実行できるのはいろいろ利点があります.
あとは, 処理時間のほとんどが waveglow です(GPU では fp16 などの高速化が効いているようですね). WaveFlow や
SqueezeWave https://github.com/tianrengao/SqueezeWave など, この部分をより軽量なものにしたら CPU 推論もアドバンテージがあるかもしれません.
ただ, やはり GPU は速いので, 使えるのであれば GPU 使ったほうがよいところですね.
ROCm では...
ROCm 3.0 で, VEGA56 で動くの確認しました. 初期化で MIOpen カーネルのコンパイルなどで 30~40 秒ほど時間かかるのですが, waveglow 推論自体は 4~5 秒で終わりました(一部, inverse 計算などで CPU に戻らないといけないものがあり, そこがボトルネックかも).
Radeon VII では現状 IntTensor 作るところでエラーになりました(int16, fp16 周りの問題?).
VEGA56 は 2020 年 1 月 17 日現在, 新品でも税込み 3 万円くらいで投げ売りされているので, バッチでたくさん TTS したい場合には活用できるかもしれません.
音声品質について
fastspeech + waveglow は Tacotron2 + waveglow に比べノイズはある感じですが, 抑揚などは fastspeech のほうが自然な感じがします. ぜひみなさんもいろいろ音声生成して聴き比べてください.
Windows 10 64bit でも動きます
windows では, 明示的に追加で pip install soundfile
が必要ですが(そうしないと librosa の呼び出しあたりで libsndfile64bit.dll が見つからないエラーが出る),
Windows 10 64bit + Python3 + Miniconda + PyTorch 1.3.1 で問題なく動くことを確認しました.
PyTorch のポータビリティ素晴らしいですね.
SqueezeWave を使う.
WaveGlow での無駄な計算を減らしたり, 軽量化することで演算量を減らして高速に mel -> wav 生成できる SqueezeWave があります.
SqueezeWave の公開コードは CUDA にハードコードされていますが, CPU 対応が出ていました.
Patch の著者による fastspeech(CPU) + SqueezeWave(CPU) があります!
"Let’s go out to the airport. The plane landed ten minutes ago." の mel から SqueezeWave での wav 生成は,
Ryzen5 1400X で 128L で 1.1 secs, 128S で 0.33 secs くらいでした.
モバイルでもそれなりの速度で動きそうですね!
libtorch mobile では, 現在 XNNPACK 対応が進んでいますので,
CPU で浮動小数点精度で推論むけ XNNPACK のメモ
https://qiita.com/syoyo/items/79400663f2d79b5f5943
XNNPACK 対応したら(pytorch mobile 1.5?), 実用レベルで on device で neural text to speech ができそうな気がします!
TODO
- 抑揚や感情をより制御できるっぽい Mellotron を試す https://github.com/NVIDIA/mellotron
- ROCm PyTorch(AMD GPU)で推論して速度を確認する.
- libtorch で C++ と Android で動かす(現状, FastSpeech モデルについては LengthRegularizer あたりで torchscript 変換でエラーが出る. コードの整理と型付けが必要)
- ESPNet https://github.com/espnet/espnet の TTS を試す(日本語 TTS あり. セットアップが面倒そうであるが...)
- 優秀な若人さまが, FastSpeech CPU 実行と SqueezeWave CPU 実行をお極めなさることで, 人類史上最速で neural text-to-speech の頂点に立ち, 至高の Neural TTS 若人さまへと昇華なされるスキームを確立する旅に出たい