메인 콘텐츠로 건너뛰기
GPU 워크로드를 스케줄링하고 실행할 수 있는 Minikube 클러스터에 W&B Launch를 설정합니다.
이 튜토리얼은 여러 개의 GPU에 직접 액세스할 수 있는 머신을 사용하는 사용자를 위한 가이드입니다. 클라우드 머신을 임대해서 사용하는 사용자를 위한 튜토리얼은 아닙니다.클라우드 머신에서 Minikube 클러스터를 설정하려는 경우, W&B는 클라우드 제공업체를 사용해 GPU를 지원하는 Kubernetes 클러스터를 생성할 것을 권장합니다. 예를 들어 AWS, Google Cloud, Azure, Coreweave 및 기타 클라우드 제공업체는 GPU를 지원하는 Kubernetes 클러스터를 생성하기 위한 도구를 제공합니다.단일 GPU를 가진 머신에서 GPU 스케줄링을 위해 Minikube 클러스터를 설정하려는 경우, W&B는 Launch Docker 큐 사용을 권장합니다. 재미로 이 튜토리얼을 따라 해 볼 수는 있지만, GPU 스케줄링은 크게 유용하지 않을 것입니다.

배경

NVIDIA container toolkit는 Docker에서 GPU를 사용하는 워크플로를 쉽게 실행할 수 있게 해줍니다. 다만 한 가지 제약은 GPU를 개수(볼륨) 단위로 스케줄링하는 기능에 대한 네이티브 지원이 없다는 점입니다. docker run 명령어로 GPU를 사용하려면 특정 GPU를 ID로 지정하거나 시스템에 있는 모든 GPU를 한 번에 요청해야 하므로, 많은 분산 GPU 워크로드에서는 비실용적입니다. Kubernetes는 요청한 리소스 개수(볼륨)에 따른 스케줄링을 지원하지만, GPU 스케줄링이 가능한 로컬 Kubernetes 클러스터를 설정하는 데는 최근까지 상당한 시간과 노력이 필요했습니다. 단일 노드 Kubernetes 클러스터를 실행하기 위한 가장 인기 있는 도구 중 하나인 Minikube는 최근 GPU 스케줄링 기능을 지원하기 시작했습니다. 이 튜토리얼에서는 다중 GPU 머신에 Minikube 클러스터를 생성하고, W&B Launch를 사용해 클러스터에 동시 Stable Diffusion 추론 작업을 실행합니다.

사전 준비 사항

시작하기 전에 다음이 필요합니다.
  1. W&B 계정
  2. 다음이 설치되어 실행 중인 Linux 머신:
    1. Docker runtime
    2. 사용하려는 GPU용 드라이버
    3. Nvidia container toolkit
이 튜토리얼을 작성하고 테스트하는 데 4개의 NVIDIA Tesla T4 GPU가 연결된 n1-standard-16 Google Cloud Compute Engine 인스턴스를 사용했습니다.

Launch 작업을 위한 대기열 생성

먼저 Launch 작업을 위한 대기열을 생성합니다.
  1. wandb.ai/launch (또는 개인 W&B 서버를 사용하는 경우 <your-wandb-url>/launch)로 이동합니다.
  2. 화면 오른쪽 상단에서 파란색 Create a queue 버튼을 클릭합니다. 그러면 화면 오른쪽에서 대기열 생성 드로어가 슬라이드되어 나타납니다.
  3. 엔터티를 선택하고 이름을 입력한 다음, 대기열의 유형으로 Kubernetes를 선택합니다.
  4. 드로어의 Config 섹션에 Launch 대기열에 사용할 Kubernetes job specification을 입력합니다. 이 대기열에서 시작되는 모든 실행은 이 job specification을 사용하여 생성되므로, 작업을 커스터마이즈하기 위해 필요에 따라 이 구성을 수정할 수 있습니다. 이 튜토리얼에서는 아래의 샘플 구성을 대기열 설정에 YAML 또는 JSON 형태로 그대로 복사해 붙여넣으면 됩니다:
