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

NvOptimusEnablementAmdPowerXpressRequestHighPerformanceを宣言 #322

Closed
wants to merge 3 commits into from

Conversation

qryxip
Copy link
Member

@qryxip qryxip commented Oct 26, 2022

内容

NvOptimusEnablementAmdPowerXpressRequestHighPerformanceを宣言し、DirectMLで良い方のGPUが使われるようにします。

関連 Issue

Fixes #309.

その他

Optimusの環境はおろか、まだ通常のWindowsの環境でも実際に動かしてません。そのためdraftとします。

@qryxip
Copy link
Member Author

qryxip commented Oct 26, 2022

cargo testがあるのでvoicevox_coreのbuild.rsにもコマンドが必要?

@Hiroshiba
Copy link
Member

PRありがとうございます!!

ちなみにAmdPowerXpressRequestHighPerformanceというのはなんでしょう?👀

@qryxip
Copy link
Member Author

qryxip commented Oct 26, 2022

AMDのグラボ+その他のグラボの組み合わせにおいて、NvOptimusEnablementのような役割を果たすシンボルのようです

世のOSSではNvOptimusEnablementとセットで宣言されることが多いように見えました。

@qryxip
Copy link
Member Author

qryxip commented Oct 27, 2022

あとは実際に効いているか確認できるといいのですが、GPU2枚のPCを持っているのが自分だけみたいなのでWindows環境構築頑張ります...
(といっても1年分近い量のWindows Update → ブラウザ, Git,gh,Visual Studioのセットアップ → このPRとmainとでexample/cpp/windows/simple_ttsの時間を軽く比較するというので十分そうですが)

@Hiroshiba
Copy link
Member

世のOSSではNvOptimusEnablementとセットで宣言されることが多いように見えました。

なるほどです!!対応ありがとうございます!!

あとは実際に効いているか確認できるといいのですが、GPU2枚のPCを持っているのが自分だけみたいなのでWindows環境構築頑張ります...

すみません、こちらもありがとうございます 🙇
もし難しそうであれば、えいやでビルドしてしまって、リリースするまでにビルドしてテスターの方を募集するというのも可能かもしれないので、その際は仰っていただければ!

@qryxip
Copy link
Member Author

qryxip commented Oct 29, 2022

Windowsで環境が構築できたので動かしてみたのですが…駄目ですね。

C API(エンジン越し)とPython APIの両方において、NvOptimusEnablementによる影響は見られませんでした。NvOptimusEnablementはちゃんと宣言されているみたいですし、AmdPowerXpressRequestHighPerformanceの宣言を抜いても同様です。

image

私のPCの場合統合GPUはRyzenのものなので、Intel Graphicsならちゃんと動く、という可能性もまだ残っていますが…

@Hiroshiba
Copy link
Member

検証ありがとうございます!!!!

おっと・・・・・・・予想外ですね・・・。
GPU 0番が使われてるわけでもないので、ほぼ間違いなくOptimusの影響な気がしますね・・・。

原因の切り分け・・・・というより追証方法ですが、いくつか挙げてみます。

  • Optimus環境依存かを確かめるために、Optimusを手動で切ってみる
  • GPUの課題か調べるために、CUDA版を使ってみる
    • まあ・・・普通に画面描画などでは使われていそうなので、たぶんGPU 0の方が使われると思うのですが・・・。

@qryxip
Copy link
Member Author

qryxip commented Oct 30, 2022

もしやと思いcrates/voicevox_core/examples/simple-tts.rsを書き、Rustの単一バイナリとして実行したらNvOptimusEnablementが効果を示しました。

NvOptimusEnablementで制御するのなら、コアじゃなくてPyInstaller(Nuitka)側の対応になりそうですね…

NvOptimusEnablement未設定:
image

NvOptimusEnablement設定:
image

@qryxip
Copy link
Member Author

qryxip commented Oct 30, 2022

@Hiroshiba
Copy link
Member

あーーー なるほどです。dllではなくexe側で定義しないとダメという感じでしょうか。

@qryxip
Copy link
Member Author

qryxip commented Oct 31, 2022

ですね。

ただwinapiでGPUの情報を取得してみたところ、うまくいったし、このi=1を↓に入れたところGeForceが使われることも確認しました (Windows 11をアップデートしたらタスクマネージャも変わってしまったので、若干わかりにくいですが)。

if #[cfg(feature = "directml")]{
session_builder
.with_disable_mem_pattern()?
.with_execution_mode(onnxruntime::ExecutionMode::ORT_SEQUENTIAL)?
.with_append_execution_provider_directml(0)?

DedicatedVideoMemoryが一番大きいデバイスを指定するというのもありなのではと思っています。

1を指定:
image

0を指定 (従来通り):
image

