Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

推論エンジンにONNXを採用し、サイズ削減とモデルポータビリティを向上させる #69

Closed
yamachu opened this issue Sep 7, 2021 · 17 comments

Comments

@yamachu
Copy link
Member

yamachu commented Sep 7, 2021

内容

現在特徴量からwave形式のfloat列を推論する each_cpp_forwarder にはTorchが使用されている。
TorchScriptを使っているためポータビリティが良く、PythonでもC++でも使用できるみたいなメリットを享受できている。

しかしTorchLibrary自体のサイズが非常に大きく、VOICEVOX ENGINEをフルビルドし動作させるためのランタイムを同梱すると4GBを超える非常に大きなものとなっている。
バージョンアップの度に4GB以上のダウンロードが行われるのは体験的に好ましくないだろう。

そこでRuntimeのサイズが小さく同等レベルのポータビリティを備えるONNXを使用することを提案する。

Pros 良くなる点

  • Runtimeが小さいため、バンドルサイズが削減できる
    • Torch単体で1GBを超えるが、ONNXは100MBを超えない
    • GPUでの推論のためにはCudaのランタイムが必要であるためその分のランタイムを同梱する必要があるが、現在のTorchが依存しているものよりは少なくなると予想される
  • ポータビリティが更に担保される
    • 多くの言語バインディングが存在し、each_cpp_forearderが存在しなくてもモデル単体を提供して多くの言語、プラットフォーム上で推論を行うことが可能
    • Webブラウザ上で推論を行うためのライブラリも提供が開始され、VOICEVOXの更なる展開が望める(?)

Cons 悪くなる点

  • CPP側で実装している箇所の大幅な書き換え(?)
    • どう実装されているのかわかっていないので想像で語っています

実現方法

  • TorchScriptでモデルを保存する際にtorch.onnx.exportで出力する
    • しかしONNXで実装されていないOperatorが存在した場合正常に出力できないなどあるので、ここで詰まることがあるかもしれません

VOICEVOXのバージョン

0.4.1

OSの種類/ディストリ/バージョン

  • Others

その他

大分古いバージョンでの作業例ですが

yamachu/nnmnkwii@7add37f

オレオレAutogradを作った場合こんな感じでONNXにする時にどう変換してほしいか書く必要があるものもあります(yukarin_s_forwarderとかsaとかその辺りがどう実装されているのかわからないので、単純にexportするだけで上手くいくかもしれません)。

もしかしたらEngineよりもCoreの方が適しているIssueかもしれませんね…

@yamachu yamachu changed the title 推論エンジンにONNXを採用する 推論エンジンにONNXを採用し、サイズ削減とモデルポータビリティを向上させる Sep 7, 2021
@Hiroshiba
Copy link
Member

Issueありがとうございます。coreリポジトリしっかりしたらそちらに移しても良いかもですね!

容量が大きいことは、VOICEVOXが抱えてる大きめの問題の1つなのでぜひ解決したいところです・・・
内部でTransformer系のモデルを使っているので、そこの変換がサクッとできるかで難度がかわるかもしれません。

そういえばいつになるか未定ですが、JVSデータセットなどで学習したモデルと推論に必要なコードを公開しようかと考えているのですが、(やるやらないは置いておいて)他に必要になりそうなコードがあれば教えて頂ければ!

@yamachu
Copy link
Member Author

yamachu commented Sep 8, 2021

JVSデータセットなどで学習したモデルと推論に必要なコードを公開しようかと考えているのですが

首を長くしてお待ちしております:tada:

推論までのコード(例えばloadして、こんな形式のパラメータを入力して…)みたいのが分かると、モデルをloadしてから再度onnxでexportみたいので変換できるのかなぁ…とか思っています(トライしてみないとわからないところではありますが)。

他に必要そうなコードは今のところ思いつかないので、もしも公開されたらこのIssueにもリンクなどをいただけると嬉しいです(Coreとかその辺りのリポジトリもウォッチ予定なので見つけ次第tryしてみますが)。

@Hiroshiba
Copy link
Member

了解しました! いつになるかわかりませんが、なるべく早く公開したいと思います 🙏

@Hiroshiba
Copy link
Member

Hiroshiba commented Sep 15, 2021

とりあえず、推論だけはできるコードを書き出してみました・・・!
https://github.com/Hiroshiba/vv_core_inference

ただ、ネットワーク構造は、依存ライブラリを全てインストールしてコードジャンプを駆使しないと追えないようになってしまっています。
ちょっと他にやらないといけないことと優先度相談して、いけそうなら依存ライブラリを全部集約してみたいと思います。

@yamachu
Copy link
Member Author

yamachu commented Sep 15, 2021

ご連絡ありがとうございます!
早速コードを眺めて移植できないか検討中です

