Elastic Fabric Adapter を使用して Amazon EKS で機械学習トレーニングを実行する - Amazon EKS

このページの改善にご協力ください

本ユーザーガイドの改善にご協力いただけませんか? このページの下部までスクロールし、[GitHub でこのページの編集] を選択します。皆さまにご協力いただくことで、あらゆる人々に使いやすいユーザーガイドになります。

Elastic Fabric Adapter を使用して Amazon EKS で機械学習トレーニングを実行する

このトピックでは、Elastic Fabric Adapter (EFA) を Amazon EKS クラスターにデプロイした Pods と統合する方法について説明します。Elastic Fabric Adapter (EFA) は、Amazon EC2 インスタンス向けのネットワークインターフェイスです。これにより、AWS で高レベルのノード間通信を必要とするアプリケーションを実行できます。カスタムビルドされたオペレーティングシステムのバイパスハードウェアインターフェイスにより、インスタンス間通信のパフォーマンスが向上します。これは、これらのアプリケーションのスケーリングに不可欠です。EFA を使用すると、Message Passing Interface (MPI) を使用するハイパフォーマンスコンピューティング (HPC) アプリケーションと NVIDIA Collective Communications Library (NCCL) を使用する Machine Learning (ML) アプリケーションを、数千の CPU または GPU にスケールできます。その結果、AWS クラウドのオンデマンドの伸縮自在性と柔軟性を備えたオンプレミスの HPC クラスターのアプリケーションパフォーマンスを実現できます。EFA と Amazon EKS クラスターで実行中のアプリケーションを統合すると、大規模な分散型トレーニングワークロードを完了する時間を短縮できます。クラスターにインスタンスを追加する必要はありません。EFA の詳細については、「Elastic Fabric Adapter」を参照してください。

EFA を使用するインスタンスタイプ

AWS EFA Kubernetes Device Plugin は、EFA を持つすべての Amazon EC2 インスタンスタイプをサポートします。EFA を持つすべてのインスタンスタイプのリストを見るには、「Amazon EC2 ユーザーガイド」の「サポートされるインスタンスタイプ」を参照してください。ただし、ML アプリケーションを迅速に実行するために、EFA に加えて、nVidia GPU、AWS Inferentia チップ、AWS Trainium チップなどのハードウェアアクセラレーションチップがインスタンスに搭載されているようにすることをお勧めします。ハードウェアアクセラレーションチップと EFA を持つインスタンスタイプのリストを見るには、「Amazon EC2 ユーザーガイド」の「高速コンピューティング」を参照してください。

インスタンスタイプを比較して選択する場合、そのインスタンスタイプで使用できる EFA ネットワークカードの数と、アクセラレータカードの数、CPU の量、メモリの量を考慮してください。ネットワークカードごとに EFA を 1 つまで割り当てることができます。EFA はネットワークインターフェイスとしてカウントされます。EFA を持つ各インスタンスタイプで使用できる EFA の数を確認するには、「Amazon EC2 ユーザーガイド」の「ネットワークカード」のリストを参照してください。

