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

docker版/Dockerfileの扱いを考える #482

Open
Hiroshiba opened this issue Oct 5, 2022 · 16 comments
Open

docker版/Dockerfileの扱いを考える #482

Hiroshiba opened this issue Oct 5, 2022 · 16 comments
Labels
機能向上 状態:実装者募集 実装者を募集している状態

Comments

@Hiroshiba
Copy link
Member

内容

ドキュメントではDocker イメージの提供のみが案内されています。
https://github.com/VOICEVOX/voicevox_engine/tree/211c48ef85eb0ccf4fcf2b2daa4a51dbace1464b#docker-%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B8

でも実際はDockerfileを使ってビルドや開発環境の構築もできます。
このisuseはdocker版やDockerfileが何を提供するかを明確にするissueです。

Pros 良くなる点

docker版の扱い方が決まってメンテナンス性が上がる。

Cons 悪くなる点

実現方法

現状を整理して意見を集める。

@Hiroshiba Hiroshiba added the 要議論 実行する前に議論が必要そうなもの label Oct 5, 2022
@Hiroshiba
Copy link
Member Author

現状のdocker/Dockerfileについて整理します。

まず僕が勝手に思っていたdockerの役割ですが、「ビルド環境の提供」と「成果物の提供」が主だと思っていました。

これに関して、時間がたつに連れいろいろわかってきました。
Mac/WindowsはGithub Actions上でビルドするのに対し、Linuxだけはdockerでビルドする流れになっていることに気づきました。
この流れを1本化することでアップデート時のコストやメンテナンスのコストを下げれないかと考えています。
(ということをPyinstaller内のissueで言及したのがこちらです)

docker周りを作っていただいたのは @aoirint さんなのですが、相談せずに独断で判断し、混乱させてしまって申し訳ありませんでした。
ビルドの流れを一本化したいという旨のissueを建てていたと勝手に思いこんでいました・・・。

@Hiroshiba
Copy link
Member Author

Hiroshiba commented Oct 5, 2022

docker版を開発環境として使えそうかという視点で調べてみました。

現状のDockerfileを見てみた感じ、エンジンをpythonを起動するコマンドは

gosu user /opt/python/bin/python3 run.py

となります。
前提知識が必要なのと、コマンドが長いのとで実用性は少し低めかもという所感です。

開発環境用に別のdockerfileを用意しても良いかもですが、まあpip installでほぼ環境構築が完了するので、dockerで開発したい方は各々好きなdocker image内にエンジンリポジトリをクローンしてpip installしてるのかなと思いました。
(僕はそうやって開発しています。プロジェクトごとにdocker imageを用意すると重いので、汎用docker imageにcloneしてvenvでpython環境作ってます)

@Hiroshiba
Copy link
Member Author

Hiroshiba commented Nov 6, 2022

Dockerfileを見直してみた感じ、ライセンス情報を生成する部分や、VOICEVOX RESOURCEを取得する部分、onnxruntimeを持ってくる部分などがActionsとDockerfileの2箇所に同じ処理が書かれている形なのがなんとかできると嬉しいのかなと思いました。

ちなみにPyInstaller化により、今まではWindowsのAction・MacのAction・LinuxのDockerfileの3箇所に書かれていたのが2箇所まで減ったので管理しやすくなりました。(thx @y-chan !)

統一する方法はいろいろありそうですが、例えばビルド用シェルスクリプトを用意してaction内とdockerfile内両方から参照するのが良いのかなと思っています。

@aoirint
Copy link
Member

aoirint commented Dec 10, 2022

DockerイメージのRustコア対応を進めたいので、あまりまとまっていないですが書いておきます...。

要点: バイナリを同梱する方式のDockerfileだけメンテナンスするようにするのもいいかも

Linuxだけはdockerでビルドする流れ

意図的に、Dockerコンテナだけでエンジンの開発を完結できる構成にしていました。

あまり覚えていないですが、いくつか意図があった気がします。

  • Dockerイメージのキャッシュ機構を利用できる(ビルドの都合で、これが一番大きい気がする)
  • ローカル環境に影響を受けにくい、共通の環境をリポジトリ上に定義できる
  • サンドボックス化された安全な開発環境で開発できる
  • ベースイメージを交換するだけで、Linux OS間の互換性を検証できる
    • 互換性の確保の仕方がわかってきたので、もうあまり意味はありません
  • forkしたサードパーティのVOICEVOX互換エンジンがLinuxとDockerに対応しやすくなる(ドキュメントがあれば...)

