Skip to content

Conversation

@tarepan
Copy link
Collaborator

@tarepan tarepan commented Apr 23, 2025

#1681 での議論が収束したため、レビュー可能になります。全体を大きく書き換えました。)

内容

NumPy のレガシー関数を置き換えて ruff NPY を適用するリファクタリングを提案します。

VOICEVOX ENGINE は数年間にわたり運用されてきたため、外部ライブラリのレガシーな関数等が残っている。
具体的には np.random.rand がレガシーであり、置き換えが必要である。

また NumPy は大規模なバージョン移行が近年あったため、古い numpy に慣れたコントリビューターが手癖でレガシー関数を新たに使うリスクがある。
これは ruff NPY ルールで予防できる。

#1646 の基準に従って整理すると、NPY ルール導入には現時点で以下の利点がある:

  • バグを減らす
    • 現時点での潜在的なバグが見つかる
      • 乱数の振る舞い等、ベストでない特性をもつレガシー関数 np.random.rand を置き換え

また将来的にも(上記に述べたように)バグ埋め込みの危険性を下げる。
NPY は 4 つのルールのみからなり、基本的に deprecated と lagacy のチェックであり、デメリットは無い。

このような背景から、NumPy のレガシー関数を置き換えて ruff NPY を適用するリファクタリングを提案します。

関連 Issue

無し

@tarepan tarepan requested a review from a team as a code owner April 23, 2025 21:59
@tarepan tarepan requested review from Hiroshiba and removed request for a team April 23, 2025 21:59
@Hiroshiba
Copy link
Member

と同様、一旦さきに静的解析を頑張る理由を整理できると嬉しいです・・・!
この変更は今のコードだとメリットしかなさそうですが、一応導入する以上他にどういうルールが有るのかは全部見ておく必要がありそうで、だとするとレビュー時間がそれなりに伸びるから一旦先に方針を考えてメンテを楽にしたいなーと。

@tarepan
Copy link
Collaborator Author

tarepan commented Apr 24, 2025

一旦さきに静的解析を頑張る理由を整理

👍️
#1646 を建てました。こちらでリンター・フォーマッターに関する広い議論をおこない、その結果を受けて本 PR を進行します。
#1646 での議論完了まで本 PR は draft 化します。

@tarepan tarepan marked this pull request as draft April 24, 2025 08:39
@Hiroshiba Hiroshiba force-pushed the master branch 3 times, most recently from e2f0df9 to 5a6877e Compare June 9, 2025 12:17
@tarepan tarepan changed the title refactor: ruff FASTNPY を適用 refactor: NumPy のレガシー関数を置き換え Jun 22, 2025
@tarepan tarepan changed the title refactor: NumPy のレガシー関数を置き換え refactor: NumPy のレガシー関数を置き換えて ruff NPY を導入 Jun 22, 2025
@tarepan tarepan changed the title refactor: NumPy のレガシー関数を置き換えて ruff NPY を導入 refactor: NumPy のレガシー関数を置き換え・ ruff NPY を導入 Jun 22, 2025
@tarepan tarepan marked this pull request as ready for review June 22, 2025 20:13
Copy link
Member

@Hiroshiba Hiroshiba left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

うーん、LGTMで!!

# Inputs
query = _gen_query(volumeScale=2, outputSamplingRate=48000, outputStereo=True)
raw_wave = np.random.rand(240).astype(np.float32)
raw_wave = np.random.default_rng().random(240).astype(np.float32)
Copy link
Member

@Hiroshiba Hiroshiba Jun 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(ただのコメントです)

こーーーーーのルールは結構おせっかいというか、思想強めな気がしますねぇ!!

deprecatedの根拠としてる部分はここですが、
https://numpy.org/doc/stable/reference/random/legacy.html#legacy-random-generation
おそらく「より良いランダムを冪等に得るにはこっちが良い」くらいの気持ちな気がしました。
「numpyのコードを正しく書こう」というより、「ランダムを正しく得よう」というモチベに立つと、たしかに非推奨になる。

でも僕達が使ってるrandomの場所はそこそこな乱数であれば良いので、むしろnp.random.randのが直感的な気がしますね・・・。
実際この関数のドキュメント見に行ってもどこにも非推奨だと書いてないし・・・。
https://numpy.org/doc/stable/reference/random/generated/numpy.random.rand.html

まあ僕達はnumpyの中の、数値ベクトルを一気に計算できるとこだけしか使ってないのでレアケース寄りなんですが・・・。
(numpyをよく使う自分的には結構ありがたいけど、VOICEVOX ENGINE的にはいまのとこ結構ありがた迷惑)

NPYルールはもう詳しくなるコストかけちゃったので、せっかくなので導入で良いと思いました!
NPY002以外は有用そうだし。

これ級のおせっかいルール・・・今回の例でもうちょっと言語化すると、そのドメインには有用だけどこっちのドメインでは手続きが増えるだけのものが、まあ結構あるだろうな~と感じました。
使ってるのが2箇所だから良いけど、これがいたるところに出てきたらたぶんデメリットのが大きい気がしました。
自分が把握しているだけで良いならむしろ適用されたほうが嬉しいんですが、新規コミッターが出くわしたらなんで?ってなりそうだよなぁと。
将来適当で良いランダム使う箇所が増えたらignoreすることになるかも。

