ドッカーコン
コンテナ内の機械学習
Jinjing Zhou 氏 (TensorChord 最高技術責任者)
写し
今日は、コンテナ内の機械学習と、機械学習の実践者のために開発環境と本番環境の間のギャップを埋める方法についてお話しします。
ジンジンです。 私は TensorChord 出身で、CTO 兼共同創設者です。 前職はAWSエンジニアとして働いていました。 主にグラフの深層学習に取り組んでいます。 私は、科学者をグラフ上の機械学習に適用するためのフレームワークであるディープグラフライブラリプロジェクトの創設メンバーであり、コア開発者です。 現在、TensorChord では、envd、openmodelz、pgvecto.rs の 3 つの製品を管理しています。 私たちはAIインフラストラクチャ企業であり、オープンソースを非常に愛しています。 そのため、当社の主要製品はすべてオープンソースであり、AIインフラストラクチャに焦点を当てています。 GitHubレポートをご覧ください。私のGitHubアカウントは@VOVAllenなので、ここでお話しできてうれしいです。
ここでは、 envd というツールを使って機械学習開発環境を封じ込める方法についてお話しします。 左側には素敵なロゴがあります。 envdの文字をロゴに取り入れました。 そして、みんな猫が大好きなので、猫のロゴにしました。
目次
なぜコンテナなのか?
最初の質問は、なぜコンテナなのかということですが、なぜコンテナはデータサイエンティストが開発環境として使用するのに適していると考えるのでしょうか。 そこで、データサイエンティストを大いに悩ませる質問があります。 1つ目は、製品ごとに環境を整えるのが難しいことです。 主な理由は、機械学習の分野では Python と C++ が頻繁に使用され、C++ ライブラリには常に混沌とした依存関係の問題があるためです。 また、CUDAではさらに悪化し、GPU版やCUDA版ではディープラーニングフレームワーク版で補う必要があり、データサイエンティストにとっては悪夢となります。 製品ごとに分離された環境を設定するのは困難です。
2つ目の問題は、データサイエンティストはモデルやアルゴリズムについて多くを学びますが、インフラストラクチャについてはあまり知りません。 調査の結果、Dockerについて聞いたことがあるのは一部のデータサイエンティストのみで、使用したことがあるのはごく一部であることがわかりました。 データサイエンティストが、適切なDockerイメージを構築するための優れたDockerfileの書き方を実際に知っていることは非常にまれです。
一部の企業では、科学者がDockerのコミットを行うだけであることさえあります。 したがって、Dockerですべてを実行し、レイヤーごとにコミットするだけです。 最後に、それは 20ギガバイトの画像のようになり、その中に何があるかは誰にもわかりません。 誰にとってもかなり悪い習慣だと思います。 データサイエンティストは、環境に実際に何があるのかを知らず、チームは、このイメージが安全かどうか、またはその内部にセキュリティ上の問題があるかどうかを知りません。
3つ目の問題は、データサイエンティストが他人の仕事を再現するのが難しいことです。 毎日多くの新しいアルゴリズムが登場しています。 そして、科学者の主要な仕事は、他の人の研究を再現するために多くの時間を費やす必要があり、再現性は工学分野では常に問題です。 コンテナは、この状況を改善するための良いツールだと考えており、使いやすくして標準になれば、誰もが簡単に他人の環境や動作を再現できるようになります。
ツール
これは、Python エコシステムの複雑さを示す図です。 通常、macOSなどの開発マシンでは、Pythonだけでは、システムに組み込まれているPythonや自作のPythonなど、ラップトップに複数のPythonがあり、実際に必要なPythonが何であるかわからないことがよくあります。 pip install somethingを実行し、それがシステムに組み込まれたPythonに移動し、Python 3で見つからないとします。 マシン全体ですべてを行うと、非常に一般的であることがわかりました。
また、Anacondaなど、これに対する既存のソリューションがいくつかありますが、それらは主にPythonエコシステムに焦点を当てており、これは問題の一部にすぎません。 ここでは、Python環境ツールに含まれていないものをリストアップしました。 そのため、Pythonエコシステムに含まれていない開発ツール(エディタ設定やCUDAなど)があります。 PyTorch などのディープ ラーニング フレームワークには、複雑な CUDA 依存関係の問題があります。 多くのツールが特定のバージョンにバインドされています。 ですから、それだけでは十分ではないと考えています。 また、OpenCV、OpenMMLab、MMDetectionなど、さらに多くのC ++ライブラリがあります。 C++ であり、Python エコシステムに含まれていないライブラリが多数あります。 コンテナは、機械学習の科学者がプロジェクトや開発環境を管理するための優れたツールであると考えています。 そのため、プロジェクトごとに個別の画像を作成できます。
envdの
機械学習サイエンティストが開発環境をコンテナ化するのをどのように支援しますか? そこで、ユーザーが機械学習用のコンテナベースの環境を作成できるように、CLIツールに戻ります。 構文は Python とまったく同じです。 実は、もともとGoogleが育てたStarlarkというPythonの方言です。 実際には、基礎構築システムを使用する言語です。 また、ユーザーがPythonのような構文を使用して環境要件を上げることができるようにするために使用しています。 彼らはすでにPythonの構文に精通しているので、これらのツールに簡単に慣れることができます。 ビルド関数を定義し、基本オペレーティング システム イメージ、CUDA バージョン、必要なパッケージなどの環境のニーズを記述するだけです。 そして、そのファイルでは、「envd up」を実行するだけで、それだけです。 コンテナ権限の開発環境は、このようなものです。 すでに最新バージョンであることがわかりますが、envd環境にいることがわかります。
もう一つの素晴らしい機能は、一般的なユーザーツールの多くのレシピを事前に定義できることです。 ここでは、例として TensorChord を使用します。 Envd lib はメインのレシピリポジトリです。 一般的なユーザーツールのレシピが多数用意されているので、envd lib のツールを直接呼び出してセットアップすることができます。 したがって、TensorChordの場合と同様に、TensorChordセットアップをインストールする必要があり、コンテナにあります。 envdがないと、イメージのエントリポイントを変更する必要がありますが、それは1つの部分にすぎません。 Docker で同時に実行する必要がある複数のプロセスがある場合があります。 そのため、純粋なDockerファイルを作成している場合は複雑になります。
3 番目の機能も Python 構文によって有効になります。 一般的な状況は、運用環境が開発環境とわずかに異なることです。 そのため、開発ツールをできるだけ開発に含めたいのですが、それを削除して、運用イメージをできるだけ最小限に抑えたいと考えています。 ここでは、上位関数がコアの依存関係を定義します。 開発と運用の両方で統合されている Python パッケージがあります。 そして、開発イメージでは、必要なツールをさらに宣言することができ、サービングイメージでは、それらを削除するだけで済みます。 そのため、別のものを定義したり、エントリポイントを定義したりできます。 そのため、サービング画像は箱から出してすぐに実行できます。
デモ時間
次に、ちょっとしたデモをします。 これはbuild.envdの空のフォルダのようなものです。 これは、envd と呼ばれるカスタム拡張機能名です。 ここでは、簡単なビルド関数を記述します。 したがって、ベースを定義し、Pythonパッケージを定義します。 デモを実行するための空のパッケージだけが必要で、Jupyter Notebook をセットアップして envd を呼び出すだけです。 すでに電話があったと思うので、最初にそれを削除する必要があります。 そして、私はただ「envd up」をします。 そのため、構築プロセスが開始され、すべてがインストールされます。 以前にビルド プロセスを実行したので、すべてがキャッシュされていることがわかります。 ユーザーは、環境をそのまま使用できます。 ここでは、すでにコンテナ内のenvd環境にいます。
ここにコンテナが見えます。 これがPythonの基本であり、定義されたポートを公開します。 また、コンテナ内にsshdサーバーが埋め込まれているため、機械学習ワーカーの一般的なシナリオであるリモートマシンで環境を簡単に使用できます。 通常は、独自の開発マシンで少し開発してから、GPU のパワーが増した強力なクラスターに移動します。 そのため、SSHのようなリモート開発が必要だと考えています。 SSH設定ファイルにエントリを追加するので、 "ssh python-basic.envd"を実行するだけで済みます。 また、環境に入ることもできます。
なぜDockerfileではないのですか?
なぜDockerfileではないのですか? なぜ独自のビルドファイル形式を定義する必要があるのですか? 最初に見つかった問題は、Dockerfile の一部のパーツを再利用するのが難しいことです。 たとえば、MMDetection やカスタム演算子など、インストールが困難なライブラリがあり、形式が十分に分散されていないとします。 そのため、一度記述すれば、それを再利用する必要がある場合は、ある Dockerfile から別の Dockerfile にコピーして貼り付けるだけで済みます。 最後に、これらの部分を更新する必要があるときに混乱します。
2つ目の問題は、Dockerfileのドメイン知識がデータサイエンティストにはあまり適していないと考えていることです。 前述したように、データサイエンティストはアルゴリズムやモデリングが得意ですが、Dockerfileの部分については、その経験があまりない可能性が高いです。 彼らにとって、優れた Dockerfile を書くのは困難です。 また、他のエンジニアが本当に優れた Dockerfile を作成するのも難しいと思います。 レイヤーを適切に設計する方法や、キャッシュを再利用する方法など、考慮すべきことはたくさんあります。 たとえば、イメージが必要で、PyTorch をインストールしたいとします。 それらの間でpipキャッシュをどのように再利用できますか、また、イメージを構築するときに、ホスト上のファイルをどのように使用しますか? コンテナーで Jupyter Notebook を実行するにはどうすればよいですか? また、Jupyter Notebook と TensorChord をコンテナーで同時に実行するにはどうすればよいでしょうか。 これらはすべて、開発環境としてコンテナを使用する場合の実際の問題のようなものです。
データサイエンティストがこのようなツールを使うのは難しいと感じています。 そのため、Starlarkベースの構文は、データサイエンティストにとってよりシンプルで馴染み深いものだと思います。
BuildKit
envd の内部構造は次のとおりです。 私たちは BuildKit に大きく依存しています。 BuildKit は、実際には Docker 用の次世代ビルド エンジンです。 これは実際には、Dockerイメージを構築するための低レベルのビルドライブラリであり、Dockerfileに依存しません。 そのため、Dockerfile バージョン 2 は BuildKit をサポートしていますが、Dockerfile を実行する必要はありません。 開発者は誰でも、独自のフロントエンド言語を定義して使用できます。
BuildKitのもう一つの素晴らしい機能は、並列ビルドをサポートしていることです。 Dockerfile では、すべてを直線的にしか実行できないため、1 つのステップは、他のステップが終了した後に実行する必要があります。 しかし、BuildKit では、さまざまなステップを並列化できます。 ネットワーク通路と重なるため、互いに重なり合う可能性のあるステップがある場合は、大幅に高速化できます。 その後、後で 2 つのステップをマージして、ビルド速度を向上させることができます。
3 番目の部分は、BuildKit と同様にキャッシュ効率が高くなります。 キャッシュライブラリ用に特別な設計になっているため、異なるビルド間でキャッシュを簡単に共有できます。 そのため、PyTorch を使用する別のプロジェクトがあるように、それらのビルド間で pip キャッシュを共有できます。 しかし、重要なのは、BuildKit は非常に低レベルであるため、ユーザー向けのインターフェースを再定義する必要があるということです。
以下は、BuildKit を使用するアーキテクチャです。 これで、製品フォルダと追加のbuild.envdがあります。 envd ファイルは、開発から運用までの環境に対応する準備ができています。 また、envd 内には、envd ファイルを内部の中間表現に変換するための StarLark 言語コンパイルがあります。 次に、それを BuildKit LLB に変換します。 したがって、LLBは低レベルビルドの略です。 これは、イメージを構築するために BuildKit 内で表されます。 そして、LLBの構築が完了したら、それをBuildKitデーモンに送信します。 そのため、デーモンはビルドに関するすべてを処理し、イメージを生成します。 最後に、イメージをDockerデーモンに送信します。 そのため、Docker ps内のイメージを別のイメージとして見ることができます。
ここでは、envd と Dockerfile を比較したベンチマークをいくつか紹介します。 最初のビルドでは、Dockerfileよりも約2倍の速度で高速です。 これは、Python のインストール手順と APT インストールパスの手順を並列化することで行われます。 ユーザーがスクリプトをビルドするのを並列化するための興味深い役割は他にもあります。 また、レビューの最適化にも特化しています。 開発者が開発環境を変更することは非常に一般的であるため、すぐにパッケージを追加することをお勧めします。 このようなシナリオに最適化しているため、再構築シナリオでは Dockerfile の約 6 倍の速度になります。
リモートビルド
私たちがサポートする他の部分は、リモートビルドに関するものです。 そのため、ユーザーは build.envd ファイルをローカルに記述し、リモートマシンでビルドを実行できます。 ですから、envdにはコンテキストの概念があります。 したがって、remote build という新しいコンテキストを作成し、指定されたビルダーを TCP アドレスとして作成するだけで済みます。 また、BuildKit も搭載しています。
これは、たとえば、機械学習ワークフローなど、ソース コードなど C++ から何かをコンパイルする必要がある場合など、ビルド プロセスで大量の CPU リソースが必要な場合に非常に便利です。 大量のCPUリソースが必要であり、機械学習のライブラリもTensorCordやPyTorchのようにギガバイトレベルとかなり大きいです。 そのため、ビルドを高速化するには、適切なネットワーク帯域幅が必要です。 リモートマシンでこれを実現するには、リモートマシンをパブリッククラウドに配置します。 したがって、パブリッククラウドマシンはネットワーク帯域幅が大きく、より多くのCPUコアを割り当てることができるため、すべてが同じように機能しますが、はるかに高速になります。 開発者にとっては、開発エクスペリエンスの向上にも役立ちます。 macOSですべてを実行する必要はなく、マシンが非常にハードになり、イメージの構築に非常に長い時間を費やすなど、気分が悪くなります。 時間の無駄です。
リモートビルドは、特にチームのCI/CDワークフローに適した機能であることがわかりました。 ビルドプロジェクトを集中管理されたマシンにアウトソーシングすることができます。 そのため、キャッシュの管理もはるかに簡単になり、クラスターのようにキャッシュを可能な限り再利用できます。
次の図は CI/CD マシンを示しており、コンテキスト クリエーターを行うため、コアが 1 つか 2 つしかない GitHub Actions マシンから専用のビルド クラスターに起動できます。 そして、最後にそれをリモートレジストリにプッシュして、すべてが箱から出してすぐに機能するようにします。 CI/CDの時間を大幅に短縮でき、開発者の時間も節約できると感じています。
結論
今日は以上ですが、本日はありがとうございました。 また、これらのスライドとenvdで多くののを手伝ってくれた同僚のKemingにも感謝します。
GitHub の TensorChord でスターを付けていただければ幸いです — 先ほど紹介したように、envd という 3 つのプロジェクトがあります。 また、openmodelzは、開発者がクラスターにモデルをデプロイするのに役立つフレームワークです。 そこにエンジニアリング インフラストラクチャが構築されるため、クラスターにマシンを追加し、モデルのデプロイを依頼するだけで済みます。 3つ目は pgvecto.rs、 これはPostgresのベクトル検索拡張機能であるため、Postgres内で直接ベクトル検索を実行できます。 それだけです。 どうもありがとうございます。
さらに詳しく
- Docker による人工知能と機械学習
- Docker ビルドキット
- Docker デスクトップの最新リリースを入手します。
- 質問がありますか? Docker コミュニティがお手伝いします。
- Docker は初めてですか? さっそく始めましょう。
- Docker Newsletter を購読してください。
自分に合ったサブスクリプションを見つける
今すぐ専門家に連絡して、Dockerサブスクリプションのコラボレーション、セキュリティ、サポートの完璧なバランスを見つけてください。