このページの改善にご協力ください
本ユーザーガイドの改善にご協力いただけませんか? このページの下部までスクロールし、[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
インスタンスタイプを比較して選択する場合、そのインスタンスタイプで使用できる 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
以降がインストールおよび設定されていること。現在のバージョンを確認するには、「
」を参照してください。macOS のaws --version | cut -d / -f2 | cut -d ' ' -f1
yum
、apt-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.29
、1.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 インターフェイスと GPUDirect RDMA を使用して、p4d.24xlarge
がバックアップされたノードグループでノードグループを作成し、EFA を使用したマルチノード NCCL パフォーマンス向けに NVIDIA Collective Communications Library (NCCL) のサンプルテストを実行するのに役立ちます。この例では、EFA を使用した Amazon EKS の分散型深層学習トレーニングのテンプレートを使用できます。
-
ノードをデプロイする対象の AWS リージョンで利用可能な、EFA をサポートする Amazon EC2 インスタンスを特定します。
を、ノードグループをデプロイする対象の AWS リージョンに置き換えます。region-code
aws ec2 describe-instance-types --region
region-code
\ --filters Name=network-info.efa-supported,Values=true \ --query "InstanceTypes[*].[InstanceType]" --output textノードをデプロイする場合、デプロイするインスタンスタイプは、ユーザーのクラスターがある AWS リージョン で利用可能である必要がります。
-
デプロイするインスタンスタイプが利用可能なアベイラビリティーゾーンを特定します。このチュートリアルでは、
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 アドレスを持つサブネットが必要です。
-
eksctl
を使用してノードグループを作成します。前提条件
デバイスまたは AWS CloudShell にインストールされている
eksctl
コマンドラインツールのバージョン0.191.0
以降。eksctl
をインストールまたはアップグレードするには、eksctl
ドキュメントの「インストール」を参照してください。 -
次の内容を
という名前のファイルにコピーします。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 -
既存のクラスターにマネージド型ノードグループを作成します。
eksctl create nodegroup -f
efa-cluster.yaml
既存のクラスターがない場合は、次のコマンドを実行してクラスターとノードグループを作成できます。
eksctl create cluster -f
efa-cluster.yaml
注記
この例で使用されているインスタンスタイプには GPU があるため、
eksctl
は NVIDIA Kubernetes デバイスプラグインを各インスタンスに自動的にインストールします。
-
-
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 テスト
-
Kubeflow MPI Operator のデプロイ
NCCL テストでは、Kubeflow MPI Operator を適用できます。MPI Operator を使用すると、Kubernetes で AllReduce スタイルの分散型トレーニングを簡単に実行できます。詳細については、「GitHub」の「MPI Operator
」を参照してください。 -
マルチノードの 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
インスタンスのすべてのリソースを使用することを意味します。-
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
-
NCCL-tests MPIJob を適用する
マニフェストを適用して
MPIJob
を送信します。これにより、2 つのp5.48xlarge
Amazon EC2 インスタンスが作成されます。kubectl apply -f nccl-tests.yaml
出力例は次のとおりです。
mpijob.kubeflow.org/nccl-tests created
-
ジョブがポッドを開始したことを検証する
実行中の 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 2m49sMPI Operator は、ランチャー Pod と 2 つのワーカー Pods (各ノードに 1 つ) を作成します。
-
ログを使用してジョブが正常に実行されていることを検証します。
nccl-tests-launcher
Pod のログを表示します。
を出力の値で置き換えます。nbql9
kubectl logs -f nccl-tests-launcher-
nbql9
-
テストが正常に完了すると、Nvidia Collective Communication Library を使用するアプリケーションをデプロイできます。