20191011のTensorFlowに関する記事は1件です。

PyTorch/TensorFlow で書かれた音声スピーチ系ネットワークを C++ でモバイルで推論するためのメモ

背景

PyTorch/TensorFlow で書かれた音声スピーチ系ネットワーク(e.g. Tacotron, FastSpeech)をモバイルで推論したい.
TensorFlow-Lite などでは RNN 系などの対応が十分ではないので変換がうまくいかない.
(少なくとも TensorFlow tacotron は .pb から toco での変換は r1.14 時点では失敗する)

libtensorflow を使う手もあるが, やりたいことに対して無駄が多すぎるし, ビルドも手間であり, また libtensorflow は Android には正式対応していない(モバイルでのオフィシャルな対応は tensorflow-lite に移行したっぽい)

libtorch もなかなかうまくいかない(ScriptModule で記述しても一部変換できない op がある)

tvm などの他のモバイル推論に特化したライブラリでも, RNN 系や音声系の対応は(2019 年 9 月時点)行われていないか, 非常に限られた対応となっている.

多少演算に時間がかかったとしても, モバイルで動かしたい.

Tacotron 系

T.B.W.

Transformer 系

使っているネットワーク op はそれほど多いわけではない.
たとえば, PyTorch 実装の FastSpeech(Transformer TTS) https://github.com/xcmyz/FastSpeech では, pytorch の op は

  • torch.bmm(batch matmul)
  • nn.Softmax
  • nn.Conv1d
  • nn.Linear
  • nn.Dropout
  • nn.LayerNorm
  • nn.Embedding
  • nn.ModuleList

あたりくらいしか使っていない.

waveglow を CUDA だけ(cuDNN は使っているが)で動かしていたりする既存の取り組みがある.

https://github.com/Saurabh-29/Waveglow_Inference_in_CUDA

=> C++ で自作したい!

PyTorch

推論(forward, inference)についての実装です.

torch.bmm

https://pytorch.org/docs/stable/torch.html#torch.bmm

行列をまとめて matmul すれば OK

nn.SoftMax, nn.Conv1d, nn.Linear

通常の NN のように実装すればよい. 特に特殊なことはなし.

nn.Embedding

https://pytorch.org/tutorials/beginner/nlp/word_embeddings_tutorial.html

word embedding などに使われる.

実装としては, int の配列([x])と重み行列(W)を受け取り, float の配列(2 次元行列)を返す.

一番簡単なのは, W[x] な感じで配列ルックアップする.

重み行列が大きく, データが sparse な場合は std::unordered_map などを使ってルックアップするといいかも?(GPU で動かす場合はハッシュ or 二分木探索とか?)

Chainer では EmbedID https://docs.chainer.org/en/stable/reference/generated/chainer.links.EmbedID.html に相当. ちなみに Chainer では initialW が与えられなかった場合, 正規分布の乱数で weight 行列を初期化している.

nn.Dropout

推論の場合はなにもしない(input をそのまま返す)

参考までに, dropout を実装したい場合は,

Chainer と TensorFlow の Dropout 実装メモ
https://qiita.com/syoyo/items/8b459cc5524eff6f54f3

を参考に実装する. PyTorch(ATen での実装) はノイズ(乱数)にベルヌーイ分布を使っている.

nn.LayerNorm

https://pytorch.org/docs/stable/nn.html#torch.nn.LayerNorm

Aten に CPU 実装があるのでそれを参考に推論を実装.
特段特殊なことはしていない.

nn.ModuleList

Module(op)をリストで保持できるようにしたもの.

MultiHeadAttension など

pytorch には nn.MultiheadAttention が 1.2 からあります(nn.Transformer も 1.2 から導入). 必要に応じて参考にしましょう.

https://pytorch.org/docs/master/nn.html#multiheadattention

その他

音声系は, ニューラルネットワークモジュールのほかにも, text の処理や wav の処理, fft などいろいろ周辺のコードも必要です.

librosa 相当や, FFT 処理

https://github.com/lighttransport/nanosnap

nanosnap にご期待ください.
stft, mfcc などがあります.
(少なくとも現時点で Tacotron のモバイル実行で必要なものはあるはず)

wav 入出力

nanosnap か, nanosnap でも使っている dr_wav がおすすめ.

https://github.com/mackron/dr_libs

inflect

inflect の C++ 実装がほしい(とくに number_to_words)

https://github.com/syoyo/tacotron-tts-cpp/tree/master/experiment/number_to_words

ご期待ください.

PyTorch のメモ

nn.init.normal_ など, アンダースコアで終わっている関数は in-place 関数.
PyTorch では in-place 関数の利用は推奨されないが, 乱数などでウェイトを初期化したいときとかは in-place 便利.

What does the underscore suffix in PyTorch functions mean?
https://stackoverflow.com/questions/52920098/what-does-the-underscore-suffix-in-pytorch-functions-mean

参考文献

その他参考になる文献です.

作って理解する Transformer / Attention
https://qiita.com/halhorn/items/c91497522be27bde17ce

TODO

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む