我尝试使用TensorFlow的Docker(Docker入门)
初次使用Docker时的备忘录(适用于初学者)。由于无法直观了解Docker Hub上提供的Docker内容,因此也记录了有关Tensorflow的Docker环境的备忘。尝试使用Tensorflow官方网站提供的Docker镜像。(截至2018/11/24)
-
- 2019/3/9: Tensorflow 2.0 Alpha版向けに更新。
- 2021/2/21: 現状のTensorflow 2.0 に合わせて1章、2章を更新。DockerのUbuntuが16.04から18.04になり(May 20 2019以降に切り替わった)、デフォルトのpythonが2系から3系になっている。
行动环境
宿主机使用 macOS High Sierra。
$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.15.7
BuildVersion: 19H114
1. 安装 Docker
从Docker的官方网站上下载Docker.dmg文件。在此过程中需要创建一个Docker Store的账户,因此先创建账户再进行下载。打开dmg文件,将其移动到Application文件夹中进行安装。启动Docker.app应用程序。在菜单栏中会出现一个鲸鱼图标,表示可以使用docker命令。
$ docker -v
Docker version 20.10.2, build 2291f61
(注意:内存)默认情况下,分配的内存为2GB。使用Tensorflow进行训练时,2GB的内存是不够的,所以可以通过菜单栏的鲸鱼图标选择“首选项…”→“资源”→“高级”→“内存”来增加分配。还可以适时更改CPU的分配数量。
(注意:磁盘大小)docker使用的磁盘空间可以通过选择“首选项…”→“资源”→“磁盘镜像位置”来设置位置,通过选择“磁盘镜像大小”来设置大小。默认情况下,会创建一个名为~/Library/Containers/com.docker.docker/Data/vms/{int}/data/Docker.raw的60GB文件,并被使用。
运行Tensorflow的docker。
2-1. 启动Docker
根据TensorFlow官方网站的指南尝试启动Docker。在TensorFlow的Docker Hub上查看,发现有许多不同的标签可供选择。由于我想要(传统的)CPU+Jupyter版本,因此我选择了latest-jupyter标签。
$ docker pull tensorflow/tensorflow:latest-jupyter #最新イメージ(Jupyter付き)をダウンロード
$ docker run -it -p 8081:8888 tensorflow/tensorflow:latest-jupyter # Start a Jupyter notebook server
启动后将显示如下内容。
[I 15:54:34.087 NotebookApp] Writing notebook server cookie secret to /root/.local/share/jupyter/runtime/notebook_cookie_secret
jupyter_http_over_ws extension initialized. Listening on /http_over_websocket
[I 15:54:34.268 NotebookApp] Serving notebooks from local directory: /tf
[I 15:54:34.269 NotebookApp] Jupyter Notebook 6.2.0 is running at:
[I 15:54:34.269 NotebookApp] http://2d5f2a274659:8888/?token=3a7bd5d12e8861bb64e008064170ed0648e4197e21feeed7
[I 15:54:34.269 NotebookApp] or http://127.0.0.1:8888/?token=3a7bd5d12e8861bb64e008064170ed0648e4197e21feeed7
[I 15:54:34.269 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
[C 15:54:34.274 NotebookApp]
To access the notebook, open this file in a browser:
file:///root/.local/share/jupyter/runtime/nbserver-1-open.html
Or copy and paste one of these URLs:
http://2d5f2a274659:8888/?token=3a7bd5d12e8861bb64e008064170ed0648e4197e21feeed7
or http://127.0.0.1:8888/?token=3a7bd5d12e8861bb64e008064170ed0648e4197e21feeed7
当我查看Tensorflow的版本时,发现它是2.4.1。
import tensorflow as tf
print(tf.__version__)
在Docker终端上进行操作.
确认Docker的状态。
在启动Docker时,一个终端被使用(默认情况下,run命令在前台运行),因此需要打开另一个终端来检查正在运行的容器的状态。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2d5f2a274659 tensorflow/tensorflow:latest-jupyter "bash -c 'source /et…" 6 minutes ago Up 6 minutes 0.0.0.0:8081->8888/tcp mystifying_khorana
使用显示的容器名称mystifying_khorana。如果在首次运行时没有使用–name指定名称,则会自动分配名称。这次它被命名为mystifying_khorana。
2-2-2. 登录到Docker终端
为了在Docker上进行操作,使用bash进入Docker。
$ docker exec -it mystifying_khorana bash
确认操作系统。Tensorflow提供的docker使用的操作系统是Ubuntu 18.04。
# cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic
DISTRIB_DESCRIPTION="Ubuntu 18.04.5 LTS"
这个描述是假设在Python3上运行的,并且自Ubuntu 18.04版开始已经弃用了以前的-py3选项(来自Docker Hub的描述)。
# python --version
Python 3.6.9
Package Version
———————- ———
absl-py 0.11.0
argon2-cffi 20.1.0
asn1crypto 0.24.0
astunparse 1.6.3
async-generator 1.10
attrs 20.3.0
backcall 0.2.0
bleach 3.2.2
cachetools 4.2.0
certifi 2020.12.5
cffi 1.14.4
chardet 4.0.0
cryptography 2.1.4
cycler 0.10.0
decorator 4.4.2
defusedxml 0.6.0
entrypoints 0.3
flatbuffers 1.12
gast 0.3.3
google-auth 1.24.0
google-auth-oauthlib 0.4.2
google-pasta 0.2.0
grpcio 1.32.0
h5py 2.10.0
idna 2.6
importlib-metadata 3.4.0
ipykernel 5.1.1
ipython 7.16.1
ipython-genutils 0.2.0
ipywidgets 7.6.3
jedi 0.18.0
Jinja2 2.11.2
jsonschema 3.2.0
jupyter 1.0.0
jupyter-client 6.1.11
jupyter-console 6.2.0
jupyter-core 4.7.0
jupyter-http-over-ws 0.0.8
jupyterlab-pygments 0.1.2
jupyterlab-widgets 1.0.0
Keras-Preprocessing 1.1.2
keyring 10.6.0
keyrings.alt 3.0
kiwisolver 1.3.1
Markdown 3.3.3
MarkupSafe 1.1.1
matplotlib 3.3.3
mistune 0.8.4
nbclient 0.5.1
nbconvert 6.0.7
nbformat 4.4.0
nest-asyncio 1.4.3
notebook 6.2.0
numpy 1.19.5
oauthlib 3.1.0
opt-einsum 3.3.0
packaging 20.8
pandocfilters 1.4.3
parso 0.8.1
pexpect 4.8.0
pickleshare 0.7.5
Pillow 8.1.0
pip 20.2.4
prometheus-client 0.9.0
prompt-toolkit 3.0.13
protobuf 3.14.0
ptyprocess 0.7.0
pyasn1 0.4.8
pyasn1-modules 0.2.8
pycparser 2.20
pycrypto 2.6.1
Pygments 2.7.4
pygobject 3.26.1
pyparsing 2.4.7
pyrsistent 0.17.3
python-dateutil 2.8.1
pyxdg 0.25
pyzmq 21.0.1
qtconsole 5.0.2
QtPy 1.9.0
requests 2.25.1
requests-oauthlib 1.3.0
rsa 4.7
SecretStorage 2.3.1
Send2Trash 1.5.0
setuptools 51.3.3
six 1.15.0
tensorboard 2.4.1
tensorboard-plugin-wit 1.8.0
tensorflow 2.4.1
tensorflow-estimator 2.4.0
termcolor 1.1.0
terminado 0.9.2
testpath 0.4.4
tornado 6.1
traitlets 4.3.3
typing-extensions 3.7.4.3
urllib3 1.26.2
wcwidth 0.2.5
webencodings 0.5.1
Werkzeug 1.0.1
wheel 0.36.2
widgetsnbextension 3.5.1
wrapt 1.12.1
zipp 3.4.0
由于在此之前的文章中,列出了 Ubuntu 16.04 版本时的 apt list 结果,而在 Ubuntu 18.04 版本中安装的软件数量大大增加,导致列表变得非常庞大,所以省略了。
附言:使用Docker来配置GPU资源
TensorflowはGPUとともに使うことが多く、tensorflowのdockerでは-gpuを設定してdocker runする必要があるが、その場合はnvidia-dockerが必要となる。macOS(High Sierra, 10.13.6時点)ではnVidiaのGPUが正式サポートされていない。WindowsではWindows Insider ProgramのDevチャンネルで最新のWindows10(2021-02-21現在、OS Build:21318.1000)にし、DockerでWSL2バックエンドを選択することで–gpus allオプションが利用できるようになる。nvidia-dockerが使えないことから、結局、dockerの場合はホストOSにUbuntuなどLinux系を使わないとGPUが使えない。macOSやWindows上で、CPUベースでのTensorflowを使った動作確認する程度であれば、dockerは便利かもしれない。TensorflowをGPU有効にして使う場合は、Windowsの場合はGPU対応されている(Dockerではなく)NativeなTensorflowを使う必要がある。macOSは今のところGPUを使った機械学習には不利な印象。
2020.06.01追記: Linuxの場合、Docker ver.19.03(2019-07-22) 以降とnvidia-container-toolkitを利用することで、docker run –gpus all –rm nvidia/cuda nvidia-smiのように–gpusオプションで、GPUが利用できるため、nvidia-dockerは不要になったようです。また、Singularityを使う方法もあります。
2021.02.21追記: Windowsの場合、Dockerではなく直接Tensorflowを使うか、Windows 10 Pro Insider Preview DevチャンネルとWSL2を使うとGPUを使うことができます。
macOS上使用GPU的讨论:Intel平台的PlaidML与AMD平台的ROCm。
在macOS上,支持使用Intel GPU作为集成图形处理器(iGPU)和使用AMD GPU作为离散图形处理器(dGPU),因此有多种方法可以使用这些GPU。在AMD方面,支持名为ROCm的机制,相当于nVidia的CUDA。类似于使用CUDA的tensorflow-gpu,也可以使用基于ROCm的tensorflow-rocm。然而,ROCm仅支持Linux系统(如Ubuntu),在macOS上无法使用。另一方面,在macOS上使用基于Intel(旧Vertex.ai)的PlaidML是一种使用GPU的方法。可以通过替换Keras的后端(使用python代码,在import keras之前设置os.environ[“KERAS_BACKEND”] = “plaidml.keras.backend”),来轻松地使用它。目前,这可能是macOS上官方唯一支持GPU的方法。此外,在包括Windows在内的使用集成GPU的方法中,PlaidML也被认为是有效的。希望它能在成为Intel旗下后有所发展。
2-2-3. 设置Docker终端环境(安装OpenCV)
在Docker内进行操作。
由于默认情况下无法使用OpenCV,所以需要进行安装。
# apt update
# apt install -y libsm6 libxext6 libxrender-dev python-pip python3-pip
# pip install opencv-python
# pip3 install opencv-python
額外的討論:使用Dockerfile
在中文中,可以这样表达:
使用Dockerfile作为脚本可以进行Docker的设置。如果使用Dockerfile,则可以准备一个类似以下的Dockerfile,并调用docker build -t tf:1 .(将Dockerfile放在相同的文件夹“.”下),创建一个名为“tf:1”的镜像。使用docker run -it -p 8081:8888 tf:1就可以启动。Dockerfile对于了解他人的工作内容很方便。但是,如果不基于像FROM ubuntu:xenial这样的基本内容,最终无法知道设置了什么样的环境。
FROM tensorflow/tensorflow
RUN apt update && apt install -y libsm6 libxext6 libxrender-dev python-pip python3-pip
RUN pip install opencv-python
RUN pip3 install opencv-python
2-3. 停止 Docker
完成在Docker终端上的工作。
# exit
关闭 Docker。
$ docker stop mystifying_khorana
2-4. 我們再次在Docker上進行作業。
要保存环境并重新执行时,可以使用已操作的容器。
重新启动Docker容器以获取Jupyter的令牌。
$ docker start mystifying_khorana
$ docker exec -it mystifying_khorana bash -c "source /etc/bash.bashrc && jupyter notebook --notebook-dir=/tf --ip 0.0.0.0 --no-browser --allow-root"
如果以与初始命令相同的方式运行
$ docker run -it -p 8082:8888 tensorflow/tensorflow:latest-jupyter
将会创建一个没有保存历史记录的全新容器。
要查看所有生成的容器,可以使用以下命令(docker ps -a)。
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8b33acd60c67 tensorflow/tensorflow:latest-jupyter "bash -c 'source /et…" 35 seconds ago Up 34 seconds 0.0.0.0:8082->8888/tcp elegant_mahavira
2d5f2a274659 tensorflow/tensorflow:latest-jupyter "bash -c 'source /et…" 2 hours ago Up 3 minutes 0.0.0.0:8081->8888/tcp mystifying_khorana
可以使用容器名称(elegant_mahavira)来停止不需要的容器(在这里是CONTAINER ID=8b33acd60c67)。
$ docker stop elegant_mahavira
$ docker rm elegant_mahavira
可以通过删除来实现。
3. 将容器保存并在另一台机器上运行
3-1. 停止容器
$ docker stop mystifying_khorana
3-2. 创造形象
在这里,创建一个名为”gallant:0.0″的图像。
$ docker commit -m "Test" mystifying_khorana gallant:0.0
可以通过docker images命令查看存储在Mac上的镜像。
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
gallant 0.0 67e9ba8e53c8 9 seconds ago 1.37GB
tensorflow/tensorflow latest 2054925f3b43 2 weeks ago 1.34GB
将图像保存到文件中。
请使用以下命令将图像保存到“~/gallant.tar.gz”。
$ docker save gallant:0.0 > ~/gallant.tar.gz
从文件中加载图像
将gallant.tar.gz复制到另一台机器上,并使用以下命令运行。
在这里,先删除映像,然后重新加载。
$ docker rmi gallant:0.0 #削除
$ docker images #削除されたことを確認
$ docker load < gallant.tar.gz #ロード
$ docker images #追加されたことを確認
从图像启动
以与首次启动Tensorflow Docker相同的方式,使用run命令启动。这次创建一个名为gallant的容器。同时,使用-d选项使其在后台启动。
$ docker run --name gallant -it -d -p 8081:8888 gallant:0.0 # Start a Jupyter notebook server
当使用ps命令来检查正在运行的容器时,可以看到gallant正在运行。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
de4373702c8a gallant:0.0 "/run_jupyter.sh --a…" 24 seconds ago Up 22 seconds 6006/tcp, 0.0.0.0:8081->8888/tcp gallant
通过上述的exec命令(docker exec -it gallant bash),您可以在终端上继续进行操作。
總結
使用在Tensorflow的官方网站上提供的Docker,构建了在Jupyter上运行的工作环境。进行了一些配置以使其可以使用OpenCV,并创建了Docker镜像并保存。将镜像以文件的形式输出,以便可以在其他机器上使用,并验证了能够通过该文件加载和重新创建开发环境。