ByteDance Spark は Wanka モデル推論の実践をサポートします

要約: この記事は、CommunityOverCode Asia 2023 での ByteDance インフラストラクチャ エンジニア Liu Chang 氏と ByteDance 機械学習システム エンジニア Zhang Yongqiang 氏による「ByteDance Spark が Wanka モデル推論の実践をサポート」の基調講演を編集したものです。
クラウド ネイティブ化の開発プロセスにおいて、Kubernetes は、その強力なエコロジー構築機能と影響力により、ビッグ データや AI を含む、ますます多くの種類の負荷アプリケーションを Kubernetes に移行できるようになりました。Byte は社内で Hadoop から Kubernetes への Spark の移行を検討しています。クラウドネイティブのジョブを実行します。 ByteDance のビッグ データ リソース管理アーキテクチャと Spark の展開の進化は、大きく 3 つの段階に分けることができます。
  • 最初の段階は、完全に YARN に基づいたオフライン リソース管理です。YARN を大規模に使用してビッグ データ クラスターを管理することで、リソースの運用とメンテナンスのコストを削減しながら、Spark リソースの使用率を効果的に向上させることができます。
  • 2 番目のステージは、オフライン リソースの混合デプロイメント ステージで、YARN と Kubernetes のハイブリッド デプロイメント クラスターを構築することで、オフライン リソースの全体的な使用率がさらに向上します。ハイブリッド展開テクノロジーにより、クラスターと単一マシンの両方のリソース使用率が大幅に向上しました。リソース使用率が向上するということは、より完全な分離手段が必要になることを意味します。そのため、私たちは Spark のコンテナ化されたデプロイメントを徐々に推進し始めました。
  • 3 番目の段階は、完全なクラウドネイティブの導入です。オフライン ロードでは管理に異なるアーキテクチャが使用されなくなり、Spark のクラウド ネイティブ性も徐々に構築され、改善されています。
もちろん、クラウド ネイティブは業界でほぼ一致した開発トレンドですが、なぜクラウド ネイティブを使用するのでしょうか?統合リソース管理ベースとして Kubernetes を使用する理由は何ですか? 1 つ目は、 効率的な運用 とメンテナンスであり、オンライン ロードであってもビッグ データ ロードであっても、継続的な開発、統合、デプロイメントを容易に実現できます。 2 つ目は、 リソース プーリング です。統合されたクラウド ネイティブ ベースにより、インフラストラクチャのオーバーヘッドが削減され、リソースの転送効率がさらに向上します。これにより、データ センター全体の使用率がより包括的かつ完全に向上し、効率が向上します。 。 3 つ目は、 生態学的繁栄 です。Kubernetes は、基本的な運用および保守機能、上位層のアプリケーション管理、基盤となるネットワークやストレージなど、標準化されたインターフェイス定義を提供することによって、ほぼ最も活発なエコシステムを備えていることがわかっています。など、Spark のクラウドネイティブな使用を容易にする管理オプションが多数あります。

ByteDance スパーク スケール

ByteDance は業界をリードする Spark ビジネス規模を持ち、毎日数百万のオフライン ジョブを実行し、数百万のコア、数万枚の GPU カードのリソースを占有し、クラスタの合計サイズは数万ノードに達します。このように大規模な Spark 負荷は、Spark を完全にネイティブに実装するのが容易ではないことを意味します。ここでは、実際に私たちが考える質問を示します。 Spark ジョブのデプロイメントはスタンドアロンによる静的デプロイメントですか、それとも K8s Native による動的デプロイメントを使用する必要がありますか? K8 でテナントレベルのリソース管理と Spark ジョブの制御を実装するにはどうすればよいですか? 管理はジョブの送信時またはポッドの作成時に実行する必要がありますか? Spark のスケジューリングのニーズをサポートするにはどうすればよいですか? Spark でジョブを送信するとき、多数のポッド作成がスケジュールのボトルネックを引き起こしますか?このような大規模な運用アーキテクチャの移行では、どのように周辺機能を構築し、運用の移行前後のエクスペリエンスをスムーズにすればよいでしょうか?
Spark のクラウド ネイティブ化の検討の過程で、パートナーは、非常に高い GPU 要件を伴う多数のオフライン バッチ処理タスクを含む多くの問題にも直面しました。オンライン クラスター ビジネスでは、低ピーク時に大量のリソースが解放される可能性があります。オンライン サービスを完全に使用できず、全体的な使用率が低くなります。機械学習は Spark の重要なパートナーであり、私たちは上記の問題を解決し、周囲のエコシステムを強化するために協力しています。また、Spark はビジネス向けにターゲットを絞ったエンジンの強化を行っており、ビジネスは Spark のクラウドネイティブなリソース、スケジューリング、管理からも恩恵を受けています。 。

