GPUDirect 및 멀티 네트워킹으로 GPU 네트워크 대역폭 극대화


이 페이지에서는 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 노드를 위한 압축 배치 정의를 참고하세요.

절차 개요

이 모든 기능을 함께 사용하려면 다음을 수행합니다.

  1. 가상 프라이빗 클라우드(VPC) 및 서브넷 만들기
  2. GKE 환경 만들기:
    1. 멀티 네트워킹이 사용 설정된 클러스터 만들기
    2. 다음 특성으로 노드 풀 만들기:
      1. gVNIC 사용 설정
      2. 각 보조 NIC에 지정된 멀티 네트워킹 서브넷
      3. 노드를 지원하는 H100 GPU가 있는 A3 머신 시리즈
      4. 최신 NVIDIA 드라이버가 설치됨
  3. GPUDirect 바이너리 및 NCCL 플러그인 설치
  4. NRI 기기 인젝터 플러그인 배포
  5. 테스트 워크로드를 배포하여 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 이상을 사용합니다.
  • 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 이상을 사용합니다.
  • 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 네트워크에는 내부 네트워크 트래픽을 허용하는 서브넷과 방화벽 규칙이 있어야 합니다.

  1. 프로젝트에서 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입니다.
  2. 네트워크가 생성되었는지 확인합니다.

    gcloud compute networks list
    

GKE 환경 만들기

멀티 네트워킹(미리보기)을 사용하는 새 GKE 클러스터를 만들고 H100 GPU와 추가 NIC가 있는 A3 머신을 사용하는 GPU 노드 풀을 만듭니다. 멀티 네트워킹을 사용하도록 기존 클러스터를 업데이트할 수는 없습니다.

GPUDirect-TCPXO

  1. GPUDirect-TCPXO를 지원하는 사용 가능한 GKE 버전을 선택합니다. 버전을 나열하려면 다음 명령어를 실행합니다.

    gcloud container get-server-config \
      --format="yaml(validMasterVersions)" \
      --zone=ZONE \
      --project=PROJECT_ID
    

    다음을 바꿉니다.

    • ZONE: 클러스터 컨트롤 플레인의 컴퓨팅 영역입니다.
    • PROJECT_ID: Google Cloud 프로젝트 ID입니다.
  2. 클러스터 만들기:

    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
    

    다음을 바꿉니다.

    • CLUSTER_NAME: 새 클러스터의 이름입니다.
    • VERSION: 요구사항에 설명된 대로 GPUDirect-TCPXO를 지원하는 GKE 버전입니다.
    • REGION: 클러스터의 Compute Engine 리전입니다.
    • ZONE: 클러스터의 컴퓨팅 영역입니다.
  3. 자신이 만든 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를 사용하는 기본 제공 네트워킹 프로그래밍을 적용하지 않습니다.

  4. 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 할당량이 충분하지 않은 경우일 수 있습니다. 할당량이 충분한지 확인하고 명령어를 다시 시도합니다.

  5. 클러스터의 노드 목록을 가져옵니다.

    kubectl get nodes
    
  6. 각 GPU 노드에 GPU가 8개 있는지 확인합니다.

    kubectl describe node NODE_NAME
    

    출력은 다음과 비슷합니다.

    Capacity:
      ...
      nvidia.com/gpu:             8
    Allocatable:
      ...
      nvidia.com/gpu:             8
    