https://github.com/Hiroshiba/vv_core_inference/blob/3b9ad87b2d015513dd50c62c531e67b3124d5eea/vv_core_inference/make_yukarin_sosoa_forwarder.py#L7
https://github.com/Hiroshiba/espnet_pytorch_library
この辺りでespnetから呼んでいるtacotron2ラッパーがONNX化出来るかが鍵に見えますね………

espnetのIssueを見る感じONNX化のために何も対応しないぞみたいなスタンスを持っていたので、もしかしたら腕力が必要かもしれませんが、トライしてみます

@chihayuki
Copy link

chihayuki commented Oct 3, 2021

ONNXを採用するならばpytorchでなくonnxruntime のような推論エンジンを採用をしたほうが良いかもしれません
理由としては onnxruntime は DirectML をサポートしているためCUDAに比べて遅いですが intel,nvidia,AMDなどのどのGPUを同一のバイナリで利用することができます
WindowsOSの機能を利用するため無駄なライブラリを同梱しなくてすみ容量も少なくなるかと思います

@Hiroshiba
Copy link
Member

DirectML、初めて知りました!良いですね!!
もともとコア(ディープラーニングのforward部分)は秘匿化する必要がある関係でC++実装を目指してため、c++用のonnx runtimeを用いることになりそうです。
推論用のコードとサンプルモデルは2つ前のコメントにて公開中なので、もしよかったらコンバートに挑戦してみてください・・・!

@Yosshi999
Copy link
Contributor

これ今どうなってますか?ちょっとやってみたいんですが

@Hiroshiba
Copy link
Member

@Yosshi999 おー!
特にアサインとかも決まっていない状態なので、自由に取り組んでいただけると!!

@Yosshi999
Copy link
Contributor

Forwarderクラスを多少いじっても大丈夫ですか?
具体的にはWrapperYukarin*** に渡すときにbatchsizeを1に限定し、

https://github.com/Hiroshiba/vv_core_inference/blob/fa19e1d7a4fd6af463dcbbbcf9d1571b7353aae9/vv_core_inference/forwarder.py#L138-L145

ここらへんのnewaxisを削除したいです

@Yosshi999
Copy link
Contributor

いまのところ以下の部分がヤバそうだということが分かっています

@Hiroshiba
Copy link
Member

Hiroshiba commented Oct 17, 2021

newaxisを削除したいです

そうすることでより単純になるのであれば大丈夫です!
ちなみにそうするとcoreを叩くcythonラッパーも変更する必要が出てくるので少しだけ工数が増えるかもです。

@Hiroshiba
Copy link
Member

ヤバそう

なるほどです!
参考になるかもなので僕の考えも載せてみます。

numpy.finfoは埋め込みで問題ないと思います!

peの置き換えに関しては、5000固定でも問題ないかもです。確か1秒で約100サンプルなので、50秒ほどまでサポートできそうです。
想定より大きい物が来たら動的生成、というロジックが一番かっこいい思います!!

@Yosshi999
Copy link
Contributor

onnx生成が出来れば次は https://github.com/Hiroshiba/voicevox_core でcore.cppの実装ですかね?
newaxisがいくらか消えましたがメモリ配置は変わっていないので、pythonとpython-C++のインターフェースは変更ないかもしれません(可読性という意味ではpythonのforwarderは変更したほうがいいかもしれない)
暗号化はさっぱりなのでおまかせします

@Hiroshiba
Copy link
Member

はい!onnx生成ができればcoreにc++実装をプルリクエストして頂ければ!!

たしかにインターフェイスはほとんど変わらなそうな気がします。サードパーティライブラリでも変更が少なくて済むはずなので、とても良さそうです。
暗号化周りはとりあえずお任せください!

@Hiroshiba
Copy link
Member

リポジトリ間の横断が必要なため、別途リポジトリ横断用のissueにしてみました。

@Hiroshiba Hiroshiba added the 優先度:高 最優先 label Dec 11, 2021
@Hiroshiba
Copy link
Member

製品版VOICEVOX COREの、onnxモデルが入ったリリースを作ってみました!!!大変おまたせしました。
https://github.com/VOICEVOX/voicevox_core/releases/tag/0.10.preview.0

この変更により、エンジン側でできることは2つほどあります。

1つ目が、7z分割をやめて、単体のファイルとしてreleasesを作ることです。これはユーザーにエンジンを配布しやすくなるので、ぜひやりたいと思っています。

2つ目は、CPU/GPU判定です。coreが対応しているデバイスを列挙するAPIが生えたので、エンジン側はそれをバイパスすることでソフトウェア側に伝えることができます。ソフトウェア側のこのissueを解決できるはずです。

それぞれのissueを作成しつつ、作成したonnx版コアに問題が合った場合はissueを作成するとして、このissueはcloseしたいと思います。
本当に長い時間がかかりましたが、ここからの仕上げも大事なはずです。onnx版リリースまで頑張りましょう・・・・・!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants