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

スレッド数に見合った性能が発揮されていない #291

Closed
2 of 5 tasks
AsPulse opened this issue Jan 16, 2022 · 15 comments
Closed
2 of 5 tasks

スレッド数に見合った性能が発揮されていない #291

AsPulse opened this issue Jan 16, 2022 · 15 comments
Labels
OS 依存:linux Linux に依存した現象 OS 依存:win Windows に依存した現象

Comments

@AsPulse
Copy link
Contributor

AsPulse commented Jan 16, 2022

内容

#282 にて、CPUスレッド数を指定できるようになりましたが、
CPUスレッド数に対して性能が上がらない、むしろ下がるという現象が発生しました。

環境によってがっつり左右されそうなので、今は実装して対応していくIssueというよりかは、
条件を変えて実験・計測したデータをココにコメントしていき、実装されている方の参考にしてほしいと思っています。

Pros 良くなる点

音声合成が早くなる。

Cons 悪くなる点

/特になし/

実現方法

上記の通り、まずは色々データをとってみて原因を考えたいと思っています。

VOICEVOXのバージョン

hiroshiba/voicevox_engine:cpu-ubuntu20.04-0.10.preview.11

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

  • Windows
  • macOS
  • Linux

今予定している検証

  • 仮想環境でも手元環境同じ現象が発生するか確認
  • 仮想環境でCPU使用率の制限を調べる
@github-actions github-actions bot added OS 依存:linux Linux に依存した現象 OS 依存:win Windows に依存した現象 labels Jan 16, 2022
@AsPulse
Copy link
Contributor Author

AsPulse commented Jan 16, 2022

現在私の手元環境で行った結果です。
ただ、他のプロセスが動いていたりすることもあり、あまり正確とは言えない検証だと思います。

イメージ: hiroshiba/voicevox_engine:cpu-ubuntu20.04-0.10.preview.11
環境: 4Core CPU搭載の Linux
指定方法: VV_CPU_NUM_THREADS環境変数を指定
調査方法: 日本国憲法50文字を、それぞれ5回ずつ読み上げさせ、所要時間を計測する

今回使用した文章
日本国民は正当に選挙された国会における代表者を通じて行動しわれらとわれらの子孫のために諸国民との協和
スレッド数 (VV_CPU_NUM_THREADS) 平均所要時間(ms) 標準偏差
3 12291.8 134.3
2 11123.6 121.9
1 18471.6 134.9

1スレッドの場合は、想像通り2スレッドの場合の二倍ほどの時間がかかっているのですが、
3スレッドの場合は2スレッドの場合よりも少し遅くなっているという結果でした。

@shigobu
Copy link

shigobu commented Jan 21, 2022

暇だったので、テストアプリを作成してテストしました。
https://github.com/shigobu/VOICEVOX_CPU_NUM_THREADS_TEST

エンジンバージョン:0.10.preview.11
OS:Windows 10 Home 20H2
CPU:Intel(R) Core(TM) i7-8700 CPU 6コア 12スレッド
指定方法:--cpu_num_threadsコマンドライン引数で指定
調査方法:AsPulseさんと同じ文章で、同じくそれぞれ5回ずつ読み上げさせ、所要時間を計測

スレッド数 平均所要時間 標準偏差
1 6205.2 36.5
2 3426.6 44.3
3 2604.8 43.7
4 2357.6 77.8
5 2339.8 23.9
6 2205.4 16.2
7 2060.0 15.7
8 1928.0 12.5
9 1814.0 22.4
10 1721.6 14.8
11 1665.2 16.6
12 1850.0 48.0

@Hiroshiba
Copy link
Member

おーーー!! なるほどです!!

デフォルトらしいスレッド数半分(6)の地点に比べると、最良の場合(11)は1.3倍くらい速くなっていますね!

最大スレッド数の12にすると逆に悪くなっているように見えますねー。
環境によっては少し小さめの値を指定したほうが良いのかもと思いました。

ありがとうございます、とても参考になりました!!
とりあえずこのissueの結論としては、スレッド数が増えていくにつれて性能は上がるが、最大スレッド数付近だと逆に劣化することがある、みたいな感じでしょうか。
いかがでしょう 👀 @AsPulse

@Hiroshiba Hiroshiba added the 要議論 実行する前に議論が必要そうなもの label Jan 21, 2022
@AsPulse
Copy link
Contributor Author

AsPulse commented Jan 23, 2022

image

@shigobu さん、ありがとうございます!
グラフ化をしてみましたが、これは4スレッド以上の並列化はほぼ意味が無いのではないか...という結論にも思えます...
また、最大スレッド数だとEngineやOSが使うリソースがなくなってしまい速度が落ちる...ということはありそうだと思いました。

(Issueの取り扱いですが、どうするのがよろしいでしょうか...?
 私はスレッド数に見合う性能が発揮できるような修正ができるまで、
 結論を出してCloseとはしない方向を考えていたのですが....。
 このIssueは優先されないままで結構ですのでゆっくりデータを集めて最終的に解決しCloseに至ればいいかなと思っています)

@shigobu
Copy link

shigobu commented Jan 23, 2022

テストアプリを改良して、エンジンプロセスの優先度を指定できるようにしました。
プロセス優先度を「リアルタイム(Windowsの最高)」に設定して、再度テストしてみました。

スレッド数 平均所要時間 標準偏差
1 6183.4 50.83542
2 3362.2 21.44201
3 2448 11.91638
4 2031.2 12.05653
5 1801.8 15.40649
6 1840.2 147.3478
7 2089.2 18.60538
8 1940.6 9.520504
9 1817.8 19.08298
10 1723.8 23.60847
11 1651.2 16.71407
12 1642.4 19.25201

最大スレッド(12)を指定したときの逆転現象は解消されましたが、それ以外はほぼ変化無しといったところでしょうか。
マルチスレッド処理は単純にスレッドを二倍にすると処理時間が二分の一になるものでは無いですし、この結果はintelのハイパースレッディングを使用してるので、なおさら処理時間の短縮効果は低くなります。
そう考えると、この結果はまあまあ良い感じに高速化ができてるのかなと思いました。
確かに4スレッド以上の並列化はほぼ意味が無いように見えますが、大量に音声合成を行う用途で有効に働くと思います。

@Hiroshiba
Copy link
Member

Hiroshiba commented Jan 23, 2022

優先度、なるほどです!

こちらのissueですが、しごぶさんのおっしゃる通り、onnxruntimeはよくあるプログラムと一緒で、スレッド数に比例してパフォーマンスが出るわけでは無いのかなと思っています。
(onnxruntimeのカタログスペックにそういった説明がない限り)

問題に感じていたのは「スレッド数が増えると性能が悪くなる可能性」で、それは優先度等の設定によるのかなと感じました。
であれば、このissueはもう解決なのかなと思っています。

onnxruntimeにはまだまだいろんなオプションがあります。
より高速に生成できる方法があるかもなので、もし見つけられたらご報告いただけるととても嬉しいです…!

@AsPulse
Copy link
Contributor Author

AsPulse commented Jan 23, 2022

shigobuさんまたの検証ありがとうございます!

もちろん、スレッド数に比例しないことはわかっているのですが、
2倍のリソースを使っているのに10%しか性能の改善がないのは流石に少し違和感があり...

Core側の実装になるかもしれませんが、accent_phraseから分割しても大丈夫な要素を切り出し、2スレッドごとに分担して起動する...のような芸当は難しいのでしょうか...

ふわっとしたイメージ:
スレッド1, 2: ニッポンコ'クミンワ/セエトオニ'/セ'ンキョ/サレタ'
スレッド3, 4: コッカイニ'/オケル'/ダイヒョオシャオ'/ツウジテ'
スレッド5, 6: コオドオ'/シ'/ワレ'ラト/ワレ'ラノ/シ'ソンノ/タメ'ニ
スレッド7, 8: ショコ'クミントノ/キョオワ'
(最後に結合)

@Hiroshiba
Copy link
Member

なるほどです、onnxruntimeではなく、コアの性能を上げる感じでしょうか。
音声合成で時間がかかっている部分は時間ごとに区切って生成することが可能なので、おっしゃることは不可能ではないと思います。

