Elastic Fabric Adapter를 사용한 Amazon EKS에서 기계 학습 훈련 실행 - Amazon EKS

이 페이지 개선에 도움 주기

이 사용자 설명서에 기여하고 싶으신가요? 이 페이지 하단으로 스크롤하여 GitHub에서 이 페이지 편집을 선택하세요. 여러분의 기여는 모두를 위한 더 나은 사용자 설명서를 만드는 데 도움이 됩니다.

Elastic Fabric Adapter를 사용한 Amazon EKS에서 기계 학습 훈련 실행

이 주제에서는 Amazon EKS 클러스터에 배포된 Pods와 Elastic Fabric Adapter(EFA)를 통합하는 방법에 대해 설명합니다. Elastic Fabric Adapter(EFA)는 Amazon EC2 인스턴스용 네트워크 인터페이스로, AWS에서 대규모로 높은 수준의 노드 간 통신을 필요로 하는 애플리케이션을 실행할 수 있도록 지원합니다. 맞춤형으로 구축된 운영 체제 바이패스 하드웨어 인터페이스는 인스턴스 간 통신의 성능을 향상시켜 애플리케이션을 확장하는 데 매우 중요합니다. EFA를 사용하면 메시지 전달 인터페이스(MPI)를 사용하는 고성능 컴퓨팅(HPC) 애플리케이션과 NVIDIA Collective Communications Library(NCCL)를 사용하는 기계 학습(ML) 애플리케이션을 수천 개의 CPU 또는 GPU로 확장할 수 있습니다. 따라서 온프레미스 HPC 클러스터의 애플리케이션 성능을 AWS 클라우드의 온디맨드 탄력성과 유연성을 통해 실현할 수 있습니다. Amazon EKS 클러스터에서 실행되는 애플리케이션과 EFA를 통합하면 클러스터에 인스턴스를 추가하지 않고도 대규모 분산 훈련 워크로드를 완료하는 데 걸리는 시간을 줄일 수 있습니다. EFA에 대한 자세한 내용은 Elastic Fabric Adapter(EFA) 섹션을 참조하세요.

EFA를 사용한 인스턴스 유형

AWS EFA Kubernetes 디바이스 플러그인은 EFA가 있는 모든 Amazon EC2 인스턴스 유형을 지원합니다. EFA가 있는 모든 인스턴스 유형 목록을 보려면 Amazon EC2 사용 설명서의 지원되는 인스턴스 유형을 참조하세요. 그러나 ML 애플리케이션을 빠르게 실행하려면 인스턴스에 EFA 외에 nVidia GPU, AWS Inferentia 칩 또는 AWS Trainium 칩과 같은 하드웨어 가속 칩이 있는 것이 좋습니다. 하드웨어 가속 칩과 EFA가 있는 인스턴스 유형 목록을 보려면 Amazon EC2 사용 설명서의 가속 컴퓨팅을 참조하세요.

인스턴스 유형을 비교하여 선택할 때는 해당 인스턴스 유형에 사용할 수 있는 EFA 네트워크 카드 수뿐만 아니라 가속기 카드 수, CPU 사용량, 메모리 크기도 고려하세요. 네트워크 카드당 최대 1개의 EFA를 할당할 수 있습니다. EFA는 네트워크 인터페이스 수 계산에 포함됩니다. EFA가 있는 각 인스턴스 유형에 사용할 수 있는 EFA 수를 확인하려면 Amazon EC2 사용 설명서의 네트워크 카드 목록을 참조하세요.

사전 조건

  • 기존 Amazon EKS 클러스터. 기존 클러스터가 없는 경우 Amazon EKS 시작하기 가이드 중 하나를 사용하여 생성합니다. 노드를 배포할 수 있는 충분한 IP 주소가 있는 프라이빗 서브넷이 하나 이상 있는 VPC에 클러스터를 배포해야 합니다. 프라이빗 서브넷에는 NAT 게이트웨이와 같은 외부 디바이스에서 제공하는 아웃바운드 인터넷 액세스가 있어야 합니다.

    eksctl을 사용하여 노드 그룹을 생성하려는 경우 eksctl이 클러스터를 생성할 수도 있습니다.

  • AWS Command Line Interface(AWS CLI) 버전 2.12.3 이상 또는 1.27.160 이상이 디바이스나 AWS CloudShell에 설치 및 구성되어 있습니다. 현재 버전을 확인하려면 aws --version | cut -d / -f2 | cut -d ' ' -f1을 사용합니다. macOS용 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.29인 경우 kubectl 버전 1.28, 1.29 또는 1.30를 함께 사용할 수 있습니다. kubectl을 설치하거나 업그레이드하려면 kubectl 및 eksctl 설정 부분을 참조하세요.

  • p4d 또는 p5와 같이 여러 Elastic Fabric Adapter를 지원하는 워커 노드를 시작하기 전에 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 설명서의 대용량 페이지 관리를 참조하세요. 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에는 출력에 반환된 가용 영역 중 하나에 사용 가능한 IP 주소가 있는 서브넷이 있어야 합니다.

  3. eksctl을 사용하여 노드 그룹을 생성합니다.

    전제 조건

    디바이스 또는 0.189.0에 설치된 버전 AWS CloudShell 이상의 eksctl 명령줄 도구. eksctl을 설치 또는 업그레이드하려면 eksctl 설명서에서 Installation을 참조하세요.

    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에 할당 가능한 리소스로 감지하고 제공합니다. 애플리케이션은 CPU 및 메모리처럼 Pod 요청 사양에 확장 리소스 유형 vpc.amazonaws.com/efa을 사용할 수 있습니다. 자세한 내용은 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 Tests를 사용할 수 있습니다. NCCL Tests는 NVIDIA Collective Communication Library를 사용하여 네트워크 성능을 평가합니다. 다음 단계는 Amazon EKS에서 NCCL 테스트를 제출합니다.

  1. Kubeflow MPI 연산자 배포

    NCCL 테스트를 위해 Kubeflow MPI 연산자를 적용할 수 있습니다. MPI 연산자를 사용하면 Kubernetes에서 Allreduce 스타일의 분산 훈련을 쉽게 실행할 수 있습니다. 자세한 내용은 GitHub에서 MPI 연산자를 참조하세요.

  2. GPUDirectRDMA/EFA 검증을 위한 다중 노드 NCCL 성능 테스트 실행

    EFA를 통한 GPUDirectRDMA를 사용하여 NCCL 성능을 검증하려면 표준 NCCL 성능 테스트를 실행합니다. 자세한 내용은 GitHub에서 공식 NCCL-Tests 리포지토리를 참조하세요.

    2개 노드 NCCL Performance Test를 실행하려면 다음 단계를 완료합니다. 예제 NCCL 테스트 작업에서 각 작업자는 8개의 GPU, 5210Mi의 hugepages-2Mi, 4개의 EFA, 8000Mi 메모리를 요청합니다. 이는 실질적으로 각 작업자가 p5.48xlarge 인스턴스의 리소스를 모두 사용한다는 것을 의미합니다.

    1. MPIJob 매니페스트 생성

      다음을 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을 제출합니다. 그러면 두 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 연산자는 런처 Pod와 작업자 Pods 2개(각 노드에 하나씩)를 생성합니다.

    4. 로그를 사용하여 작업이 성공적으로 실행되고 있는지 확인

      nccl-tests-launcher Pod에 대한 로그를 확인합니다. nbql9를 출력된 값과 바꿉니다.

      kubectl logs -f nccl-tests-launcher-nbql9

테스트가 성공적으로 완료되면 Nvidia Collective Communication Library를 사용하는 애플리케이션을 배포할 수 있습니다.