VOICEVOX / voicevox_project

VOICEVOX内のプロジェクトを管理するリポジトリ
15 stars 3 forks source link

モデル構造変更(フレームレベルピッチの調整可能化)に伴うバージョン・エディション管理に関する議論 #26

Open y-chan opened 1 year ago

y-chan commented 1 year ago

目的

長音・フレームレベルピッチ対応のコアをエディションとして分けたい

理由

今までと音質や声質に変化が生じ、その上モデルが一つ増えてデータフローに変化が生じるため、新しいデフォルトにしたくない

解決策

  1. (同じコア内で)別モデルファイルとして扱う
    • 現在制作中の音声ライブラリ管理機能と提案中のvvm形式によるモデル読み込みを活用
      • 要はvvlibの中にvvmを内包する感じ
      • コア側がvvmを読めるようにならないといけない(仕様の確定とかも含め)
      • 結構道遠いかも
    • これの問題は、コアが双方(新・旧)のデータフローに対応しなければならないこと、つまりコア内での互換性の確保
      • SHAREVOXの場合はmodel_config.jsonなんてものを用意していますが、使えるかは不明
      • もちろんエンジンの中でも新旧双方のデータフローに対応する必要がある
  2. 別コアとして扱う
    • こちらはvvmとかは考えず、vvlibの中にコアを入れて音声ライブラリ管理機能で管理するイメージ
      • VOICEVOXで音声ライブラリ機能を使う場合はこの形の想定だった
    • コアは破壊的変更を加えてもOK
      • ただし、エンジンは双方のデータフローに対応する必要がある
  3. 別エンジンとして扱う
    • 互換性を完全に無視して破壊的変更をエンジン・コア双方に対してできる
      • ただし、エディションを分けたいという意味合いでは、別エンジンにするのは少し違うかも

問題

その他

Hiroshiba commented 1 year ago

ちょっと目的が議論したい対象と違っているかもと思いました。 「長音・フレームレベルピッチ対応のコアをエディションとして分けたい」は具体例で、「エディションを分けたい」が目的になるかなと思いました。 今回のことだけでなく、未来起こる問題にも対応できるようなのを考えておきたいです。

エディションの定義ですが、「あるキャラのあるスタイルの音声が生成できる別手法」かなと思ってます。 長音対応版・高速版・高品質版などなど。

Hiroshiba commented 1 year ago
  1. (同じコア内で)別モデルファイルとして扱う

コアが過去のモデルをずっと読み込めるよう互換性を保たないといけない点が問題だと感じています。 (長音対応エディションだけでなく、過去含め任意のモデルファイルが渡されるので)

となると挙げられていたデータフロー以外にも、将来的にはライブラリやデータ構造などでも問題に直面しそうです。 例えばVOICEVOXコアは以前torchからonnxruntimeに移行しましたが、この方式だとどちらのライブラリも所持する必要があります。

  1. 別エンジンとして扱う

これは現状でもできる方法でお手頃ではあると思いますが、完全に別物になってUIで区別付けられないのが不便になるかもと思いました。 プロトタイプ版を先行配布する用途とかなら結構ありかも。

  1. 別コアとして扱う

まあなんだかんだこれが妥当なのかなぁと思いました。

qryxip commented 1 year ago

よくよく考えてみたのですが、やっぱり2.(別コアとして扱う)ですかね。

現在VOICEVOX COREは

  1. VOICEVOX ENGINEが使うDLL
  2. HTTP越しではなくDLLとして直接使える、VOICEVOX ENGINEのようなことができる何か (ユーザー向けにAPIドキュメントを整備している方)

という二つの役割があります。

AudioQueryとOpen JTalkが扱え、PyO3によるAPIもでき、APIのasync/await化とvvm読み込みも実装されようとしており、辞書更新も現実味を帯びてくることで2.の要素も充実してきました。そのため2.として過去のモデルのロードもできないかなと考えていました。

しかし1.の領域(≒ モデルを読む部分)にはtorchやonnxruntimeや将来移行するかもしれないランタイムが全部必要となり、とどめに暗号化の必要があります。今後の状況によってはRust以外の言語(GoとかZigとか?)に移行することになるかもしれません。Rust APIとかNode.js APIとかJava APIとかの直接提供を考えていた私としては出来ない事が一つ増えてちょっと残念なことではありますが、互換性の維持は困難でしょう。

1.の方に今からでも別の名前(仮にvoicevox_loader)を付けてしまって分離してしまえば2.としてvvlibを読めるのではと思い、一応そのような案を考えてもみました。https://github.com/VOICEVOX/voicevox_core/issues/388#issuecomment-1398128605から着想を得ています。バージョン≦0.14のCOREはそのままのDLLのまま、概念的にはすべて"loader"ということにしてしまいます。

(追記) "loader"というより、"runtime"とかの方がいいかも

flowchart TD
    models_and_ort["vvm × (voicevox_)onnxruntime.dll"] --> voicevox_loader["voicevox_loader (cdylib) (プロプライエタリかどうかはここではどうでもよい)"]
    voicevox_loader -->|vvlib| voicevox_core["voicevox_core (rlib)"]
    voicevox_loader -->|vvlib| voicevox_engine["VOICEVOX ENGINE"]
    voicevox_core -->|Cargo| voicevox_core_c_api["voicevox_core_c_api (cdylib)"]
    voicevox_core -->|Cargo| voicevox_core_python_api["voicevox_core_python_api (whl)"]
    voicevox_core -->|Cargo| etc["…"]
    voicevox_core_python_api -->|pip| voicevox_engine_["VOICEVOX ENGINE?"]

ただこれも"VOICEVOX CORE"という名前が既にユーザーに十分知られている以上、開発者にもユーザーにも混乱を招くかなと思っています。何よりVOICEVOX全体としてはそんなに利点がない。

Hiroshiba commented 1 year ago

なるほどです。runtime部分が新のコア部分っぽいなぁと思いました。 だいぶ考えたのですが、vvlibはコア部分だけを持つ設計のがきれいなのかはちょっと考えきれませんでした。

実はエンジンの機能をコアに移しているとき、エンジンから該当機能をなくそうとしていました。AudioQueryとか。 ただエンジン側でこれを利用すると、新旧コアに対応するために複数通りの経路ができてしまうだけだということに気づいて、旧コア(runtime部分)だけ使うコードになっていたりします。

仮にvvlibにruntime部分だけ持たせると、またそれがなにかの制約になってしまうかもです。なのでとりあえず現コアの大多数の機能をvvlibにしておいて、バージョン1.0.0になるときに設計を見直すのが良いのかなと思いました・・・!!

Hiroshiba commented 1 year ago

に「エンジン・コア・runtime・ライブラリの役割分離を見直す」というのを追加しておきました。