컨테이너 가상화 기술인 Docker는 다양한 웹 서비스 이외에도 여러 응용 어플리케이션 배포에 많이 사용된다. AI의 발달로 각종 GPU를 사용하는 서비스를 배포하기 위해 NVIDIA GPU를 Docker 위에서 사용해야할 소요는 늘어나고, 이를 위해 단순 도커 설치 뿐 아니라 NVIDIA가 제공하는 플러그인이 필요하다. 그것이 NVIDIA Container Toolkit
이다.
과거에는 nvidia-docker2
로 지원되었으나, 이는 초기버전의 도구이고 현재는 nvidia-container-toolkit
으로 제공되어 최신의 런타임을 지원하고 있다. 과거에 작성한 포스팅(하단 접혀있는 내용)은 nvidia-docker2
를 언급하고 있어, nvidia-container-toolkit
의 내용으로 최신화한다.
해당 내용은 docker
가 설치되어있다는 것을 전제로 한다.
설치 환경
본인의 작업환경이다.
- Docker Version: 27.1.2
- OS: Ubuntu 22.04
- GPU: NVIDIA RTX 3090 Ti
- NVIDIA-driver: 535.183.01
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
- 해당 작업으 ㅣ결과
/etc/apt/sources.list.d/nvidia-container-toolkit.list
파일에 GPG 키가 기록된다.
- 해당 작업으 ㅣ결과
- APT 업데이트 수행
$ sudp apt update
- 툴킷 설치
$ sudo apt install nvidia-container-toolkit
필수 설정
본인이 사용하는 컨테이너 엔진에 맞게 설정 적용 후 서비스를 재시작 해준다. 해당 포스팅의 경우엔 docker 를 사용하는 유저가 적용하면 된다.
$ sudo nvidia-ctk runtime configure --runtime=docker
$ sudo systemctl restart docker
테스트
nvidia-container-toolkit
의 옵션들을 적용하지 않았을 때와 적용했을 때의 결과를 비교해보자.
$ docker run --rm ubuntu nvidia-smi
실행 결과는 다음과 같다.
docker: Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "nvidia-smi": executable file not found in $PATH: unknown.
제대로 nvidia-container-toolkit의 옵션을 붙여서 실행하면 다음과 같다.
$ docker run --rm --runtime=nvidia --gpus all ubuntu nvidia-smi
>
+---------------------------------------------------------------------------------------+
| NVIDIA-SMI 535.183.01 Driver Version: 535.183.01 CUDA Version: 12.2 |
|-----------------------------------------+----------------------+----------------------+
| 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 NVIDIA GeForce RTX 3090 Ti Off | 00000000:01:00.0 On | Off |
| 0% 44C P8 30W / 450W | 987MiB / 24564MiB | 42% Default |
| | | N/A |
+-----------------------------------------+----------------------+----------------------+
+---------------------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=======================================================================================|
+---------------------------------------------------------------------------------------+
기본 런타임에 nvidia-container-toolkit 사용
2022년 12월 버전에도 언급했는데 모든 런타임을 nvidia 런타임을 사용하게 하는 설정이다.
/etc/docker/daemon.json
해당 파일을 열어 "default-runetime": "nvidia",
를 추가해주는 것이다. 콤마 부분 및 기존 내용을 지우지 않도록 조심하자.
{
"default-runtime": "nvidia",
"runtimes": {
"nvidia": {
"args": [],
"path": "nvidia-container-runtime"
}
}
}
해당 작업은 docker run ...
명령어 실행 시 --runtime=nvidia
부분을 생략하게 해주는 효과를 가진다. 다른 런타임 플러그인이 있다면 명시해야함에 주의하자.
GPU 직접 지정
과거에는 --gpus
다음에 숫자로 0
혹은 0,1
이런식으로 입력해서 지정할 수 있었는데 nvidia-container-toolkit
으로 넘어오면서 명세가 바뀐 부분이 있는 것 같다.
숫자 입력이 안먹힌다는 것은 아니고 아래 내용을 보자.
$ sudo docker run --rm --gpus 1 ubuntu nvidia-smi
$ sudo docker run --rm --gpus '"device=0"' ubuntu nvidia-smi
이 두 명령어가 동작이 같다. --gpus
뒤에 0
을 넣으면 작동이 되지 않았다. nvidia 측의 도큐먼트를 보니 숫자로는 GPU의 개수를 의미하는 것으로 확인된다. 그래서 특정 GPU를 언급하려면 "device=0"
과 같은 형식으로 붙여 쓰는 것이 좋겠다.
혹은 환경변수를 이용한 통제를 해보고 싶다면 다음과 같이도 사용 가능하다.
sudo docker run --rm -e NVIDIA_VISIBLE_DEVICES=0 ubuntu nvidia-smi
다양한 선택지가 있으니 공식 문서와 항상 가까이하여 여러 방법을 찾아보자.
Reference
Specialized Configurations with Docker
Installing the NVIDIA Container Toolkit
Running a Sample Workload
2022년 12월 버전
Docker 를 설치하고 나면 기본적으로 컨테이너에서 원하는 작업을 수행 할 수 있게 된다. 그러나 격리된 컨테이너에서 GPU를 사용하는 AI/ML/DL 관련 작업을 하려고 하면 nvidia-smi
를 터미널에서 입력해도 GPU 자원을 사용할 수 없기 때문에 작업을 진행 할 수 없다. 이를 해결 해 줄 수 있는 것이 Nvidia-docker
다. 설치를 후 조금의 옵션을 추가하면 자신의 컨테이너에서 GPU를 사용할 수 있다.
설치 환경
- Docker Version: 20.10.5
- OS/Arch: linux - Ubuntu 18.04 / amd64
- GPU: Nvidia Geforce RTX 3090
- Nvidia-driver: 460.73.01
- CUDA: 11.1
요구 환경
- Linux x86_64 커널 버전 > 3.10
- Docker >= 19.03
- NVIDIA GPU with Architecture >= Kepler (or compute capability 3.0)
- Kepler GPU 아키텍쳐는 GTX 600 시리즈 이상이면 된다.
- NVIDIA Linux drivers >= 418.81.07
도커 설치
도커 프로그램에 대한 설치는 이전에 포스팅했던 우분투 도커 설치하기 포스팅을 참고한다.
설치
저장소 및 GPG 키 설정
$ distribution=$(. /etc/os-release;echo $ID$VERSION_ID) \
&& curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add - \
&& curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
Nvidia-docker install
$ sudo apt-get update
$ sudo apt-get install -y nvidia-docker2
docker 서비스 재시작
$ sudo systemctl restart docker
여기까지 실행하였다면 어떤 도커 이미지라도 컨테이너 실행하여서 제대로 설치가 되었는지 테스트를 해볼 수 있다.
나는 테스트로 Ubuntu 18.04
이미지를 컨테이너로 실행하여 테스트 하였다. GPU 사용을 위해 추가한 부분은 --gpus all
이다
docker run --rm --gpus all ubuntu:18.04 nvidia-smi
결과는 다음과 같이 확인할 수 있다.
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 460.73.01 Driver Version: 460.73.01 CUDA Version: 11.2 |
|-------------------------------+----------------------+----------------------+
| 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 GeForce RTX 3090 Off | 00000000:01:00.0 On | N/A |
| 48% 44C P8 36W / 370W | 671MiB / 24267MiB | 4% Default |
| | | N/A |
+-------------------------------+----------------------+----------------------+
+-----------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=============================================================================|
+-----------------------------------------------------------------------------+
GPU 자원을 사용하며 도커 실행
컨테이너 실행 시
Docker 를 실행할 때 GPU 자원을 사용하는 방식은 대략 2가지정도를 설명할 수 있다.
- 첫 번째는
--gpus
옵션을 주는 것.--gpus
사용 사용 예제는 다음과 같다. 예제에 사용된 컨테이너 이미지는Ubuntu:18.04
로 한다.docker run --rm --gpus all ubuntu:18.04 nvidia-smi
- 특정 gpu만을 지정하여 사용하려면
all
대신 디바이스 번호인0
,1
등으로 지정해주면 된다.docker run --rm --gpus 0 ubuntu:18.04 nvidia-smi
- 두 번째는
--runtime
과 환경변수로-e NVIDIA_VISIBLE_DEVICES
옵션을 주는 것.--runtime
사용 해당 옵션을 사용할 때는 환경변수NVIDIA_VISIBLE_DEVICES
를 같이 준다.docker run --rm --runtime=nvidia -e NVIDIA_VISIBLE_DEVICES=all ubuntu:18.04 nvidia-smi
- 해당 옵션 또한 특정 GPU 디바이스를 지정할 수 있다.
docker run --rm --runtime=nvidia -e NVIDIA_VISIBLE_DEVICES=0 ubuntu:18.04 nvidia-smi
기본으로 nvidia runtime을 사용하게 하기
docker build
명령어를 통해 도커 이미지를 사용할 때 가끔 GPU 자원이 필요한 경우가 있다. 이때는docker run
명령어가 아니라서 빌드 시 GPU 자원을 사용하게 해주기가 쉽지 않다. 다음과 같이 해결 가능하다.
$ sudo systemctl stop docker
$ sudo systemctl stop docker.socket
$ sudo vi /etc/docker/daemon.json
다음 문구를 추가해준다. 앞선 설정이 있다면 콤마(,
)를 붙이고 넣어준다.
"default-runtime": "nvidia"
도커를 재시작한다.
$ sudo systemctl start docker
댓글남기기