前提条件

  • 既存の Amazon EKS クラスター。既存のクラスターがない場合は、Amazon EKS の使用を開始する ガイドのいずれかを活用して作成してください。クラスターは、ノードをデプロイするのに十分な IP アドレスを持つ、少なくとも 1 つのプライベートサブネットがある VPC にデプロイする必要があります。プライベートサブネットには、NAT ゲートウェイなどの外部のデバイスから提供されるアウトバウンドのインターネットアクセスが必要です。

    eksctl を使用してノードグループを作成する予定がある場合、eksctl でクラスターを作成することもできます。

  • ご使用のデバイスまたは AWS CloudShell で、バージョン 2.12.3 以降、または AWS Command Line Interface (AWS CLI) のバージョン 1.27.160 以降がインストールおよび設定されていること。現在のバージョンを確認するには、「aws --version | cut -d / -f2 | cut -d ' ' -f1」を参照してください。macOS の yumapt-get、または Homebrew などのパッケージマネージャは、AWS CLI の最新バージョンより数バージョン遅れることがあります。最新バージョンをインストールするには、「AWS Command Line Interface ユーザーガイド」の「AWS CLI のインストール、更新、およびアンインストール」と「aws configure でのクイック設定」を参照してください。AWS CloudShell にインストールされている AWS CLI バージョンは、最新バージョンより数バージョン遅れている可能性もあります。更新するには、「AWS CloudShell ユーザーガイド」の「ホームディレクトリへの AWS CLI のインストール」を参照してください。

  • デバイスまたは AWS CloudShell に、kubectl コマンドラインツールがインストールされていること。バージョンは、ご使用のクラスターの Kubernetes バージョンと同じか、1 つ前のマイナーバージョン以前、あるいはそれより新しいバージョンが使用できます。例えば、クラスターのバージョンが 1.30 である場合、kubectl のバージョン 1.291.30、または 1.31 が使用できます。kubectl をインストールまたはアップグレードする方法については、「kubectl および eksctl のセットアップ」を参照してください。

  • p4d または p5 などの複数の Elastic Fabric Adapters をサポートするワーカーノードを起動する前に、Amazon VPC CNI plugin for Kubernetes バージョン 1.7.10 以降をインストールしておく必要があります。Amazon VPC CNI plugin for Kubernetes バージョンの更新する方法の詳細については、「Amazon VPC CNI を使用してPodsに IP を割り当てる」を参照してください。

重要

Kubernetes で EFA を導入するために必要となる重要な考慮事項は、クラスター内のリソースとして Huge Pages を設定および管理することです。詳細については、「Kubernetes ドキュメント」の「Huge Page の管理」を参照してください。EFA ドライバーがインストールされた Amazon EC2 インスタンスでは、5128 2MiB Huge Page が事前に割り当てられます。このページは、ジョブの仕様で使用するリソースとしてリクエストできます。

ノードグループの作成

