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

アーキテクチャを考慮した共有ライブラリのロードをする #324

Closed
HyodaKazuaki opened this issue Feb 14, 2022 · 12 comments · Fixed by #327
Closed

アーキテクチャを考慮した共有ライブラリのロードをする #324

HyodaKazuaki opened this issue Feb 14, 2022 · 12 comments · Fixed by #327
Labels

Comments

@HyodaKazuaki
Copy link
Contributor

内容

#322 (comment) にあるように、VOICEVOXエンジンはアーキテクチャを考慮して共有ライブラリをロードする機構がありません。
このIssueでは、この機能を実装することを提案します。

Pros 良くなる点

x86_64以外のアーキテクチャ(aarch64など)で共有ライブラリをロードすることができるようになる。

Cons 悪くなる点

実現方法に記載するように、アーキテクチャの情報はplatformライブラリを使って取得します。
しかし、これで得られる値はコンピュータによって様々です。
例えば、64bitのIntel/AMD CPUでは、x86_64 / x64 / AMD64などの値が返ってきます。
そのため、これらを網羅しなければならないのですが、platformライブラリのドキュメントには記載がありません。
https://docs.python.org/ja/3/library/platform.html#platform.machine
これにより、対応しているアーキテクチャを持ったコンピュータが弾かれてしまい、利用できない可能性があります。

実現方法

Pythonのplatformライブラリを利用します。
以下の各関数で行われているOS判定に加えて、アーキテクチャの判定を行います。

def load_runtime_lib(runtime_dirs: List[Path]):
if sys.platform == "win32":
lib_file_names = ["torch_cpu.dll", "torch_cuda.dll", "onnxruntime.dll"]
lib_names = ["torch_cpu", "torch_cuda", "onnxruntime"]
elif sys.platform == "linux":
lib_file_names = ["libtorch.so", "libonnxruntime.so"]
lib_names = ["torch", "onnxruntime"]
elif sys.platform == "darwin":
lib_file_names = ["libonnxruntime.dylib"]
lib_names = ["onnxruntime"]
else:
raise RuntimeError("不明なOSです")
for lib_path in runtime_dirs:
for file_name in lib_file_names:
try:
CDLL(str((lib_path / file_name).resolve(strict=True)))
except OSError:
pass
for lib_name in lib_names:
try:
CDLL(find_library(lib_name))
except (OSError, TypeError):
pass

def check_core_type(core_dir: Path) -> Optional[str]:
if sys.platform == "win32":
if (core_dir / "core.dll").is_file() or (core_dir / "core_cpu.dll").is_file():
return "libtorch"
elif (core_dir / "core_gpu_x64_nvidia.dll").is_file() or (
core_dir / "core_cpu_x64.dll"
).is_file():
return "onnxruntime"
elif sys.platform == "linux":
if (core_dir / "libcore.so").is_file() or (
core_dir / "libcore_cpu.so"
).is_file():
return "libtorch"
elif (core_dir / "libcore_gpu_x64_nvidia.so").is_file() or (
core_dir / "libcore_cpu_x64.so"
).is_file():
return "onnxruntime"
elif sys.platform == "darwin":
if (core_dir / "libcore_cpu_universal2.dylib").is_file():
return "onnxruntime"
return None

def load_core(core_dir: Path, use_gpu: bool) -> CDLL:
model_type = check_core_type(core_dir)
if model_type is None:
raise RuntimeError("コアが見つかりません")
if sys.platform == "win32":
if model_type == "libtorch":
if use_gpu:
try:
return CDLL(str((core_dir / "core.dll").resolve(strict=True)))
except OSError:
pass
try:
return CDLL(str((core_dir / "core_cpu.dll").resolve(strict=True)))
except OSError:
return CDLL(str((core_dir / "core.dll").resolve(strict=True)))
elif model_type == "onnxruntime":
try:
return CDLL(
str((core_dir / "core_gpu_x64_nvidia.dll").resolve(strict=True))
)
except OSError:
return CDLL(str((core_dir / "core_cpu_x64.dll").resolve(strict=True)))
elif sys.platform == "linux":
if model_type == "libtorch":
if use_gpu:
try:
return CDLL(str((core_dir / "libcore.so").resolve(strict=True)))
except OSError:
pass
try:
return CDLL(str((core_dir / "libcore_cpu.so").resolve(strict=True)))
except OSError:
return CDLL(str((core_dir / "libcore.so").resolve(strict=True)))
elif model_type == "onnxruntime":
try:
return CDLL(
str((core_dir / "libcore_gpu_x64_nvidia.so").resolve(strict=True))
)
except OSError:
return CDLL(str((core_dir / "libcore_cpu_x64.so").resolve(strict=True)))
elif sys.platform == "darwin":
if model_type == "onnxruntime":
try:
return CDLL(
str(
(core_dir / "libcore_cpu_universal2.dylib").resolve(strict=True)
)
)
except OSError:
pass
raise RuntimeError("コアの読み込みに失敗しました")

