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

Linux用実行バイナリの自動ビルドを追加 (#95) #96

Merged
merged 24 commits into from
Sep 19, 2021

Conversation

aoirint
Copy link
Member

@aoirint aoirint commented Sep 15, 2021

ref: #95
ref: #85

内容

Docker内でLinux用実行バイナリを自動ビルドするGitHub Workflowを追加します。

run.pyをNuitkaでビルドし、成果物をGitHub ActionsのArtifactとして書き出します。

ビルドしたバイナリの動作には、CUDA/cuDNN(GPUの場合)とlibsndfileを別途インストールすることが必要です。

# On Ubuntu 20.04
sudo apt install libsndfile1

TODO

  • Docker内でLinux用実行バイナリをビルドする
  • GitHub Actions上でビルドする
  • OSベースイメージを変えたDockerコンテナ内、またはUbuntu 20.04以外のLinux OSで動くかテストをする
    • glibc 2.31(ubuntu:focal)でビルドしたバイナリの互換性チェック(glibc 2.29を要求)
      • ✔ Ubuntu 20.04(コンテナ内; glibc 2.31)
      • ❌ Ubuntu 18.04(コンテナ内; glibc 2.27)
      • ✔ Debian 11(コンテナ内; glibc 2.31)
      • ✔ Fedora 34(コンテナ内; glibc 2.33)
      • ❌ CentOS 8(コンテナ内; glibc 2.28)
      • ❌ CentOS Stream 8(コンテナ内; glibc 2.28)
    • glibc 2.27(ubuntu:bionic)でビルドしたバイナリの互換性チェック
  • Nuitka cacheの動作確認
  • 実行タイミング
    • masterブランチにpush
    • GitHub Release作成
  • masterの変更 f3527e4 に追従
    • speakers.jsonを除外 f3527e4
    • CPU版ビルド・GPU版ビルドの作成 89fddfe
  • LibTorch共有ライブラリのコピーを修正(*.soに加えて*.so.*をコピー)
  • libcore.soのLibTorchへのリンクを相対パスに書き換え
  • runに実行権限を付与(実装したが、GitHub Artifactの仕様により意味がなかった)
  • Artifact名: 固定(バージョン名などを付与すると他のWorkflowやJobから参照できない)
  • 76eac98 動作チェック
    • https://github.com/aoirint/voicevox_engine/actions/runs/1249432164
    • Ubuntu 20.04
      • CPU (ubuntu:focal, 9d6a8699fb5c9c39cf08a0871bd6219f0400981c570894cd8cbea30d3424a31f
      • GPU (nvidia/cuda:11.4.1-cudnn8-runtime-ubuntu20.04, ddd2828688c94c18b77f095577652faa053052cc40e32b870481087918f04a64)
    • Debian 11
      • CPU (debian:stable-20210902, a9cb4a9ddf9f28bc17fc390baba42ac7eb067ae54d20b55720ed9ff3323b1d87)
    • Fedora 34
      • CPU (fedora:34, d18bc88f640bc3e88bbfacaff698c3e1e83cae649019657a3880881f2549a1d0)
    • Debian 11, Fedora 34のGPU動作(CUDA)については、公式のnvidia/cudaイメージが存在しないため、Docker上で検証するにも自分でメンテナンスする必要があり、また需要がなさそうに思うので、ひとまず対応しない形にする
      • CentOS 8の公式イメージは存在するため、libcoreがCentOS 8(Ubuntu 18.04相当)に対応した際には、あらためて対応する方針
  • 対応バージョン・動作環境・実行方法のドキュメント化: Linux用実行バイナリの動作検証 #106 (仮)

Docker内でビルドする利点

  • 環境構築スクリプトを二重に実装する必要がない
    • ちなみに、autoconfcmakeを使ったビルドスクリプト構築の知見はもっていません
  • ビルド環境のキャッシュをDocker Hubに保管できる

(ネイティブビルドの方がよさそうであればCloseするかもです)

Dockerイメージのpushについて

  • *-buildcacheというビルド環境のキャッシュ用のDockerイメージのみpushします(--cache-toオプション)
  • バイナリを実行するDockerイメージがあってもいいかもしれませんが、その自動ビルドを実行するGitHub ActionsのJobは、役割的にbuild-docker.ymlの方に記述したほうがいいかもしれません

キャッシュについて

@aoirint
Copy link
Member Author

aoirint commented Sep 17, 2021

NuitkaのキャッシュをうまくGitHub Actions上で保存できていなかったのでDraftにしていましたが、解決しました。
キャッシュ対象のファイルをみつけられていませんでしたが、キャッシュに使うディレクトリを作業ディレクトリから2階層深いサブディレクトリにするのをやめたら見つけられるようになったようです( 12b806e )。

@aoirint
Copy link
Member Author

aoirint commented Sep 17, 2021

このPRは、masterブランチにpush、またはGitHub Release作成のタイミングで、
Ubuntu 20.04、Debian 11、Fedora 34で動くLinux用実行バイナリを自動ビルドできる状態です。
Ubuntu 18.04、Cent OS 8、Cent OS Stream 8では、工夫しないと動きません(工夫の例: https://github.com/Hiroshiba/voicevox_engine/pull/98#issuecomment-921240899 )。

成果物は、master pushまたはRelease作成後、およそ1.5時間後にGitHub Artifact(GitHub Actionsの実行結果ページ)にアップロードされます。
デフォルトかつ最大の保持期間は90日で、保持期間を経過すると削除されます。

バイナリの動作確認は各LinuxディストリビューションのDockerコンテナ内でしていますが、実環境では、テストしたDockerコンテナとディストリビューションは同じでも、動作する環境と動作しない環境が出てくる可能性はあります。
この場合、現在原因として想定しているのは、以下の2点です。

このPRで考慮していない ディストリビューションやCPUの種類など への対応に関する議論、
実環境での動作報告などは、
その都度IssueやPull Requestで対応する方向性で、いったんマージする形でも大丈夫でしょうか?
VOICEVOX ENGINEの正式リリースとしては、しばらくバイナリを含めなくてもいいかもしれません。

動作状況

amd64 (x86_64)

  • ✔ Ubuntu 20.04(glibc 2.31)
  • ❌ Ubuntu 18.04(glibc 2.27)
  • ✔ Debian 11(glibc 2.31)
  • ✔ Fedora 34(glibc 2.33)
  • ❌ CentOS 8(glibc 2.28)
  • ❌ CentOS Stream 8(glibc 2.28)

要求する共有ライブラリ・バージョン

  • glibc 2.29以降
    • 調べ方: /lib/x86_64-linux-gnu/libc.so.6 または/lib64/libc.so.6を実行
  • libstdc++ GLIBCXX_3.4.26に対応するバージョン
    • 調べ方: strings /usr/lib/x86_64-linux-gnu/libstdc++.so.6 | grep GLIBCXXを実行
  • libsndfile:
    • Ubuntu/Debian: sudo apt install libsndfile1
    • Fedora: sudo yum install libsndfile
  • CUDA/cuDNN (GPU動作の場合)

@aoirint
Copy link
Member Author

aoirint commented Sep 17, 2021

現在差分にはコマンドの実行ユーザを簡便に切り替えるためのgosuが含まれているので、 #105 とコンフリクトしています。

このPRでgosuを使っているのは、entrypoint.shをrootユーザで実行し、ビルドを一般ユーザで実行したいためです(依存関係は一般ユーザ用にインストールしている)。

ホスト側のディレクトリをコンテナにマウントして成果物とキャッシュを取り出している関係で、entrypointでroot権限を使って、chown -Rでマウントしたディレクトリの所有者をコンテナ内の一般ユーザに書き換えています。

マウントされたディレクトリの所有者は、ホスト側にディレクトリが存在しない場合rootに、存在する場合もともとの所有者(ホスト側のUID・GID)になります。変更にはroot権限が必要です。

対応の候補として考えているもの

  1. gosuを実行用イメージには含めず、ビルド用イメージには含める
  2. ビルド用イメージでUSER命令を使用してあらためてrootユーザに切り替える
  3. docker build中に実行バイナリをビルドする実装に切り替える(2の発展)

@aoirint
Copy link
Member Author

aoirint commented Sep 17, 2021

一応、docker runではなく、docker buildの方で実行バイナリをビルドする実装も試そうと思っています。

バイナリを実行するコンテナにも拡張できそうです。

ビルド成果物やNuitkaのキャッシュは、
イメージを1度コンテナとして起動する必要はありますが、docker cpで取り出す想定です。

ただ、Dockerイメージのキャッシュの扱いが難しそうです

@aoirint aoirint marked this pull request as ready for review September 17, 2021 07:55
@aoirint
Copy link
Member Author

aoirint commented Sep 17, 2021

要点

  • Ubuntu 20.04, Debian 11, Fedora 34に対応し、Ubuntu 18.04やCentOS 8では動かない形でいったんマージして問題ないか
  • そのほか実環境での細かい動作確認
    • 今後のIssueやPull Requestで対応する形で問題ないか
  • entrypoint.sh内にスペースインデントが入ってしまう問題の対応と可読性の向上 #105 とのコンフリクトをどう解消するか
    • このPR内でgosuを使わないようにするべきか
    • 現在のdocker runでディレクトリをマウントする実装をやめ、Dockerイメージビルド時に実行バイナリをビルドする実装に切り替えるべきかもしれない

ready for reviewにしていましたが、masterにマージされた変更が影響しそうなのでdraftに戻します

@aoirint aoirint marked this pull request as draft September 17, 2021 11:45
@Hiroshiba
Copy link
Member

詳細ありがとうございます!

Ubuntu 20.04, Debian 11, Fedora 34に対応し、Ubuntu 18.04やCentOS 8では動かない形でいったんマージして問題ないか

対応バージョンがわかるようになっていれば全く問題ないと思います。

今後のIssueやPull Requestで対応する形で問題ないか

こちらもその方針で大丈夫です。

gosuの削除 #105 とのコンフリクトをどう解消するか

こちら、僕自身よくわかっていなくて申し訳ないのですが、gosuを使うメリット・使わない場合のデメリットをご教示頂けると非常に助かります・・・。
(entrypoint.shをrootユーザで実行し、ビルドを一般ユーザで実行するメリット・そうしない場合のデメリットを知りたい感じです。)

@aoirint
Copy link
Member Author

aoirint commented Sep 18, 2021

entrypoint.shをrootユーザで実行し、ビルドを一般ユーザで実行するメリット・そうしない場合のデメリット

実行用のイメージ runtime-env の実装を負債として? 引きずっているためで、メリット・デメリットについては考えていませんでした。

バイナリを実行する実行用のイメージを配布する可能性を想定していることも背景にあります(このイメージを配布するメリットはいまのところ思いつきませんが、バイナリにすることでプログラムの実行が高速になる、などがあれば意味があるかもしれません)。

デメリットについては、
依存するPythonパッケージやライブラリ・プログラムが悪意を持った場合に、root権限で実行されることくらいでしょうか。
gosuのバイナリは数MBで、容量については気にしなくていいと思っています。

メリットについては、 https://github.com/Hiroshiba/voicevox_engine/pull/105#issuecomment-922242197 の前半で言及した内容で、ビルド時ではありますが、ホスト側が影響を受ける可能性を予防しようとしています。

ちなみに、gosuの利用を継続するようであれば、gosuはディストリビューションのリポジトリからもインストールできる(apt install gosu)ようだったので、GitHub Releaseから取得するのではなく、ディストリビューションのリポジトリを信頼して、そちらを使うのもいいと思っています。
少しバージョンが古いですが、役割には影響しないと思います。
GitHub Releaseから取得する場合、厳密には、gosuのハッシュ値チェックもした方がいいかもしれません。

と、思ったのですが、 #105 の方でディストリビューションのリポジトリを使用する形に対応 e6d725d されていますね。

@Hiroshiba
Copy link
Member

なるほどです!
#105 の議論の結果からもgosuを利用する方針で良さそうだと感じたので、gosu利用を継続する形で進めて頂ければと思います!

@aoirint
Copy link
Member Author

aoirint commented Sep 19, 2021

Dockerfileにおけるバイナリビルド用スクリプトの書き出しについて、
ヒアドキュメントが3重になっていて、すこし読みにくいように思いました。

ファイルに書き出してもいいのですが、Dockerの外部から使うことを想定していないスクリプトのため、
Dockerfile内に記述しています。

./docker/scripts/のようなディレクトリを作るというのも考えましたが、Dockerfileを
./docker/Dockerfileに配置したくなり、コンテキストの関係でDockerビルドコマンドが複雑になるので採用していません。

また、バイナリビルド用スクリプトをdocker runで呼び出す方法は、ビルド成果物を含むレイヤーが作成されないため、Dockerのキャッシュが利用できず、バイナリビルド後の処理を追加したときに、バイナリビルド自体も再実行されてしまうという問題を抱えています。

個人的には、これらは、それほど大きな問題ではないと思うので、希望、またはいい方法があれば、将来のPRで対応するのがよいと思っていますが、このPRで考えた方がよさそうでしょうか。

ちなみに、以前言及していたdocker buildのタイミングでバイナリビルドする方法(ビルド成果物を含むレイヤーを作成する方法、https://github.com/Hiroshiba/voicevox_engine/pull/96#issuecomment-921534213 )は、GitHub Actionsの14GBの容量を使い切って、成果物の取り出しに失敗してしまうようだったので、むずかしそうです。複数のJobやWorkflowにDockerビルドとArtifactアップロードを分ければできるかも、とは思っています。

実環境での動作検証については、 #106 で募集し、 #95 はこのPRと一緒に閉じていいと思っています。

fork先での現在 Hiroshiba@28eba6e のビルド: https://github.com/aoirint/voicevox_engine/actions/runs/1250414693

@aoirint aoirint marked this pull request as ready for review September 19, 2021 10:43
Copy link
Member

@Hiroshiba Hiroshiba left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

./docker/scripts/のようなディレクトリを作るというのも考えましたが

VOICEVOXリポジトリと同じ用に、./build/ディレクトリを作る手もありそうです。
でも結局実行するのは数コマンドだけだし、Dockerfile内に記述されていてもあまり問題ではないかなと思いました!

docker runで呼び出す方法

僕も同意見で、docker buildとdocker runどちらでも良いと思っています。
軽量化されたり、よりよい方法が見つかったときに変更を考えましょう!

(artifactじゃなくreleasesにアップロードできるくらい軽量化したいですね・・・。)

@Hiroshiba Hiroshiba merged commit 3eed8e0 into VOICEVOX:master Sep 19, 2021
@Hiroshiba
Copy link
Member

ちなみにwindows版も自動ビルドを試される予定はありますか?
(ビルドスクリプトがとても参考になったので、もしよろしければぜひプルリクエストを頂ければなと思っています・・・!)

@aoirint
Copy link
Member Author

aoirint commented Sep 19, 2021

ちなみにwindows版も自動ビルドを試される予定はありますか?

ビルドまでの道筋は整っていると思ったので、#107 を開いてみました。

coreの自動ビルド準備時のGitHub Workflowが似ていたので、参考にさせていただいています。

@Hiroshiba
Copy link
Member

@aoirint はい、ぜひ参考にしてください!

また、CPU版やubuntu18ビルド版も用意してみました。もしよかったらお使いください!
https://github.com/Hiroshiba/voicevox_core/releases/tag/0.5.4

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

Successfully merging this pull request may close these issues.

2 participants