컨테이너 가상화 기술인 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가지정도를 설명할 수 있다.

  1. 첫 번째는 --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
      
  2. 두 번째는 --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


댓글남기기