spec:
  template:
    spec:
      containers:
        - image: ${image_uri}
          resources:
            limits:
              cpu: 4
              memory: 12Gi
              nvidia.com/gpu: '{{gpus}}'
      restartPolicy: Never
  backoffLimit: 0
대기열 설정에 대한 자세한 내용은 Set up Launch on KubernetesAdvanced queue setup guide를 참조하세요. ${image_uri}{{gpus}} 문자열은 대기열 설정에서 사용할 수 있는 두 가지 유형의 변수 템플릿 예시입니다. ${image_uri} 템플릿은 에이전트가 시작하는 작업의 이미지 URI로 대체됩니다. {{gpus}} 템플릿은 작업을 제출할 때 Launch UI, CLI, 또는 SDK에서 재정의할 수 있는 템플릿 변수로 사용됩니다. 이 값들은 job specification 안에 배치되어, 작업에서 사용되는 이미지 및 GPU 리소스를 제어하는 올바른 필드를 수정하도록 합니다.
  1. gpus 템플릿 변수를 커스터마이즈하기 위해 Parse configuration 버튼을 클릭합니다.
  2. TypeInteger로 설정하고 Default, Min, Max를 원하는 값으로 설정합니다. 이 템플릿 변수의 제약 조건을 위반하는 실행을 이 대기열에 제출하려는 시도는 거부됩니다.
Queue 생성 드로어
  1. Create queue를 클릭하여 대기열을 생성합니다. 새 대기열의 대기열 페이지로 리디렉션됩니다.
다음 섹션에서는 방금 생성한 대기열에서 작업을 가져와 실행할 수 있는 에이전트를 설정합니다.

Docker + NVIDIA CTK 설정

이미 Docker와 NVIDIA 컨테이너 툴킷이 머신에 구성되어 있다면, 이 섹션은 건너뛰어도 됩니다. 시스템에 Docker 컨테이너 엔진을 설정하는 방법은 Docker 공식 문서를 참고하세요. Docker를 설치한 후, NVIDIA 공식 문서의 안내에 따라 NVIDIA 컨테이너 툴킷을 설치하세요. 컨테이너 런타임이 GPU에 액세스할 수 있는지 확인하려면 다음 명령을 실행하세요:
docker run --gpus all ubuntu nvidia-smi
nvidia-smi 출력에 머신에 연결된 GPU 정보가 표시되어야 합니다. 예를 들어, 이 문서에서 사용한 환경에서는 출력이 다음과 같습니다.
Wed Nov  8 23:25:53 2023
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 525.105.17   Driver Version: 525.105.17   CUDA Version: 12.0     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|                               |                      |               MIG M. |
|===============================+======================+======================|
|   0  Tesla T4            Off  | 00000000:00:04.0 Off |                    0 |
| N/A   38C    P8     9W /  70W |      2MiB / 15360MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
|   1  Tesla T4            Off  | 00000000:00:05.0 Off |                    0 |
| N/A   38C    P8     9W /  70W |      2MiB / 15360MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
|   2  Tesla T4            Off  | 00000000:00:06.0 Off |                    0 |
| N/A   40C    P8     9W /  70W |      2MiB / 15360MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
|   3  Tesla T4            Off  | 00000000:00:07.0 Off |                    0 |
| N/A   39C    P8     9W /  70W |      2MiB / 15360MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                                  |
|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
|        ID   ID                                                   Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+

Minikube 설정

Minikube에서 GPU를 사용하려면 v1.32.0 이상의 버전이 필요합니다. 최신 설치 안내는 Minikube 설치 문서를 참고하세요. 이 튜토리얼에서는 다음 명령어로 최신 Minikube 릴리스를 설치했습니다.
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
다음 단계는 GPU를 사용해 minikube 클러스터를 시작하는 것입니다. 로컬 머신에서 다음을 실행하세요:
minikube start --gpus all
위 명령의 출력 결과를 보면 클러스터가 성공적으로 생성되었는지 알 수 있습니다.

launch agent 시작

