はじめに
研究をやっていると
- 査読対応のために実験を追加したいが,環境をいじってしまっている
- 既存手法を実行するために,tensorflowの特定のバージョンを使いたい.それに伴って特定のバージョンのcudaをインストールしなければならない
みたいなことが発生する. pythonだけならcondaやpipenvでなんとかなるが,cudaなどが絡んでくると色々めんどくさくなる.
そこで,Dockerを使って環境を構築することでこの問題を解決することを試みる. もう1台のパソコンや会社のPCで同じことをやるので記録を残す.
cuda+dockerで検索するとnvidia-docker2を使うように書いてある記事がたくさんヒットするが,公式によると,nvidia-docker2はdepercatedでDocker 19.03以降はnvidia-container-toolkitを入れればいいらしい.
環境
家のパソコン
- Ubuntu18.04
- GeForce GTX 750 Ti, Core(TM) i7-7700 CPU
- Docker version 19.03.1, build 74b1e89
gpuが年季入ってる感じなので不安だったけど大丈夫だった.
作りたい環境
- cuda+pytorchの環境をjupyter notebook上で実行する
- 作ったファイルはホスト上から参照,編集できるようにする
以下では,ほぼクリーンなubuntuに順番に環境を作っていく.
nvidia-driverのインストール
Dockerを使う場合でも,ホスト側にnvidiaのドライバを入れておく必要がある. 今どきはaptでいれると普通に動いてくれるので良い. ubuntu-driversでrecommendされたバージョンをインストールする.
sudo add-apt-repository ppa:graphics-drivers/ppa sudo apt update ubuntu-drivers devices sudo apt install nvidia-driver-430 # recommended
参考:
Dockerのインストール
公式Documentに従ってインストールしていく.
sudo apt install apt-transport-https ca-certificates curl gnupg-agent software-properties-common curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" sudo apt install docker-ce docker-ce-cli containerd.io sudo docker info
参考:
docker groupの設定
docker groupにuserを追加しておくと,管理者権限なしにdockerを実行できるようになる. dockerグループにはセキュリティ上の問題があると言っている記事もあるので,やらないほうがいいのかもしれないが理解できていないので,あまり検討できてない.
sudo gpasswd -a $USER docker sudo reboot
本当はログアウトして再度ログインするだけでいいはずだけど,自分の環境では再起動するまでgroupがうまく変更されていなかった.
ubuntu何もわからんになってる pic.twitter.com/SepQg6OKJP
— けいの (@ksknw) 2019年8月31日
docker hubのアカウント作成/ログイン
docker hubには様々なレポジトリが公開されており,これを利用することで誰かが作った色々盛り盛りの環境をさくっと利用することができる. 今回はnvidiaが公開しているものが使いたいので,これに登録,ログインしておく. ログインは以下のようにしてコマンドラインから実行する.
docker login
nvidia-container-toolkit のインストール
cuda+dockerで検索するとnvidia-docker2を使うように書いてある記事がたくさんヒットするが,公式によると,nvidia-docker2はdepercatedでDocker 19.03以降はnvidia-container-toolkitを入れればいいらしい.
最近またdocker2を入れる方法に変わったらしい。なんにせよ公式にその時書かれている手順に従うのが良い
Note that with the release of Docker 19.03, usage of nvidia-docker2 packages are deprecated since NVIDIA GPUs are now natively supported as devices in the Docker runtime.
Documentに従って,nvidia-container-toolkitをインストールする.
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
docker build/run
以下では色々書いているけどnvidiaが公開しているDockerイメージをpullして使うと万事オッケーだと思う nvidiaが公開しているdocker image
ここでは勉強も兼ねて自分でDockerfileを以下のように作る.
FROM nvidia/cuda:10.1-cudnn7-devel-ubuntu18.04 ARG USERNAME RUN apt-get update RUN apt-get -y upgrade RUN apt-get -y install python3 RUN apt-get -y install python3-pip RUN apt-get -y install nano wget curl RUN pip3 install jupyter click numpy matplotlib seaborn pandas tqdm RUN pip3 install torch torchvision RUN useradd -m -s /bin/bash ${USERNAME} USER ${USERNAME} RUN jupyter notebook --generate-config \ && sed -i.back \ -e "s:^#c.NotebookApp.token = .*$:c.NotebookApp.token = u'':" \ -e "s:^#c.NotebookApp.ip = .*$:c.NotebookApp.ip = '0.0.0.0':" \ -e "s:^#c.NotebookApp.open_browser = .*$:c.NotebookApp.open_browser = False:" \ /home/${USERNAME}/.jupyter/jupyter_notebook_config.py WORKDIR /home/${USERNAME}
参考:
これをおいたフォルダで以下のようにしてイメージをビルドする.
docker build ./ --build-arg USERNAME=$USER -t notebook
ここではbuildの際にホスト側と同じユーザー名のユーザーを作っている. これによって,docker内で作ったファイルが,ホスト側で編集できるようになる. こちらにやると,別のマシンでビルドしたものを使うときにはこれだとだめらしいが,自分のマシンでしか使わないので,これでオッケー -tはイメージの名前なので何でも良い.
RUNしてみて,コンテナからGPUが見えることを確認する.
docker run --gpus all --rm notebook nvidia-smi
ちゃんと動いていることが確認できた.
次にbashを実行してみる.
- -itオプションをつけると,docker上でインタラクティブに操作できる.
- また,-vでホームディレクトリをdocker内のhostディレクトリにマウントしておく.
- -pはdockerのポートをホストのポートに飛ばすオプションで,jupyterを起動するポートをホストに飛ばしておく. これによって,docker上で起動したjupyterにホスト側からアクセスできるようになる.
docker run --gpus all --rm -v /home/kei:/home/kei/host -p 127.0.0.1:8888:8888 -it notebook bash
あとは普通にjupyter notebookを立ち上げると,いつもと同じようにホスト側のブラウザからlocalhost:8888にアクセスするだけで操作できる. bashを実行しているので,pythonを実行してもよい.
一応動作確認.
家でやる場合はないけど,リモートサーバーでたてたdocker上のjupyter notebookにアクセスするときは,sshで入るときにポートフォワードすればよい.
参考:
おわりに
- dockerを使うのはほぼ初めてなので,何か間違っているかもしれない.
- 毎回--rmをつけてコンテナを使い捨てにするのが再現性的にはいいかなと思っている.
- nvidia-docker2周りが最近変わったばかりっぽく,nvidia-docker2を入れろと書いてあるブログが多々あって混乱した.
- これからはプロジェクトごとにDockerfileを作る感じでやっていきたい.
参考
- Ubuntu Linux 18.04にGPUドライバをインストールする|setoyama60jp|note
- Redirecting…
- https://qiita.com/matyapiro31/items/3e6398ce737e2cdb5a22
- Docker Hub
- GitHub - NVIDIA/nvidia-docker: Build and run Docker containers leveraging NVIDIA GPUs
- リモートサーバ上の Docker コンテナで Jupyter Notebook を使う - CUBE SUGAR CONTAINER
- dockerでvolumeをマウントしたときのファイルのowner問題 - Qiita
- sshポートフォワーディング - Qiita