実際にはほとんど使われておらず、このリポジトリでこの状態をメンテナンスするモチベーションがなさそうなので、ビルドの一本化でビルド過程をメンテナンスしやすくする方が重要だと思いました。

docker版を開発環境として使えそうか

サンドボックス化された環境はIDE/言語サーバと相性が悪そうで、結局ローカル環境(venv)にライブラリをインストールしないと補完が効かないので、コードが書きにくいなと思いました。

この観点で、ローカルで開発用にDockerイメージをビルドできる状態を維持することをあきらめて、配布用のバイナリを同梱する方式のDockerfileに切り替えるのもありかもしれないと思えてきました...。その場合は、リポジトリのルートにおくよりも、.githubディレクトリの中とか、dockerディレクトリの中とかにおいて、ファイル名をDockerfile.deployとかに変えたいですね...。

ソースコードを同梱する方式の場合、(キャッシュがあれば)バイナリビルドしないので、動かせる状態になるまでが速いのが利点だと思いますが、いまプレビュービルドでやっているような、プルリクエスト・新規の変更の動作検証で使うことを考えると、DockerだけでなくいろいろなOSで検証しそうなので、あまり重要ではなさそうかもです。latestビルドの提供も関係するかもです。

現状のDockerfileを見てみた感じ、エンジンをpythonを起動するコマンドは
...
プロジェクトごとにdocker imageを用意すると重いので、汎用docker imageにcloneしてvenvでpython環境作ってます

Dockerコンテナの中にshellで入ってコマンドを打つ使い方を考えていますか? 
CMD命令でエンジンの実行コマンドは定義しているので、docker run --rm image / make run-linux-docker-ubuntu20.04するだけという使い方で考えていました。

ただ、FastAPIのホットリロード機能を使えないのはいまいちかもですね...(Makefileもソースコードをマウントしていないので、ソースコードを変更するたびにビルドが必要)。

わたしは汎用のDockerイメージ(例えば、Python + ONNX Runtimeだけが入っているようなベースイメージ用のイメージを考えています)を作ることはあまりなくて、プロジェクトごとにDockerイメージ(Dockerfile)を作って開発しています...(富豪的?)。代わりに、マルチステージ機能を使っています。

例でいうと、Pythonのバージョン、ONNX Runtimeのバージョンをベースイメージ側で管理すると、たくさんタグを定義したり、バージョンごとにコマンドを変えたりして、汎用性を高める必要が出てきて大変なので、プロジェクト側で制御したい感じです。そういうベースイメージを誰かがメンテナンスしてくれていて、用途に合っていれば使うかもです(例えば、python:3.10とか)。

容量やビルド時間より、環境の定義をリポジトリに載せて、再現できるようにすることを重視している感じです。もちろん、単体でみたときに容量もビルド時間も減らしたいですが...。

2箇所に同じ処理が書かれている

シェルスクリプトがうまく共通化できればよさそうですが、統一はなかなか難しそうかも・・・

@Hiroshiba
Copy link
Member Author

サンドボックス化された環境はIDE/言語サーバと相性が悪そうで、

VSCodeとかなら、Dockerコンテナを起動するとこからコンテナ上で作業するとこまでサポートしてくれる公式extensionがあったりしますね!
使ってみたのですが、毎プロジェクト設定が大変だなというのが個人的な感想でした。

Dockerコンテナの中にshellで入ってコマンドを打つ使い方を考えていますか? 

そうです!
具体的にはちょっと違って、dockerコンテナ側でsshdを起動し、VSCodeのリモートサーバー上での開発用extensionを介して使っています。
.ssh/configに設定を1回だけ書けば、VSCodeのターミナルがdockerコンテナの中で勝手に立ち上がる感じです。(僕はこの形で開発しています)

バイナリを同梱する方式のDockerfileだけメンテナンスするようにするのもいいかも

なるほどです!
gitpodなどの普及によってdockerコンテナ上での開発がより浸透してきたら、公式で開発用Dockerコンテナを提供するのがマジョリティになってくるかもとちょっと思いました。
(まあエディタ側はelectron GUIを起動しないといけないのでdockerコンテナでは不可能だったりと、VOICEVOX的には相性悪いかもですが・・・。)