새 클러스터용 launch agent는 wandb launch-agent를 직접 호출해서 시작하거나, W&B에서 관리하는 helm 차트를 사용해 배포하여 시작할 수 있습니다. 이 튜토리얼에서는 에이전트를 호스트 머신에서 직접 실행합니다.
에이전트를 컨테이너 밖에서 실행하면 클러스터에서 실행할 이미지를 빌드하기 위해 로컬 Docker 호스트를 사용할 수 있습니다.
에이전트를 로컬에서 실행하려면, 기본 Kubernetes API 컨텍스트가 Minikube 클러스터를 가리키도록 설정되어 있는지 확인한 다음, 다음을 실행하세요:
pip install "wandb[launch]"
에이전트의 종속성을 설치합니다. 에이전트 인증을 설정하려면 wandb login을 실행하거나 WANDB_API_KEY 환경 변수를 설정하십시오. 에이전트를 시작하려면 다음 명령을 실행하십시오:
wandb launch-agent -j <max-number-concurrent-jobs> -q <queue-name> -e <queue-entity>
터미널에서 Launch 에이전트가 폴링 메시지를 출력하기 시작한 것을 확인할 수 있습니다. 축하합니다. 이제 Launch 에이전트가 Launch 큐를 폴링하고 있습니다. 큐에 작업이 추가되면 에이전트가 이를 가져와 Minikube 클러스터에서 실행되도록 스케줄링합니다.

작업 실행

이제 에이전트에 작업을 보내 보겠습니다. W&B 계정으로 로그인된 터미널에서 다음 명령으로 간단한 “hello world” 작업을 실행할 수 있습니다:
wandb launch -d wandb/job_hello_world:main -p <target-wandb-project> -q <your-queue-name> -e <your-queue-entity>
원하는 어떤 잡이나 이미지로 테스트해도 되지만, 클러스터가 해당 이미지를 가져올 수 있는지 반드시 확인하세요. 추가 안내는 Minikube 설명서를 참고하세요. 또한 공개 잡 중 하나를 사용해 테스트할 수도 있습니다.

(선택 사항) NFS를 사용한 모델 및 데이터 캐싱

ML 워크로드에서는 여러 작업이 동일한 데이터에 액세스해야 하는 경우가 자주 있습니다. 예를 들어, 데이터셋이나 모델 가중치처럼 용량이 큰 리소스를 반복해서 다운로드하지 않도록 공유 캐시를 두고 싶을 수 있습니다. Kubernetes는 이를 PersistentVolume 및 PersistentVolumeClaim을 통해 지원합니다. PersistentVolume은 Kubernetes 워크로드에서 volumeMounts로 마운트하는 데 사용할 수 있으며, 공유 캐시에 대한 직접적인 파일 시스템 액세스를 제공합니다. 이 단계에서는 모델 가중치를 위한 공유 캐시로 사용할 수 있는 Network File System(NFS) 서버를 설정합니다. 첫 단계는 NFS를 설치하고 구성하는 것입니다. 이 과정은 운영 체제마다 다릅니다. 이 VM은 Ubuntu에서 실행 중이므로, nfs-kernel-server를 설치하고 /srv/nfs/kubedata 경로에 export를 구성했습니다:
sudo apt-get install nfs-kernel-server
sudo mkdir -p /srv/nfs/kubedata
sudo chown nobody:nogroup /srv/nfs/kubedata
sudo sh -c 'echo "/srv/nfs/kubedata *(rw,sync,no_subtree_check,no_root_squash,no_all_squash,insecure)" >> /etc/exports'
sudo exportfs -ra
sudo systemctl restart nfs-kernel-server
호스트 파일 시스템에서 서버의 export 위치와 NFS 서버의 로컬 IP 주소를 기록해 두십시오. 다음 단계에서 이 정보가 필요합니다. 다음으로, 이 NFS를 위한 PersistentVolume과 PersistentVolumeClaim을 생성해야 합니다. PersistentVolume은 매우 세밀하게 커스텀할 수 있지만, 여기서는 단순함을 위해 기본적인 설정을 사용합니다. 아래 YAML을 nfs-persistent-volume.yaml이라는 이름의 파일에 복사하고, 원하는 볼륨 용량과 클레임 요청 값을 채워 넣으십시오. PersistentVolume.spec.capcity.storage 필드는 기본 볼륨의 최대 크기를 제어합니다. PersistentVolumeClaim.spec.resources.requests.stroage는 특정 클레임에 할당되는 볼륨 용량을 제한하는 데 사용할 수 있습니다. 이 문서의 사용 사례에서는 두 필드 모두에 동일한 값을 사용하는 것이 합리적입니다.
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-pv
spec:
  capacity:
    storage: 100Gi # 원하는 용량으로 설정하세요.
  accessModes:
    - ReadWriteMany
  nfs:
    server: <your-nfs-server-ip> # TODO: 여기에 입력하세요.
    path: '/srv/nfs/kubedata' # 또는 사용자 지정 경로
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 100Gi # 원하는 용량으로 설정하세요.
  storageClassName: ''
  volumeName: nfs-pv