Spark クラウド ネイティブ ソリューションとエンジンの機能強化

Spark クラウド ネイティブ テクノロジ ソリューションの現在の主流の使用方法には、Spark Native と Google のオープンソース Spark Operator があります。 2 つのメソッドは同じ目標を達成し、最終的には Spark-submit コマンド ライン ツールを呼び出します。違いは、Google の Spark Operator がより豊富なセマンティクスをサポートし、Operator と Mutatingwebhook を通じて K8 に近いより豊富な機能を注入することです。
Byte Spark のクラウド ネイティブ テクノロジ ソリューションは 2 つあり、1 つは YARN の送信方法を変更する必要のないスムーズな移行で、もう 1 つは Yodel を介してスケジューリングするために Spark Native Submit です。 Arcee を通じてスケジュール システムに送信されます。ここで説明する必要がある概念は次のとおりです。 Gödel は Byte によって開発された分散リソース スケジューリング システムであり、YARN と Kubernetes のリソース スケジューリング機能をホストし、Kubernetes と YARN のリソース プール、クォータ、スケジューリング、分離を統合します。 Byte 自体による。YARN ジョブ タイプをサポートし、YARN の RM および NM コンポーネントを変換します。 Arcee は、Byte が独自に開発した統合クラウドネイティブ ビッグ データ オペレーターであり、Spark や Flink などのビッグ データ ロードをより便利に管理できます。 Yodel と Arcee の違いは、Yodel は「YARN プロトコルと互換性のある」ゲーデル ソリューション上のビッグデータであるのに対し、Arcee は「K8s プロトコルと互換性のある」ゲーデル ソリューション上のビッグデータであることです。同じ Gödel Scheduler と Kubelet テクノロジーを再利用します。
このプラクティスは完全なクラウドネイティブ展開であり、Arce Operator を通じて送信されます。主に、ジョブ ライフ サイクル管理、ジョブ リソース管理、および一部のエンジン カスタマイズ機能が含まれます。

アーシーの紹介

Arceeの核となる設計アイデアは 2 レベルのジョブ管理であり 、YARN の 2 レベルの管理モデルを利用しています。中央管理サービス AM は主にビッグ データ ジョブの作成と維持を担当し、AM はコンピューティングの作成と維持を担当します。労働者。 Spark ジョブに対応して、Arcee はドライバーを作成し、ドライバーは必要なエグゼキューターを作成します。この管理モデルは、ビッグデータのジョブ ステータスを効果的に管理および表現し、ジョブ管理戦略をカスタマイズできます。その一方で、コンピューティング エンジンがコンピューティング ジョブの動作を完全に制御し、必要に応じてリソースの使用量を調整できることも保証できます。
Arcee Operator には 6 つのモジュール が 含まれています Arcee CRDモジュールは、ArceeApplication と ArceeCommand という 2 つのリソース タイプを定義します。 ArceeApplication は、主に Webhook モジュールに使用される操作を記述します。 アプリケーション/ポッドの構成の挿入と検証を担当します。PodSetManager ジョブのリソース管理を担当します。EngineManager 、一部のエンジンのカスタマイズ機能を実装するために 使用 れます Spark などのビッグ データ ジョブとバッチ スケジューラのインターフェイスを完了します。
完全なジョブ送信プロセスは、Arnold (機械学習プラットフォーム) が Spark ジョブの送信を開始し、Spark クライアントを呼び出し、必要なパラメーターを入力してジョブを K8s に送信するというものです。 Arcee モードでは、Spark クライアントは組み込みの Arcee クライアントを使用して Spark ArceeApplication を作成します。これは Webhook によって前処理され、APIServer に送信されます。次に、Arcee コントローラーはアプリケーションの作成イベントを受け取り、対応するジョブ ステータスを生成し、アプリケーションの説明に従ってドライバーを作成します。ドライバーは、必要に応じてすべてのエグゼキューターを監視し続けます。関連する構成の挿入も実行されます。アプリケーション内のドライバーとエグゼキューターのすべてのポッドは、リソース使用量統計のために Arcee の PodsetManager で維持され、関連情報を他のモジュールに提供します。

