- Published on
Kubernetes에서 GPU 사용하기
- Authors
- Name
- Jay
container에서 GPU 사용하도록 설정
digialocean에서 설명된 방법으로 Docker를 Ubuntu20.04에 설치를 하였다.
sudo apt install -y apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"
apt-cache policy docker-ce
sudo apt install -y docker-ce
이제 gpus를 사용해서 docker container를 아래처럼 실행한다.
sudo docker run -it --runtime=nvidia --gpus all python:3.9 bash
하지만 아래와 같은 에러 메세지와 함께 nvidia로 설정하여 실행할 수가 없다.
docker: Error response from daemon: unknown or invalid runtime name: nvidia.
See 'docker run --help'
Container에서 nvida driver를 사용할 수 있도록 nvidia-container-toolkit을 설치해야 한다. 문서에 나온 것처럼 아래와 같이 설치를 한다.
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \
&& curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list \
&& \
sudo apt-get update
sudo apt-get install -y nvidia-container-toolkit
sudo nvidia-ctk runtime configure --runtime=docker
docker config 파일이 아래처럼 nvidia-container-runtime
을 사용하도록 설정된 것을 확인할 수 있다.
$ sudo cat /etc/docker/daemon.json
{
"runtimes": {
"nvidia": {
"args": [],
"path": "nvidia-container-runtime"
}
}
해당 config가 적용될 수 있도록 docker daemon을 재시작한다.
sudo systemctl restart docker
이제 runtime option을 nvidia로 설정을 해도 정상적으로 실행이 될 수 있다.
sudo docker run -it --runtime=nvidia --gpus all python:3.9 bash
pytorch 사용해보기
이제 pytorch를 containerization을 해서 사용해본다. 먼저 nvidia-smi
로 CUDA version을 확인한다.
$ nvidia-smi
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 470.199.02 Driver Version: 470.199.02 CUDA Version: 11.4 |
|-------------------------------+----------------------+----------------------+
| 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 On | 00000000:00:05.0 Off | Off |
| N/A 27C P8 8W / 70W | 0MiB / 16127MiB | 0% Default |
| | | N/A |
+-------------------------------+----------------------+----------------------+
+-----------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=============================================================================|
| No running processes found |
+-----------------------------------------------------------------------------+
위에서처럼 CUDA version이 11.4
라고 하면, torch를 11.4
를 사용할 수 있도록 설치를 한다. 먼저 python 3.9 image로 container를 실행하고,
sudo docker run -it --runtime=nvidia --gpus all python:3.9 bash
원하는 버전의 package들을 설치한다.
pip install torch==1.12.1+cu113 torchvision==0.13.1+cu113 torchaudio==0.12.1+cu113 -f https://download.pytorch.org/whl/torch_stable.html
이제 torch가 설치가 완료되면 python interpreter를 실행해서 torch가 사용하는 CUDA version을 아래와 같이 확인한다. 아래처럼 11.3
값을 리턴하는 것을 확인할 수 있다.
>>> import torch
>>> torch.version.cuda
'11.3'
그리고 cuda를 사용가능한지 확인해보면 True
가 리턴되는 것을 확인 할 수 있다.
>>> torch.cuda.is_available()
True
CUDA version이 상위 버전이면 아래와 같은 에러 메세지가 발생한다.
import torch
>>> torch.cuda.is_available()
/usr/local/lib/python3.9/site-packages/torch/cuda/__init__.py:138: UserWarning: CUDA initialization: The NVIDIA driver on your system is too old (found version 11040). Please update your GPU driver by downloading and installing a new version from the URL: http://www.nvidia.com/Download/index.aspx Alternatively, go to: https://pytorch.org to install a PyTorch version that has been compiled with your version of the CUDA driver. (Triggered internally at ../c10/cuda/CUDAFunctions.cpp:108.)
return torch._C._cuda_getDeviceCount() > 0
False
Kubernetes에서 torch application을 실행하기
이제 kubernetes에서 pod로 container가 실행할 때 kubelet이 GPU를 사용하도록 설정을 해야 한다. Kubernetes에서는 device plugin를 제공하여 kubelet이 특정 device를 인지하고 사용할 수 있도록 한다. 따라서 NVIDIA에서 k8s-device-plugin을 제공한다.
device plugin을 DaemonSet object로 Host의 /var/lib/kubelet/device-plugins
경로에 mount하여 설정할 수 있다. 설치하는 DaemonSet의 manifest 파일을 확인하면 아래와 같다.
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: nvidia-device-plugin-daemonset
namespace: kube-system
spec:
selector:
matchLabels:
name: nvidia-device-plugin-ds
updateStrategy:
type: RollingUpdate
template:
metadata:
labels:
name: nvidia-device-plugin-ds
spec:
tolerations:
- key: nvidia.com/gpu
operator: Exists
effect: NoSchedule
# Mark this pod as a critical add-on; when enabled, the critical add-on
# scheduler reserves resources for critical add-on pods so that they can
# be rescheduled after a failure.
# See https://kubernetes.io/docs/tasks/administer-cluster/guaranteed-scheduling-critical-addon-pods/
priorityClassName: 'system-node-critical'
containers:
- image: nvcr.io/nvidia/k8s-device-plugin:v0.14.1
name: nvidia-device-plugin-ctr
env:
- name: FAIL_ON_INIT_ERROR
value: 'false'
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: ['ALL']
volumeMounts:
- name: device-plugin
mountPath: /var/lib/kubelet/device-plugins
volumes:
- name: device-plugin
hostPath:
path: /var/lib/kubelet/device-plugins
테스트하는 kubernetes cluster의 container runtime이 containerd
로 되어 있기 때문에, Docker 예제에서 한것처럼 문서를 따라서 아래와 같이 설정을 해준다.
sudo nvidia-ctk runtime configure --runtime=containerd
sudo systemctl restart containerd
그리고 마지막으로 테스트로 해당 Pod를 띄우면
$ cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: gpu-pod
spec:
restartPolicy: Never
containers:
- name: cuda-container
image: nvcr.io/nvidia/k8s/cuda-sample:vectoradd-cuda10.2
resources:
limits:
nvidia.com/gpu: 1 # requesting 1 GPU
tolerations:
- key: nvidia.com/gpu
operator: Exists
effect: NoSchedule
EOF
아래처럼 정상적으로 테스트를 통과한 Pod 로그를 확인할 수 있다.
Test PASSED
Done
이제 kubernetes에서 정상적으로 셋팅이 되었으니, GPU를 사용하여 torch application을 실행할 수 있다. 그런데 여기서 주의할 것은 kubeblet이 GPU hardware를 사용하도록 container을 실행할 때 아래와 같이 resource request/limit이 없으면 기본으로 CPU를 사용하도록 한다.
resources:
limits:
nvidia.com/gpu: 1 # requesting 1 GPU