次の手順は、EFA インターフェイスと GPUDirect RDMA を使用して、p4d.24xlarge がバックアップされたノードグループでノードグループを作成し、EFA を使用したマルチノード NCCL パフォーマンス向けに NVIDIA Collective Communications Library (NCCL) のサンプルテストを実行するのに役立ちます。この例では、EFA を使用した Amazon EKS の分散型深層学習トレーニングのテンプレートを使用できます。

  1. ノードをデプロイする対象の AWS リージョンで利用可能な、EFA をサポートする Amazon EC2 インスタンスを特定します。region-code を、ノードグループをデプロイする対象の AWS リージョンに置き換えます。

    aws ec2 describe-instance-types --region region-code \ --filters Name=network-info.efa-supported,Values=true \ --query "InstanceTypes[*].[InstanceType]" --output text

    ノードをデプロイする場合、デプロイするインスタンスタイプは、ユーザーのクラスターがある AWS リージョン で利用可能である必要がります。

  2. デプロイするインスタンスタイプが利用可能なアベイラビリティーゾーンを特定します。このチュートリアルでは、p5.48xlarge インスタンスタイプが使用されているため、前のステップで指定した AWS リージョン の出力が返されているはずです。本番クラスターにノードをデプロイするときは、p5.48xlarge を前のステップで返されたいずれかのインスタンスタイプに置き換えます。

    aws ec2 describe-instance-type-offerings --region region-code \ --location-type availability-zone --filters Name=instance-type,Values=p4d.24xlarge,p5.48xlarge \ --query 'InstanceTypeOfferings[*].Location' --output text

    出力例は次のとおりです。

    us-west-2a us-west-2c us-west-2b

    後のステップで使用するために、返されたアベイラビリティーゾーンをメモします。ノードをクラスターにデプロイする場合、VPC には、出力で返されるアベイラビリティーゾーンの 1 つに使用可能な IP アドレスを持つサブネットが必要です。

  3. eksctl を使用してノードグループを作成します。

    前提条件

    デバイスまたは AWS CloudShell にインストールされている eksctl コマンドラインツールのバージョン 0.191.0 以降。eksctl をインストールまたはアップグレードするには、eksctl ドキュメントの「インストール」を参照してください。

    1. 次の内容を efa-cluster.yaml という名前のファイルにコピーします。example values を自分の値に置き換えます。p5.48xlarge を異なるインスタンスに置き換えることができますが、その場合、availabilityZones の値がステップ 1 でインスタンスタイプに対して返されたアベイラビリティーゾーンであることを確認してください。

      apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: my-efa-cluster region: region-code version: "1.XX" iam: withOIDC: true availabilityZones: ["us-west-2a", "us-west-2c"] managedNodeGroups: - name: my-efa-ng instanceType: p5.48xlarge minSize: 1 desiredCapacity: 2 maxSize: 3 availabilityZones: ["us-west-2a"] volumeSize: 300 privateNetworking: true efaEnabled: true
    2. 既存のクラスターにマネージド型ノードグループを作成します。

      eksctl create nodegroup -f efa-cluster.yaml

      既存のクラスターがない場合は、次のコマンドを実行してクラスターとノードグループを作成できます。

      eksctl create cluster -f efa-cluster.yaml
      注記

      この例で使用されているインスタンスタイプには GPU があるため、eksctl は NVIDIA Kubernetes デバイスプラグインを各インスタンスに自動的にインストールします。

  4. EFA Kubernetes デバイスプラグインをデプロイします。

    EFA Kubernetes デバイスプラグインでは、EFA インターフェイスを Kubernetes に割り当て可能なリソースとして検出およびアドバタイズできます。アプリケーションでは、拡張リソースタイプ vpc.amazonaws.com/efa を CPU やメモリのように Pod リクエスト仕様で使用できます。詳細については、「Kubernetes ドキュメント」の「拡張したリソースの消費」を参照してください。リクエストされると、プラグインは EFA インターフェイスを自動的に Pod に割り当ておよびマウントします。デバイスのプラグインを使用すると、EFA の設定が簡単になります。Pod を特権モードで実行する必要はありません。

    helm repo add eks https://aws.github.io/eks-charts helm install aws-efa-k8s-device-plugin --namespace kube-system eks/aws-efa-k8s-device-plugin

(オプション) EFA のパフォーマンスをテストする

