GPU対応のDockerコンテナ作成

サーバ開発で当たり前のように使われるコンテナ技術(Docker等)ですが、GPUが絡んでくると最初の設定でつまづくことが多々あります。ここでは、こうやったらできたというのをメモとして残しておきたいと思います。

ホスト側のGPU設定

コンテナを作る前に、そのコンテナが動くホストのGPUが使える状態になっていないと、当然コンテナでも使えません。なので、まず初めにホスト側のGPUが使えるかの確認です。ホストOSはubuntuを前提に書きます。

GPUが使えるかどうかは、nvidia-smiコマンドで確認できます。これで、GPUの使用率などが表示されたら使える状態です。nvidia-smiコマンドが見つからない場合は、/usr/local/cuda等を探してみましょう。それでも入ってなさそうな場合は、cudaをインストールする必要があります。

CUDAのインストールは、ubuntu20.04の場合、

wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/cuda-keyring_1.1-1_all.deb
sudo dpkg -i cuda-keyring_1.1-1_all.deb
sudo apt-get update
sudo apt-get -y install cuda

と、1行ずつ実行すればインストールできます。

nvidia-smiコマンドもインストールされていると思います。nvidia-smiコマンドでGPUの情報が見られればOKです。

AWSのGPUインスタンスを使う場合は、AWSから提供されているDeepLearning Base AMI (ubuntu20.04)を使うと楽です。

GPUのDockerコンテナ作成

GPU対応のDockerコンテナを作成する場合、元となるイメージも普通のubuntuイメージではなく、nvidia/cudaのイメージを使う必要があります。

こちらのDocker Hubで、nvidia/cudaのイメージリストがありますので、この中から選んで docker pullすることでイメージをダウンロードでき、イメージからコンテナを作成できます。

作成したコンテナの中に入り、GPUが使えるように設定していきます。

まず、NVIDIA Container Toolkitをインストールします。

これはLinuxのDistributionごとにURLが変わるので、まずコンテナ内のLinuxのDistributionを見なければいけないです。

$ cat /etc/os-release

とすれば、OS情報が見れます。この中のIDとVERSION_IDをくっつけたものがDistribution名になります。

bashであれば、下記のコマンドで distributionという変数にDistribution名を格納できます。

$ distribution=$(. /etc/os-release;echo $ID$VERSION_ID)

そしてこの distribution変数を使って、curlでapt用のパッケージリストをとってきます。

$ 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
$ sudo apt update && sudo apt install -y nvidia-container-toolkit 

これで、dockerコンテナ起動時に、–-gpus all オプションをつければ、コンテナ内でGPUが利用できるようになっています。

$ docker run -it -d --gpus all --name [container_name] docker_image_name:tag
$ docker exec -it [container_name] sh

コンテナ内で nvidia-smiコマンドを実行して、GPU情報がでてくれば大丈夫です。

docker-composeでGPUコンテナを起動

docker-composeでコンテナを作成する場合は、–-gpusオプションと同等のオプションが無いため、もう少しやることがあります。

まず、nvidia-container-runtimeをインストールします。

$ sudo apt install nvidia-container-runtime

設定ファイルを /etc/docker/daemon.jsonに作成します。

{ "runtimes": 
  { "nvidia": 
    { "path": "nvidia-container-runtime", 
      "runtimeArgs": [] 
    } 
  } 
}

これで、docker-composeの設定ファイルで runtime: nvidia ができるようになります。

docker-compose.ymlの例を記載します。

version: '2.3'
services:
  [service_name]:
    image: [image_name]:[tag_name]
    container_name: [container_name]
    runtime: nvidia
    environment:
      - NVIDIA_VISIBLE_DEVICES=all
    tty: true
    ports:
      - 80:80
      - 443:443
    volumes:
    - /var/host:/var/docker

このdocker-compose.ymlファイルがある場所で、docker-compose up -d でコンテナを立ち上げて、コンテナ内で nvidia-smiを実行し、GPU情報が見れればコンテナ内でもGPUが使えます。

おまけ(コンテナ内の環境設定)

作りたてのコンテナでは、GPU以外にもいろいろとインストール・設定することがあると思います。これもメモですが、だいたいこのあたりは使うだろうというものを書いておきます。

コンテナ内がubuntuの例で書きます。

$ apt-get update

これはすでに上記のGPU設定でやってますが、一応書きます。これでいろいろ必要なものをインストールできるようになります。

あと、gccとかmakeとかも入ってないのでこのあたりの開発コマンドを入れます。

$ apt update 
$ apt install build-essential

pythonも使うなら、

$ apt-get install python3-distutils 
$ apt-get install python3-dev

pipのインストールは

$ apt-get install wget 
$ wget https://bootstrap.pypa.io/get-pip.py 
$ python3 get-pip.py

ここまでやれば、AWSでubuntuのEC2インスタンスを立ち上げたぐらいの状態になってると思います。

ただひとつ困ったことがありました。dockerのシェル上で、Ctrl-pが使えないのです。(dockerのdetachのコマンドのため) Ctrl-pは、ひとつ前のコマンドを実行したいときに多用するので、これが使えないと困ります。一応2回押せばできるんですが、そんなのは無理です。 上矢印キーでもできるんですが、手をホームポジションから動かすのは嫌です。

ですので、Ctrl-pを使えるようにします。

~/.docker/config.json の設定ファイルの中に

"detachKeys": "ctrl-\\"

と書いて、detach key をCtrl-pとは違うキーに割り当てます。これで、Ctrl-pが使えるようになります。

これでubuntuで遊べるようになりました。せっかくなので、この状態をイメージに保存しておきたいと思います。イメージとして保存しておけば、この状態からコンテナを作成できるようになります。

$ docker commit [container_name] [image_name]:[tag_name]

これで、このコンテナが、[image_name]で保存されて、[tag_name]というタグが付いています。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です