Jupyter Notebookを非インタラクティブに実行する

この投稿はrioyokotalab Advent Calendar 2020 11日目の投稿です。

adventar.org

リモートサーバーのJupyter Notebookを長時間動かしたい

Jupyter Notebookは

  • リモートサーバー上に配置したデータをダウンロードすることなく操作できる
  • インタラクティブに実行結果を確認できる

という2点において、機械学習やデータ分析のコーディングに有利なツールとなっています。しかし、これは同時に、コードの実行中はJupyter Notebookのサーバーを立てていないといけなかったり、実行中のブラウザ画面を常に表示していないと、勝手に中断されたりと、不便さも同時に引き起こします。

1日以内の実行であれば、これらの不便さは我慢できるかもしれないですが、3日を超えるコードの実行が必要な場合、なんらかの工夫をしなければ、サーバーのポートを無駄に食い潰したり、手元のPCの取り回しがめんどくさくなったりします。あとは、ノートブックだと実行が最後まで終了した後も、プロセスが終了しないので、GPUメモリが確保されたままになっていたり...

今回は、Jupyter Notebookを通常のプログラムと同じように、コマンドライン上から起動、実行、出力の集積を行う方法を紹介します。

nbconvert

Jupyter Notebookは、nbconvertコマンドを用いてスクリプト形式やHTML形式に変換することができます。変換形式にnotebookという形式を選択することが可能で、これを実行すると、選択したJupyter Notebookがすべて実行され、実行結果が保存されます。

この形式をとった方が、Jupyter Notebook固有のメソッドであるIPythonモジュールをを使えたり、インタラクティブな途中経過の確認を保存できたりして、便利です。データの操作が正しく行えているかを可視化できるとミスやデバッグの手間が減らせます。

コマンド

jupyter nbconvert --ExecutePreprocessor.timeout=-1 --to notebook --execute notebook.ipynb --output results/notebook.ipynb

ABCI1上など、スパコン上で使う場合は、次のようなシェルスクリプトrun.shを作成して投げています。

#!/bin/bash
#$ -cwd
#$ -l rt_F=1
#$ -l h_rt=24:00:00
#$ -o log/o.$JOB_ID
#$ -j y


source /etc/profile.d/modules.sh
module load gcc/7.4.0
module load python/3.7/3.7.6
module load cuda/10.1/10.1.243
module load cudnn/7.6/7.6.5
module load nccl/2.5/2.5.6-1

source ./venv/bin/activate

mkdir results/$JOB_ID
cp $1 results/$JOB_ID/
jupyter nbconvert --ExecutePreprocessor.timeout=-1 --to notebook --execute $1 --output results/$JOB_ID/$1

ABCI上でジョブを投げるときに使うqsubコマンドはshコマンドのように引数を渡すことができるので、

qsub -g [group_id] run.sh notebook.ipynb

とすることで、notebookの実行が可能になります。

まとめ

もともと、Kaggle Kernelのcommitのような実行結果も含めたバージョン管理、実験管理が目的でこの方式を考えました。

インタラクティブデバッグと可視化+実験の実行と保存をうまく組み合わせることができれば、機械学習の実験の取り回しがもっと楽になると思います。