アーシーにスパーク

Arcee 上の Spark は、Spark ネイティブ デプロイメント モデルをある程度改良したものと考えることができます。主な違いは、Spark クライアントに組み込まれている K8s クライアントが、ドライバーの負荷を管理するコンポーネントに置き換えられていることです。 Arcee Operator と Executor が相互に独立し、メンテナンス用に統合された Arcee アプリケーションが作成されます。 Arcee は、ジョブのライフサイクル管理、スケジュールのシールド、およびその他の関連機能も提供します。

スパークエンジンの最適化

前のセクションで紹介したビジネス バックグラウンド プラクティスに基づいて、Spark エンジン側で次の機能強化が行われました。各問題の発生と解決策は次のとおりです。
  • Executor は MPS ステータス異常を回避するために正常に終了します
      現在、GPU の使用を必要とする一部の Spark データベース フラッシュ ジョブは K8 上で実行され、オンライン サービスと混合されています。これらのジョブは、MPS を介してホスト上の GPU デバイスを共有します (MPS は、Nvidia が提供するマルチプロセス サービス テクノロジであり、さまざまな処理を可能にします)。カーネルの実行時に複数の共有プロセスの 1 つが強制終了されると、ハードウェア レベルで致命的な例外が発生しやすくなります。これにより、GPU 上の他のプロセスが終了することになるため、各プロセスの正常な終了を処理する必要があります。
      K8 で実行すると、特定のスケジュール上の理由によりリソースが枯渇し、コンテナーがエビクトまたは強制終了される可能性があります。ドライバー、エグゼキューター、デーモン、ワーカーの関係から、さまざまなエグゼキューターとワーカーの終了状況を注意深く分析しました。 Executor の正常な終了をコンテナ環境に実装し、終了信号をキャプチャして cudaDeviceSync を自動的に実行することで、オフライン終了によって MPS が未定義の状態になることを防ぎます。
  • クォータを通じて多数の保留中のポッドの問題を解決する
      Spark は DynamicAllocation をサポートしています。現在、ユーザーは多数の保留中のポッドが生成されるのを防ぐために、Max を開始するのに十分な場合にのみ Max を設定します。エグゼキュータは、実際に K8s に送信できます。それ以外の場合は、Arnold サービスのキューで待機します。ただし、Max を使用してクォータを確認することの現在の欠点は、リソースを浪費しやすいことです。キュー内に Max より小さいクォータがある場合、現在のタスクの特性に従って、タスクを最初に開始して現在のリソースを使用できます。ただし、現在のクォータ チェック ロジックにより、リソースのこの部分が使用されなくなります。使用できず、タスクは常に上位層でキューに入れられます。この問題は次の方法で解決できます。
    • Spark.kubernetes.allocation.batch.size パラメーターを使用して、各バッチでプルアップされる Pod の数を制御します。
    • Spark.kubernetes.allocation.maxPendingPods パラメーターを使用して、単一ジョブのペニング ポッドの最大数を制限します。
    • ただし、パラメーターを調整しても、同じ期間に同じキューに多数の送信がある問題は解決できません。そのため、Webhook を使用してキューに基づいてクォータを確認できます。クォータがない場合、ポッドの作成は失敗します。 . Spark は、例外を処理し、ポッド作成戦略を追加し、作成時間間隔を大幅に増加させて、この問題を解決します。
  • 混合場所の 不安定なリソースシナリオにおける運用の堅牢な最適化
