Skip to content

GPU(CUDA・DirectML)版コアが期待通りに動いていない可能性がある #143

@PickledChair

Description

@PickledChair

不具合の内容

Twitter における報告(現象・ログを参照)から、DirectML 版コアで yukarin_sa が期待したように動いていない可能性が考えられました。推論結果として異常な数値が返ってくるようです。

現象・ログ

当該現象が報告されたツイート: https://twitter.com/maki07061210/status/1531507875234861056

以下、引用です:

GPU版に限り、イントネーションのバーが
限界突破しており

冥鳴ひまりが下方向にイントネーションが振れております

青山流星は上方向にイントネーションが振れております。

CPU版では特にありませんでした

再現手順

https://github.com/VOICEVOX/voicevox/releases/tag/0.12.0 で配布されているプレビュー版の VOICEVOX(DirectML 版)を起動し、冥鳴ひまり・青山流星の音声合成を試みる。

期待動作

GPU (CUDA, DirectML) 版コアでも CPU 版とほぼ同じ推論結果を得られる。


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

  • Windows (10? 11?)

Linux の GPU 版でも同様の問題が発生するかどうかは、今のところ不明です。


その他

Discord におけるやりとりで、以下のような追加情報が得られています。

1. CUDA 版も挙動がおかしいかもしれない

関連は不明ですが、CUDA 版の挙動が CPU 版と異なるという現象は、以前からあったかもしれないことが指摘されていました。CUDA 版も同様の問題を抱えている可能性があります:

なんかそういえばCUDA使ってたときyukarin_saだけもGPUとCPUで挙動違うみたいなのあった気がする。
その辺りが実はメモリ参照とかがぶっ壊れてて、DIrectML版だと運が良くてこうなったりするのかな。。。

2. 全ての Ort::Session インスタンスに対して GPU オプションが設定されるような変更があった

以前のコアでは、yukarin_sa は CPU で動かすようになっていたはず、という指摘がありました:

あれ、でも今も昔もyukarin_saはCPUで動かすようになってませんでしたっけ
あ、モデル複数読み込みを実装した時に崩壊したっぽい...?
もしかしたら、yukarin_saはDirectMLが壊れてるようにCUDAも壊れてる可能性はありそうではある...?

確認したところ、バージョン 0.11 以前では実際に、decode モデルに対応する Ort::Sessionインスタンスだけに OrtCUDAProviderOptions が設定されていました:

Ort::SessionOptions session_options;
session_options.SetInterOpNumThreads(cpu_num_threads).SetIntraOpNumThreads(cpu_num_threads);
yukarin_s = Ort::Session(env, yukarin_s_model.data(), yukarin_s_model.size(), session_options);
yukarin_sa = Ort::Session(env, yukarin_sa_model.data(), yukarin_sa_model.size(), session_options);
if (use_gpu) {
const OrtCUDAProviderOptions cuda_options;
session_options.AppendExecutionProvider_CUDA(cuda_options);
}
decode = Ort::Session(env, decode_model.data(), decode_model.size(), session_options);

それに対してバージョン 0.12 現在は、Status の初期化時に GPU のオプションが設定され、以降全ての Ort::Session インスタンスに対してこのオプションが適用されています:

session_options.SetInterOpNumThreads(cpu_num_threads).SetIntraOpNumThreads(cpu_num_threads);
if (use_gpu) {
#ifdef DIRECTML
session_options.DisableMemPattern().SetExecutionMode(ExecutionMode::ORT_SEQUENTIAL);
Ort::ThrowOnError(OrtSessionOptionsAppendExecutionProvider_DML(session_options, 0));
#else
const OrtCUDAProviderOptions cuda_options;
session_options.AppendExecutionProvider_CUDA(cuda_options);
#endif

今後、元の実装に近づけることも提案されました。これで問題が解決される可能性があります:

今やるなら、common_session_optionsとdecode_session_optionsを用意する感じになりそう...?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions