やりたいこと
ベースイメージに gcr.io/deeplearning-platform-release/tf-gpu.2-9:m95
などを使用して tensorflow-gpu
をインストールした Docker イメージを作ります。
イメージ名的に tensorflow-gpu
をインストールする必要はなさそうな雰囲気を感じますが、インストールしないと GPU を使っての学習はしてくれないようです。
2022年12月時点で GCP から案内されている、利用可能なイメージは以下のドキュメントで案内されています。
以下の GCS バケットでは各ベースイメージにインストールされている Python パッケージの内容を確認できます。
まずは結論
- 最新版の tensorflow を使う場合は
gcr.io/deeplearning-platform-release/tf-gpu.2-6:m95
を使い、インストール済みの tensorflow のバージョンを上書きするのが一番楽 -
gcr.io/deeplearning-platform-release/tf-gpu.2-9:m95
を使うとインストール済みのnumpy
を上書きする必要がある
結論だけ見てもよくわからないと思うので、上記結論に至った経緯をつらつらと書いていきます。
最新版のベースイメージを使用して tesnorflow-gpu
をインストール
2022年12月時点で GCP が案内している最新版のベースイメージは gcr.io/deeplearning-platform-release/tf-gpu.2-9:m95
です。このベースイメージには元々 tensorflow == 2.9.2
がインストールされていますが、tensorflow-gpu
をインストールして最新版の tensorflow
で上書きします。
以下の Dockerfile でビルドします。
FROM gcr.io/deeplearning-platform-release/tf-gpu.2-9:m95
RUN pip install tensorflow-gpu
ビルドしてコンテナを起動し、インストールされている tensorflow のバージョンを確認すると現時点での最新版であるtensorflow==2.11.0
がインストールされていることがわかります。
$ docker build -t tf29 .
# 依存関係がぶっ壊れている、という pip の警告メッセージが大量に出ますがビルド自体は成功しているので一旦無視で OK です
$ docker run -it --rm tf29 /bin/bash
root@380290e871f0:/# pip list | grep tensor
tensorboard 2.11.0
tensorboard-data-server 0.6.1
tensorboard-plugin-wit 1.8.1
tensorflow 2.9.1
tensorflow-cloud 0.1.16
tensorflow-datasets 4.4.0
tensorflow-estimator 2.11.0
tensorflow-gpu 2.11.0
tensorflow-hub 0.12.0
tensorflow-io 0.23.1
tensorflow-io-gcs-filesystem 0.26.0
tensorflow-metadata 1.9.0
tensorflow-probability 0.14.1
tensorflow-serving-api 2.9.1
tensorflow-transform 1.9.0
しかし ipython で tensorflow のバージョンを確認するために import してみると以下のエラーで落ちます。numpy のバージョンエラーのようです。
RuntimeError: module compiled against API version 0xe but this version of numpy is 0xd
import tensorflow as tf
2022-12-13 01:51:53.047766: I tensorflow/core/platform/cpu_feature_guard.cc:193] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations: AVX2 FMA
To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
---------------------------------------------------------------------------
RuntimeError Traceback (most recent call last)
RuntimeError: module compiled against API version 0xe but this version of numpy is 0xd
---------------------------------------------------------------------------
ImportError Traceback (most recent call last)
ImportError: numpy.core.multiarray failed to import
The above exception was the direct cause of the following exception:
SystemError Traceback (most recent call last)
SystemError: <built-in method __contains__ of dict object at 0x7f2d8c095690> returned a result with an error set
The above exception was the direct cause of the following exception:
ImportError Traceback (most recent call last)
<ipython-input-1-64156d691fe5> in <module>
----> 1 import tensorflow as tf
/opt/conda/lib/python3.7/site-packages/tensorflow/__init__.py in <module>
35 import typing as _typing
36
---> 37 from tensorflow.python.tools import module_util as _module_util
38 from tensorflow.python.util.lazy_loader import LazyLoader as _LazyLoader
39
/opt/conda/lib/python3.7/site-packages/tensorflow/python/__init__.py in <module>
35
36 from tensorflow.python import pywrap_tensorflow as _pywrap_tensorflow
---> 37 from tensorflow.python.eager import context
38
39 # pylint: enable=wildcard-import
/opt/conda/lib/python3.7/site-packages/tensorflow/python/eager/context.py in <module>
32 from tensorflow.python import pywrap_tfe
33 from tensorflow.python import tf2
---> 34 from tensorflow.python.client import pywrap_tf_session
35 from tensorflow.python.eager import executor
36 from tensorflow.python.eager import monitoring
/opt/conda/lib/python3.7/site-packages/tensorflow/python/client/pywrap_tf_session.py in <module>
17 # pylint: disable=invalid-import-order,g-bad-import-order, wildcard-import, unused-import
18 from tensorflow.python import pywrap_tensorflow
---> 19 from tensorflow.python.client._pywrap_tf_session import *
20 from tensorflow.python.client._pywrap_tf_session import _TF_SetTarget
21 from tensorflow.python.client._pywrap_tf_session import _TF_SetConfig
ImportError: initialization failed
numpy のバージョンを確認してみる
numpy のバージョンエラーが出たため、使用されている numpy のバージョンを確認します。まずはインストールされている numpy を pip で確認します。
root@380290e871f0:/# pip list | grep numpy
numpy 1.21.6
1.21.6
がインストールされているみたいです。続いて ipython で使用している numpy のバージョンを確認してみます。
root@380290e871f0:/# ipython
Python 3.7.12 | packaged by conda-forge | (default, Oct 26 2021, 06:08:53)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.33.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: import numpy as np
In [2]: np.__version__
Out[2]: '1.19.5'
1.19.5
…?こいつがどこから来ているのかを調べてみます。
In [3]: np.__file__
Out[3]: '/opt/conda/lib/python3.7/site-packages/numpy/__init__.py'
numpy はここの site-packages を参照していることがわかります。続いて参照している numpy のバージョンを確認してみます。
root@380290e871f0:/# ls -la /opt/conda/lib/python3.7/site-packages | grep numpy
drwxr-xr-x 18 root root 4096 Aug 6 08:08 numpy
drwxr-xr-x 2 root root 4096 Aug 6 08:08 numpy-1.19.5.dist-info
drwxr-xr-x 2 root root 4096 Aug 6 08:08 numpy-1.21.6.dist-info
drwxr-xr-x 2 root root 4096 Aug 6 08:08 numpy.libs
root@380290e871f0:/# cat /opt/conda/lib/python3.7/site-packages/numpy/version.py
# THIS FILE IS GENERATED FROM NUMPY SETUP.PY
#
# To compare versions robustly, use `numpy.lib.NumpyVersion`
short_version = '1.19.5'
version = '1.19.5'
full_version = '1.19.5'
git_revision = '8f4b73a0d04f7bebb06a154b43e5ef5b5980052f'
release = True
if not release:
version = full_version
numpy は 1.19.5
と 1.21.6
の2つのバージョンがインストールされていますが、参照しているのは 1.19.5
になっていることが確認できました。
なぜ pip list
で参照される numpy のバージョンが 1.21.6
になっているのかは正直ちゃんとわかっていないです。 pip がどのようにパッケージのバージョンを参照しているのかという仕組みから調査する必要があります。
ちなみにこの 1.21.6
というバージョンは、ベースイメージに元からインストールされているものであるため、「2つのバージョンがインストールされている」という問題を根本解決することはできません。
numpy が複数バージョンインストールされている状況への対処
改めて numpy をインストールするほかありません。普通に pip install
すると既に最新版である旨のメッセージが出てしまうため、インストール済みの如何に関わらず強制的に再インストールします。
root@380290e871f0:/# pip install -U numpy --ignore-installed
root@380290e871f0:/# cat /opt/conda/lib/python3.7/site-packages/numpy/version.py
from ._version import get_versions
__ALL__ = ['version', 'full_version', 'git_revision', 'release']
vinfo = get_versions()
version: str = vinfo["version"]
full_version: str = vinfo['version']
git_revision: str = vinfo['full-revisionid']
release = 'dev0' not in version and '+' not in version
short_version: str = vinfo['version'].split("+")[0]
del get_versions, vinfo
root@380290e871f0:/# cat /opt/conda/lib/python3.7/site-packages/numpy/_version.py
# This file was generated by 'versioneer.py' (0.19) from
# revision-control system data, or from the parent directory name of an
# unpacked source archive. Distribution tarballs contain a pre-generated copy
# of this file.
import json
version_json = '''
{
"date": "2022-04-11T17:43:10-0600",
"dirty": false,
"error": null,
"full-revisionid": "ef0ec786fd4c7622ad2fa0e54d3881f3b9bbd792",
"version": "1.21.6"
}
''' # END VERSION_JSON
無事 1.21.6
を参照するようになっていそうです。
改めて動作確認
import tensorflow as tf
2022-12-19 15:36:15.199638: I tensorflow/core/platform/cpu_feature_guard.cc:193] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations: AVX2 FMA
To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
2022-12-19 15:36:16.507049: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer.so.7'; dlerror: libnvinfer.so.7: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /usr/local/cuda/lib64:/usr/local/cuda/lib:/usr/local/lib/x86_64-linux-gnu:/usr/local/nvidia/lib:/usr/local/nvidia/lib64:/usr/local/nvidia/lib:/usr/local/nvidia/lib64
2022-12-19 15:36:16.507233: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer_plugin.so.7'; dlerror: libnvinfer_plugin.so.7: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /usr/local/cuda/lib64:/usr/local/cuda/lib:/usr/local/lib/x86_64-linux-gnu:/usr/local/nvidia/lib:/usr/local/nvidia/lib64:/usr/local/nvidia/lib:/usr/local/nvidia/lib64
2022-12-19 15:36:16.507262: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Cannot dlopen some TensorRT libraries. If you would like to use Nvidia GPU with TensorRT, please make sure the missing libraries mentioned above are installed properly.
ちゃんと tensorflow が import できました。
ちょっと古いベースイメージを使用して tesnorflow-gpu
をインストール
ここまでに、複数の numpy がベースイメージに混在していることでその対処が必要になっていたため、逆に最初から単一の numpy がインストールされているベースイメージを探しました。
選ばれたのは(単一バージョンの numpy がインストールされていたのは) gcr.io/deeplearning-platform-release/tf-gpu.2-6:m95
でした。
前段で実施した手順と同じ手順でイメージをビルドし、動作確認します。
FROM gcr.io/deeplearning-platform-release/tf-gpu.2-6:m95
RUN pip install tensorflow-gpu
$ docker build -t tf26 .
$ docker run -it --rm tf26 /bin/bash
root@5e274c7ddda1:/# pip list | grep numpy
numpy 1.21.6
root@5e274c7ddda1:/# ipython
Python 3.7.12 | packaged by conda-forge | (default, Oct 26 2021, 06:08:53)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.33.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: import tensorflow as tf
2022-12-19 15:51:46.765250: I tensorflow/core/platform/cpu_feature_guard.cc:193] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations: AVX2 FMA
To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
2022-12-19 15:51:48.094737: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer.so.7'; dlerror: libnvinfer.so.7: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /usr/local/cuda/lib64:/usr/local/cuda/lib:/usr/local/lib/x86_64-linux-gnu:/usr/local/nvidia/lib:/usr/local/nvidia/lib64:/usr/local/cuda/lib64:/usr/local/cuda/lib:/usr/local/lib/x86_64-linux-gnu:/usr/local/nvidia/lib:/usr/local/nvidia/lib64:/usr/local/nvidia/lib:/usr/local/nvidia/lib64
2022-12-19 15:51:48.094938: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer_plugin.so.7'; dlerror: libnvinfer_plugin.so.7: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /usr/local/cuda/lib64:/usr/local/cuda/lib:/usr/local/lib/x86_64-linux-gnu:/usr/local/nvidia/lib:/usr/local/nvidia/lib64:/usr/local/cuda/lib64:/usr/local/cuda/lib:/usr/local/lib/x86_64-linux-gnu:/usr/local/nvidia/lib:/usr/local/nvidia/lib64:/usr/local/nvidia/lib:/usr/local/nvidia/lib64
2022-12-19 15:51:48.094969: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Cannot dlopen some TensorRT libraries. If you would like to use Nvidia GPU with TensorRT, please make sure the missing libraries mentioned above are installed properly.
特に問題なく import できました。
改めて結論
- 最新版である
gcr.io/deeplearning-platform-release/tf-gpu.2-9:m95
を使う場合は numpy のバージョンをいじる必要がある -
gcr.io/deeplearning-platform-release/tf-gpu.2-6:m95
では不要 - つまりベースイメージは
gcr.io/deeplearning-platform-release/tf-gpu.2-6:m95
を使って新しい tensorflow をインストールする、という運用が一番楽
いつかどこかの誰かの役に立つことを祈っています。