Cannot allocate memory: Docker + Tensorflow + Keras: Dockerのコンテナのメモリが足りない

274, 2021-06-21

目次

Dockerと「Cannot allocate memory」

Dockerを使ってKerasの機械学習のチュートリアルをやっていました。
チュートリアルのコードを実行したところ↓のようなエラーが出ました。

OSError: [Errno 12] Cannot allocate memory

結論から言うとDockerのコンテナで使用できるメモリが不足していて、↑のようなエラーが出るということでした。
これを解決するには↓のようにコンテナのメモリを「-m」オプションで指定して増量します。

$ docker run -itp 8888:8888 -m 8192M tensorflow/tensorflow:nightly-jupyter

↑のように-m8192Mのメモリ量を指定したところエラーは出なくなりました。

関連記事

環境

  • OS: Windows10

  • Docker: Docker Engine v20.10.5

Windows10にWindows用のDockerをインストールして使っています。

経緯

Kerasのチュートリアルの記事は↓です。

このチュートリアルはDockerの環境内にTensorflowとKerasの実行環境を用意して、それをJupyter Notebookで学習するというものです。
Dockerで簡単にTensorflowの実行環境を用意できるのが特徴です。
一回、Dockerではなくvenvなどで環境を用意しようとしたんですが、私の環境ではうまくいきませんでした。
そのためDockerで環境を構築することにしました。

Jupyter Notebookでチュートリアルのコードを実行するわけなんですが、そのコードは↓のようなものです。

import numpy as np

import tensorflow as tf

!pip install -q tensorflow-hub
!pip install -q tfds-nightly
import tensorflow_hub as hub
import tensorflow_datasets as tfds

print("Version: ", tf.__version__)
print("Eager mode: ", tf.executing_eagerly())
print("Hub version: ", hub.__version__)
print("GPU is", "available" if tf.config.experimental.list_physical_devices("GPU") else "NOT AVAILABLE")

上記のコードはTensorflowのバージョンなどを表示するチュートリアル内の「Hello, World!」的なコードです。
このコード内では!pip install ...を実行しています。
この!pip install ...は環境内にパッケージをインストールするコマンドです。
Jupyter Notebookでは行頭に「!」を付けるとコマンドを実行することができます。

この!pip install ...を実行する所で↓のようなエラーが出ました。

OSError: [Errno 12] Cannot allocate memory

これは見たままですが、メモリの確保に失敗した場合に発生するエラーです。
これの原因を調べてみました。

原因

Jupyter Notebookを使う場合、Dockerのコンテナを走らせます。
このコンテナ内でTensorflowやKerasの環境が使えるという感じです。
つまりこのコンテナで使用できるメモリの量が少なくて、Pythonがメモリの確保に失敗しているというのが原因です。

機械学習は比較的に他のジャンルと比べてもメモリを沢山使うらしいので、このようなエラーが出るということです。

(^ _ ^)

メモリが好きな機械学習

解決

走らせているコンテナを一旦ストップします。

$ docker stop コンテナのID

そして新しくコンテナを走らせます。
Tensorflowが搭載されていて、Jupyter Notebookが起動するコンテナを走らせるには↓のコマンドを実行します(これは例です。メモリの指定は後述します)。

$ docker run -itp 8888:8888 tensorflow/tensorflow:nightly-jupyter

↑のコマンドを実行するとhttp://localhost:8888にJupyter Notebookのログイン画面が表示されます。
端末に表示されているJupyter Notebookのトークンをコピペしてログイン時に入力するとJupyter Notebookの環境に入ることができます。

メモリの量はショートオプションの「-m」かロングオプションの「--memory」で指定することができます。

参考: Runtime options with Memory, CPUs, and GPUs | Docker Documentation

-m or --memory=

The maximum amount of memory the container can use. If you set this option, the minimum allowed value is 4m (4 megabyte).

コンテナが使用できるメモリの最大量。 このオプションを設定した場合、最小許容値は4m(4メガバイト)です。

ちなみにデフォルトで指定されるメモリ量は調べてみたんですが、よくわかりませんでした。
無制限とか2.0GBとかの記述がありましたが、不明です。
まぁ無制限ならエラーが発生しないはずなので、私の環境のDockerでは2.0GBだったということでしょうか。

使っているホストマシンのメモリ量は16GBあります。
ですので今回はその半分の8GB(8192M)を割り当ててみました。
↓のコマンドを実行してメモリを指定したコンテナを走らせます。

$ docker run -itp 8888:8888 -m 8192M tensorflow/tensorflow:nightly-jupyter

このコンテナで先ほどのコードを試してみたところエラーは出なくなりました。

おわりに

私のホストマシンのメモリは16GBありますが、こういうことに遭遇するともっとメモリが欲しくなりますね。
やはり開発ではメモリ32GBが必須の時代がもうすぐ来る感じでしょうか。

(^ _ ^)

メモリは膨らむどこまでも



この記事のアンケートを送信する