いくつかの例を挙げると、リソース安定性の最適化のスケジュール設定中の複数のストレス テスト中に、Spark Executor Pod が異常に拒否される (UnexpectedAdmissionError) ことがよくあります。一元的な調査により、一連の Kubelet ロジックにおける複数の競合状態の問題が修正され、1 日あたりの平均混合リソースが制限充填率の安定した増加に達しました。また、一連の調整と変換を実行し、リソース使用量の観察を容易にするためにいくつかの GPU インジケーター収集ポイントを追加し、ブラックリストや推測などのパラメーターを通じてリソースの不安定性に対するタスクのフォールト トレランスを向上させました。

周囲の生態学的統合

K8s 上の Spark 環境では、ログと監視インジケーターも非常に重要です。これらは、クラスター、コンテナー、タスク全体の実行ステータスを観察し、ログと監視に基づいて問題を迅速に特定し、タイムリーに処理するのに役立ちます。 。そのため、Spark クラウドのネイティブ化のプロセス中に、Trace システムが徐々に構築されていきました。 Arcee Operator と Gödel スケジューラはいくつかのジョブ インジケーターを提供し、Spark はビジネス インジケーターを提供し、スタンドアロンの Metrics Collector コンポーネントは物理マシン インジケーターとコンテナー インジケーターを提供します。ログに関しては、各ノードで実行されているログ エージェントが指定されたパスのログを収集し、分析とクエリのためにログ プラットフォームに自動的にアップロードされます。 Arnold 機械学習トレーニング プラットフォームに基づいて、すべてのインジケーターとログをリアルタイムでクエリできます。また、ユーザーは、レポート作成、ジョブの最適化、ジョブの異常検出など、ニーズに基づいて高度なクエリを実行できます。等。同時に、Arnold はイメージ管理を通じてタイムリーに更新情報を取得することもできます。

ワンカモデル推理の練習

現在のクラスターは主にオフライン クラスターとオンライン クラスターに分かれており、オフライン クラスターは主にトレーニング タスクに重点を置き、主にタスクのスループットに重点を置いています。オンライン クラスターは主にオンライン推論サービスに重点を置いています。レイテンシとスループットに重点を置き、主に T4、A10、A30 などの小型カードを使用し、合計で数万枚の GPU カードを搭載しています。

主な矛盾

現在の主な矛盾は、オフライン クラスター クォータが完全に割り当てられていることです。論理的に言えば、リソースは割り当てられていますが、オフライン クラスターの全体的な使用率にはまだ改善の余地がたくさんあります。さらに、満たされていない社内コンピューティングのニーズも数多くあります。たとえば、これらの高品質のタスクは、実際には石のようなものですが、石の間にはまだ多くの隙間があります。したがって、問題の定義は、これらのギャップを見つけて砂で埋めること、つまり、適切な再利用可能なリソースを見つけて、適切なタスクを提案することです。

リソース

オフライン クラスター: 低品質のタスク

1 つ目は、オフライン クラスター内の優先度の低いタスクです。この部分はオフライン クラスター全体に含まれており、これらのアイドル状態のリソースを優先度の低いときに使用し、空き時間に優先度の低いタスクをスケジュールします。その後、優先度の高いタスクがある場合、それらはプリエンプトされます。同時に、これらはカード全体のリソースであり、オフラインの提出自体には明確なルールがなく、全体的な分離レベルが比較的低いため、それらの供給には明確なルールがありません。

