やりたいこと
- Deep Learning向けのAIMを、Amazon AWSのEC2で動かす
- Proxy内からもアクセスできるように、Jupyter NotebookをPort443で動かす
- 通常は安く動かし、必要なときだけパワフルなGPUで動かす
- インスタンスタイプを変更したらJupyter Notebookが自動で起動
- インスタンスタイプを変更してもIPアドレスが変わない
Machine Learning や Deep Leaning を学習していると、自分のPCではパワーが足りなかったり、複数の環境を整えるために容量が足りなくなってきたりします。また、時間がかかる処理をさせている時には、コーヒーを飲みながらサクサクとWebサーフィンして待ちたいです。
そこでAmazonのAWS上にEC2インスタンスとして環境を作ります。Lazy Girlの記事を見ると、まさにDeep Learning向けのAMIが用意されている。GPUも使えます。
A Lazy Girl's Guide to Setting Up Jupyter on EC2 for Deep Learning
Deep Learning AMIを起動
Lazy Girlの記事に従ってセットアップし、デフォルトのPort 8888 できちんとJupyter Notebookにアクセスできることを確認する。
3点ほど補足:
私はDeep Learning AMI Ubuntu Version を選んだので、デフォルトのユーザ名は ec2-userではなく ubuntu.
なのでSSHするときは
ssh -i <PATH_TO_PEM> ubuntu@ec2-xx-xxx-xx-xxx.eu-west-1.compute.amazonaws.com
また、
source src/anaconda3/bin/activate root
をするだけで、
> which jupyter ~/src/anaconda3/bin/jupyter
となったので、.bash_profile にPATHを追加するくだりは必要なかった。
Kerasはすでにインストールされている。
Port 443 で Jupyter Notebookを起動
Portを8888から、Proxyを通過できる443へ変更します。
nano ~/.jupyter/jupyter_notebook_config.py
> c.NotebookApp.port = 443
そのままubuntuユーザでjupyter notebookを起動させようとすると、443のような低い番号のポートはダメだと怒られるので、rootで起動します。
sudo jupyter notebook --allow-root
Port 8888 を Proxyが通過できる443へフォワードする
Jupyter Notebookを Port 443で起動するには rootユーザで起動しなければいけないのですが、せっかくubuntuユーザで動くように設定してあるGPUがうまく動かないようです。
なのでubuntuユーザでPort 8888 でJupyter Notebookを起動させて、Port 8888 を 443へフォワードするようにします。
sudo iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-ports 8888
自動起動の設定
インスタンスタイプを変更するには、一度EC2インスタンスをStopする必要があります。
自動的にJuypter Notebookが立ち上がるようにserviceとして登録しておくと便利です。
(会社のProxyがPort 22を通してくれないので、SSHして手動で起動させられない問題も解決)
Service を定義
sudo nano /etc/systemd/system/jupyter.service
[Unit]
After=network.target
[Service]
User=ubuntu
ExecStart=/home/ubuntu/start_jupyter.sh
[Install]
WantedBy=default.target
sudo chmod 664 /etc/systemd/system/jupyter.service
起動スクリプト
nano /home/ubuntu/start_jupyter.sh
#!/bin/bash
source /home/ubuntu/src/anaconda3/bin/activate root
sudo iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-ports 8888
cd /home/ubuntu/notebook
jupyter notebook
chmod 744 /home/ubuntu/start_jupyter.sh
GPU用の環境変数の設定
コマンドプロンプトからstart_jupyter.shを呼び出したときはimport keras
がうまくいくのですが、サービスの自動起動ではなぜかimport errorとなりました。
どうやらセキュリティを確保するために環境変数LD_LIBRARY_PATHを引き継がない機能があるようです。しょうがないのでjupyterのコンフィグレーションを読み込む時に設定するようにします。
nano ~/.jupyter/jupyter_notebook_config.py
# Configuration file for jupyter-notebook.
c = get_config()
c.NotebookApp.certfile = u'/home/ubuntu/certs/mycert.pem'
c.NotebookApp.keyfile = u'/home/ubuntu/certs/mycert.key'
c.NotebookApp.ip = '*'
c.NotebookApp.open_browser = False
c.NotebookApp.password = u'sha1:xxxxxxxxxxxx'
c.NotebookApp.port = 8888
import os
os.environ['LD_LIBRARY_PATH'] = '/home/ubuntu/src/torch/install/lib:/home/ubuntu/src/torch/install/lib:/home/ubuntu/src/cntk/bindings/python/cntk/libs:/usr/local/cuda/lib64:/usr/local/lib:/usr/lib:/usr/local/cuda/extras/CUPTI/lib64:/usr/local/mpi/lib:/home/ubuntu/src/cntk/bindings/python/cntk/libs:/usr/local/cuda/lib64:/usr/local/lib:/usr/lib:/usr/local/cuda/extras/CUPTI/lib64:/usr/local/mpi/lib:’
サービスを登録してスタート
きちんと動いていることを確認。
~$ sudo systemctl enable jupyter.service
~$ sudo systemctl start jupyter.service
~$ sudo systemctl status jupyter.service
Elastic IP でIPを固定
EC2インスタンスは再起動すると、IPアドレスが変わってしまいます。
Elastic IPサービスを使用すると、同じIPアドレスでアクセスできるようになります。
EC2 Management Console -> Elastic IPs -> Allocate new address
なお、EC2インスタンスをSTOPしている時にはElastic IPサービスの利用料が掛かります。(EC2インスタンスにattachされている時にはElastic IPサービスの部分は無料)
N.Virginiaでの料金だと、倹約のためにEC2インスタンスをSTOPしていても月に$3.6掛かります。t2.nanoをずっと動かし続けた$4.18とほとんど変わらない。でもセキュリティ上、使わない時にはSTOPしていたほうがいいでしょう。
Instance Type | Monthly $ |
---|---|
stopped | 3.60 |
t2.nano | 4.18 |
t2.micro | 8.35 |
おまけ (System Shell Command)
会社のProxyは非常に厳しく、Port 22を通してくれません。SSHでサーバにアクセスしてGitHubからexampleをダウンロードしたり、必要なモジュールをインストールしたりしたい時に困ります。
でもJupyter NotebookにさえWebブラウザからアクセスできればなんとかなります。
Jupyter NotebookのPython promptでは、!ping www.bbc.co.uk
のように「!」で行をスタートすればシステムシェルコマンドが打てます。
所感
これでやっと厚いProxyの壁に阻まれた会社内からでもJupyter Notebookへアクセスして学習を続けられるようになりました。
簡単に対処できると思っていましたが、意外とハマリポイントがいくつもあって難儀しました。会社で学ぶよりも家で学ぶほうが手軽にできる世の中って不思議ですね。