かなで技術日誌

プログラミングやエンジニアリング周りについて

主なアウトプットはScrapboxObsidianにまとめてます。

GCEでGPUインスタンスを立ててJupyter Notebookを導入するまで

f:id:kana_kanade:20190430164935j:plain

Google Compute EngineでGPUインスタンスを立てて、SSH接続してJupyter Notebookを使えるようにする手順をまとめました。
深層学習やkaggleなどをやるに当たって手元の計算資源が心もとない場合は、クラウドのリソースを使うことになると思いますがその際の環境構築についてまとめました。

結果として参考にした記事を継ぎ接ぎしただけ感が否めませんが、また自分でググる時が面倒なので記事として上げておきます。

いつものように、誤りがあればご指摘いただければと思います。

一応ローカルの環境

$ sw_vers
ProductName:	Mac OS X
ProductVersion:	10.14.4
BuildVersion:	18E226

Ubuntu16.04LTSへのcudaのインストールについては以下の記事を参考にしました。
qiita.com
cudaやAnacondaインストール後のJupyter Notebookの設定周りについては以下の記事を参考にしました。
qiita.com


大まかな手順は以下の通りです。

  1. Google Cloud SDKをインストールして初期化する
  2. VMインスタンスを立ち上げてcudaをインストールする
  3. Anacondaをインストールする
  4. ネットワーク設定を変更してJupyter Notebookを開けるようにする


1. Google Cloud SDKのインストール〜初期化するまで
まずはローカルでgcloudコマンドが使えるようにするため、Google Cloud SDKをインストールします。
基本的には以下の公式ドキュメントに従っていれば問題ないと思います。
cloud.google.com
セットアップが終わったら、gcloudコマンドが使えるか確認して、使えるようであれば次に進みます。

2. GPUインスタンスの立ち上げ〜cudaのインストール
上で上げた記事にも言及がありますが、コンソールからインスタンスを作成してもうまくいかないようで、一番最初はここで自分もはまりました。
なので、ローカルからgcloudコマンドでインスタンスを立ち上げる必要があります。
インスタンスを立ち上げる前にいくつか確認する項目がありますが、まずは参考までに以下が自分が叩いたコマンドです。{}内は適宜合わせてください。

$ gcloud beta compute instances create {INSTANCE_NAME} --machine-type n1-standard-4 --zone us-east1-d --boot-disk-size 20GB --accelerator type=nvidia-tesla-k80,count=1 --image-family ubuntu-1604-lts --image-project ubuntu-os-cloud --maintenance-policy TERMINATE --restart-on-failure --metadata startup-script='#!/bin/bash
# Install CUDA
if ! dpkg-query -W cuda; then
  curl -O http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/cuda-rep
o-ubuntu1604_8.0.61-1_amd64.deb
  dpkg -i ./cuda-repo-ubuntu1604_8.0.61-1_amd64.deb
  apt-get update
  apt-get install cuda -y
fi'

1 リージョンとGPU(?)の割り振りの確認
accelerator typeで指定しているGPU(?)はリージョンによって使える使えないがあります。
以下のコマンドで、どのリージョンでどのGPUが使えるのか確認できるので、それに合わせて設定してください。

$ gcloud beta compute accelerator-types list

2 APIの割り当ての確認
GPUの割り当てには上限があり、デフォルトでは1つなのでcount=1であれば大丈夫ですが、2以上積みたい場合はまず割り当てを確認し、足りない場合は申請する必要があります。
IAMの管理→割り当てから使うGPUでフィルタをかけて割り当て数を確認できます。
足りない場合は、チェックをして割り当てを編集から必要事項を入力してリクエストを送りましょう。

晴れてgcloudコマンドでインスタンスを立てたら、コンソールに移動してインスタンスが作成されていることを確認してください。
作成されていれば、SSHボタンを押すとコンソール画面が開きます。

開いたらcudaの環境設定をします。
(自分はsudoつけないとだめだった)

$ echo "export PATH=/usr/local/cuda-9.0/bin\${PATH:+:\${PATH}}" >> ~/.bashrc
$ source ~/.bashrc
$ sudo /usr/bin/nvidia-persistenced

終わったら、以下のコマンドを実行してドライバー情報が表示されたらインストール完了です。

$ nvidia-smi

もし表示されなかったら、インスタンス作成時にcudaがうまく入っていない可能性があるので、このコンソールで入れ直します。
sudoをつければうまくいくと思います。
cudaのインストールは結構時間がかかりますので気長に待ちましょう。

3. Pythonのインストール
Anacondaが安定だと思うのでインストールします。
www.anaconda.com
必要に応じてsudoをつけてください。
{USER_NAME}は置き換えてください。