あ。エラーではなく、自動修正されるとかならまぁ別に良いかもです。

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NumPy docs より:

This class should only be used if it is essential to have randoms that are identical to what would have been produced by previous versions of NumPy.

「This class should only be used」との記述からすると、deprecated ではないが特殊用途(どこでも使うのは非推奨)、が自然な解釈だと私は理解しました。

こっちのドメインでは手続きが増えるだけのもの

現時点では一理あると感じます。機能的に十分で、かつ、とても書き慣れた記法です。

ただ、新コードは既存コードの慣習を引きずりやすいため、「良い乱数がほしいな、あ、近くに書いてある np.random.rand 使えばいいか」で危険な乱数が導入される将来のリスクがあると考えます。

一方で、NPY002 導入によるコード増加量は default_rng(). という14文字だけです。
この14文字で「直感性が凄い落ちた」と感じるのは、私含めた、NumPy 1 のレガシーに慣れたプログラマーのみだと思います。NumPy 公式が述べている「This class should only be used」に沿ってコーディングしてきた NumPy 2 ネイティブは「乱数ってそうやって作るものでしょ?」と感じそうです。

今回に関しては、新記法にするのがトータルプラスだと考えます。


(似た議論が他でも今後ありそうなので)

ルールは結構おせっかいというか、思想強めな気が

ひとつの基準として、「公式が言っている推奨法をルール化したもの」「linter 作者の思想をルール化したもの」の分けるのがよさそうと今回のを見て感じました。

  • 前者であれば基本従う
  • 後者が多いルールは導入 NoGo 寄り(議論コストに見合わない可能性がそれなり)

とすれば、だいぶ議論コストを下げられそうです。
後者に関しては、PR 作成者が責任を持って導入メリットを述べた場合に限って議論すれば良さそうです。

Copy link
Member

@Hiroshiba Hiroshiba Jun 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

危険な乱数が導入される将来のリスクがあると考えます

この小さな差が致命的になるような機能が追加されることはあまり思いつかないですねー。
役立つのは統計を取るときとか、数億個くらいの乱数を高頻度に作るときとか、論文書くときくらいかなと。

NPY002 導入によるコード増加量は default_rng(). という14文字だけです。

文字数ではなく、どちらかというと「開発者が意味わからないエラーに遭遇してコミットを辞めたくなる」とかを懸念しています。
この辺ですかね。↓

image

これ単体なら大丈夫だと思いますが、ルールを導入しまくってこういうのが10個20個ある状況になるとだいぶしんどいと思います。
(僕はいっぱいあるうちの1つを適用する場合、こういう最終的にどうなりうるかを想像しながら導入すべきか考えてます。実は無駄なのかも。)

今回に関しては、新記法にするのがトータルプラスだと考えます。

今回は他のルールが優秀そうなので導入でOKだと思います。

「公式が言っている推奨法をルール化したもの」「linter 作者の思想をルール化したもの」

思想が強いという表現がちょっと良くなかったかもです。
今回のが微妙な理由は違ってて、ルールは目的のために導入するけど、その目的が自分たちにとって問題ではなく、かつルールによってデメリットが生じてる状況だと思います。

つまりまあ、どっちであるかはあまり関心がないかなぁと。
それでメリットがどれだけあり、デメリットがどれだけないかだと思います。
(僕はpython公式がl使うなと言ってるのも、フォントが変わった今これに従うのはデメリットのが大きいと感じます)


今後まだたぶんルール追加のすると思うので、今の個人的な感想をメモしておきます:

  • 考え方があってないルールはたぶん今後結構ある
  • 細かいデメリットよりメリットの量を考えると最終的な考えに近いところから始められる
  • 恩恵がなくてデメリットだけあると感じるものは全てオフにする、みたいな指針もありかもしれない

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

危険な乱数が導入される将来のリスクがあると考えます

これに関して念のため指摘しておきます。
そもそもこのモジュールはセキュリティや暗号化のためには設計されていないと書かれています。
https://numpy.org/doc/stable/reference/random/index.html

Warning
The pseudo-random number generators implemented in this module are designed for statistical modeling and simulation. They are not suitable for security or cryptographic purposes. See the secrets module from the standard library for such use cases.

そのためLegacy Generatordefault_rng置き換えてもセキュリティ用途に使っている限り危険であると思います。

@Hiroshiba
Copy link
Member

たぶん大丈夫だと思うのでマージします!!

@sabonerune さんもありがとうございました!!

@Hiroshiba Hiroshiba enabled auto-merge August 2, 2025 14:15
@Hiroshiba Hiroshiba added this pull request to the merge queue Aug 2, 2025
Merged via the queue into VOICEVOX:master with commit 18ce0a2 Aug 2, 2025
5 checks passed
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.

3 participants