その他

#322 を実現するために必要なIssueです。
私(@HyodaKazuaki )が担当します。

コードを確認していた所、onnxruntimeをバックエンドに利用する場合にGPUフラグが動作していないように思えました。

if use_gpu:
try:
return CDLL(str((core_dir / "core.dll").resolve(strict=True)))
except OSError:
pass
try:
return CDLL(str((core_dir / "core_cpu.dll").resolve(strict=True)))
except OSError:
return CDLL(str((core_dir / "core.dll").resolve(strict=True)))
elif model_type == "onnxruntime":
try:
return CDLL(
str((core_dir / "core_gpu_x64_nvidia.dll").resolve(strict=True))
)
except OSError:
return CDLL(str((core_dir / "core_cpu_x64.dll").resolve(strict=True)))

これは正常な仕様でしょうか?

@y-chan
Copy link
Member

y-chan commented Feb 14, 2022

個人的に、ライブラリのロードに際してアーキテクチャを考慮する必要はないと思っています。
というのも、基本的に(MacのUniversal Binaryのような例外を除いて)ビルドする際はアーキテクチャごとにビルドしますし、開発の際もアーキテクチャは基本固定されます。
開発の手順を楽にするために、各アーキテクチャごとに対応したコードを書くよりも、開発時・ビルド時に各自がバイナリの名前を固定した名前(core.dllなど)に変更するように指定・READMEなどで指示する方が楽(今後のことも考えた保守性が高い)なのではないかと思いました。
ただでさえ現状のcore wrapperはif文が多く、ネストされているのに、これ以上アーキテクチャごとのコードを増やすとなると可読性・保守性が落ちることは目に見えているのではないでしょうか...

あくまで個人的な意見ですし、私の見識が狭いだけかもしれないですが...

その他のonnxruntimeを利用する際のコードは単純にミスな気がします...

P.S. 私自身アーキテクチャを分ける目的がいまいち見えていない気がしたのですが、aarch64などでは現状書かれているlibtorchやonnxruntimeのライブラリ以外に何か必要ということでしょうか....?(だとしたら話は変わってくると思います)

@HyodaKazuaki
Copy link
Contributor Author

開発の手順を楽にするために、各アーキテクチャごとに対応したコードを書くよりも、開発時・ビルド時に各自がバイナリの名前を固定した名前(core.dllなど)に変更するように指定・READMEなどで指示する方が楽(今後のことも考えた保守性が高い)なのではないかと思いました。

確かに、そちらのほうが良さそうです。
run.pyに与えている実行時引数--voicelib_dir--voicelib_pathに変更して直接共有ライブラリを指定する形でしょうか。

その他のonnxruntimeを利用する際のコードは単純にミスな気がします...

わかりました。
では、このIssueに対するPRで対応したいと思います。

P.S. 私自身アーキテクチャを分ける目的がいまいち見えていない気がしたのですが、aarch64などでは現状書かれているlibtorchやonnxruntimeのライブラリ以外に何か必要ということでしょうか....?(だとしたら話は変わってくると思います)

このIssueで取り上げている問題は、VOICEVOX Coreのファイル名がcore_wrapper.pyにハードコードされているために、aarch64などの環境下で適切なVOICEVOX Coreをロードできないという点です。
目的は、この問題を解決するために以下のいずれかの手をとることで、この問題を解決することです。

  • アーキテクチャを考慮してVOICEVOX Coreをロードするようにする
    このIssueで最初に提案した方法です。
  • --voicelib_pathなどでライブラリを直接指定してロードするようにする
    @y-chan に提案していただいた方法です。

ですので、この他にライブラリが必要というわけではありません。

@PickledChair
Copy link
Member

PickledChair commented Feb 14, 2022

@HyodaKazuaki

