LoginSignup
3
5

More than 3 years have passed since last update.

深層学習用Dockerを作る際の注意点

Last updated at Posted at 2020-12-13

はじめに

Dockerの利用の主なターゲットとしてはWebサービスの運用などが想定されているように思えます。
よってあまり書かれていない微妙に注意が必要な点があったので良い機会なので書き留めていこうと思います。

GPUとの連携

NVIDIAのGPU関係との連携はネイティブのDockerではサポートされておらず、nvidia-dockerを入れる必要があります。
インストールにあってはNVIDIAの佐々木さんの書いた
NVIDIA Docker って今どうなっているの?が最新の情報をフォローしていていいように思えます。
最新の情報的には nvidia-docker2を入れればOKになっています。

イメージ

基本的にはpytorch/tensorflowの公式のイメージを使いましょう。

pythonバージョン指定問題

再現性を確保するために公式のイメージでは足りない場合、pythonをビルドしたりする必要があります。なんか苦戦した覚えがあったのでメモしておこうと思ったのですが、最近はわかりやすいページができていました。pyenvを使ってビルドするのが手軽なように思えます。
https://www.python.jp/install/build_python_unix.html

Docker内でのnvidia-smiの結果について

nvidia-smiを使うとCUDAのバージョンが表示されますが、これはDocker内で有効化されているCUDAのバージョンとは何も関係なく、ドライバーがサポートするCUDAのバージョンが表示されるだけのようなので、意味がないです。nvidia-dockerを使うモチベーションのひとつに古いCUDAのライブラリを使いたいというものがあるので混乱しがちなので注意しましょう。
バージョンを見たい場合はnvcc -Vやインストールされているパスを確認するのが一般的なようです。

CUDAを使ったビルドについて

デフォルトではdocker buildの間に、CUDAなどを使うことができません。これはpytorch/tensorflowなどを使っている場合は問題ないですが、独自にライブラリをビルドしたかったりする場合は不便です。これは/etc/docker/daemon.jsonでデフォルトのランタイムをいじることで解決します。
https://stackoverflow.com/questions/59691207/docker-build-with-nvidia-runtime

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

docker-composeの利用

正直言って、composeは深層学習用には不要かもしれないです。composeは複数のコンテナを建てなければいけないような状況に向けて作られており、単に適当に学習させるコンテナを建てるだけならオーバースペックの感もあり、さらにnvidiaランタイムとの相性はイマイチです。
composeの利用には

さてcomposeはyamlファイルは結構独特のフォーマットで、最初に使ったときは混乱した覚えがあります。yamlファイルを扱ったことのない人は一度シンタックスを確認しておくとよいでしょう。

composeで出来ることは基本的にコマンドラインからできるので、適当なシェルスクリプトを作った方が良いというシチュエーションもあるかもしれないということを踏まえつつ書きます。

    runtime: nvidia
    environment:
      - NVIDIA_VISIBLE_DEVICES=all
      - NVIDIA_DRIVER_CAPABILITIES=all

複数米のGPUのうち一部のGPUのみ使いたい場合は

runtime: nvidia
environment:
- NVIDIA_VISIBLE_DEVICES=0,1
- NVIDIA_DRIVER_CAPABILITIES=all

などのように書きます。

ボリュームマウント

ボリュームのマウント方法

学習用として使いたい場合、結果をコンテナの外に出力したくなります。またデータセットをマウントしたくなることがあります。このためにはVolumeのマウントが必要です。
Dockerのvolumeのマウント方法には二通りの方法があり、一つが-v/-volume オプションもう一つが--mountオプションです。--mount オプションは-vオプションの上位互換です。docker-composeだとこちらの方が読みやすい気がするのでこちらがおすすめです。
以下mountオプションについて軽く説明します。mountにはbind/volume/mountの三つのオプションがあります。

bind

おそらく機械学習などで使う際には手軽に使うにはbindが便利です。bindはsrcのパスを直接Docker上にマウントできるものです。データセットのマウント、結果用フォルダのマウント両方できます。

mount

volumeは書き込んだデータがDocker専用になるので、外から使う時に面倒です。またコンテナ外データを参照するといった作業にも不向きです。
ただしDocker間でデータを共有したい、などの時にはより推奨されるオプションのようです。

tmpfs

tmpfsはメモリ上に一時的なディレクトリを作るというもので、保存には使えないです。

詳細は公式ドキュメントを読むといいでしょう。この三つのページとても似ているため非常に判別がつきにくいです。。。

Owner 問題

しかしDockerでコンテナにログインすると基本はrootとしてログインすることになります。その状態でファイルを生成するとファイルの権限がrootになってしまいコンテナ外からデータの読み書きをしたい際に非常に不便です。そのため、Dockerfile内にユーザーを作ってログインをしたいところですが、Dockerfileにログインユーザー名を書くと再利用性が下がる懸念があります。

この問題にはdockerでvolumeをマウントしたときのファイルのowner問題が参考になりました。
最も手軽なのは/etc/group/etc/passwdをマウントしてしまう方法です。
/etc/passwdと聞くと何かパスワード関連のファイルをマウントしている感じがあり怪しげですが、最近のディストリビューションでは/etc/passwdにパスワードは書いていないことが多いので特に問題はないです。ログインの際に使わなければいけないファイルなので全てのユーザーが読むこともできます。
-v /etc/group:/etc/group:ro -v /etc/passwd:/etc/passwd:ro

何で開発するか問題

VSCodeを使うと、リモートマシン(例えば計算用のサーバー)で走っているコンテナに直接アクセスできます。ただし、こちらもコンテナのホームディレクトリにプログラムを転送してリモート実行するため、一度ルートで立ち上げた後、ユーザー権限でログインしようとするとアップデートに失敗してログインできなくなるのような現象が起きたりするので注意です。
ssh接続先のdockerコンテナにVSCodeのRemote Developmentで繋ぐ
なんかが参考になります

その他

ライセンスの関係でMujocoが使えないので深層強化学習には使いにくかったりします。
Dockerは機械学習用に緩く使っているためあまり良くない習慣なども書いてしまったりしているかもしれないので指摘をお願いしたいです。

参考

3
5
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
5