Closed qryxip closed 10 months ago
なかなか巨大になりそうですね…!! お待ちしてます!!
大体考えて組んだので、draftを外します。
モジュールinfer
の登場人物は主に3つに分けられます。これらをもとに抽象化を組んでいます。
(ただinfer.rsは115行しかないといっても、中身の圧が強いのでファイル分割すべきかもしれません)
trait InferenceRuntime
(e.g. Onnxruntime
)
trait Session
trait RunBuilder
trait InputScalar
(e.g. i64
, f32
)trait Signature
trait Output
(e.g. (Vec<f32>,)
)enum SignatureKind { PredictDuration, PredictIntonation, Decode }
)
struct PredictDuration: Signature<Kind = SignatureKind>
struct PredictIntonation: Signature<Kind = SignatureKind>
struct Decode: Signature<Kind = SignatureKind>
struct SessionSet<K (= SignatureKind), R: InferenceRuntime>
struct SessionOptions
補足としては:
crate::infer::runtimes::onnxruntime
に隔離しました。model_file
モジュール (復号部分), SessionOptions
, SessionSet
, InferenceModels
などはinfer
モジュールに移しました。
status::SessionSet
とvoice_model::InferenceModels
はenum-mapクレートを用いてEnumMap<SignatureKind, …>
のような形で表現しています。<R: InferenceRuntime>
の型引数はSynthesisEngine
のあたりで止めています。またSignatureKind
(= PredicutDuration | …
)もstatus
モジュールに直接登場させています。crates::infer::runtimes
に新しいランタイムを増設します。
crate::infer::signature
を変更します。
([f32],)
以外の出力にするときは、infer/runtimes/onnxruntime.rsのimpl Output<Onnxruntime> for (Vec<f32>,)
の部分を拡張します。enum SignatureKind
の存在を二つに分割してそれぞれについてEnumMap
を管理します。enum SignatureKind
を複数作って抽象化します。色々再構成しました。 https://github.com/VOICEVOX/voicevox_core/pull/675/commits/e0f29c649df39a4006a47c8813208ac9232cb9d1 https://github.com/VOICEVOX/voicevox_core/pull/675/commits/cb1db348ab43b01b542c6404e6c0283e9aae251b https://github.com/VOICEVOX/voicevox_core/pull/675/commits/c3e08dd4da27b9691203f071c2bf716badf1e087 https://github.com/VOICEVOX/voicevox_core/pull/675/commits/e4b91abbf4fa95711a9f62f72e5fcf00b0735999 https://github.com/VOICEVOX/voicevox_core/pull/675/commits/8584d2727252c1bd6971f01150386ebd3adc73e7 https://github.com/VOICEVOX/voicevox_core/pull/675/commits/47953098a19c70f252e210dcff3e8b9e1843f1a1 https://github.com/VOICEVOX/voicevox_core/pull/675/commits/a5dbbddaa3109d7c859f30feadc2fd89900c41d2 https://github.com/VOICEVOX/voicevox_core/pull/675/commits/525f4b1821fff4dc67b0469497d3e4213f5e150a
主な変更点として:
trait InferenceRuntime
を継承する次の3つのトレイトを導入し、これらに役割を持たせました。
trait SupportsInferenceInputTensor<I>
(I
の例: Array1<i64>
)trait SupportsInferenceInputSignature<I>
(I
の例: PredictDurationInput
)trait SupportsInferenceOutput<O>
(O
の例: (Vec<f32>,)
)trait Signature
をInferenceSignature
とInferenceInputSignature
に分離しました。またtrait InputScalar
とtrait Output
は、上記のInferenceRuntime
のサブトレイトに吸収される形で消えました。 (https://github.com/VOICEVOX/voicevox_core/pull/675#discussion_r1384224966)RunBuilder
は(基本的に)自分で関数を持たなくなったので、RunContext
としました。(https://github.com/VOICEVOX/voicevox_core/pull/675#discussion_r1384216221)RunContext
を除きprefixにInference
を付けるようにしました。(https://github.com/VOICEVOX/voicevox_core/pull/675#discussion_r1384216221)https://github.com/VOICEVOX/voicevox_core/pull/675/commits/8b4f3b6f4f5be8a083eb22427c031ba53ae85cfd
Signature
の"kind"は、"model kind"ということにしました。というのもこれをキーにしたmapでsessionを管理したりするので、"model"と呼ぶ方が実態と合っているかなと思ったので。
(それに伴いtrait InferenceModelGroup
という概念を追加しました)
https://github.com/VOICEVOX/voicevox_core/pull/675/commits/1b1b7bfc32d7b7d21cc98cbf219046fc257d75bd: status
モジュールをinfer
モジュール下に移しました。それに加え、InferenceGroupImpl
の存在をStatus
から外し、Status<R: InferenceRuntime, G: InfereceGroup>
として運用するようにしました。Synthesizer
の四層構造について以前、二層まで圧縮できるのではないかと言った気がするのですが、Status
がこういう役割を果たせることがわかったので今は三層(Synthesizer
→ InferenceCore<R>
→ Status<R, G>
)で十分かなと思っています。
(追記) decode
のworkaround処理をsignatures.rsに統合したら、InfereceCore
も消して二層にできそう。
https://github.com/VOICEVOX/voicevox_core/pull/675/commits/c39f48cb5c560b6f4dde212767ba78beba941606: trait RunContext
を削除しました (InferenceRuntime::RunContext
はそのまま)
InferenceDomain::{INPUT,OUTPUT}_PARAM_INFOS
を統合し、タプルのEnumMap
にしました。であれば、もう一旦マージして、階層構造を小さくすることに取り組むのが良いのかなと思いました。 実装していく上でまた新しい課題が見つかったりもする可能性も全然あると思いますし。
構造の変更はもうこのプルリクエスト内ではやめて、名称の変更やドキュメントの追加だけにして、次に進むというのはどうでしょう・・・? (1回のレビューに3時間かかっており。。。。)
はい。それがよいと思います。
階層構造ですが、今InferenceCore
でやっている「入出力のworkaround処理」をdomain.rs(旧signatures.rs)に移せれば、こんな感じにできるのではと思っています。
synthesizer.rs --+--> infer/status.rs -----> infer/runtimes/
+--> infer/domain.rs
|
+--> open_jtalk.rs
こんな感じにできるのではと思っています。
なるほどです、良さそうに思いました!!
なんとなくの直感ですが、statusがかなり多くの責務を担いそうだなと思いました。statusという名称が曖昧なので便利屋さんみたいになりがちかも。将来なんか名前変えられると良さそう! あとSynthesizerが何を見れるべきかを考えていくとアーキテクチャ作りやすいのかなとか思いました。RuntimeやSessionは見れるべきではない、など?
voicevox_core
内の」という表現を「Rust APIクレート内の」と置き換えました。ArrayExt
を、マクロの中に押し込める修正確認しました!!マージします!!!
内容
ONNX Runtimeとモデルのシグネチャ(?)の存在を、別のモジュールに分離します。
以下の改革の前準備です。
https://github.com/VOICEVOX/voicevox_core/pull/553#issuecomment-1656366892
関連 Issue
545
その他