Jupyterでコード書いて機械学習しようとしたとき、エラー吐いてどハマりしたので共有しといた方が良いと思った話です。
#環境
Anaconda+JupyterとCUDA+TensorFlowGPU+Kerasでディープラーニングさせている。CUDAは10.0、cuDNNも該当バージョンをインストール済み。CPU版はアンインストールした。ちゃんと動くはずの環境。ていうか今までちゃんと動いてた。
#状況
Kerasで学習をさせようとするとエラーを吐く。1回目はちゃんと動く。でも、他のコードを実行すると止まる。場合によっては1回目でも止まる。PC再起動させると1回は治る。でも2回目はエラー。えらー。error。
昨日までちゃんと動いてたのに。何もしてないのに壊れた。
具体的にはこんな感じのエラーメッセージが出て動かない。
UnknownError: 2 root error(s) found. (0) Unknown: Failed to get convolution algorithm. This is probably because cuDNN failed to initialize, so try looking to see if a warning log message was printed above. [[{{node conv2d_1/convolution}}]] [[metrics/acc/Mean/_193]]
#調べる
エラーを読むと、cuDNNの初期化に失敗してるらしい。ググってみたらどうやらcuDNNのPATHが通ってないとこうなるよ、とのこと。
環境変数調べる。ちゃんとパス通ってるように見える。Anacondaごと再インストールしても症状が治らない。そもそも1回はちゃんと動くのが最高に意味不明でCOOL。
入れなおせど入れなおせど我が症状治らざり。
Jupyter終了させているのにPythonプロセスが生きてた。しかもえらい量メモリ確保してる。この辺でなにかおかしいことに気付く。もしかしてJupyterって終了させてもメモリ解放しない?いやいやそんなまさか…
#再度調べる
そのまさかだった。JupyterNotebookはタブを閉じてもプログラムは終了しないとのこと。まじか。今までタブを閉じて終わらせてた。無知って怖い。
このあたりでJupyterのこの辺の仕様が原因な気がしだしてTensorFlowのGPU確保の仕方も調べる。
#そしてTensorFlowの仕様
TensorFlow-GPUは、デフォルトだとGPUの空いている領域をすべて確保しようとする。すべてです。ALL。
つまり、TensorFlow-GPUを使った機械学習プログラムを複数同時に走らせると1つめは普通に通るけど2つめはGPUを確保できないので初期化に失敗する。これがcuDNN failed to initialize
の正体。
そしてJupyterをタブ閉じで終わらせるとGPUを確保したままゾンビ化する。その後Jupyterを立ち上げ直してもGPUはゾンビ化したコードに専有されたままなのでこれも初期化失敗する。これが1回目でも学習失敗する症状の正体。
試しに1つめのコードを走らせたあと、Jupyter上でコードを停止させてから2つめを走らせると、普通に動いた。CUDAもcuDNNもAnacondaも悪くない。悪いのはGPUをひとり占めしようとするTensorFlowとタブを消したらゾンビ化するJupyterやったんや。
#結論
コードは実行が終わったらちゃんと停止させましょう。Jupyterを終了させるときはちゃんとQuiteで終わらせましょう。TensorFlowが確保するメモリ量を制限するやり方も有効です。やり方は以下の記事が分かりやすいです。おわり。
#参考文献