다음 명령을 실행해 클러스터에 리소스를 생성합니다:
kubectl apply -f nfs-persistent-volume.yaml
실행에서 이 캐시를 활용하려면 launch queue 구성에 volumesvolumeMounts를 추가해야 합니다. launch 구성을 수정하려면 wandb.ai/launch (또는 wandb server 사용자의 경우 <your-wandb-url>/launch)로 돌아가서, 사용 중인 queue를 찾은 뒤 queue 페이지로 이동하고 Edit config 탭을 클릭합니다. 기존 구성은 다음과 같이 수정할 수 있습니다:
spec:
  template:
    spec:
      containers:
        - image: ${image_uri}
          resources:
            limits:
              cpu: 4
              memory: 12Gi
              nvidia.com/gpu: "{{gpus}}"
					volumeMounts:
            - name: nfs-storage
              mountPath: /root/.cache
      restartPolicy: Never
			volumes:
        - name: nfs-storage
          persistentVolumeClaim:
            claimName: nfs-pvc
  backoffLimit: 0
이제 작업을 실행하는 컨테이너에서 NFS가 /root/.cache에 마운트됩니다. 컨테이너가 root가 아닌 다른 사용자로 실행되는 경우에는 마운트 경로를 조정해야 합니다. 기본적으로 Hugging Face 라이브러리와 W&B 아티팩트는 모두 $HOME/.cache/를 사용하므로, 다운로드는 한 번만 이루어지면 됩니다.

stable diffusion으로 실험해 보기

새 시스템을 시험해 보기 위해 stable diffusion의 추론 파라미터를 가지고 실험해 보겠습니다. 기본 프롬프트와 적절한 파라미터로 간단한 stable diffusion 추론 작업을 실행하려면 다음 명령을 실행하세요:
wandb launch -d wandb/job_stable_diffusion_inference:main -p <target-wandb-project> -q <your-queue-name> -e <your-queue-entity>
위 명령은 컨테이너 이미지 wandb/job_stable_diffusion_inference:main을(를) 큐에 제출합니다. 에이전트가 작업을 가져가 클러스터에서 실행하도록 스케줄하면, 네트워크 상태에 따라 이미지를 가져오는(pull) 데 다소 시간이 걸릴 수 있습니다. 작업 상태는 wandb.ai/launch의 큐 페이지(또는 wandb 서버 사용자의 경우 <your-wandb-url>/launch)에서 확인할 수 있습니다. 실행이 완료되면 지정한 프로젝트에 작업 아티팩트가 생성됩니다. 프로젝트의 작업 페이지(<project-url>/jobs)에서 작업 아티팩트를 확인할 수 있습니다. 기본 이름은 job-wandb_job_stable_diffusion_inference이지만, 작업 이름 옆의 연필 아이콘을 클릭해 작업 페이지에서 원하는 이름으로 변경할 수 있습니다. 이제 이 작업을 사용하여 클러스터에서 Stable Diffusion 추론을 더 실행할 수 있습니다. 작업 페이지에서 오른쪽 상단의 Launch 버튼을 클릭해 새로운 추론 작업을 구성하고 큐에 제출할 수 있습니다. 작업 구성 페이지에는 원래 실행에서 사용된 파라미터가 미리 채워져 있지만, launch drawer의 Overrides 섹션에서 값을 수정하여 원하는 대로 변경할 수 있습니다.
Launch UI