オンライン -> オフライン: タイド

もう 1 つの部分は、オンラインからオフラインへの潮流リソースです。この部分は、オンライン クラスターのアイドル リソースをオフライン クラスターに貸す必要があります。この部分も、カード リソース全体であり、その供給は です。ビジネスの浮き沈みには明らかなパターンがあり、オンライン ビジネスがピークに達すると、リソースが自動スケーリングによって解放され、その容量がオフライン クラスターに貸し出されます。これは中程度の分離レベルであり、オフライン ポッドは同じマシン上で実行する必要がありますが、カードは引き続き分離できます。

オンライン→オフライン: 通常のコロケーション

もう 1 つの部分は、オンラインからオフラインへの通常のコロケーション リソースです。この部分は、実際には、オンライン クラスター内の比較的使用率の低い GPU のコンピューティング能力の一部をオフライン クラスターに貸与することを意味します。その主な理由は、一部のモデルです。カード全体は使用されず、空になります。コンピューティング能力は再利用でき、全体的な実装は Virtual-Kubelet + ByteCUDA + MPS に基づいています。
ByteCUDA は、独自に開発された CUDA フックで、上位層のメモリ分離と時分割多重化にいくつかの機能を果たし、下位層の MPS は空間分割多重化を通じて全体の分離レベルを向上させます。貸与されるものは実際には非統合カード リソースです。つまり、このカードにはオンライン タスクとオフライン タスクを含めることができます。利点は、サービスのこの部分が自動的に拡張または縮小されず、最も高い分離レベルを持つことです。
通常のコロケーションに関する大きな疑問は、オフラインがオンラインに影響を与えるのをどのように防ぐかということです。まず、メモリの分離と計算能力の分離を行う必要があります。さらに、負荷適応型の動的レンディング アルゴリズム、またはレンディング戦略を使用して、ウィンドウ期間内の GPU の電力消費を観察し、それに基づいて判断します。オンラインの世界への影響を少なくするために、オフラインの計算ではオンラインの計算リクエストを積極的に回避する必要がありますか?
さらに、MPS は障害伝播問題で有名です。上記の問題は正常な終了によって解決されます。上記のレンダリングから、コロケーションの前後でオンライン スループットがほとんど変化せず、遅延が約 0.75 ミリ秒増加することがわかります。実際、その使用率は当初の 10% から 70% に増加しましたが、全体の収益にはわずかな影響しかありませんが、使用率は大幅に向上しました。

タスク

リソースの後にはタスクがあり、これが砂と呼ばれるものです。 1 つ目は、彼の要求が十分に大きくなければならないということです。そうでない場合は、「いじる」必要はありません。さらに、これらは断片化されたリソース自体であるため、必要なタスクのサイズは比較的中程度である必要があり、特に大きなタスクにすることはできません。また、これらのタスクは、ディスクやネットワークなどの非分離リソースを大量に消費できないことも必要です。さらに、これらのリソースは弾力性があるため、タスクはリソースの自動拡張や縮小にも適応できなければなりません。リソースは、タスクを拡張するときに自動的に使用される必要があり、縮小する場合でも、この縮小によって妨げられることはありません。

Spark ベースのオフライン推論タスク

上記の実装要件に基づいて、Spark に基づくオフライン推論タスクが最終的にロックされました。まず、内部のオフライン推論要件が十分に大きいため、推論タスクのプロセスが比較的単純です。また、Executor 間には何も必要がなく、オンライン カードや RDMA などは必要ありません。また、大量のデータは実際には Spark と互換性があります。同時に、Spark のデータ処理機能とデータ配布機能、および動的割り当てに基づいて容量を動的に拡張および縮小する機能も使用する必要があります。

SDKビルド

