-
Notifications
You must be signed in to change notification settings - Fork 117
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
Python APIのSynthesizer
をclose()
可能にする
#555
Conversation
個人的には
これはあっても良いなと思います! |
まずONNX Runtimeのsessionに注目すると、メモリというよりは外部リソースに近いものだと理解しています (「計算資源」という表現はよくなかったかもしれません)。 あとPython以外だと、ONNX Runtimeの公式Java APIでは 肝心のPython APIにはそのようなものはありませんが、それ以前に ❯ rg ReleaseSession ./onnxruntime/python/
❯ echo $?
1 ❯ rg __del__ ./onnxruntime/python/
❯ echo $?
1 以上より ただこれはさっき気づいたのですが、 何で今こんなことを言うのかというと、Java APIとC# APIの需要があるかもしれないことでそれらの実装が現実的になったからですね。慣習に反しない範囲においては、合わせるのがよいのではないかと思っています。 @windymelt @shigobu @yamachu お時間があるならでいいのですが、一点ご意見を伺えると幸いです。
その説明だと、広義のRAIIとして括ってよいのでは?という気がします。RAMも拡大解釈すれば、リソースと言えるでしょうし。
NumPyはまあ、その仕組み上容易には提供できないということではないでしょうか。 あと今回の件で改めて思ったのですが、今の |
ちょっと言語レベルの話をすると議論が平行しそうなので、APIを利用するユーザーのニーズベースで話すと早いかもと思いました。
synthesizer = Synthesizer()
@POST_API
def set_vvm(vvm_path: str):
synthesizer.unload_all()
synthesizer.load(vvm_path)
@POST_API
def synthesize(text: str):
return synthesizer.synthesis(text) このコードはwithを使って書けないんですよね。 withが必要になるありそうなユースケースがあれば納得できると思います。
少なくともメモリーリークしないのであれば、まあ困ることはほぼないだろうなと思いました。 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
まあでも、リソースを全部キレイに掃除したいという需要がPythonユーザーに絶対ないかというと、そんなことは無いと思います。
別に重い実装でもない(メンテナンスコストが高い訳では無い)ので、あとはテストがあれば良いかな~と思いました・・・!!
JupyterとかColabで with await Synthesizer.new_with_initialize(open_jtalk) as synthesizer:
await synthesizer.load_voice_model(vvm)
aq = await synthesizer.audio_query("こんにちは", 0)
wav = await synthesizer.synthesis(aq, 0)
IPython.display.Audio(wav)
...VRAMをですか? それは少しばかりハードルが高いような... |
あー APIを利用するユーザーのニーズベースなので、ユーザーが何の作業をしているときにそのコードを書くのかのユースケースが知りたい感じでした。「Web APIサーバーを作るとき」とか。
普通のメモリを想像してました。まあともかくユースケースかなと!!
どれでもOKです! |
|
なんか名無し。さんのJavaもちゅうこさんのC#も、"closable"にする方向になっている...? |
内部でRustの型を持つためにJNIEnv.set_rust_fieldを使っているんですけど、これはtake_rust_fieldを呼ばないとメモリリークするんですよね。Safetyに「AutoClosableとかを実装して、closeされることを保証すべき」と書かれているのでcloseを追加しました。(finalizerもあったらしいんですけどJava9から非推奨になってるので) |
@sevenc-nanashi |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
テストの実装だけお願いします 🙇
e2eテストで、withしたあとにcloseされているべきリソースにアクセスできない、みたいな感じのテストでもいいのかなと。
(withが使えることの正常系テストをやっときたい感じです!)
ちなみにwithを2回呼べないことに関して、Pythonはそれがどちらかというと普通みたいな感じでした!
https://docs.python.org/ja/3/library/contextlib.html#single-use-reusable-and-reentrant-context-managers
|
|
確かに。 |
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!!!
調整ありがとうございます!!明確で綺麗なテストに感じました。
コメントいただければマージしたいと思います。
crates/voicevox_core_python_api/python/test/test_pseudo_raii_for_synthesizer.py
Show resolved
Hide resolved
マージします! |
内容
以下のことをやります。
https://discord.com/channels/879570910208733277/893889888208977960/1131974735920635985
Synthsizer
は計算資源を大きく占有するため、丸ごと破棄する選択肢をPython APIでも取れるようにした方がよいと思いました。また慣習的にも、close()
で破棄できるのが期待される可能性はそこそこあるんじゃないかと思います。逆に
UserDict
やOpenJtalk
あたりは、まあGCに任せてもいいのかなと思います。関連 Issue
ref #545
その他
もしかしたら必要なのは
unload_all(self) -> None
かもしれない...? (この場合C APIにも同じものがあった方がよい)