이 페이지에서는 GPUDirect-TCPXO, GPUDirect-TCPX, gVNIC, 멀티 네트워킹이 포함된 Standard 클러스터를 사용하여 Google Kubernetes Engine(GKE)에서 고성능 GPU 워크로드의 네트워크 대역폭과 처리량을 극대화하는 방법을 보여줍니다.
이 페이지는 ML 워크로드를 지원하는 머신러닝(ML) 엔지니어 및 플랫폼 관리자를 대상으로 합니다. 이 페이지를 읽기 전에 네트워크 인터페이스 카드(NIC) 및 TCP와 같은 네트워킹 기술과 NVIDIA Collective Communications Library(NCCL)와 같은 가속기 기술을 숙지해야 합니다.
인공지능(AI), ML, 고성능 컴퓨팅(HPC) 애플리케이션에는 작업 완료 시간을 단축하여 성능을 최적화하기 위한 강력한 가속이 필요합니다. 예를 들어 대화형 AI 및 이미지 생성에 중점을 둔 ML 모델에는 높은 확장성과 컴퓨팅 성능이 필요합니다.
Google Cloud GPU 슈퍼컴퓨터 정보
Google Cloud에는 확장 가능한 대규모 모델을 위해 설계된 가속기 최적화 슈퍼컴퓨터가 있습니다. 이러한 머신의 이점은 다음과 같습니다.
- 머신당 NVIDIA H100 GPU 8개
- 기본 NIC에서 최대 200Gbps의 대역폭
- 보조 NIC(A3 Mega 머신 유형의 경우 최대 8개, A3 High 머신 유형의 경우 최대 4개)에서 GPU 데이터 전송에 각각 최대 200Gbps의 대역폭 지원
이점의 전체 목록은 Compute Engine 문서의 A3 머신 계열을 참조하세요.
GKE 워크로드는 반드시 단일 노드에서 사용 가능한 모든 GPU와 사용 가능한 모든 보조 NIC를 사용하고 사용 가능한 대역폭의 상당 부분을 사용해야 합니다. 이 페이지에서 설명하는 솔루션은 고성능, 높은 처리량, 짧은 지연 시간을 요구하는 워크로드에 적합합니다.
대역폭 극대화에 필요한 특징 및 기능
GPU 슈퍼 컴퓨터 노드에서 네트워크 대역폭을 극대화하려면 다음 기능을 모두 사용합니다.
- GPUDirect 네트워킹 스택: A3 머신 시리즈는 커스텀 원격 직접 메모리 액세스(RDMA)를 위한 두 가지 네트워킹 스택을 지원합니다.
- A3 High 머신 유형에서는 GPUDirect-TCPX를 사용하여 GPU와 주고받는 패킷 페이로드를 전송하는 데 필요한 오버헤드를 줄이므로 GPUDirect를 사용하지 않는 GPU에 비해 대규모 처리량이 크게 개선됩니다.
- A3 Mega 머신 유형에서는 GPU와 VM 간의 통신을 더욱 개선하는 GPUDirect-TCPXO를 활용합니다.
- gVNIC: 패킷 헤더 분할, 흐름 스티어링, 버퍼 관리와 같은 GPUDirect 기능을 사용 설정합니다. GPUDirect-TCPX 또는 GPUDirect-TCPXO를 사용하려면 gVNIC가 필요합니다. gVNIC에 대한 자세한 내용은 GPU 노드의 네트워크 트래픽 속도 향상을 참조하세요.
- 멀티 네트워킹: 가속기 최적화 머신에 보조 NIC를 추가합니다. 각 NIC는 충돌을 피하기 위해 자체 VPC에서 별도의 서브넷과 연결됩니다. 다중 네트워크 지원에 대한 자세한 내용은 포드에 대한 다중 네트워크 지원 설정을 참조하세요.
- 배치 정책: 리소스 배치 정책으로 특정 워크로드의 모든 GPU 노드를 물리적으로 가까운 서버에 배치하여 지연 시간을 최소화합니다. 자세한 내용은 GKE 노드를 위한 압축 배치 정의를 참고하세요.
절차 개요
이 모든 기능을 함께 사용하려면 다음을 수행합니다.
- 가상 프라이빗 클라우드(VPC) 및 서브넷 만들기
- GKE 환경 만들기:
- 멀티 네트워킹이 사용 설정된 클러스터 만들기
- 다음 특성으로 노드 풀 만들기:
- gVNIC 사용 설정
- 각 보조 NIC에 지정된 멀티 네트워킹 서브넷
- 노드를 지원하는 H100 GPU가 있는 A3 머신 시리즈
- 최신 NVIDIA 드라이버가 설치됨
- GPUDirect 바이너리 및 NCCL 플러그인 설치
- NRI 기기 인젝터 플러그인 배포
- 테스트 워크로드를 배포하여 GPUDirect 설정 확인
시작하기 전에
시작하기 전에 다음 태스크를 수행했는지 확인합니다.
- Google Kubernetes Engine API를 사용 설정합니다. Google Kubernetes Engine API 사용 설정
- 이 태스크에 Google Cloud CLI를 사용하려면 gcloud CLI를 설치한 후 초기화합니다. 이전에 gcloud CLI를 설치한 경우
gcloud components update
를 실행하여 최신 버전을 가져옵니다.
- H100 GPU의 할당량이 충분한지 확인합니다. 할당량 상향을 요청하려면 GPU 할당량을 참조하세요.
요구사항
다음 요구사항은 달리 명시되지 않는 한 GPUDirect-TCPX 및 GPUDirect-TCPXO 모두에 적용됩니다.
- GPUDirect-TCPX는 GKE 버전 1.27 이상에서 지원되며 다음이 필요합니다.
- A3 High 머신 유형(예:
a3-highgpu-8g
) - GKE 버전 1.27의 경우 GKE 패치 버전 1.27.7-gke.1121000 이상을 사용합니다.
- GKE 버전 1.28의 경우 GKE 패치 버전 1.28.8-gke.1095000 이상을 사용합니다.
- GKE 버전 1.29의 경우 GKE 패치 버전 1.29.3-gke.1093000 이상을 사용합니다.
- GKE 버전 1.30의 경우 GKE 패치 버전 1.30.2-gke.1023000 이상을 사용합니다.
- A3 High 머신 유형(예:
- GPUDirect-TCPXO는 GKE 버전 1.28 이상에서 지원되며 다음이 필요합니다.
- A3 Mega 머신 유형(예:
a3-megagpu-8g
) - GKE 버전 1.28의 경우 GKE 패치 버전 1.28.9-gke.1250000 이상을 사용합니다.
- GKE 버전 1.29의 경우 GKE 패치 버전 1.29.4-gke.1542000 이상을 사용합니다.
- GKE 버전 1.30의 경우 GKE 패치 버전 1.30.4-gke.1129000 이상을 사용합니다.
- A3 Mega 머신 유형(예:
- GPU 노드에서 NVIDIA 드라이버 버전 535 이상을 사용해야 합니다.
- GKE Dataplane V2를 사용해야 합니다.
- GKE 노드는 Container-Optimized OS(COS) 노드 이미지를 사용해야 합니다. Ubuntu 및 Windows 노드 이미지는 지원되지 않습니다.
제한사항
다음과 같은 제한사항이 적용됩니다.
- Autopilot 클러스터에서는 GPUDirect-TCPX 및 GPUDirect-TCPXO가 지원되지 않음
- GPUDirect-TCPX 및 GPUDirect-TCPXO는 멀티 인스턴스 GPU, GPU 시간 공유 또는 NVIDIA MPS를 지원하지 않습니다.
- NCCL FastSocket을 사용할 수 없습니다.
- GKE 워크로드는 반드시 단일 노드에서 사용 가능한 모든 GPU와 사용 가능한 모든 보조 NIC를 사용해야 합니다. 여러 포드가 단일 노드에서 GPUDirect-TCPX 또는 GPUDirect-TCPXO를 사용할 수 없습니다.
VPC 및 서브넷 만들기
노드에 추가할 가상 NIC마다 프로젝트에 별도의 VPC 네트워크를 만듭니다. 각 VPC 네트워크에는 내부 네트워크 트래픽을 허용하는 서브넷과 방화벽 규칙이 있어야 합니다.
프로젝트에서 GPUDirect용 VPC 네트워크를 만들고 각각 서브넷과 방화벽 규칙을 설정합니다. A3 High 머신 유형의 경우 GPUDirect-TCPX 탭, A3 Mega 머신 유형의 경우 GPUDirect-TCPXO 탭을 선택하고 다음 안내를 완료합니다.
GPUDirect-TCPXO
대역폭을 최대화하려면 새 네트워크를 8개 만드는 것이 좋습니다.
for N in $(seq 1 8); do gcloud compute networks create PROJECT_ID-net-$N \ --subnet-mode=custom \ --mtu=8244 gcloud compute networks subnets create PROJECT_ID-sub-$N \ --network=PROJECT_ID-net-$N \ --region=REGION \ --range=SUBNET_RANGE gcloud compute firewall-rules create PROJECT_ID-internal-$N \ --network=PROJECT_ID-net-$N \ --action=ALLOW \ --rules=tcp:0-65535,udp:0-65535,icmp \ --source-ranges=SOURCE_RANGE done
다음을 바꿉니다.
PROJECT_ID
: Google Cloud 프로젝트 ID입니다.REGION
: 각 서브넷의 Compute Engine 리전입니다.SUBNET_RANGE
: CIDR 표기법으로 표시된 각 서브넷의 IP 주소 범위입니다. 이 명령어 예시는 8개의 서브넷을 반복하므로 변수를 사용하여 각 서브넷의 IP 주소를 변경해야 합니다. 예를 들어 첫 번째 서브넷은192.168.1.0/24
, 두 번째 서브넷은192.168.2.0/24
등을 사용하도록192.168.$N.0/24
를 지정합니다.SOURCE_RANGE
: 인그레스 트래픽을 허용하는 방화벽 규칙의 소스 IP 주소 범위로서 CIDR 표기법으로 나타냅니다. 예를 들면192.168.0.0/16
입니다.
GPUDirect-TCPX
대역폭을 최대화하려면 새 네트워크를 4개 만드는 것이 좋습니다.
for N in $(seq 1 4); do gcloud compute networks create PROJECT_ID-net-$N \ --subnet-mode=custom \ --mtu=8244 gcloud compute networks subnets create PROJECT_ID-sub-$N \ --network=PROJECT_ID-net-$N \ --region=REGION \ --range=SUBNET_RANGE gcloud compute firewall-rules create PROJECT_ID-internal-$N \ --network=PROJECT_ID-net-$N \ --action=ALLOW \ --rules=tcp:0-65535,udp:0-65535,icmp \ --source-ranges=SOURCE_RANGE done
다음을 바꿉니다.
PROJECT_ID
: Google Cloud 프로젝트 ID입니다.REGION
: 각 서브넷의 Compute Engine 리전입니다.SUBNET_RANGE
: CIDR 표기법으로 표시된 각 서브넷의 IP 주소 범위입니다. 이 명령어 예시는 4개의 서브넷을 반복하므로 변수를 사용하여 각 서브넷의 IP 주소를 변경해야 합니다. 예를 들어 첫 번째 서브넷은192.168.1.0/24
, 두 번째 서브넷은192.168.2.0/24
등을 사용하도록192.168.$N.0/24
를 지정합니다.SOURCE_RANGE
: 인그레스 트래픽을 허용하는 방화벽 규칙의 소스 IP 주소 범위로서 CIDR 표기법으로 나타냅니다. 예를 들면192.168.0.0/16
입니다.
네트워크가 생성되었는지 확인합니다.
gcloud compute networks list
GKE 환경 만들기
멀티 네트워킹(미리보기)을 사용하는 새 GKE 클러스터를 만들고 H100 GPU와 추가 NIC가 있는 A3 머신을 사용하는 GPU 노드 풀을 만듭니다. 멀티 네트워킹을 사용하도록 기존 클러스터를 업데이트할 수는 없습니다.
GPUDirect-TCPXO
GPUDirect-TCPXO를 지원하는 사용 가능한 GKE 버전을 선택합니다. 버전을 나열하려면 다음 명령어를 실행합니다.
gcloud container get-server-config \ --format="yaml(validMasterVersions)" \ --zone=ZONE \ --project=PROJECT_ID
다음을 바꿉니다.
ZONE
: 클러스터 컨트롤 플레인의 컴퓨팅 영역입니다.PROJECT_ID
: Google Cloud 프로젝트 ID입니다.
클러스터 만들기:
gcloud --project ${PROJECT} beta container clusters create CLUSTER_NAME \ --enable-dataplane-v2 --enable-ip-alias --zone=ZONE \ --enable-multi-networking --cluster-version=VERSION --no-enable-autoupgrade
다음을 바꿉니다.
자신이 만든 VPC 네트워크 및 서브네트워크에 해당하는 클러스터에서 Network 및 GKENetworkParamSet 리소스를 만듭니다.
kubectl apply -f - <<EOF apiVersion: networking.gke.io/v1 kind: Network metadata: name: vpc1 spec: parametersRef: group: networking.gke.io kind: GKENetworkParamSet name: vpc1 type: Device --- apiVersion: networking.gke.io/v1 kind: Network metadata: name: vpc2 spec: parametersRef: group: networking.gke.io kind: GKENetworkParamSet name: vpc2 type: Device --- apiVersion: networking.gke.io/v1 kind: Network metadata: name: vpc3 spec: parametersRef: group: networking.gke.io kind: GKENetworkParamSet name: vpc3 type: Device --- apiVersion: networking.gke.io/v1 kind: Network metadata: name: vpc4 spec: parametersRef: group: networking.gke.io kind: GKENetworkParamSet name: vpc4 type: Device --- apiVersion: networking.gke.io/v1 kind: Network metadata: name: vpc5 spec: parametersRef: group: networking.gke.io kind: GKENetworkParamSet name: vpc5 type: Device --- apiVersion: networking.gke.io/v1 kind: Network metadata: name: vpc6 spec: parametersRef: group: networking.gke.io kind: GKENetworkParamSet name: vpc6 type: Device --- apiVersion: networking.gke.io/v1 kind: Network metadata: name: vpc7 spec: parametersRef: group: networking.gke.io kind: GKENetworkParamSet name: vpc7 type: Device --- apiVersion: networking.gke.io/v1 kind: Network metadata: name: vpc8 spec: parametersRef: group: networking.gke.io kind: GKENetworkParamSet name: vpc8 type: Device --- apiVersion: networking.gke.io/v1 kind: GKENetworkParamSet metadata: name: vpc1 spec: vpc: PROJECT_ID-net-1 vpcSubnet: PROJECT_ID-sub-1 deviceMode: NetDevice --- apiVersion: networking.gke.io/v1 kind: GKENetworkParamSet metadata: name: vpc2 spec: vpc: PROJECT_ID-net-2 vpcSubnet: PROJECT_ID-sub-2 deviceMode: NetDevice --- apiVersion: networking.gke.io/v1 kind: GKENetworkParamSet metadata: name: vpc3 spec: vpc: PROJECT_ID-net-3 vpcSubnet: PROJECT_ID-sub-3 deviceMode: NetDevice --- apiVersion: networking.gke.io/v1 kind: GKENetworkParamSet metadata: name: vpc4 spec: vpc: PROJECT_ID-net-4 vpcSubnet: PROJECT_ID-sub-4 deviceMode: NetDevice --- apiVersion: networking.gke.io/v1 kind: GKENetworkParamSet metadata: name: vpc5 spec: vpc: PROJECT_ID-net-5 vpcSubnet: PROJECT_ID-sub-5 deviceMode: NetDevice --- apiVersion: networking.gke.io/v1 kind: GKENetworkParamSet metadata: name: vpc6 spec: vpc: PROJECT_ID-net-6 vpcSubnet: PROJECT_ID-sub-6 deviceMode: NetDevice --- apiVersion: networking.gke.io/v1 kind: GKENetworkParamSet metadata: name: vpc7 spec: vpc: PROJECT_ID-net-7 vpcSubnet: PROJECT_ID-sub-7 deviceMode: NetDevice --- apiVersion: networking.gke.io/v1 kind: GKENetworkParamSet metadata: name: vpc8 spec: vpc: PROJECT_ID-net-8 vpcSubnet: PROJECT_ID-sub-8 deviceMode: NetDevice EOF
이러한 리소스는 GPU 트래픽을 위한 NIC를 패스 스루 모드로 구성하도록 GKE에 지시합니다. GKE는 이 트래픽에 eBPF를 사용하는 기본 제공 네트워킹 프로그래밍을 적용하지 않습니다.
H100 GPU용 노드 풀을 만듭니다.
gcloud beta container node-pools create NODE_POOL_NAME \ --zone=ZONE \ --cluster=CLUSTER_NAME \ --project=PROJECT_ID \ --accelerator=type=nvidia-h100-mega-80gb,count=8,gpu-driver-version=LATEST \ --machine-type=a3-megagpu-8g \ --num-nodes=2 \ --additional-node-network network=PREFIX-net-1,subnetwork=PREFIX-sub-1 \ --additional-node-network network=PREFIX-net-2,subnetwork=PREFIX-sub-2 \ --additional-node-network network=PREFIX-net-3,subnetwork=PREFIX-sub-3 \ --additional-node-network network=PREFIX-net-4,subnetwork=PREFIX-sub-4 \ --additional-node-network network=PREFIX-net-5,subnetwork=PREFIX-sub-5 \ --additional-node-network network=PREFIX-net-6,subnetwork=PREFIX-sub-6 \ --additional-node-network network=PREFIX-net-7,subnetwork=PREFIX-sub-7 \ --additional-node-network network=PREFIX-net-8,subnetwork=PREFIX-sub-8 \ --enable-gvnic \ --no-enable-autoupgrade \ --scopes "https://www.googleapis.com/auth/cloud-platform" \ [--placement-policy=POLICY_NAME \ --reservation-affinity=specific \ --reservation=RESERVATION_NAME \ --host-maintenance-interval=PERIODIC]
NODE_POOL_NAME
을 노드 풀 이름으로 바꿉니다.이 예시에서
--scopes
'https://www.googleapis.com/auth/cloud-platform' 인수는 테스트 편의를 위해 노드 인스턴스의 범위를cloud-platform
으로 설정합니다. 프로덕션의 경우 범위를 제한하여 더 세분화된 사용자 인증 정보를 구성하는 것이 좋습니다.예약을 사용하는 경우
--placement-policy
,--reservation-affinity
,--reservation
플래그를 사용합니다. 이러한 플래그를 지정하여 노드 풀에서 정책 이름과 예약을 구성합니다.이 명령어가 실패한다면 프로젝트에 H100 GPU 할당량이 충분하지 않은 경우일 수 있습니다. 할당량이 충분한지 확인하고 명령어를 다시 시도합니다.
클러스터의 노드 목록을 가져옵니다.
kubectl get nodes
각 GPU 노드에 GPU가 8개 있는지 확인합니다.
kubectl describe node NODE_NAME
출력은 다음과 비슷합니다.
Capacity: ... nvidia.com/gpu: 8 Allocatable: ... nvidia.com/gpu: 8
GPUDirect-TCPX
표준 클러스터 만들기
gcloud container clusters create CLUSTER_NAME \ --location=LOCATION \ --cluster-version=VERSION \ --enable-dataplane-v2 --enable-ip-alias \ --enable-multi-networking \ --no-enable-autoupgrade \
다음을 바꿉니다.
CLUSTER_NAME
: 새 클러스터의 이름입니다.LOCATION
: 클러스터의 Compute Engine 리전입니다.VERSION
: 클러스터의 GKE 버전입니다. 요구사항 섹션에 설명된 대로 지원되는 버전을 사용합니다.
자신이 만든 VPC 네트워크 및 서브네트워크에 해당하는 클러스터에서 Network 및 GKENetworkParamSet 리소스를 만듭니다.
kubectl apply -f - <<EOF apiVersion: networking.gke.io/v1 kind: Network metadata: name: vpc1 spec: parametersRef: group: networking.gke.io kind: GKENetworkParamSet name: vpc1 type: Device --- apiVersion: networking.gke.io/v1 kind: Network metadata: name: vpc2 spec: parametersRef: group: networking.gke.io kind: GKENetworkParamSet name: vpc2 type: Device --- apiVersion: networking.gke.io/v1 kind: Network metadata: name: vpc3 spec: parametersRef: group: networking.gke.io kind: GKENetworkParamSet name: vpc3 type: Device --- apiVersion: networking.gke.io/v1 kind: Network metadata: name: vpc4 spec: parametersRef: group: networking.gke.io kind: GKENetworkParamSet name: vpc4 type: Device --- apiVersion: networking.gke.io/v1 kind: GKENetworkParamSet metadata: name: vpc1 spec: vpc: PROJECT_ID-net-1 vpcSubnet: PROJECT_ID-sub-1 deviceMode: NetDevice --- apiVersion: networking.gke.io/v1 kind: GKENetworkParamSet metadata: name: vpc2 spec: vpc: PROJECT_ID-net-2 vpcSubnet: PROJECT_ID-sub-2 deviceMode: NetDevice --- apiVersion: networking.gke.io/v1 kind: GKENetworkParamSet metadata: name: vpc3 spec: vpc: PROJECT_ID-net-3 vpcSubnet: PROJECT_ID-sub-3 deviceMode: NetDevice --- apiVersion: networking.gke.io/v1 kind: GKENetworkParamSet metadata: name: vpc4 spec: vpc: PROJECT_ID-net-4 vpcSubnet: PROJECT_ID-sub-4 deviceMode: NetDevice EOF
이러한 리소스는 GPU 트래픽을 위한 NIC를 패스 스루 모드로 구성하도록 GKE에 지시합니다. GKE는 이 트래픽에 eBPF를 사용하는 기본 제공 네트워킹 프로그래밍을 적용하지 않습니다.
H100 GPU용 노드 풀을 만듭니다.
gcloud container node-pools create NODE_POOL_NAME \ --cluster=CLUSTER_NAME \ --location=LOCATION \ --machine-type=a3-highgpu-8g \ --accelerator=type=nvidia-h100-80gb,count=8,gpu-driver-version=LATEST \ --additional-node-network=network=PROJECT_ID-net-1,subnetwork=PROJECT_ID-sub-1 \ --additional-node-network=network=PROJECT_ID-net-2,subnetwork=PROJECT_ID-sub-2 \ --additional-node-network=network=PROJECT_ID-net-3,subnetwork=PROJECT_ID-sub-3 \ --additional-node-network=network=PROJECT_ID-net-4,subnetwork=PROJECT_ID-sub-4 \ --enable-gvnic \ --no-enable-autoupgrade
NODE_POOL_NAME
을 노드 풀의 이름으로 바꿉니다.이 명령어가 실패한다면 프로젝트에 H100 GPU 할당량이 충분하지 않은 경우일 수 있습니다. 할당량이 있는지 확인하고 명령어를 다시 시도합니다.
클러스터의 노드 목록을 가져옵니다.
kubectl get nodes
각 GPU 노드에 GPU가 8개 있는지 확인합니다.
kubectl describe node NODE_NAME
출력은 다음과 비슷합니다.
Capacity: ... nvidia.com/gpu: 8 Allocatable: ... nvidia.com/gpu: 8
GPUDirect 바이너리 설치 및 NCCL 구성
이 섹션에서는 A3 머신 유형(A3 High의 경우 GPUDirect-TCPX, A3 Mega의 경우 GPUDirect-TCPXO) 및 DaemonSet을 사용하는 특정 NCCL 라이브러리 버전을 기준으로 GPUDirect 바이너리를 설치하는 방법을 보여줍니다.
GPUDirect-TCPXO
GitHub의
nccl-tcpxo-installer.yaml
Daemonset 매니페스트를 검토합니다. 이 DaemonSet에서 다음을 수행합니다.- GPUDirect-TCPXO 관련 구성을 설정하기 위한 사전 설치
- 노드에 NCCL 라이브러리 및 GPUDirect-TCPXO 바이너리 설치
- VM의
/home/kubernetes/bin/nvidia/lib64
디렉터리에 라이브러리와 바이너리를 저장합니다. 기본적으로 GKE는 NCCL 및 GPUDirect-TCPXO를 사용해야 하는 GPU 컨테이너의/usr/local/nvidia/lib64
경로에 이 디렉터리를 마운트합니다.
DaemonSet를 배포합니다.
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/gpudirect-tcpxo/nccl-tcpxo-installer.yaml
NCCL 플러그인이 실행되기 시작하는 데 약 2분이 걸립니다.
DaemonSet 포드의 상태를 확인합니다.
kubectl get pods -n=kube-system -l=name=nccl-tcpxo-installer
출력은 다음과 비슷합니다.
# Output nccl-tcpxo-installer-6c2pv 1/1 Running 0 2m11s nccl-tcpxo-installer-qgg82 1/1 Running 0 2m11s
GPUDirect-TCPX
GitHub의
nccl-tcpx-installer.yaml
Daemonset 매니페스트를 검토합니다. 이 DaemonSet에서 다음을 수행합니다.- 노드에 NCCL 라이브러리와 GPUDirect-TCPX 바이너리를 설치합니다.
- VM의
/home/kubernetes/bin/nvidia/lib64
디렉터리에 라이브러리와 바이너리를 저장합니다. 기본적으로 GKE는 NCCL 및 GPUDirect-TCPX를 사용해야 하는 GPU 컨테이너의/usr/local/nvidia/lib64
경로에 이 디렉터리를 마운트합니다.
DaemonSet를 배포합니다.
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/gpudirect-tcpx/nccl-tcpx-installer.yaml
NCCL 플러그인이 실행되기 시작하는 데 약 2분이 걸립니다.
DaemonSet 포드의 상태를 확인합니다.
kubectl get pods -n=kube-system -l=name=nccl-tcpx-installer
출력은 다음과 비슷합니다.
nccl-tcpx-installer-6c2pv 1/1 Running 0 2m11s nccl-tcpx-installer-qgg82 1/1 Running 0 2m11s
NRI 기기 인젝터 플러그인 배포
이 섹션에서는 DaemonSet을 사용하여 NRI 기기 인젝터를 설치하는 방법을 보여줍니다. 두 H100 머신 유형(A3 High의 경우 GPUDirect-TCPX, A3 Mega의 경우 GPUDirect-TCPXO) 모두 동일한 NRI 기기 인젝터 플러그인을 설치합니다.
GitHub의
nri-device-injector.yaml
배포 매니페스트를 검토합니다. 이 DaemonSet에서 다음을 수행합니다.- H100 GPU가 있는 노드에서 노드 리소스 인터페이스(NRI)를 사용 설정합니다.
- 포드 주석에 지정된 컨테이너에 GPU 기기를 삽입하는 NRI 기기 인젝터 플러그인 컨테이너를 배포합니다.
DaemonSet를 배포합니다.
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/nri_device_injector/nri-device-injector.yaml
NCCL 플러그인이 실행되기 시작하는 데 약 2분이 걸립니다.
DaemonSet 포드의 상태를 확인합니다.
kubectl get pods -n=kube-system -l=name=device-injector
출력은 다음과 비슷합니다.
# Output device-injector-md6hb 1/1 Running 0 4h54m device-injector-vh9bm 1/1 Running 0 4h54m
테스트 워크로드 배포
이 섹션에서는 샘플 워크로드를 배포하여 NCCL 및 GPUDirect-TCPX 또는 GPUDirect-TCPXO가 정상적으로 작동하는지 확인합니다.
GPUDirect-TCPXO
이 워크로드에는 포드가 GPUDirect-TCPXO를 사용하도록 허용하는 서비스를 실행하는 tcpxo-daemon이라는 사이드카 컨테이너가 포함되어 있습니다. 자체 환경에서 GPUDirect-TCPXO를 사용해야 하는 모든 포드에 이 사이드카 컨테이너를 추가해야 합니다. 매니페스트에 추가해야 하는 필드의 스니펫은 매니페스트에 GPUDirect 추가를 참조하세요.
GitHub의
nccl-test-latest.yaml
매니페스트를 검토합니다. 이 매니페스트는 다음을 수행합니다.- H100 GPU가 있는 노드에서 각각 실행되는 포드 2개를 배포합니다.
- 포드가 GPUDirect-TCPXO를 사용할 수 있도록 각 포드에
tcpxo-daemon
이라는 사이드카 컨테이너를 배포합니다.
테스트 워크로드가 포함된 포드 2개를 배포합니다.
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/gpudirect-tcpxo/nccl-test-latest.yaml
다음 명령어를 실행하여 두 노드의 NCCL all-gather 테스트를 트리거합니다.
kubectl exec --stdin --tty --container=nccl-test nccl-test-host-1 -- /scripts/allgather.sh nccl-host-1 nccl-host-2
출력은 다음과 비슷합니다.
# out-of-place in-place # size count type redop root time algbw busbw #wrong time algbw busbw #wrong # (B) (elements) (us) (GB/s) (GB/s) (us) (GB/s) (GB/s) 1048576 16384 float none -1 4654.5 0.23 0.21 0 3890.9 0.27 0.25 0 2097152 32768 float none -1 4117.2 0.51 0.48 0 5153.5 0.41 0.38 0 4194304 65536 float none -1 6417.4 0.65 0.61 0 7295.5 0.57 0.54 0 8388608 131072 float none -1 7872.1 1.07 1.00 0 6451.4 1.30 1.22 0 16777216 262144 float none -1 6990.7 2.40 2.25 0 5609.3 2.99 2.80 0 33554432 524288 float none -1 8254.0 4.07 3.81 0 7415.1 4.53 4.24 0 67108864 1048576 float none -1 5546.3 12.10 11.34 0 6484.0 10.35 9.70 0 134217728 2097152 float none -1 6507.3 20.63 19.34 0 6015.4 22.31 20.92 0 268435456 4194304 float none -1 6744.1 39.80 37.32 0 7023.1 38.22 35.83 0 536870912 8388608 float none -1 8939.8 60.05 56.30 0 11706 45.86 43.00 0 1073741824 16777216 float none -1 8241.7 130.28 122.14 0 8375.2 128.20 120.19 0 # Out of bounds values : 0 OK # Avg bus bandwidth : 22.449
GPUDirect-TCPX
이 워크로드에는 포드가 GPUDirect-TCPX를 사용하도록 허용하는 서비스를 실행하는 tcpx-daemon이라는 사이드카 컨테이너가 포함되어 있습니다. 자체 환경에서 GPUDirect-TCPX를 사용해야 하는 모든 포드에 이 사이드카 컨테이너를 추가해야 합니다. 매니페스트에 추가해야 하는 필드의 스니펫은 매니페스트에 GPUDirect 추가를 참조하세요.
- GitHub의
nccl-config.yaml
ConfigMap 매니페스트를 검토합니다. 이 매니페스트는 NCCL all-gather 테스트를 초기화하고 NCCL 관련 구성 설정을 설정하는 스크립트를 배포합니다. GitHub의
nccl-test-latest.yaml
배포 매니페스트를 검토합니다. 이 매니페스트는 다음을 수행합니다.- H100 GPU가 있는 노드에서 각각 실행되는 포드 2개를 배포합니다.
- 포드가 GPUDirect-TCPX를 사용할 수 있도록 각 포드에
tcpx-daemon
이라는 사이드카 컨테이너를 배포합니다.
ConfigMap 및 테스트 워크로드를 배포합니다.
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/gpudirect-tcpx/nccl-config.yaml kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/gpudirect-tcpx/nccl-test-latest.yaml
다음 명령어를 실행하여 노드의 NCCL all-gather 테스트를 트리거합니다.
kubectl exec \ --stdin --tty --container=nccl-test nccl-test-host-1 \ -- /configs/allgather.sh nccl-host-1 nccl-host-2
출력은 다음과 비슷합니다.
# out-of-place in-place # size count type redop root time algbw busbw #wrong time algbw busbw #wrong # (B) (elements) (us) (GB/s) (GB/s) (us) (GB/s) (GB/s) 1048576 16384 float none -1 696.8 1.50 1.41 0 729.0 1.44 1.35 0 2097152 32768 float none -1 776.4 2.70 2.53 0 726.7 2.89 2.71 0 4194304 65536 float none -1 774.3 5.42 5.08 0 805.1 5.21 4.88 0 8388608 131072 float none -1 812.1 10.33 9.68 0 817.6 10.26 9.62 0 16777216 262144 float none -1 1035.2 16.21 15.19 0 1067.8 15.71 14.73 0 33554432 524288 float none -1 1183.3 28.36 26.59 0 1211.8 27.69 25.96 0 67108864 1048576 float none -1 1593.4 42.12 39.49 0 1510.5 44.43 41.65 0 134217728 2097152 float none -1 2127.8 63.08 59.13 0 2312.7 58.03 54.41 0 268435456 4194304 float none -1 3603.0 74.50 69.85 0 3586.2 74.85 70.17 0 536870912 8388608 float none -1 7101.7 75.60 70.87 0 7060.9 76.03 71.28 0 # Out of bounds values : 0 OK # Avg bus bandwidth : 29.8293
필수 NCCL 구성 설정을 사용하여 성능 개선
다음 키-값 쌍은 GPUDirect-TCPX 및 GPUDirect-TCPXO에 필요한 NCCL 구성 설정입니다. NCCL을 사용하는 워크로드를 배포할 때는 성능을 최적화하기 위해 환경 변수로 설정합니다.
GPUDirect-TCPXO
## required
"LD_LIBRARY_PATH=\"${LD_LIBRARY_PATH}:/usr/local/nvidia/lib64\"",
"NCCL_FASTRAK_CTRL_DEV=eth0",
"NCCL_FASTRAK_IFNAME=eth1,eth2,eth3,eth4,eth5,eth6,eth7,eth8",
"NCCL_SOCKET_IFNAME=eth0",
"NCCL_CROSS_NIC=0",
"NCCL_ALGO=Ring,Tree",
"NCCL_PROTO=Simple",
"NCCL_MIN_NCHANNELS=4",
"NCCL_TUNER_PLUGIN=libnccl-tuner.so",
"NCCL_TUNER_CONFIG_PATH=/usr/local/nvidia/lib64/a3plus_tuner_config.textproto",
"NCCL_SHIMNET_GUEST_CONFIG_CHECKER_CONFIG_FILE=/usr/local/nvidia/lib64/a3plus_guest_config.textproto",
"NCCL_DYNAMIC_CHUNK_SIZE=524288",
"NCCL_P2P_NET_CHUNKSIZE=524288",
"NCCL_P2P_PCI_CHUNKSIZE=524288",
"NCCL_P2P_NVL_CHUNKSIZE=1048576",
"NCCL_FASTRAK_NUM_FLOWS=2",
"NCCL_FASTRAK_USE_SNAP=1",
"NCCL_FASTRAK_PLUGIN_ACCEPT_TIMEOUT_MS=600000",
"NCCL_FASTRAK_ENABLE_CONTROL_CHANNEL=0",
"NCCL_BUFFSIZE=8388608",
"CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7",
"NCCL_NET_GDR_LEVEL=PIX",
"NCCL_FASTRAK_ENABLE_HOTPATH_LOGGING=0",
"NCCL_FASTRAK_USE_LLCM=1",
"NCCL_NVLS_ENABLE=0"
## recommended, to log NCCL errors
"NCCL_DEBUG=WARN",
"NCCL_DEBUG_SUBSYS=INIT,NET,ENV,COLL,GRAPH"
필요한 경우 다음 단계에 따라 모든 구성을 한 번에 설정할 수 있습니다.
워크로드 컨테이너 매니페스트에 다음 키-값 쌍을 환경 변수로 추가합니다.
NCCL_LIB_DIR="/usr/local/nvidia/lib64"
워크로드 컨테이너가 시작될 때
nccl-env-profile.sh
스크립트가 실행되는지 확인합니다. 예를 들어 포드 사양에서 컨테이너의 명령어를 재정의하는 방법으로 이를 수행하여 다음을 포함할 수 있습니다.source ${NCCL_LIB_DIR}/nccl-env-profile.sh
GPUDirect-TCPX
## required
"LD_LIBRARY_PATH=\"${LD_LIBRARY_PATH}:/usr/local/tcpx/lib64\"",
"NCCL_SOCKET_IFNAME=\"eth0\"",
"NCCL_ALGO=Ring",
"NCCL_PROTO=Simple",
"NCCL_CROSS_NIC=0",
"NCCL_NET_GDR_LEVEL=PIX",
"NCCL_P2P_PXN_LEVEL=0",
"NCCL_GPUDIRECTTCPX_SOCKET_IFNAME=eth1,eth2,eth3,eth4",
"NCCL_GPUDIRECTTCPX_CTRL_DEV=eth0",
"NCCL_DYNAMIC_CHUNK_SIZE=524288",
"NCCL_P2P_NET_CHUNKSIZE=524288",
"NCCL_P2P_PCI_CHUNKSIZE=524288",
"NCCL_P2P_NVL_CHUNKSIZE=1048576",
"NCCL_BUFFSIZE=4194304",
"NCCL_NSOCKS_PERTHREAD=4",
"NCCL_SOCKET_NTHREADS=1",
"NCCL_GPUDIRECTTCPX_TX_BINDINGS=\"eth1:8-21,112-125;eth2:8-21,112-125;eth3:60-73,164-177;eth4:60-73,164-177\"",
"NCCL_GPUDIRECTTCPX_RX_BINDINGS=\"eth1:22-35,126-139;eth2:22-35,126-139;eth3:74-87,178-191;eth4:74-87,178-191\"",
"NCCL_GPUDIRECTTCPX_PROGRAM_FLOW_STEERING_WAIT_MICROS=500000"
"NCCL_NVLS_ENABLE=0"
매니페스트에 GPUDirect 추가
이 섹션에서는 포드에서 GPUDirect를 사용하기 위해 Kubernetes 매니페스트에 추가해야 하는 필수 필드를 보여줍니다.
GPUDirect-TCPXO
포드 메타데이터에 다음 주석을 추가합니다. 이러한 주석이 없으면 포드에는
hostNetwork:true
,tcpxo-daemon
컨테이너에는privileged:true
가 필요합니다.metadata: annotations: devices.gke.io/container.tcpxo-daemon: |+ - path: /dev/nvidia0 - path: /dev/nvidia1 - path: /dev/nvidia2 - path: /dev/nvidia3 - path: /dev/nvidia4 - path: /dev/nvidia5 - path: /dev/nvidia6 - path: /dev/nvidia7 - path: /dev/nvidiactl - path: /dev/nvidia-uvm - path: /dev/dmabuf_import_helper networking.gke.io/default-interface: 'eth0' networking.gke.io/interfaces: | [ {"interfaceName":"eth0","network":"default"}, {"interfaceName":"eth1","network":"vpc1"}, {"interfaceName":"eth2","network":"vpc2"}, {"interfaceName":"eth3","network":"vpc3"}, {"interfaceName":"eth4","network":"vpc4"}, {"interfaceName":"eth5","network":"vpc5"}, {"interfaceName":"eth6","network":"vpc6"}, {"interfaceName":"eth7","network":"vpc7"}, {"interfaceName":"eth8","network":"vpc8"} ]
포드 사양에 다음 필드를 추가합니다.
spec: volumes: - name: libraries hostPath: path: /home/kubernetes/bin/nvidia/lib64 - name: sys hostPath: path: /sys - name: proc-sys hostPath: path: /proc/sys - name: aperture-devices hostPath: path: /dev/aperture_devices
tcpxo-daemon
서비스를 실행하려면 다음 컨테이너를 매니페스트에 추가합니다. (TCPXO_DAEMON_IMAGE
)를 최신 이미지인us-docker.pkg.dev/gce-ai-infra/gpudirect-tcpxo/tcpgpudmarxd-dev:v1.0.11
로 바꿉니다.- name: tcpxo-daemon image: TCPXO_DAEMON_IMAGE imagePullPolicy: Always command: ["/bin/sh", "-c"] args: - | set -ex chmod 755 /fts/entrypoint_rxdm_container.sh /fts/entrypoint_rxdm_container.sh --num_hops=2 --num_nics=8 --uid= --alsologtostderr securityContext: capabilities: add: - NET_ADMIN - NET_BIND_SERVICE volumeMounts: - name: libraries mountPath: /usr/local/nvidia - name: sys mountPath: /hostsysfs - name: proc-sys mountPath: /hostprocsysfs env: - name: LD_LIBRARY_PATH value: /usr/local/nvidia/lib64
모든 GPU 컨테이너에 다음 환경 변수를 추가합니다.
env: - name: LD_LIBRARY_PATH value: /usr/local/nvidia/lib64 - name: NCCL_FASTRAK_LLCM_DEVICE_DIRECTORY value: /dev/aperture_devices
모든 GPU 컨테이너에 다음 volumeMounts를 추가합니다.
aperture_devices
설정이 없으면 GPU 컨테이너에privileged:true
가 필요합니다.volumeMounts: - name: aperture-devices mountPath: /dev/aperture_devices
NCCL 옵션을 구성하는 환경 변수를 추가합니다. 자세한 내용은 권장 NCCL 구성 설정을 사용하여 성능 개선을 참조하세요.
완성된 포드 사양은 다음과 같습니다.
apiVersion: v1
kind: Pod
metadata:
name: a3plus-workloads
annotations:
devices.gke.io/container.tcpxo-daemon: |+
- path: /dev/nvidia0
- path: /dev/nvidia1
- path: /dev/nvidia2
- path: /dev/nvidia3
- path: /dev/nvidia4
- path: /dev/nvidia5
- path: /dev/nvidia6
- path: /dev/nvidia7
- path: /dev/nvidiactl
- path: /dev/nvidia-uvm
- path: /dev/dmabuf_import_helper
networking.gke.io/default-interface: 'eth0'
networking.gke.io/interfaces: |
[
{"interfaceName":"eth0","network":"default"},
{"interfaceName":"eth1","network":"vpc1"},
{"interfaceName":"eth2","network":"vpc2"},
{"interfaceName":"eth3","network":"vpc3"},
{"interfaceName":"eth4","network":"vpc4"},
{"interfaceName":"eth5","network":"vpc5"},
{"interfaceName":"eth6","network":"vpc6"},
{"interfaceName":"eth7","network":"vpc7"},
{"interfaceName":"eth8","network":"vpc8"}
]
...
containers:
- name: tcpxo-daemon
image: TCPXO_DAEMON_IMAGE
imagePullPolicy: Always
command: ["/bin/sh", "-c"]
args:
- |
set -ex
chmod 755 /fts/entrypoint_rxdm_container.sh
/fts/entrypoint_rxdm_container.sh --num_hops=2 --num_nics=8 --uid= --alsologtostderr
securityContext:
capabilities:
add:
- NET_ADMIN
- NET_BIND_SERVICE
volumeMounts:
- name: libraries
mountPath: /usr/local/nvidia
- name: sys
mountPath: /hostsysfs
- name: proc-sys
mountPath: /hostprocsysfs
env:
- name: LD_LIBRARY_PATH
value: /usr/local/nvidia/lib64
- name: main-application-container
...
env:
- name: LD_LIBRARY_PATH
value: /usr/local/nvidia/lib64
- name: NCCL_FASTRAK_LLCM_DEVICE_DIRECTORY
value: /dev/aperture_devices
securityContext:
volumeMounts:
- name: aperture-devices
mountPath: /dev/aperture_devices
resources:
limits:
nvidia.com/gpu: 8
volumes:
- name: libraries
hostPath:
path: /home/kubernetes/bin/nvidia
- name: sys
hostPath:
path: /sys
- name: proc-sys
hostPath:
path: /proc/sys
- name: aperture-devices
hostPath:
path: /dev/aperture_devices
GPUDirect-TCPX
포드 메타데이터에 다음 주석을 추가합니다. 이러한 주석이 없으면 포드에는
hostNetwork:true
,tcpx-daemon
컨테이너에는privileged:true
가 필요합니다.metadata: annotations: devices.gke.io/container.tcpx-daemon: |+ - path: /dev/nvidia0 - path: /dev/nvidia1 - path: /dev/nvidia2 - path: /dev/nvidia3 - path: /dev/nvidia4 - path: /dev/nvidia5 - path: /dev/nvidia6 - path: /dev/nvidia7 - path: /dev/nvidiactl - path: /dev/nvidia-uvm networking.gke.io/default-interface: 'eth0' networking.gke.io/interfaces: | [ {"interfaceName":"eth0","network":"default"}, {"interfaceName":"eth1","network":"vpc1"}, {"interfaceName":"eth2","network":"vpc2"}, {"interfaceName":"eth3","network":"vpc3"}, {"interfaceName":"eth4","network":"vpc4"}, ]
포드 사양에 다음 필드를 추가합니다.
spec: volumes: - name: libraries hostPath: path: /home/kubernetes/bin/nvidia/lib64 - name: sys hostPath: path: /sys - name: proc-sys hostPath: path: /proc/sys
tcpx-daemon 서비스를 실행하려면 다음 컨테이너를 매니페스트에 추가합니다.
- name: tcpx-daemon image: us-docker.pkg.dev/gce-ai-infra/gpudirect-tcpx/tcpgpudmarxd-dev:v2.0.9 command: - /tcpgpudmarxd/build/app/tcpgpudmarxd - --gpu_nic_preset - a3vm - --gpu_shmem_type - fd - --uds_path - /run/tcpx - --setup_param - \"--verbose 128 2 0 \" securityContext: capabilities: add: - NET_ADMIN volumeMounts: - name: libraries mountPath: /usr/local/nvidia/lib64 - name: tcpx-socket mountPath: /run/tcpx - name: sys mountPath: /hostsysfs - name: proc-sys mountPath: /hostprocsysfs env: - name: LD_LIBRARY_PATH value: /usr/local/nvidia/lib64
GPU를 요청하는 컨테이너에 다음 볼륨 마운트를 추가합니다.
volumeMounts: - name: tcpx-socket mountPath: /tmp - name: libraries mountPath: /usr/local/nvidia/lib64
모든 GPU 컨테이너에 다음 환경 변수를 추가합니다.
env: - name: LD_LIBRARY_PATH value: /usr/local/nvidia/lib64
NCCL 옵션을 구성하는 환경 변수를 추가합니다. 자세한 내용은 이 페이지의 권장 NCCL 구성 설정을 사용하여 성능 개선 섹션을 참조하세요.
완성된 포드 사양은 다음과 같습니다.
apiVersion: v1
kind: Pod
metadata:
name: a3-gpu-workloads-example
labels:
name: a3-gpu-workloads-example
annotations:
devices.gke.io/container.tcpx-daemon: |+
- path: /dev/nvidia0
- path: /dev/nvidia1
- path: /dev/nvidia2
- path: /dev/nvidia3
- path: /dev/nvidia4
- path: /dev/nvidia5
- path: /dev/nvidia6
- path: /dev/nvidia7
- path: /dev/nvidiactl
- path: /dev/nvidia-uvm
networking.gke.io/default-interface: 'eth0'
networking.gke.io/interfaces: |
[
{"interfaceName":"eth0","network":"default"},
{"interfaceName":"eth1","network":"vpc1"},
{"interfaceName":"eth2","network":"vpc2"},
{"interfaceName":"eth3","network":"vpc3"},
{"interfaceName":"eth4","network":"vpc4"}
]
spec:
containers:
- name: tcpx-daemon
image: us-docker.pkg.dev/gce-ai-infra/gpudirect-tcpx/tcpgpudmarxd-dev:v2.0.11
imagePullPolicy: Always
command:
- /tcpgpudmarxd/build/app/tcpgpudmarxd
- --gpu_nic_preset
- a3vm
- --gpu_shmem_type
- fd
- --uds_path
- /run/tcpx
- --setup_param
- \"--verbose 128 2 0 \"
securityContext:
capabilities:
add:
- NET_ADMIN
volumeMounts:
- name: libraries
mountPath: /usr/local/nvidia/lib64
readOnly: true
- name: tcpx-socket
mountPath: /run/tcpx
- name: sys
mountPath: /hostsysfs
- name: proc-sys
mountPath: /hostprocsysfs
env:
- name: LD_LIBRARY_PATH
value: /usr/local/nvidia/lib64
- name: a3-gpu-workloads-example
...
volumeMounts:
- name: tcpx-socket
mountPath: /tmp
- name: libraries
mountPath: /usr/local/nvidia/lib64
readOnly: true
resources:
limits:
nvidia.com/gpu: 8
env:
- name: LD_LIBRARY_PATH
value: /usr/local/nvidia/lib64
...
volumes:
- name: libraries
hostPath:
path: /home/kubernetes/bin/nvidia/lib64
- name: tcpx-socket
emptyDir:
- name: sys
hostPath:
path: /sys
- name: proc-sys
hostPath:
path: /proc/sys
다음 단계
- GKE 네트워킹 권장사항 알아보기
- NVIDIA GPU의 데이터 이동 및 액세스를 위한 NVIDIA GPUDirect 기술 제품군 자세히 알아보기
- GKE의 현재 GPU 버전 가용성 및 GPU 요청 알아보기