GPUDirect-TCPX

  1. 표준 클러스터 만들기

    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 버전입니다. 요구사항 섹션에 설명된 대로 지원되는 버전을 사용합니다.
  2. 자신이 만든 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를 사용하는 기본 제공 네트워킹 프로그래밍을 적용하지 않습니다.

  3. 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 할당량이 충분하지 않은 경우일 수 있습니다. 할당량이 있는지 확인하고 명령어를 다시 시도합니다.

  4. 클러스터의 노드 목록을 가져옵니다.

    kubectl get nodes
    
  5. 각 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

  1. GitHub의 nccl-tcpxo-installer.yaml Daemonset 매니페스트를 검토합니다. 이 DaemonSet에서 다음을 수행합니다.

    1. GPUDirect-TCPXO 관련 구성을 설정하기 위한 사전 설치
    2. 노드에 NCCL 라이브러리 및 GPUDirect-TCPXO 바이너리 설치
    3. VM의 /home/kubernetes/bin/nvidia/lib64 디렉터리에 라이브러리와 바이너리를 저장합니다. 기본적으로 GKE는 NCCL 및 GPUDirect-TCPXO를 사용해야 하는 GPU 컨테이너의 /usr/local/nvidia/lib64 경로에 이 디렉터리를 마운트합니다.
  2. DaemonSet를 배포합니다.

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/gpudirect-tcpxo/nccl-tcpxo-installer.yaml
    

    NCCL 플러그인이 실행되기 시작하는 데 약 2분이 걸립니다.

  3. 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

  1. GitHub의 nccl-tcpx-installer.yaml Daemonset 매니페스트를 검토합니다. 이 DaemonSet에서 다음을 수행합니다.

    1. 노드에 NCCL 라이브러리와 GPUDirect-TCPX 바이너리를 설치합니다.
    2. VM의 /home/kubernetes/bin/nvidia/lib64 디렉터리에 라이브러리와 바이너리를 저장합니다. 기본적으로 GKE는 NCCL 및 GPUDirect-TCPX를 사용해야 하는 GPU 컨테이너의 /usr/local/nvidia/lib64 경로에 이 디렉터리를 마운트합니다.
  2. DaemonSet를 배포합니다.

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/gpudirect-tcpx/nccl-tcpx-installer.yaml
    

    NCCL 플러그인이 실행되기 시작하는 데 약 2분이 걸립니다.

  3. 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 기기 인젝터 플러그인을 설치합니다.

  1. GitHub의 nri-device-injector.yaml 배포 매니페스트를 검토합니다. 이 DaemonSet에서 다음을 수행합니다.

    1. H100 GPU가 있는 노드에서 노드 리소스 인터페이스(NRI)를 사용 설정합니다.
    2. 포드 주석에 지정된 컨테이너에 GPU 기기를 삽입하는 NRI 기기 인젝터 플러그인 컨테이너를 배포합니다.
  2. DaemonSet를 배포합니다.

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/nri_device_injector/nri-device-injector.yaml
    

    NCCL 플러그인이 실행되기 시작하는 데 약 2분이 걸립니다.

  3. 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 추가를 참조하세요.

  1. GitHub의 nccl-test-latest.yaml 매니페스트를 검토합니다. 이 매니페스트는 다음을 수행합니다.

    1. H100 GPU가 있는 노드에서 각각 실행되는 포드 2개를 배포합니다.
    2. 포드가 GPUDirect-TCPXO를 사용할 수 있도록 각 포드에 tcpxo-daemon이라는 사이드카 컨테이너를 배포합니다.
  2. 테스트 워크로드가 포함된 포드 2개를 배포합니다.

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/gpudirect-tcpxo/nccl-test-latest.yaml
    
  3. 다음 명령어를 실행하여 두 노드의 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 추가를 참조하세요.

  1. GitHub의 nccl-config.yaml ConfigMap 매니페스트를 검토합니다. 이 매니페스트는 NCCL all-gather 테스트를 초기화하고 NCCL 관련 구성 설정을 설정하는 스크립트를 배포합니다.
  2. GitHub의 nccl-test-latest.yaml 배포 매니페스트를 검토합니다. 이 매니페스트는 다음을 수행합니다.

    1. H100 GPU가 있는 노드에서 각각 실행되는 포드 2개를 배포합니다.
    2. 포드가 GPUDirect-TCPX를 사용할 수 있도록 각 포드에 tcpx-daemon이라는 사이드카 컨테이너를 배포합니다.
  3. 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
    
  4. 다음 명령어를 실행하여 노드의 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"

필요한 경우 다음 단계에 따라 모든 구성을 한 번에 설정할 수 있습니다.

  1. 워크로드 컨테이너 매니페스트에 다음 키-값 쌍을 환경 변수로 추가합니다.

    NCCL_LIB_DIR="/usr/local/nvidia/lib64"
    
  2. 워크로드 컨테이너가 시작될 때 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

  1. 포드 메타데이터에 다음 주석을 추가합니다. 이러한 주석이 없으면 포드에는 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"}
          ]
    
  2. 포드 사양에 다음 필드를 추가합니다.

    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
    
  3. 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
    
  4. 모든 GPU 컨테이너에 다음 환경 변수를 추가합니다.

    env:
    - name: LD_LIBRARY_PATH
      value: /usr/local/nvidia/lib64
    - name: NCCL_FASTRAK_LLCM_DEVICE_DIRECTORY
      value: /dev/aperture_devices
    
  5. 모든 GPU 컨테이너에 다음 volumeMounts를 추가합니다. aperture_devices 설정이 없으면 GPU 컨테이너에 privileged:true가 필요합니다.

    volumeMounts:
      - name: aperture-devices
        mountPath: /dev/aperture_devices
    
  6. 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

  1. 포드 메타데이터에 다음 주석을 추가합니다. 이러한 주석이 없으면 포드에는 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"},
          ]
    
  2. 포드 사양에 다음 필드를 추가합니다.

    spec:
      volumes:
      - name: libraries
        hostPath:
          path: /home/kubernetes/bin/nvidia/lib64
      - name: sys
        hostPath:
          path: /sys
      - name: proc-sys
        hostPath:
          path: /proc/sys
    
  3. 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
    
  4. GPU를 요청하는 컨테이너에 다음 볼륨 마운트를 추가합니다.

    volumeMounts:
    - name: tcpx-socket
      mountPath: /tmp
    - name: libraries
      mountPath: /usr/local/nvidia/lib64
    
  5. 모든 GPU 컨테이너에 다음 환경 변수를 추가합니다.

    env:
    - name: LD_LIBRARY_PATH
      value: /usr/local/nvidia/lib64
    
  6. 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

다음 단계