@Hiroshiba
Copy link
Member Author

Hiroshiba commented Jan 9, 2023

こちら、本格的に進められればと考えています。

いろいろまとめつつ提案すると、こんな感じでしょうか。

  • 前提条件
    • 実行用のdocker imageが必須
    • 開発用のdocker imageがあると良い
    • ビルド周りのコードはGithub Actions含めて統一したい
  • アプローチは3つある
  • 1. ↑2つを同じimageにする
    • ビルド周りを全部シェルスクリプトにし、Actions側も含めて統一すれば良い
    • ローカル環境でもビルドしやすい
    • 洗い出しからやっていくことになり、結構根気が必要
  • 2. 開発用docker imageを諦めて実行用docker imageを作る
    • 実行用imageだけでよければ、Github Actionsでビルドしたバイナリをdocker image内に含める手がある
    • 既存コードの大多数を利用できるので
    • 開発用imageは利用者は少ないだろうし、使う人は自作できるだろうから、致命的ではない
  • 3. それぞれ作る
    • 実行用imageは2の手法で、rootと違うとこにDockerfileを置いておく
    • 開発用imageはrootにDockerfileを置いておく

まあ、とりあえず2をやって、余力あれば3かなと思いました!
3をやる前提なら今までのDockerfileは一旦置いといて2用のDockerfileをどこかに作れば良いのかなと。

@Hiroshiba
Copy link
Member Author

もしよければまた @aoirint さんのお力を借りたいのですが、おまかせできたりしませんか・・・・・・・? 👀

このタスクはたぶんActions周り・docker周りと、あとlinux周りの知識が必要だろうなと感じてます。
僕もファイルパーミッションくらいならわかりますが、lddとかの辺りになってくると本当にわからないので・・・。

もしよければぜひお願いしたいです 🙇‍♂️

@tarepan tarepan added 機能向上 状態:実装者募集 実装者を募集している状態 and removed 要議論 実行する前に議論が必要そうなもの labels Mar 4, 2024
@sabonerune
Copy link
Contributor

ちょっと個人的に色々試してみたことで得られた知見を書いておきます

  1. Raspberry Pi (arm64) 向けビルドの追加 #322 実現のためにはビルド用のターゲットが必要。
    GithubのランナーにはLinux/arm64環境はありません。そのためDocker+Qemuを使うらしいのですがそうすると通常のGitHub Workflow構文のコードは使用できません。
    ref: https://docs.docker.com/build/guide/export/

  2. 実行用イメージに無駄な依存が多い。
    runtime-envに実行時には必要ない依存が多い気がします。compile-python-envの方で依存パッケージのビルド、その他のファイルのダウンロードをすればかなり削れるはずです。
    また、Pythonのビルドに関しても全てのオプション機能のビルドは不要な気がします。

ちなみにビルド時の依存はbuild-essential libffi-dev libssl-dev zlib1g-dev(pyopenjtalk用のgit)、実行時はopensslだけで十分でした。

  • ここから先は自信がない
  1. ENTRYPOINTの使い勝手
    ref: https://docs.docker.com/develop/develop-images/instructions/#entrypoint

he best use for ENTRYPOINT is to set the image's main command, allowing that image to be run as though it was that command, and then use CMD as the default flags.

ENTRYPOINTはrun.pyまで書くべき?

  1. ビルドのしやすさ関係
    Dockerfile内でコアとランタイムをDLしているがベースイメージが更新されるとキャッシュが無効にになってしまうので無駄なダウンロードが増えてしまう?
    しかしリソースのようにリポジトリのファイルを置き換えてからビルドするのは若干面倒な気がする

とりあえずこんな感じでしょうか?

あとファイルアクセスや権限周りも怪しい気がするのですが自分はその辺りのベストプラクティスが見つけられませんでした。

@aoirint
Copy link
Member

aoirint commented May 3, 2024

ENTRYPOINTについて

#482 (comment)
ENTRYPOINTはrun.pyまで書くべき?

補足としてどういう挙動になるかという説明を書いておくと、以下のような形になると思います(実際にはPythonにPATHが通っていないのでより複雑ですが)。
Docker Composeで実行する場合も同様です。

ENTRYPOINT命令

Dockerfile

ENTRYPOINT [ "gosu", "user", "python", "run.py" ]
CMD []

実行例

