2ヶ月くらい前に「現場で使える! TensorFlow開発入門 Kerasによる深層学習モデル構築手法」という書籍を買ってみたのですが手をつけずに放置してました..。サンプルコードぐらい動かそうということで環境構築をAzure上で行いました。
この本の中では nvidia-docker
を使ってコンテナの中でjupyter notebookを起動するので以前にfast.ai用に作ったAzureラッパースクリプトを少し修正しました。
サンプルプログラムを動かすための環境構築は基本的に翔泳社のサイトからダウンロードできる補足資料のpdfの通りに進めれば何も問題ないです。
が、
↑のラッパースクリプトを使うとjupyter notebookのトークン認証のトークンを毎回手動でコピペして入力する必要がなくなるので毎回の立ち上げのストレスが減ります :-)
個人的にはすごい便利です。
今回はリモートマシンのdockerコンテナで起動しているjupyter notebookのトークンを取得して自動でブラウザで開く方法について書きます。
起動中のjupyter notebookのトークンを取得する
$ jupyter notebook list
で起動しているjupyter notebookのtokenつきのURLが取得できます。
具体的には以下のような出力が得られます。
Currently running servers: http://localhost:8888/?token=1864c580501c69e7a331707d7901bc2e4263bffd54c70538 :: /notebooks
この出力から "http://localhost:8888/?token=xxx" の部分を抜き出し、localhostをリモートマシンのIPアドレスに置き換えたURLをopen
コマンドで開けばokです(Macの場合)。
ちなみに、複数のjupyter notebookインスタンスを起動しているときはhttp://localhost:xxxx/?token=xxx が複数行出力されます。
dockerコンテナでjupyter notebookを動かしているとき
dockerコンテナでjupyter notebookが起動しているときはnvidia-docker
コマンドを使って
$ sudo nvidia-docker exec YOUR_CONTAINER_NAME jupyter notebook list
でjupyter notebookのtokenつきのURLが取得できます。
ここで "YOUR_CONTAINER_NAME" はjuypter notebookを起動しているdockerコンテナの名前です。
本のサンプルの場合だと、
sudo nvidia-docker run --rm --name tfbook -p 80:8888 -p 6006:6006 -v /notebooks:/notebooks tfbook
というようにtfbook
というコンテナ名で jupyter notebookを起動しています。
(--name
で指定しているtfbookがコンテナ名で末尾のtfbookはdockerイメージ名)
このコマンドだと明示的にjupyter notebookを起動していませんが 大元のDockerfileの中で定義されています。
CMD ["/run_jupyter.sh", "--allow-root"] # 最終行
この1行があるのでコンテナ生成時にjupyter notebookが起動します。
ちなみに、nvidia-docker run
だと空の出力になってしまいます。
nvidia-docker exec
を使って既存のコンテナ上でjupyter list
コマンドを実行することがポイントです。
リモートマシンのjupyter notebookのトークンを取得
リモートマシンで先のコマンドを実行するにはssh
コマンドを使います。
最近まで知らなかったのですが(汗)、ssh ユーザー名@リモート端末のIPアドレス 任意のコマンド
とするとリモートマシン上で任意のコマンドを実行できます。
なので、今回の場合、以下のようなコマンドになります。
ssh -i ${privateKeyPath} ubuntu@${instanceId} 'sudo nvidia-docker exec tfbook jupyter notebook list'`
あとは このコマンド出力からtokenつきのURLの箇所を抜き出して、localhost をリモートマシンのIPアドレスに置換してブラウザに渡せばokです。
完成形スクリプト
最終的には以下のシェルスクリプトを実行することによってリモートマシン上で起動しているjupyter notebookを自動的にブラウザで開くことができます。
list=`ssh -i ${privateKeyPath} ubuntu@${instanceId} 'sudo nvidia-docker exec tfbook jupyter notebook list'` url=`echo $list | grep http | sed -e "s/localhost/${instanceId}/g" | sed -e "s/:8888//g" | awk '{print $4}'` echo $url open $url
また、リモートマシンに明示的にログインせずにリモートマシン上でjupyter notebookを起動するには、同様にして
ssh -i ${privateKeyPath} -o "StrictHostKeyChecking no" ubuntu@${instanceId} "sudo nvidia-docker run --rm --name tfbook -p 80:8888 -p 6006:6006 -v /notebooks:/notebooks tfbook"
となります。
docker使わない場合は、もっとシンプルに
ssh -i ${privateKeyPath} -o "StrictHostKeyChecking no" ubuntu@${instanceId} "cd /path/to/notebook_dir; jupyter notebook"
です。