コードを確認していた所、onnxruntimeをバックエンドに利用する場合にGPUフラグが動作していないように思えました。
これは正常な仕様でしょうか?

ご質問ありがとうございます。私は実装者ではないのですが、この部分の変更が行われた PR のレビューに参加していたので、このコードの意図がある程度わかっているつもりで解答させていただきます(もしかしたら考え違いがあるかもしれないので、その場合はコードの正しい意図をどなたかご教示いただけると幸いです)。

この部分のコードは一応正常に動作するという認識です(ただし、状況を整理するうちに、改善の余地がありそうだと思えてきました)。-> ご指摘の通り、onnxruntime 版のコアの読み込みにフラグがないので CPU 版コアの読み込みに関して問題がありそうです(GPU 対応版コアがある場合は CPU 版コアを読み込めなくても良い、という仕様にする案もありそう?)。参考:#324 (comment)

不自然なコードに見えるのは、おそらくこの部分のコードが「GPU を使用するかどうか」を切り替えるものではなく、「GPU 対応の core を使用するかどうか」を決定するコードであることに起因していると思われます(GPU 対応の core でも CPU モードを使うことができるので、GPU を使用するかどうかと GPU 対応の core を使用するかどうかは異なった問題になります)。また、 run.py の起動オプション --voicelib_dir に渡すパスとして

の両方を利用可能にしていることも、このコードの意図の分かりにくさの一因となっているように思います。

onnxruntime 版の core を読み込む場合

#254 で Python の ctypes モジュールを用いて core を読み込むように変更された際、エンジン内蔵の core(この PR 時点では onnxruntime 版に移行済み)として https://github.com/VOICEVOX/voicevox_core/releases からダウンロードしたものをリネームせずに VOICEVOX アプリケーションへ同梱し、用いるようになりました(build.yml で指定された voicevox_core_dll_name をそのまま用いています)。

build-windows:
strategy:
matrix:
include:
# Windows CPU
- os: windows-2019
python_architecture: 'x64'
voicevox_core_dll_name: core_cpu_x64.dll
onnxruntime_url: https://github.com/microsoft/onnxruntime/releases/download/v1.10.0/onnxruntime-win-x64-1.10.0.zip
ccache_url: https://github.com/ccache/ccache/releases/download/v4.4.1/ccache-4.4.1-windows-64.zip
artifact_name: windows-cpu
nuitka_cache_path: nuitka_cache
pip_cache_path: ~\AppData\Local\pip\Cache
# Windows NVIDIA GPU
- os: windows-2019
python_architecture: 'x64'
voicevox_core_dll_name: core_gpu_x64_nvidia.dll
onnxruntime_url: https://github.com/microsoft/onnxruntime/releases/download/v1.10.0/onnxruntime-win-x64-gpu-1.10.0.zip
cuda_version: '11.4.2'
cudnn_url: https://developer.download.nvidia.com/compute/redist/cudnn/v8.2.4/cudnn-11.4-windows-x64-v8.2.4.15.zip
ccache_url: https://github.com/ccache/ccache/releases/download/v4.4.1/ccache-4.4.1-windows-64.zip
artifact_name: windows-nvidia
nuitka_cache_path: nuitka_cache
pip_cache_path: ~\AppData\Local\pip\Cache

--include-data-file="download/core/${{ matrix.voicevox_core_dll_name }}=./" \

このことから、use_gpu フラグを用いなくても core のファイル名からその core が GPU 対応版であるかどうかが判別できます。core_gpu_x64_nvidia.dll の読み込みが失敗すれば、代わりに CPU 版の core が存在すると仮定して core_cpu_x64.dll を読み込もうとします。その後、以下の self.core.initialize(".", use_gpu, cpu_num_threads) の実行で GPU を使用するかどうかを core に伝えています(CPU 版のコア使用時に use_gpuTrue だった場合は False が返ると思いますが):

if not self.core.initialize(".", use_gpu, cpu_num_threads):

https://github.com/VOICEVOX/voicevox_core/releases で配布されている core を使用する場合でも、core の名前が ENGINE 内蔵版と同じであるため、必要な処理は共通になります。

libtorch 版の core を読み込む場合

libtorch 版の場合は少し複雑で、--voicelib_dir オプションに渡すパスが VOIEVOX ENGINE のパスであるか、あるいは https://github.com/VOICEVOX/voicevox_core/releases で配布されている core のパスであるかで、core の名前が違うということに注意しなければなりません。