$ wget https://repo.anaconda.com/archive/Anaconda3-2019.03-Linux-x86_64.sh
$ sh ./Anaconda3-2019.03-Linux-x86_64.sh
$ echo ". /home/{USER_NAME}/anaconda3/etc/profile.d/conda.sh" >> ~/.bashrc
$ source ~/.bashrc

終わったら仮想環境を作成します。
versionをpyhton3.6で指定して、仮想環境を作成し有効にします。

$ conda create -n {VENV_NAME} python=3.6
$ conda activate {VENV_NAME}

あとはconda install でTensorflowなりPyTorchなりをいれてください。

4. Jupyter Notebookの設定
Jupyter Notebookの設定を変更し、立ち上げるところまでやります。
Jupyter NotebookのConfigファイルを作成します。

$ cd ~
$ jupyter notebook --generate-config
$ cd .jupyter

SSL用の鍵を作成します。

openssl req -x509 -nodes -days 365 -newkey rsa:1024 -keyout mykey.key -out mycert.pem

色々聞かれますが、それっぽい内容を入力しましょう。以後この情報が必要になることは今の所ありません。

入力が終わったら、pythonインタプリタからハッシュを生成します。

$ python
>>> from notebook.auth import passwd; passwd()

2回パスワードを入力した後にハッシュが表示されます。
パスワードはJupyter Notebookを開く際に、ハッシュはこの後設定ファイルを変更する際に必要となるので控えておきましょう。

次にConfigファイルを編集します。
編集方法は

cd .jupyter
$ vi jupyter_notebook_config.py

でファイルの中身が開きます。
キーボードのiを押すと編集可能になり、保存して閉じる場合は
1.Escapeキーを押す
2.「:wq」と入力する
と保存されます。

$ cat jupyter_notebook_config.py

でコンソールに表示して確認ができます。

Configファイルはだいぶ長いですが、上からc.NotebookAppのアルファベット順で以下のように並んでるので、コメントアウトを外して修正してください。
{HASH}には、先ほど控えておいたパスワードのハッシュをいれてください。

# OpenSSLで作ったファイルへのパス
c.NotebookApp.certfile = u'/home/username/.jupyter/mycert.pem'

# どのIPアドレスからのアクセスも受け入れる
c.NotebookApp.ip = '0.0.0.0'

# OpenSSLで作ったファイルへのパス
c.NotebookApp.keyfile  = u'/home/username/.jupyter/mykey.key'

# 勝手にブラウザを起動しない
c.NotebookApp.open_browser = False

# passwd()コマンドで作ったパスワードのハッシュを貼る
c.NotebookApp.password = u'{HASH}'

# 外部からアクセスするためのポート番号を指定する
c.NotebookApp.port = 8888

終わったらGCPのコンソールに移動します。
作成したインスタンスのページに移動し、インスタンス名をクリックするとインスタンスの情報が表示されます。
上の編集ボタンを押して、編集可能な状態にします。

ネックワークインターフェースのdefault → ネットワークのdefaultを選択してVPCネットワークの詳細を開きます。
「ファイアーウォール ルール」タブを選択し、ファイアーウォールルールを追加を押して、以下のように追加します。

ターゲットタグ: https-server
ソースタグ: 0.0.0.0/0
指定したプロトコルとポート: tcpにチェックして8888と入力

これで新たなファイアーウォールルールが追加されます。


追加したら編集画面まで戻り、先ほどのネットワークインターフェースの下に、ファイアーウォールの「HTTPSトラフィックを許可する」にチェックが付いているか確認し、なければチェックしてください。

チェックしたらVMインスタンスのページまで戻って、外部IPのアドレスが表示されていると思うのでクリックします。

クリックすると「このサイトにアクセスできません」と表示されると思います。(IPアドレスは隠しています)
f:id:kana_kanade:20190430162950p:plain

これは正しいポート番号を指定していないからです。
追加したファイアーウォールルールでポート番号を8888と指定しているので、IPアドレスの末尾に:8888と追加してアクセスしてみます。
f:id:kana_kanade:20190430163235p:plain

警告が出ていますが、これはSSL証明書が正規のものではないため(?)にこのような表示となっています。
(正直この辺は怪しいので理解があってるか微妙です。)
左下の詳細設定を押すと以下のように表示されます。
f:id:kana_kanade:20190430163900p:plain

アクセスしてみるとパスワード入力欄があるので、pythonでハッシュを生成する際に入力したパスワードを入力して、無事Jupyter Notebookが開くと思います。

終了する場合はCtrl+CでJupyter Notebookを終了し、VMインスタンスを停止して終了となります。(重要)

インスタンスは作っては壊してができますし、慣れるとそんなに時間もかからないと思います。

参考になれば幸いです。