タスクをロックした後、できる限りベスト プラクティスをカプセル化する必要があります。 上記は、Pytorch や Tensorflow などの一般的なモデル推論をサポートする Tide Box である SDK の概略図です。パーティションレベルのチェックポイント。このようにして、リソースが取り消されるときに計算を繰り返す必要がなくなるため、コンピューティング能力の無駄が回避され、バッチ処理をサポートすることで全体的なリソースの使用率が向上します。

プラットフォーム構築

SDK の構築後は、プラットフォームの構築も非常に重要な側面となります。これは、制御が不便なため、ユーザーが Spark Submit を通じてコマンドを直接実行することを望んでいません。したがって、Arnold 機械学習プラットフォームをベースとしてこれらのリソースを統合管理し、ノートブックの開発とデバッグに基づいて、ユーザーが手動で送信を検索することなく、必要な変数を 1 つのステップで事前に設定することもできます。異なるシナリオでリソースを同時に切り替えることも比較的便利です。
さらに、タスクの起動方法は、上流イベント トリガー、タイミング トリガー、API トリガーなどの複数の方法をサポートできるため、ユーザーは使いやすくなります。たとえば、パイプラインやユーザーの自動化要件を整理したい場合、これらの方法を使用して柔軟に実装できます。さらに、タスクの運用と保守も非常に重要であり、ワンクリックでタスクの履歴を表示したり、問題を遡ったりすることができます。

タスクとリソースのマッチング

Spark 推論タスクにはさまざまな種類があります。その 1 つは、リソース需要のこの部分が比較的大きく、時間も緊急であるため、通常はオフラインの低最適化を使用する必要があります。 Tide は、より包括的なカードと強力なコンピューティング能力を備えたリソースです。さらに、定期的な再実行が必要で、リソース要件が比較的大きく、タスクの緊急度が平均的なタスクをバッチ バックトラックし、これらのリソースを潮時展開と通常の混合展開で使用する必要があります。日常的なタスクは日レベルであり、リソース要件が中程度である場合があり、それらをサポートするために、比較的安定した通常のコロケーション リソースの供給を使用します。
オンライン貸出からオフラインまでのピーク状態は約 10,000 以上の Tidal GPU ですが、通常の混合デプロイメントは約 20,000 以上であり、全体の使用率は毎回約 100 以上のオフライン推論タスクになります。このタスクには 5,000 GPU を超える上限があり、それを制限しないと、ユーザーがそれをさらに増やす可能性があり、その結果、一般的なデータベース ブラッシング タスクを実行するには、安定したリソースが 9.5 日間必要になります。この柔軟なリソースにより、スケジュールは完了までに 7.5 時間に短縮されました。

今後の展望

将来的には、柔軟なコロケーション リソースは、全体的なリソース使用率を向上させるだけでなく、全体的なリソースを最適化するために、さらに多くのことを行う必要があります。まず、オンライン業務への影響を回避し、オフラインでの利用を増やし、より高い利用率を達成するように努めます。さらに、全体の規模と収益を拡大するには、より多くのビジネスを接続する必要があります。同時に、不必要なリソースのロールバックによって引き起こされる関連する問題を可能な限り軽減または回避します。
仲間のニワトリがDeepin-IDE を 「オープンソース」化し、ついにブートストラップを達成しました。 いい奴だ、Tencent は本当に Switch を「考える学習機械」に変えた Tencent Cloud の 4 月 8 日の障害レビューと状況説明 RustDesk リモート デスクトップ起動の再構築 Web クライアント WeChat の SQLite ベースのオープンソース ターミナル データベース WCDB がメジャー アップグレードを開始 TIOBE 4 月リスト: PHPは史上最低値に落ち、 FFmpeg の父であるファブリス ベラールはオーディオ圧縮ツール TSAC をリリースし 、Google は大規模なコード モデル CodeGemma をリリースしました 。それはあなたを殺すつもりですか?オープンソースなのでとても優れています - オープンソースの画像およびポスター編集ツール
{{名前}}
{{名前}}

おすすめ

転載: my.oschina.net/u/5941630/blog/10581528