EFA セットアップをテストすることをお勧めします。GitHub の aws-samples/awsome-distributed-training リポジトリで NCCL テストを使用できます。NCCL テストは、Nvidia Collective Communication Library を使用してネットワークのパフォーマンスを評価します。次のステップでは、Amazon EKS で NCCL テストを送信します。

  1. Kubeflow MPI Operator のデプロイ

    NCCL テストでは、Kubeflow MPI Operator を適用できます。MPI Operator を使用すると、Kubernetes で AllReduce スタイルの分散型トレーニングを簡単に実行できます。詳細については、「GitHub」の「MPI Operator」を参照してください。

  2. マルチノードの NCCL パフォーマンステストを実行して、GPUDirectRDMA/EFA を検証する

    GPUDirectRDMA over EFA を使用した NCCL パフォーマンスを検証するには、標準の NCCL パフォーマンステストを実施します。詳細については、「GitHub」で公式の「NCCL-Tests」(NCCL テスト) を参照してください。

    2 つのノード NCCL Performance Test を実行するには、次のステップを実行します。サンプルの NCCL テストジョブでは、各ワーカーが 8 つの GPU、5210Mi の hugepages-2Mi、4 つの EFA、8000Mi のメモリをリクエストします。これは事実上、各ワーカーが p5.48xlarge インスタンスのすべてのリソースを使用することを意味します。

    1. MPIJob マニフェストを作成する

      次の JSON を nccl-tests.yaml という名前のファイルにコピーします:

      apiVersion: kubeflow.org/v2beta1 kind: MPIJob metadata: name: nccl-tests spec: runPolicy: cleanPodPolicy: Running backoffLimit: 20 slotsPerWorker: 8 mpiReplicaSpecs: Launcher: replicas: 1 template: spec: restartPolicy: OnFailure containers: - image: public.ecr.aws/hpc-cloud/nccl-tests:latest imagePullPolicy: IfNotPresent name: test-nccl-launcher env: - name: PATH value: $PATH:/opt/amazon/efa/bin:/usr/bin - name: LD_LIBRARY_PATH value: /opt/amazon/openmpi/lib:/opt/nccl/build/lib:/opt/amazon/efa/lib:/opt/aws-ofi-nccl/install/lib:/usr/local/nvidia/lib:$LD_LIBRARY_PATH - name: NCCL_DEBUG value: INFO - name: NCCL_BUFFSIZE value: '8388608' - name: NCCL_P2P_NET_CHUNKSIZE value: '524288' - name: NCCL_TUNER_PLUGIN value: /opt/aws-ofi-nccl/install/lib/libnccl-ofi-tuner.so command: - /opt/amazon/openmpi/bin/mpirun - --allow-run-as-root - --tag-output - -np - "16" - -N - "8" - --bind-to - none - -x - PATH - -x - LD_LIBRARY_PATH - -x - NCCL_DEBUG=INFO - -x - NCCL_BUFFSIZE - -x - NCCL_P2P_NET_CHUNKSIZE - -x - NCCL_TUNER_PLUGIN - --mca - pml - ^cm,ucx - --mca - btl - tcp,self - --mca - btl_tcp_if_exclude - lo,docker0,veth_def_agent - /opt/nccl-tests/build/all_reduce_perf - -b - "8" - -e - "16G" - -f - "2" - -g - "1" - -c - "1" - -n - "100" Worker: replicas: 2 template: spec: nodeSelector: node.kubernetes.io/instance-type: "p5.48xlarge" containers: - image: public.ecr.aws/hpc-cloud/nccl-tests:latest imagePullPolicy: IfNotPresent name: nccl-tests-worker volumeMounts: - name: shmem mountPath: /dev/shm resources: limits: nvidia.com/gpu: 8 hugepages-2Mi: 5120Mi vpc.amazonaws.com/efa: 32 memory: 32000Mi requests: nvidia.com/gpu: 8 hugepages-2Mi: 5120Mi vpc.amazonaws.com/efa: 32 memory: 32000Mi volumes: - name: shmem hostPath: path: /dev/shm
    2. NCCL-tests MPIJob を適用する

      マニフェストを適用して MPIJob を送信します。これにより、2 つの p5.48xlarge Amazon EC2 インスタンスが作成されます。

      kubectl apply -f nccl-tests.yaml

      出力例は次のとおりです。

      mpijob.kubeflow.org/nccl-tests created
    3. ジョブがポッドを開始したことを検証する

      実行中の Pods を表示する。

      kubectl get pods

      出力例は次のとおりです。

      NAME READY STATUS RESTARTS AGE nccl-tests-launcher-nbql9 0/1 Init:0/1 0 2m49s nccl-tests-worker-0 1/1 Running 0 2m49s nccl-tests-worker-1 1/1 Running 0 2m49s

      MPI Operator は、ランチャー Pod と 2 つのワーカー Pods (各ノードに 1 つ) を作成します。

    4. ログを使用してジョブが正常に実行されていることを検証します。

      nccl-tests-launcher Pod のログを表示します。nbql9 を出力の値で置き換えます。

      kubectl logs -f nccl-tests-launcher-nbql9

テストが正常に完了すると、Nvidia Collective Communication Library を使用するアプリケーションをデプロイできます。