#254 がマージされる以前は、以下に示すように、VOICEVOX ENGINE に同梱される core は GPU 版・CPU 版ともに core.dll にリネームされるようになっていました。:

build-windows:
strategy:
matrix:
include:
# Windows CPU
- os: windows-2019
python_architecture: 'x64'
voicevox_core_dll_name: core_cpu_x64.dll
onnxruntime_url: https://github.com/microsoft/onnxruntime/releases/download/v1.10.0/onnxruntime-win-x64-1.10.0.zip
ccache_url: https://github.com/ccache/ccache/releases/download/v4.4.1/ccache-4.4.1-windows-64.zip
artifact_name: windows-cpu
nuitka_cache_path: nuitka_cache
pip_cache_path: ~\AppData\Local\pip\Cache
# Windows NVIDIA GPU
- os: windows-2019
python_architecture: 'x64'
voicevox_core_dll_name: core_gpu_x64_nvidia.dll
onnxruntime_url: https://github.com/microsoft/onnxruntime/releases/download/v1.10.0/onnxruntime-win-x64-gpu-1.10.0.zip
cuda_version: '11.4.2'
cudnn_url: https://developer.download.nvidia.com/compute/redist/cudnn/v8.2.4/cudnn-11.4-windows-x64-v8.2.4.15.zip
ccache_url: https://github.com/ccache/ccache/releases/download/v4.4.1/ccache-4.4.1-windows-64.zip
artifact_name: windows-nvidia
nuitka_cache_path: nuitka_cache
pip_cache_path: ~\AppData\Local\pip\Cache

cp download/core/${{ matrix.voicevox_core_dll_name }} download/voicevox_core_source/example/python/core.dll

つまり、ENGINE 同梱の core を読み込む場合は use_gpu フラグを使用する必要はなく、一律に core.dll を読み込むようにすれば良いということになります。逆に言えば、ENGINE 同梱の core は initialize するまではそれが GPU 対応版であるかどうかを判断することが不可能です。

一方、https://github.com/VOICEVOX/voicevox_core/releases で配布されている core はリネーム前であるため、GPU 版の core は core.dll、CPU 版の core は core_cpu.dll という名前になっています。ここで、ENGINE 同梱の core を読み込む時のように一律に core.dll をまず読み込む、ということにすると、CPU 版の core である core_cpu.dll を使用する手段がなくなってしまいます。そこで、use_gpu フラグが False であるときは、優先的に core_cpu.dll を読み込むようにする、ということにして、これを通して CPU 版の core を使用できるようにしていると考えられます。その上で、実際に GPU を使用するかどうかは onnxruntime 版 core を使用するときと同様に self.core.initialize(".", use_gpu) で指定します。

改善の余地がありそうな点

以下の2点が考えられます:

  • libtorch 版 core を読み込む処理で、use_gpuFalse である時に core_cpu.dll をまず読み込むようにする、という意図がコードから伝わりづらい
  • load_core 関数の use_gpu という引数の名称・役割が紛らわしい

1点目について

直観的には use_gpu フラグが True である時に core.dll を読み込む、という処理が強調されているように見えます。繰り返しになってしまいますが、おそらくこの部分のコードの本来の意図は use_gpuFalse である時にまず core_cpu.dll を読み込むことによって、https://github.com/VOICEVOX/voicevox_core/releases で配布されている core の CPU 版の方を利用可能にする、ということだと思われます。したがって、そちらの処理の方が強調されるべきだと思われました。

2点目について

load_core 関数は GPU を使用するかどうかに関わっていません。GPU 対応版 core を使用するかどうかを担っています。したがって、use_gpu という引数名は紛らわしいものであり、役割も「優先的に core_cpu.dll を読み込むかどうか判断する」という、名前からは想像しづらいものです。use_cpu_core などという引数に変えると同時に、「優先的に core_cpu.dll を読み込むかどうか判断する」という処理は load_core 関数の外部に出してしまった方が意図が分かりやすくなるかも、と感じました(改善策についてはもっと良い案があるかもしれません)。

@PickledChair
Copy link
Member

PickledChair commented Feb 14, 2022