# 実行例1. 実行されるコマンド: `gosu user python run.py`
docker run --rm voicevox/voicevox_engine:latest 

# 実行例2. 実行されるコマンド: `gosu user python run.py --help`
docker run --rm voicevox/voicevox_engine:latest --help

# 実行例3. 実行されるコマンド: `gosu user python run.py gosu user python run.py`(エラー)
docker run --rm voicevox/voicevox_engine:latest gosu user python run.py

CMD命令

Dockerfile

ENTRYPOINT []
CMD [ "gosu", "user", "python", "run.py" ]

実行例

# 実行例1. 実行されるコマンド: `gosu user python run.py`
docker run --rm voicevox/voicevox_engine:latest 

# 実行例2. 実行されるコマンド: `--help`(エラー)
docker run --rm voicevox/voicevox_engine:latest --help

# 実行例3. 実行されるコマンド: `gosu user python run.py`
docker run --rm voicevox/voicevox_engine:latest gosu user python run.py

コメント

考えたことを参考として書いておきます。

使いやすさの面では、ENTRYPOINT命令でrun.pyまで指定するように変更してもいいんじゃないかなと思っていますが、破壊的変更に当たる可能性があるのでちょっと慎重です。

なお実際の変更内容としては、ENTRYPOINT命令には現状ライセンス情報を表示するシェルスクリプトが指定されているので、CMD命令を廃止して、ENTRYPOINT命令のシェルスクリプトにCMD命令の記載内容を移動するというものになると思います。

いまのCMD命令の課題としては、Dockerイメージのユーザがrun.pyの引数を変更したくなった場合、、Dockerfileを読まないと分からない冗長な記述をすることになるという点があります。

互換性の維持を重視するのであれば、現状引数でしか変更できない設定について、対応する環境変数を追加して、環境変数で設定を変更できる範囲を広げるという方法もあると思います。こちらの方法の場合、引数と環境変数の優先度について考える必要が出る可能性があって、こちらはこちらで互換性に影響するかもしれません。

メリット・デメリットについて

ENTRYPOINT命令に変更した場合にうれしい点は、一般的なコマンドでいうと、ffmpegという名前のDockerイメージがあったとして(ないですが)、ffmpeg --versionというコマンドの頭にdocker run --rmをつけるだけで、docker run --rm ffmpeg --versionのようにDockerコンテナとして実行できるというところかなと思っています(実際にはマウント設定なども必要になる場合があると思いますが)。

VOICEVOX ENGINEでは、実行ファイルの名前はDockerイメージの名前と同じvoicevox_engineではなく、runですが、./run --helprun --helpと同様に、docker run --rm voicevox/voicevox_engine:latest --helpのように記述できるという形になります。

一方で、ENTRYPOINTで指定したコマンドではない他のコマンドを実行することは複雑になります。イメージ内に存在するコマンドを実行したつもりでも、上記ENTRYPOINT命令の実行例3のように、意図しないコマンドに変換されて実行に失敗するようになります。

ただし、DockerfileでENTRYPOINTを指定している場合でも、特殊な場合にしか使われないと思いますが、実行時にENTRYPOINTを無効化することはできて、docker run --rm --entrypoint "" voicevox/voicevox_engine:latestのようにすれば無効化できます。

また、上記ENTRYPOINT命令の実行例3の場合に、gosu user python run.pyが実行されるようにしているDockerイメージも見かけます。
そのような場合、おそらくENTRYPOINTでシェルスクリプトなどを実行して、最初の引数${0}をパースして、ハイフンや既知のサブコマンドで始まっていないかを確認したり、一致する名前のコマンドの存在を確認したりして、内容によってプレフィックスを付けないで実行する、というような分岐をDockerイメージ作成者が実装していると思います。

Dockerイメージ開発の方向性について

ENTRYPOINTを指定すると、Dockerイメージの用途が1つのコマンドに絞られると思います。

このIssueで言及のある開発用途のDockerイメージ #482 (comment) という観点では、build_utilディレクトリ以下のスクリプトも実行できることが望ましいと思います。

しかしヒホさんの言及 #482 (comment) のように、開発用途のDockerイメージについて考えるより、一般ユーザ向けのDockerイメージで、バイナリと同様にrun.pyを提供できる方が重要だと思います。

Dockerイメージvoicevox/voicevox_engineについて、run.pyに絞って使いやすいインタフェースで提供する(実行用docker imageに注力する)を目指して変更を進めていいんじゃないかなと思いました。

