技術研究所(技研)のまつけんです。
技研では現在、3台のゲーミングデスクトップPCにLinux (Ubuntu)とJupyterをインストールして、共有で計算サーバとして使っています。私も、画像処理や機械学習のタスクをJupyterで行っています。また、開発中のソースコードなどはSubversionで管理しています。今回は、私が実践しているJupyter上でのソースコードのバージョン管理の手法について紹介したいと思います。
具体的には、各notebook (.ipynbファイル) の冒頭に専用のセルを用意し、そこに以下のスクリプトを入れておきます (この例ではabc.ipynbというnotebookを想定):
F = 'abc' ; FB = F + '.ipynb' ; FP = F + '.py' |
### commit resp. |
#!date ; sed -e 's#[ t]+(\n",)$#1#g' -i $FB ; svn commit $FB -m "$F (ipynb)" |
#!date ; jupyter nbconvert --to script $FB ; sed -e 's/# In[[0-9]+]:/# In[ ]:/' -e 's#[ t]+$##' -i $FP ; svn commit $FP -m "$F (py)" |
### commit both |
#!date ; sed -e 's#[ t]+(\n",)$#1#g' -i $FB ; jupyter nbconvert --to script $FB ; sed -e 's/# In[[0-9]+]:/# In[ ]:/' -e 's#[ t]+$##' -i $FP ; svn commit $FP $FB -m "$F (both)" |
### diff resp. |
#!date ; sed -e 's#[ t]+(\n",)$#1#g' -i $FB ; svn diff $FB |
#!date ; jupyter nbconvert --to script $FB ; sed -e 's/# In[[0-9]+]:/# In[ ]:/' -e 's#[ t]+$##' -i $FP ; svn diff $FP |
### diff both |
#!date ; sed -e 's#[ t]+(\n",)$#1#g' -i $FB ; jupyter nbconvert --to script $FB ; sed -e 's/# In[[0-9]+]:/# In[ ]:/' -e 's#[ t]+$##' -i $FP ; svn diff $FP $FB |
### revert |
#!date ; svn revert $FP $FB |
### commit all |
#!date ; F='*' ; sed -e 's#[ t]+(\n",)$#1#g' -i $FB ; jupyter nbconvert --to script $FB ; sed -e 's/# In[[0-9]+]:/# In[ ]:/' -e 's#[ t]+$##' -i $FP ; svn commit $FP $FB -m 'all .ipynb, .py' |
### diff all |
#!date ; F='*' ; sed -e 's#[ t]+(\n",)$#1#g' -i $FB ; jupyter nbconvert --to script $FB ; sed -e 's/# In[[0-9]+]:/# In[ ]:/' -e 's#[ t]+$##' -i $FP ; svn diff *.py *.ipynb |
del F, FB, FP |
print('================ DONE ================') |
7つのブロックに分かれたシェルスクリプトが書いてありますが、上から順に
- commit respectively: .ipynbと.pyを個別にコミット
- commit both: .ipynbと.pyを両方ともコミット
- diff respectively: .ipynbと.pyの差分を個別に表示
- diff: .ipynbと.pyの差分を両方とも表示
- revert: 元に戻す
- commit all: ディレクトリ内の全ての.ipynbと.pyをコミット
- diff.all: ディレクトリ内の全ての.ipynbと.pyの差分を表示
です。使う際は、コメントアウトを解除 (行頭の「#」を一時的に除去) して、ctrl-enter (Ctrlキーを押しながらEnterキーを押す) で実行します。
バージョン管理するのは、.ipynbファイルだけでも良いのですが、svn diffなどで差分を見る際に、ipynbファイルの差分を見るとなると少し見辛いので、一緒に.pyファイルもコミットすることにしています。jupyter nbconvert –to scriptで.ipynbを.pyに変換できるので、それを組み込んでいます。また、行末のスペースをsedコマンドで除去しています。
なお、svnサーバの容量節約のためと、diffの見やすさを考えると、.ipynbファイルをコミットする前に”clear output”を実行するのがオススメですが、
cp -af $FB $FB.bak ; jupyter nbconvert --clear-output --inplace $FB |
と
mv -f $FB.bak $FB |
をcommitとdiffの前後に入れてしまうのも良さそうです (または、「–ClearOutputPreprocessor.enabled=True」) [1]。
最初に「F = ‘abc’」という形でnotebookの自身のファイル名を指定しています。Notebook自身のファイル名を取得する方法[2]はありますが、新たにnotebookを作成した際に手動で指定してしまえば、その後は変更することも無いので、そのようにしています。
Subversion以外にも (Gitなどでも) 利用できるかと思いますので、よろしければ試してみてください。