-
Notifications
You must be signed in to change notification settings - Fork 206
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
PyInstaller: DirectML版で良いGPUが使われるように、編集したbootloaderを使う #502
Comments
詳細なissueありがとうございます!! PyInstallerをforkしてmain.cを書きかえ、そのPyInstallerをビルドに使用する必要があるという感じでしょうか。 まあまずはPyInstallerがmainブランチに入ってからかなと思います。 とりあえずforkしてみました!デフォルトのdevelopブランチでリリースしてるっぽい・・・? |
こちらのissue、pyinstaller版がマージされたので続行できそうですね! GPU版VOICEVOX遅くない?みたいなツイートをちょくちょく見かけます。結構損していそうなので、優先度ラベルを中にしたいと思います。 |
bootloaderに変更を加え、高性能グラフィックスがデバイス一覧の先頭に来るように制御できたVOICEVOX Engineがビルドできました。 ローカルでIssueに書かれている通りの手法でビルドしたものとなります。 一応、詳細な手段を書いておきます。
以上です。 ここまでの議論では、VOICEVOX Org側でPyInstallerをフォークして保守することが挙げられていましたが、2行の変更で済むので、このリポジトリ上でパッチファイルを保持し、GitHub Actions上で実行する方が保守性が高いかも?と思いました。 |
その形でもいいのかなと思いました! |
パッチというより、独立した.cファイルを放り込めばちゃんとコンパイルしてリンクしてくれるみたいです。 #ifdef _WIN32
#include <windows.h>
__declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
__declspec(dllexport) DWORD AmdPowerXpressRequestHighPerformance = 0x00000001;
#endif |
以下のコメントが非常に参考になった。 @y-chan に感謝する。 VOICEVOX#502 (comment) Co-authored-by: Yuto Ashida <[email protected]>
内容
bootloaderをカスタムしてPyInstallerを使うことで、 VOICEVOX/voicevox_core#309 を解決します。
以下、 VOICEVOX/voicevox_core#309 と VOICEVOX/voicevox_core#322 での議論内容を簡潔にまとめます。
Discordでも話題に出たと思うのですが、現行のDirectML版のVOICEVOXにはそこそこ重大な問題があります。複数のGPUがあるPCでは統合GPUの方(例: Intel Graphics)が使われてしまう、という問題です。
この問題はC++実装のコアに特有のものではなく、Rust実装のものにおいても同様です。
ここでDirectMLがどのGPUを選択するのかを調べるべく、私の使っているAlienware m15 Ryzen Edition R5でNVIDIA Control Panelを開き、アプリケーションでどちらのGPUを使うかの設定を"Auto Select"にしてみます。
この状態でONNX Runtimeのドキュメントに従ってWin32 APIでGPUを列挙してみると、GPUの名前とメモリ量が得られます (結果は簡略化しています)。
試しにNVIDIA Control PanelでGeForceを使うように設定すると、GeForceが最初に来るようになります。
コアでDirectMLのONNX Runtimeを使う際、現在はこの
0
番目(0-based)のGPUを指定しています。選択肢1: コア側で一番メモリが多いGPUを選択する
ここで
0
番目ではなくメモリが最大のデバイスを指定する、というのが考えられる一つ目の選択肢です。選択肢2: エンジン側でCのグローバル変数を定義する
ユーザーにNVIDIA Control Panelを操作させる以外にも、デバイス情報の順番を変化させる方法があります。Cレベルでグローバル変数を定義するとGeForceが最初に来るようになります。 グローバル変数を定義して強いGPUが
0
番目に来るようにしてから、それを選ぶというのが二つ目の選択肢です。ただこっちの方法だと、コア側で対処することはできません。プロセスの開始時にドライバーから読める必要があるからです。VOICEVOXの場合はPyInstaller側で対応する必要があります。
比較
これで2つの選択肢があるわけですが、この2つを比較してみます。
UX
まず「大多数の人が意図した挙動になり、意図しない挙動をする場合は変更可能になっている」というのが理想ではあります。
しかしどちらの方法においても、ユーザー側から挙動を変更することはできません (グローバル変数を宣言した場合、NVIDIA Control Panelから統合GPUの方を使うことはできなくなります)。その点で両者に違いはあまり無いと考えられます。
コア側での対応だとユーザーが選択できるように将来拡張できるのですが、エディタのUIまで考えて実装しなければならないことを考えるとコストが大きいかと思われます。
そもそも外付けGPUではなく統合GPUの方を使いたいという人がさほどいないであろうことを考えると、ユーザー側での変更可能性はUXにはあまり影響しないという見方もできます。
実装コスト & メンテナンス性
コア側での対応だと、ユーザーの環境の多様性を考えると不安が残ります。今はまだx86_64のWindowsのDirectMLに対応するだけなのですが、将来サポート対象を拡大することを考えると、これだけのOSに対し
これだけの数のEP (execution provider)があることも考えなくてはなりません。
一方でエンジン側でやるときのコストですが、あまりイメージが掴めていません。このissue内で伺えたらと思っています。
以上より実装してメンテするコストが低いのであれば、PyInstaller側でグローバル変数を定義するのがいいのではないか、というのが私と @Hiroshiba さんの考えです。
実現方法
bootloaderをビルドする方法が公式で説明されているため、以下のコードを加えたbootloaderを使うようにすればいいのではないかと考えています。
やっている人の例
OSの種類/ディストリ/バージョン
その他
#439
The text was updated successfully, but these errors were encountered: