たった2つのライブラリで、docker-compose内のコンテナでGPUを走らせ、最短の労力で開発を進める方法(2020年2月2日確認)


docker-composeを使う理由

docker-composeはみなさん使ってますか?

docker-composeはdocker runの際のoptionを全てyamlファイルで記述することができ、再現性を高めることができます。しかし、docker-compose内でnvidia-smiを走らせる、GPUを使うには一手間いるので今回は紹介したいと思います。

僕はoptunaHyperparameter Tuningするときに、探索結果を保存するmysqlのコンテナを立ち上げる必要があり、今回調査しました。


単純に、container内でgpuを走らせる場合は docker run に --gpus というオプションがあって、すぐに走らせられます。
hotoさんの記事mahoroiさんの記事が分かりやすかったです。
19.03以降のdockerに実装されたオプションのようで、詳しくはNTT Labのこちらの記事から

しかし、docker-compose内でGPUを走らせるには、
いろいろ詰まりどころがあったので、つまったところを詳しく解説します
@hgojさんの記事@verb55さんの記事を参考にさせていただきました。

この記事の要約

  • nvidia周りのdockerは開発サイクルが早く、情報が乱立している。
  • docker, docker-composeだけでなく、nvidia-docker, nvidia-container-runtimeも入れましょう
  • stackoverflow や githubのissueは偉大

概要

  1. nvidia-dockerのインストール
  2. nvidia-container-runtimeのインストール
  3. nvidia-docker2のインストールと/etc/docker/daemon.jsonの設定
  4. docker-compose.ymlとDockerfileの準備
  5. 出くわしたエラー

 環境

OS           : 18.04.3 LTS (Bionic Beaver)
docker       : 19.03.5
Cuda         : 10.1
nvidia-driver: nvidia-driver-440
cuDNN        : 7.6.5.32-1+cuda10.1
GCC          : 8.3.0 

前提条件

NvidiaDriver等、docker-compose, dockerが入っていて、GPUを回せる状態にあること 

1. nvidia-dockerのインストール

Githubの公式サイト通りにします。

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
sudo apt-get update && sudo apt-get install -y nvidia-container-toolkit
sudo systemctl restart docker

unknown flag: --gpusのエラーはdockerのアップデートで解決

2. nvidia-container-runtimeのインストール

こちらもGithubの公式サイトから

curl -s -L https://nvidia.github.io/nvidia-container-runtime/gpgkey | \
  sudo apt-key add -
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-container-runtime/$distribution/nvidia-container-runtime.list | \
  sudo tee /etc/apt/sources.list.d/nvidia-container-runtime.list
sudo apt-get update
sudo apt-get install nvidia-container-runtime

3. nvidia-docker2のインストールと/etc/docker/daemon.jsonの設定

ここが一番詰まったところです。このコメントコメントで解決しました。

sudo apt-get install nvidia-docker2 
sudo systemctl daemon-reload
sudo systemctl restart docker
{
    "runtimes": {
        "nvidia": {
            "path": "/usr/bin/nvidia-container-runtime",
            "runtimeArgs": []
        }
    }
}

nvidia-docker2のインストールでファイルに自動的に書き込まれるため、こちらの設定はいらなくなりました。
一行目の"default-runtime": "nvidia",の追加だけ、必要です。stackoverflowの記事

{
    "default-runtime": "nvidia",
    "runtimes": {
        "nvidia": {
            "path": "/usr/bin/nvidia-container-runtime",
            "runtimeArgs": []
        }
    }
}

4. docker-compose.ymlとDockerfileの準備

FROM python:3.7

RUN \
  apt-get update && \
  pip install torch numpy 
docker-compose.yml
version: '2.3'

services:
  app:
    build: .
    runtime: nvidia
    environment:
      - NVIDIA_VISIBLE_DEVICES=all
      - NVIDIA_DRIVER_CAPABILITIES=all
    volumes:
      - .:/workdir
    working_dir: /workdir
    tty: true

5. 出くわしたエラー

1つ目 unknown flag: --gpus

19.03以降にアップデートする
Githubのissueを参考にしました。

sudo apt-get install docker-ce-cli

2つ目 Unknown runtime specified nvidia

dockerの再起動で解決

sudo systemctl daemon-reload
sudo systemctl restart docker

GitHubのIssueを参考にしました

感じたこと

  • nvidia-docker-composeを使う選択肢もあったけど、公式じゃないので敬遠しました
  • 19:03以降で、nvidia-docker2以外を使って、docker-composeする方法があったら、誰か教えてください。
  • 本当にdockerを理解したいなら、ドキュメントやrelease noteを読まないといけないなと、

以上、最後まで読んでいただき、ありがとうございました。