互換性について

CMDを明示して変更しているユーザに対しては破壊的変更なので、変更時には、互換性を維持できるか、維持するかの検討と、ユーザ向けの告知は必要だと思います。

さらに踏み込むと、こういった、Dockerイメージでどういったインタフェースをユーザに提供することを保証するか、保証しないかという点について、自動テストで確認するようにできないかなと思っています。自動テストが実装されているPythonコードと違って、どこを変更しても構わないか分からないので、Dockerfileを変更しにくい状態になっていそう、という課題を感じています。

@aoirint
Copy link
Member

aoirint commented May 3, 2024

Dockerイメージ内のファイルアクセスや権限周りについて

#482 (comment)
ファイルアクセスや権限周り

Dockerイメージのビルド時や実行時の範囲でいうと、gosuや一般ユーザを使っている理由については、以前言及していた ( #96 (comment), #105 (comment) ) ことはあるんですが、当時とは状況や考え、理解が変わっている部分もあると思います。gosu周り以外でも、気になった点があれば教えてほしいと思います。

Pythonプロセスを一般ユーザで実行した方がいいという考えは変わっていませんが、過去に議論したことがある点も含めて、いまのDockerイメージにはいろいろと課題があると思っています。参考として・整理のため:

  • run.pyのあるディレクトリ以下に設定ファイルがある場合、書き込み権限がない(/opt/voicevox_engineがroot所有のため)
    • エンジン側のプリセットAPIなどはDockerでは動かない気がします
  • Pythonビルドをルートユーザで実行している
    • 一般ユーザで実行するようにしたい
  • Pythonビルドをするコードをメンテナンスする必要があるか?
    • 理由
      • CUDA入りベースイメージに、固定されたバージョンのPythonをインストールするため
      • 公式Pythonイメージpython:3.11.XのOSはDebianであって、Ubuntuではない
      • CUDA入りベースイメージのOSはUbuntuであって、Debianではない
    • DockerイメージのOSをDebianに変更して、GPU版ではCUDAをうまくコピーしてくるような実装ができれば、Pythonをビルドする冗長なコードはいらなくなると思っています
  • Pythonプロセスの実行ユーザがUID:GID=1000:1000にハードコーディングで固定されていて、変更できない
    • docker run --user "1001:1001"のようにユーザを変更できると、Dockerイメージの利用者が実行環境に合わせて変更しやすくなる(設定ファイルの書き込み権限の設定などで便利になる)
    • デフォルトは一般ユーザになっている方がいい
  • /opt/python/bin/pythonにパスが通っていないため、Dockerfileの記述が冗長になる
    • 以前の議論の結果、PATHを通さないという判断になっている気がしますが、個人的には問題ないと思うようになりました
    • rootユーザから見えるpythonをOSのものではなく、独自のものに変更するのはOSの安定性としてよくないという考えだったと思います
    • イメージ内でOS側にPythonが入っていない環境であって、VOICEVOX ENGINE関連以外のプロセスが実行されることもないという理解になったので、いまは問題ないと思っています
  • Pythonパッケージのキャッシュは使われることがないがイメージに残っている(/home/user/.cache/pip、90MBくらい)
    • イメージビルド時の環境変数を、pip installをする各ステージでARG PIP_NO_CACHE_DIR=1のように設定すれば、キャッシュを保存しなくなると思います
    • しかし、キャッシュを保存しないようにするより、以下の--mount=type=cacheを使うようにした方が効率はよくなると思います
  • Pythonパッケージが再ビルド時にキャッシュされていない

Dockerの新しい機能で、以下のようにしてイメージサイズを増やさずに、ビルド間で指定ディレクトリのキャッシュを共有できるようになっています。

RUN --mount=type=cache,uid=1000,gid=1000,target=/home/user/.cache/pip <<EOF
    set -eu

    gosu user /opt/python/bin/pip install -r ./requirements.txt
EOF
  • __pycache__が生成できない(/opt/voicevox_engineがroot所有のため)
    • PythonプロセスがPythonコードを改変できないようにするため、ソースコードがroot所有なのは問題ないと思っています
    • いま__pycache__なしでどう動いているのかはよくわかっていません(メモリ上に持っているか、実行時に/tmpに生成されるか?)

以下のようにして、Dockerイメージビルド時に__pycache__を事前生成しておくことができると思います(実際にはDockerイメージビルド時だけ書き込みできるようにするような工夫が必要そう)。

gosu user /opt/python/bin/python -m compileall /opt/voicevox_engine

@aoirint
Copy link
Member

aoirint commented May 3, 2024

#322 の実現について

#482 (comment)
#322 実現のためにはビルド用のターゲットが必要。

VOICEVOX ENGINEのarm64版Dockerイメージは提供されている #639 と思うので、arm64版PyInstallerバイナリを提供するということになると思います。
その過程で、ビルド環境を提供するDockerイメージが必要になるのではないか、ということだと思っています。

QEMUによるCPUエミュレーションはDockerであっても、そうでない仮想環境であってもビルド時間が長くなると思うので、できればPyInstallerに、x64環境でarm64ビルドを可能にする、クロスコンパイル機能があればいいなとは思っています。
クロスコンパイル機能がある場合、ビルド環境を提供するDockerイメージは不要になると思います。
クロスコンパイル機能がない場合、必要になると思います。

その前にarm64環境では、python-soundfileライブラリがlibsndfileを同梱していないため、libsndfileの事前インストールが必要という課題 #839 があって、私がpython-soundfile側にPRを出して解決するというところで、申し訳ないんですが、手が止まっていると思います。こちらについては今後進めていければと思っています。

@aoirint
Copy link
Member

aoirint commented May 3, 2024

実行用イメージの依存関係について

#482 (comment)
実行用イメージに無駄な依存が多い

指摘の通りで、依存を減らしていけるといいと思います。

Pythonライブラリのインストール時にgccやmakeを使ったビルドを要求される場合に対応するため、runtime-envbuild-essentialなどをインストールしていますが、ビルド済みのwheelを別のステージでビルドするか、site-packagesをコピーするような対応ができれば、不要になりそうです。

注意が必要そうな点としては、Pythonバージョンやパッケージバージョンを変更した場合にも動作し続けるかどうかで、
PyPIにビルド済みのwheelがアップロードされているPythonパッケージでは、ビルドが不要だという認識で、
Pythonバージョンやパッケージバージョンを変更した場合に、Pythonバージョンとパッケージバージョンの組み合わせに対応するwheelがパッケージ提供元によってPyPIにアップロードされていないと、gccやmakeを使ったビルドが必要になる場合が出てくるという認識です。

@aoirint
Copy link
Member

aoirint commented May 3, 2024

ダウンロードファイルのキャッシュについて

#482 (comment)
Dockerfile内でコアとランタイムをDLしているがベースイメージが更新されるとキャッシュが無効にになってしまう

この点については、許容してもいいと思っていますが、ビルド時間を短くするために、なにかいい方法があるかもしれません。
ほかの点でも、Dockerの新しい機能を使うなどしてキャッシュなどで最適化できるところがあるかもしれません。

GitHub Actionsでの実行については、ベースイメージに更新がない場合、masterブランチのビルドキャッシュが利用されます。ベースイメージに更新がある場合、masterブランチのビルドキャッシュは破棄されて、ベースイメージの更新・OSパッケージの更新をリリースに反映することができるようになっていると思っています。

ローカル環境での実行については、ベースイメージを更新しない限りはローカルのDockerイメージのビルドキャッシュが使われると思います。

ベースイメージを更新しても、基本的にはダウンロード成果物の内容が変わるわけではないので、確かにキャッシュを利用したい気はします。ダウンロードロジックやダウンロードに使ったプログラムに問題があることがわかった場合、キャッシュを捨てるのが難しくなるという懸念はあると思います。

実装方法としては、ダウンロード成果物を詰めたスクラッチイメージをビルドしてタグを打ち、VOICEVOXでメンテナンスするような形が思いつきます。
もしかすると、#709 や、 https://github.com/VOICEVOX/voicevox_additional_libraries の仕組みに乗っかって、メンテナンスをしやすくできる可能性はあるかもです。

キャッシュ周りについては他に、リリース時にビルドがうまくいかなかったとき、バージョン番号を再利用する運用することがある関係で、DockerイメージのキャッシュはURL文字列ベースの比較になってしまうので、キャッシュがうまく動いているか不安にはなります。
バージョン番号を再利用しているのはおそらくエディタだけというのと、エンジンのDockerイメージでは、リリース時にビルドキャッシュを保存しないようにしている、その他のキャッシュについては手動操作しているというので、現状問題ないとは思っています。

エンジンのDockerイメージでリリース時にビルドキャッシュを保存しないようにしている理由は、VOICEVOX ENGINEは現状マイナーバージョンごとにブランチを切っていて、マイナーバージョンごとにキャッシュを分離する仕組みを実装するのが難しくて、保留になっているという認識です。

他に、ダウンロードファイルのハッシュ値をARGに持って、期待されたファイルがダウンロードされているか検証するような変更はできるかもしれません。

@Hiroshiba
Copy link
Member Author

@sabonerune
いろいろ検討ありがとうございます!

  1. 実行用イメージに無駄な依存が多い。

に関しては、バーボイスボックスリソースの方が圧倒的に容量がでかいので現状の優先度的には低そうに感じました。
そもそも個人的にはビルド済みのバイナリだけ突っ込む形がいいんじゃないかな~と思ってます。これだったら容量は最小なはず。

ENTRYPOINTの設計

これは盲点でした。後のコメントにまとめて書きますが、個人的には変更に賛成です!

@Hiroshiba
Copy link
Member Author

@aoirint 色々ありがとうございます、勉強になりました!!

ENTRYPOINT

run.pyまでENTRYPOINTに含める形で良さそうに思いました!

破壊的変更

難しいところですが、まあ案内すればOKな範疇に思いました!

互換性について

個人的にはこうかなぁと。

  • ENTRYPOINTにrun.pyまで書く
  • CMDでgosu user python run.pyと書いたらなにかしらのエラーになる
  • 破壊的変更になるので、ツイートとリリースノートでの案内はする
  • 公式でサポートするのはエンジン起動周りだけ
  • ENTRYPOINTの迂回とかはサポートしないけど意図的に防ぐこともしない
  • サポートするならテストを書くべき

--

エンジン側のプリセットAPIなどはDockerでは動かない気がします

個人的にはむしろ動かない方が良い気がしました!
ここに保存されたファイルはdockerコンテナが消えたら消えるので・・・。

Pythonビルドをするコードをメンテナンスする必要があるか?

CUDA imageとpython imageでディストリが違うのは盲点でした!
そもそもどっかコンテナ内でPythonを持っておくのをやめて、Gihtub Actions上でビルドしたものDocker imageにコピーするというのはダメでしょうか?
これだったらPythonの問題もCUDAの問題も権限周りの問題もがらっと解決できそうな気がしました!!

ただその代わりarm64が超課題になります。。。。。
Github Actions(x64)上でのarm64ビルドってできるのかな。。

#322 の実現について

と思ったらarm64のことを検討してくださってました!!

確かにビルドするためにarm64のDocker環境必要そうだなと感じました。。。
(どうやらPyinstallerのクロスコンパイル機能はないっぽい。。)

や~~~~~~~~Docker環境でのビルドを考えるとなかなかの大改革が必要そうですねぇ。。。
Actions上でしかビルドとできないものもあるのでそのあたりの共通化も考えると。。。
チャレンジングだなと感じました!!

ちょっとジャストアイディアですが、もしかしたら参考になるかもと思ったのでアイデアメモまで。

  • たしかGithub Actionsでarm64?のM1 macOSが使えるようになった
    • これを使ってlinux用arm64のビルドができたりしないですかね。。
  • いっそPyinstallerをやめる

@Hiroshiba
Copy link
Member Author

Hiroshiba commented May 6, 2024

↑でちょこっと言及したpython-build-standaloneについてちょっと調べたり考えたりしたので共有です 🙏 cc @aoirint

一言でいうと万能ではないなという印象でした。

ビルドするツールではなくpython.exe.py全部を配布するような形で、いろんなアーキテクチャに対応してるからarm64の課題は解決するかもですが、エンジンが起動するrun.exeを作れない問題がありました。
このまま配布すると、エンジンを起動するサードパーディにはpython /path/to/voicevox/run.pyを実行してもらう必要があり、互換性が失われるのと、なんか別の問題も出てきそうな気がします。
ということで「どうにかしてrun.exeを作る」というタスクとメンテコストが追加されるので、まあ万能薬ではないなぁという気持ちになりました。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
機能向上 状態:実装者募集 実装者を募集している状態
Projects
None yet
Development

No branches or pull requests

4 participants