すみません、自分の文章を読み返して気づいたのですが、onnxruntime 版では逆に https://github.com/VOICEVOX/voicevox_core/releases で配布されている core の使用時に core_cpu_x64.dll を使用する手段がないですね……(core のディレクトリから core_gpu_x64_nvidia.dll を移動 or 削除すれば可能ですが)。ご指摘の通り、確かにこの部分にもフラグを持たせる必要がありそうです(あるいは指定されたパスに GPU 対応版 core が存在している場合はそちらのみを読み込むようにし、CPU 版は読み込まないようにする、という仕様にするのも1つの手かもしれません)。

一方、load_core 関数の use_gpu という引数名・役割が紛らわしいかもしれない、という考えはそのままなので、上のコメントは覚え書きとしてそのまま残しておきたいと思います。

@y-chan
Copy link
Member

y-chan commented Feb 14, 2022

あー、なるほど...!
すみません、私自身がctypesを用いた旧コアのロードが可能なエンジンの仕様をうまく把握できていなかったようです...
確かに、ファイル名でGPU依存/非依存といったことを区別しているのであれば、アーキテクチャを考慮した共有ライブラリのロードが必要になりますね...

ただ、コードの煩雑さ的にこれを実装するのはやはり保守性の問題を避けられないと思うので、どこか妥協点を探したいところです(個人的にはハードコードされるのはlibcore.dlllibcore.so/.dylibといった汎用名だけにし、ユーザーにはその名前変えてもらうといった対応に変える・もしくは HyodaKazuaki さんの言うように引数でパスを指定するようにすれば、Issueとして挙げられている問題は解決しそうだと思いました)。

ただ、現状の汎用コアロード実装のモチベーションとして、releasesやVOICEVOXディレクトリをそのまま使用したいという点があるのかなと思います。
例えば、スクリプトで旧コアを導入する等を前提とすることで、旧コア導入を簡単化しつつ、Engineのコードの保守性を上げられそうな気はしますが、今度はそのスクリプトを保守しなければならなかったり、そのスクリプトのユーザーサポートが必要だったりと、大きくコストがかかる気がします。

最初に提案されている通り、エンジン自体をアーキテクチャを考慮した形に変更するのが一番楽なんですかね...(私にもわかりません...)

@PickledChair
Copy link
Member

@HyodaKazuaki @y-chan これまでの意見や提案をまとめると、考慮すべき事項が大きく分けて3つありそうでした:

  • アーキテクチャ(x86_64/aarch64 等)を考慮した共有ライブラリのロード
  • GPU依存/非依存を考慮した共有ライブラリのロード
  • ユーザーの使い勝手を考慮(旧コア導入を容易にする)

このうち最初の2つをどう整理・実現するかはっきりさせることが重要そうです。3つ目の使い勝手も最終的に外してはならない要素ですが、最初の2つの整理なしには議論できなさそうな気がします。

個人的には、アーキテクチャ・GPU依存/非依存をユーザーが明示的に指定して起動できる仕組みを最初に作り、その後に、明示的指定がない場合に暗黙的にロードすべきコアを選択する仕組みを作る方法が一番堅実だと感じます(後者が「使い勝手」を担う部分です)。

条件を明示的に指定して起動する仕組みを実装するにあたっては、libtorch 版と onnxruntime 版の VOICEVOX CORE/ENGINE の差異を吸収する必要があります(これに関して、知っている範囲の知識で私も協力できそうです)。これが実装できれば、ロードすべきコアの暗黙的・自動的解決の実装前に、ある程度仕様のあいまいさが排除されて助かる気がしています。

@Hiroshiba
Copy link
Member

Hiroshiba commented Feb 14, 2022

なるほどです!

--voicelib_pathなどでライブラリを直接指定してロードするようにする

たしかvoicelib_dirの役割はdll+必要なバイナリの場所指定で、voicelib_pathにするとバイナリの場所を指定する引数も必要になってややこしくなるかもです(認識違うかも)

アーキテクチャ・GPU依存/非依存をユーザーが明示的に指定して起動できる仕組み

仮にエディタでエンジンを起動しようとすると結局platformで自動判別が必要になるので、ここを明示的に指定としても全体的な複雑性は変わらないかもです。
あと、引数にあるuse_gpuはコアの引数に指定するものでもあります。
アーキテクチャは変更することがないので、自動判別でも良さそうです。

アーキテクチャを考慮してVOICEVOX Coreをロードするようにする

なので、こちらが良いのかなと思いました。
見逃し等あればご指摘お願いします・・・!