@Hiroshiba
Copy link
Member

Hiroshiba commented Oct 31, 2022

詳細な検証ありがとうございます!!

DedicatedVideoMemoryが一番大きいデバイスを指定するというのもありなのではと思っています。

仰る通りこちらの方法もありだと考えています。
ちょっとユーザー満足度の最大化・メンテナンス性・実装コストの観点から考えを整理してみました。

まず、UX考えると、「大多数の人が意図した挙動になり、意図しない挙動をする場合は変更可能になっている」というのが良いのかなと思いました。
この点だと、メモリ最大のものを利用するパターンも、シンボルで制御する場合も、そもそも意図しない挙動をするPCが相当少ない気がしました。
シンボル定義の場合はOSレベルでコントロール可能な気がしますが、対象者数が極端に少なそうなのでいったん他の項目を優先して良さそうに感じます。

メンテナンス性に関して言えばシンボル側が楽な気がします。
メモリ最大のものを取得するとなると、OSやGPUデバイス、下手したらドライバごとにいろいろ違っていそうだからです。
一方シンボル側は公式が足並みをそろえてくれそうなので、楽そうです。

最後に実装コストの面ですが、↑の理由でいろんなデバイスでメモリを取得するのが大変そうに感じました。
仮にpythonビルドでシンボルを定義できそうなのであれば、こちらを優先すると良いのかなと思いました。

@qryxip さんの調査のおかげでいろんな手段とコストが見えてきました、ありがとうございます!!!

@qryxip
Copy link
Member Author

qryxip commented Nov 1, 2022

シンボル定義の場合はOSレベルでコントロール可能な気がしますが

こちらについてですが、シンボルを宣言した実行バイナリではNVIDIA Control Panelで統合GPUを使うように指示したとしてもGeForceが一番最初に来るようになります。つまりおそらくはユーザ側での制御はできなくなります。

メンテナンス性に関して言えばシンボル側が楽な気がします。
メモリ最大のものを取得するとなると、OSやGPUデバイス、下手したらドライバごとにいろいろ違っていそうだからです。
一方シンボル側は公式が足並みをそろえてくれそうなので、楽そうです。

こちらには同意します。現在VOICEVOX COREは

の3通りでしかGPUの利用をサポートしていないため、今問題を解決するにはx86_64のWindows上でGeForce (or Radeon)を探し当てられさえすればいいのですが、将来サポート対象を増やすことを視野に入れると

  • Windows x86_64 (第一級サポート)
  • Windows aarch64
  • macOS x86_64
  • macOS aarch64
  • Linux x86_64
  • Linux aarch64
  • Android?
  • iOS/iPadOS?

に対してこれだけのproviderがあることを考えなくてはなりません。macOSのGPUを使えるようになるのは今後も望めなさそうだしスマホに複数のGPUは無いでしょうから、WindowsとLinuxだけ考えればよさそうではあるのですが。

あとはPyInstaller側での実装とメンテが楽ならいいのですが。公式で方法が紹介されているので、いけるんじゃないかとは思ってます。

(ところでPyInstaller側の対処を選択肢に入れるなら、そろそろengineの方にissueを作るか、Discordで呼びかけるかした方がいいんじゃないかと)
追記: いや VOICEVOX/voicevox_engine#439 で紹介すればいいですね

@Hiroshiba
Copy link
Member

シンボルを宣言した実行バイナリではNVIDIA Control Panelで統合GPUを使うように指示したとしてもGeForceが一番最初に来るようになります

なるほど・・・・・・。これは勘違いしていました、ありがとうございます。

に対してこれだけのproviderがあることを考えなくてはなりません

リストアップありがとうございます!
こう見るとonnxruntimeだいぶすごいですね。

ところでPyInstaller側の対処を選択肢に入れるなら、そろそろengineの方にissueを作るか、Discordで呼びかけるかした方がいいんじゃないかと

仰るとおりだと思います。まあ先に僕たちの間で握っておかないと話がこんがらがるので!

そちらのissueはpyinstaller化がメインなので、別でissueを作ると優しいのかなと感じました。
知識量は圧倒的に @qryxip さんの方が上なので、もしよければissue作成をお願いしてもよいでしょうか。
(お時間難しければこちらでまとめて作ろうかなと思います 🙏 )

@qryxip
Copy link
Member Author

qryxip commented Nov 2, 2022

issue立てたのでこのPRは閉じます(題名の通りの実装は不可能であるため)。

@qryxip qryxip closed this Nov 2, 2022
@Hiroshiba
Copy link
Member

issue作成と、あと詳細な検証も本当にありがとうございました・・・!!!

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

Successfully merging this pull request may close these issues.

(DirectML環境で)一番良いGPUを自動選択・GPUを選択可能にする
2 participants