ただ、チューニングは至難の技だと思います。
大げさかもですが、onnxruntime(マイクロソフト)ができてない領域のチューニングを行うということなので、かなりの専門知識と労力が必要だと思います。

VOICEVOXの技術的には、計算速度を上げるよりも、そもそも計算リソースを必要としない手法を目指すほうが現実的なため、注力するとしたらこちらになりそうです。
実際、実はもう計算コストを下げた技術はある程度準備できていて、あとはコード側がいろんなコアが使えるようになれば用意できそうです。

もし高速化にチャレンジされたい場合は仰って頂ければ・・・・・・!
他にも魅力的なプロジェクトがあるので良かったらこちらもどうぞ!!
https://github.com/VOICEVOX/voicevox_project/issues

@modeverv
Copy link

modeverv commented Apr 16, 2023

すみません。。。
https://qiita.com/uezo/items/7e476147ec6312ad8a2c
の記事を見まして、並列で生成できないの?と思ったのですが、

指定方法:--cpu_num_threads

を指定して起動すると並列で音声生成してくれる機能があるという理解でよろしいのでしょうか?
例えば4とかを指定すると4つまで同時に受け入れて生成プロセスが走って欲しいのですが。。
すみません、教えていただけると幸いです。。
自分で検証しろ、ってその通りなのですが、ちょっと立て込んでまして。。。

@modeverv
Copy link

modeverv commented Apr 16, 2023

4つまでで動かしてあとは機械を横に並べてロードバランスすればいけそうですね。
4coreあれば良いのでそこそこリーズナブルな機械を並べれば戦えそうですね。

@aoirint
Copy link
Member

aoirint commented Apr 16, 2023

@modeverv

このIssueと--cpu_num_threadsオプションは、1つの音声生成に対して使用するCPUパワーの割合に関するもので、
複数の音声生成を処理するものではないと思います。

このIssueの趣旨と関係ないためここでの議論は避けたいです。別途適切なIssueを見つけるか、なければ作成するとよさそうです。

参考情報ですが、長文の生成中に短文の生成をリクエストしたとき、先に短文の応答を返す、というような並列生成機能は、いまのVOICEVOXにはないと思います。

個人的な意見ですが、記事の著者のように、中継サーバで制御するのが手っ取り早いと思います(コストがかけられるならば、複数のVOICEVOX ENGINEサーバを用意してリクエストを分散するなど)。

将来的に、潤沢なRAM/VRAMを前提として、同じバージョンの音声合成コア(動的ライブラリ=VOICEVOX CORE)を複数利用可能にする機能が実装されれば、それぞれのコアに生成処理を分散する機能が提案されるかもしれません(仕様的に実現可能かはよくわかりません)が、あまり進んでいなさそうです(興味のある開発者がいれば進むかもです)。

@Hiroshiba
Copy link
Member

Hiroshiba commented Apr 16, 2023

issueのタイトルの内容に対する疑問は #291 (comment) で解消しているはずなので、closeしたいと思います。

@modeverv
並列で複数生成する部分は @aoirint さんの仰る通りサポートしていません。

たしかにコア数4程度のマシンを大量に並べるのが効率良さそうに思います。
(16コアある場合、4個エンジンを稼働させたら効率はどうなるのかちょっと気になりました。)

なにかおもしろい計測結果が得られたらissueやTwitterハッシュタグ #VOICEVOX などで知らせていただけると嬉しいです・・・!!

@modeverv
Copy link

@aoirint
@Hiroshiba
ガイダンスありがとうございます。
coreらへんのソースを弄れば並列動作できるかも、ですね。
ちょっとソース落としてみてみます。
ありがとう。

@modeverv
Copy link

engine側で吸収して同時処理性能上がりました!私は満足です!時間がないのできちんとまとめることができません。ごめんなさい!
https://qiita.com/lovesaemi/items/0538af6203291efdd38e

@Hiroshiba
Copy link
Member

@modeverv 動いてそうですね!!

単体起動した場合との速度差が気になりました。
もしかしたら並列起動している同士が邪魔しあって逆に遅くなってるかもしれないです。
またわかったことがあればぜひ・・・!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
OS 依存:linux Linux に依存した現象 OS 依存:win Windows に依存した現象
Projects
None yet
Development

No branches or pull requests

6 participants