結構ややこしい課題だなぁと感じました。

「明示的に指定」「platformで自動判定」の他にも、「コア配布パッケージを良い感じにする」手もあると思います。
良い感じとは、環境ごとにコア配布パッケージを分ける形です(過去のコア配布パッケージも含め)。

明示的に指定はエンジン的には綺麗ですが、結局エディタ側に複雑性が移るだけなるかもと思いました。

となると自動判定か配布パッケージの改善ですが、正直保守を考えると自動判定が一番楽なのかなと感じました。
配布パッケージは過去バージョンのマイグレーションが大変で、やるならマイグレーション用のリポジトリを用意することになり、なかなか大変そうです。

@HyodaKazuaki
Copy link
Contributor Author

アーキテクチャを考慮してVOICEVOX Coreをロードするようにする

なので、こちらが良いのかなと思いました。
見逃し等あればご指摘お願いします・・・!

コアの複雑さをフロントエンドまで持ち込む必要はないので、エンジンあたりで処理してしまうのがいいかと思います。

ところで1つ疑問なのですが、GPUで利用可能なコア(ここではGPUコアと呼びます)をロードし、失敗した場合にCPUで利用可能なコア(ここではCPUコアと呼びます)をロードする仕様はなぜ存在しているのでしょうか?
VOICEVOXの製品として利用する場合、内部にはGPUコアかCPUコアのいずれかしか入っておらず、core_wrapper.pyで切り替える必要性がないように感じます。
また、VOICEVOXエンジン単体で利用する場合、利用者がGPUコアかCPUコアのいずれかを用意すれば良いのではないでしょうか。

("たられば"で申し訳ないのですが)コアをcore.zipでまとめて配布するのではなく、onnxruntimeのようにOS/アーキテクチャごとに配布することができていれば、core_wrapper.pyはOS判定(dllなのかsoなのかdylibなのか判定するため)だけで済んだのかなと思います。
例えばこの方法に変更する場合、VOICEVOX CoreのReleaseを変更する必要がありますが、それぞれのRelease tagが打たれているコミットでビルドし、ReleaseのAssetsに追加することは難しいでしょうか...?

@takana-v
Copy link
Member

GPUでも利用可能なコア(ここではGPUコアと呼びます)をロードし、失敗した場合にCPUで利用可能なコア(ここではCPUコアと呼びます)をロードする仕様はなぜ存在しているのでしょうか?

core.zipを解凍したものを--voicelib_dirに指定した時に、GPUコアを優先的に使用するためだったと思います。
GPUコアを使った場合、/supported_devicesでCPU、GPU両方使えることが分かりますが、CPUコアを使った場合はGPUが使えない、という結果が返ってきます。
それが「PCの環境的にGPUを使えない」のか「GPUは使えるけどCPUコアを使っているから使えない扱いになっている」のかが分からなくなってしまうため、GPUコアを優先的に読み込む仕様にしたはずです。

@Hiroshiba
Copy link
Member

Hiroshiba commented Feb 15, 2022

@HyodaKazuaki

例えばこの方法に変更する場合、VOICEVOX CoreのReleaseを変更する必要がありますが、それぞれのRelease tagが打たれているコミットでビルドし、ReleaseのAssetsに追加することは難しいでしょうか...?

OSやアーキテクチャごとにzipを分けるのは賛成なのですが、過去のReleaseをどう扱うかは微妙に困ってたりします。
今の仕様に合わせて過去のReleaseにAssetsを追加するのは可能だと思います。
問題は、未来に互換性パッケージを追加したいときにどんどんややこしくなりそうなんですよね・・・

@HyodaKazuaki
Copy link
Contributor Author

なるほど、回答ありがとうございます。

おそらくこのあたりはかなり複雑で、後方互換性を必ず維持するという体制を取り続けるのであれば簡単に決められることではなさそうです。
このIssueではそのことを一旦考慮せずに、当初からの目標としていた「プラットフォームの考慮」を実現するということで対応したいと思います。
途中から行われていた「コアライブラリをどう扱うか」という議論は、VOICEVOX/voicevox_project/issues/3#303 で検討されるべきでした。議論を脱線させてしまい申し訳ありません。

@Hiroshiba
Copy link
Member

まあ、いつか考えないといけないことを今考えてただけなので・・・!
とりあえずプラットフォーム考慮を増やすので僕も良いと感じました!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
5 participants