GCPでディープラーニング学習後に自動でシャットダウン仕組みを手軽に設定する方法

## GCPでディープラーニングするとき怖いもの
　GCP(Google Cloud Platform)等のクラウドサービスでディープラーニングの学習を行うとき、一番怖いものは何でしょうか？

　過学習？エラーによる学習中断？もちろんそれらも恐ろしいですが、やっぱり一番怖いのは、インスタンスのシャットダウン忘れによる課金が引き起こすクラウド破産ですね（個人の感想です）。

　ディープラーニングの長時間の学習のとき、自分が寝ている間に学習しておいて欲しいと思う人は多いと思います。ただ、学習が終わったあと学習が走っているインスタンスを止めないと、課金され続けてしまいます。このままではゆっくり眠ることもできません。

　そこで、必要なのが学習が終わったらスマートかつ即座にシャットダウンする仕組みです。この方法が、探しても意外に見つからなかったり、よさそうな情報を試しても自分の環境だとうまくいかなかったりします。

　そもそもあんまり需要ないのかもしれませんが、自分なりの方法をようやく見つけ出したので共有したいと思います。

## 注意事項
　最初に書いておきますが、本記事の内容を実践したことによる責任は、当方は一切保証できません。実行環境・内容によっては正しく動作しない可能性がありますので、必ず各自で十分に事前確認した上で使用ください。より良い方法の提案も大歓迎です。

## 自動シャットダウンスクリプトの設定方法
　色々調べて、1番自分のやりたいことに近くて自分が実践できた以下の記事を全面的に参考にしました。　

[【GCP/AWS】インスタンスのシャットダウンし忘れを防ぐ](https://qiita.com/Gri_Gra/items/8789a921ad9e2ed8a171)

　ただ、そのままでは色々うまくいかなかったり、少し手間が大きかったので手軽に使えるように工夫してみました。成果物は以下のリポジトリにまとめています。

<a href="https://github.com/karaage0703/gcp_tools"><img src="https://github-link-card.s3.ap-northeast-1.amazonaws.com/karaage0703/gcp_tools.png" width="460px"></a>

### GCPの事前設定
　GCPに関しては、以下の記事をベースにAI Platform上でインスタンスを立てた前提で記載します。

[GCPでのディープラーニング学習環境構築方法](https://qiita.com/karaage0703/items/77d6d75db9105a5e8983)

　GCP上での他の設定のインスタンスやAWS等の他のクラウドサービスでも応用のきく手法だとは思いますが、動作確認などは実施していませんのでご了承ください。

　インスタンスを立ち上げたら、SSHでアクセスしてください（上記の記事に方法は記載してあります）。

　ここから先は、SSHアクセスしたGCPのターミナル上でコマンド実行していくことを前提に説明していきます。


### シャットダウンスクリプトの自動実行設定
　設定は、以下3行でOKです。

```sh
$ cd && git clone https://github.com/karaage0703/gcp_tools
$ sudo apt-get install bc
$ crontab ~/gcp_tools/cron.txt
```

　それぞれの行で実施していることは、以下となります。

- ホームディレクトリ直下に必要なスクリプトや設定ファイルをダウンロード（git clone)
- シェル上で計算を行うbcコマンドをインストール
- cronによるスクリプトの自動実行の設定

　シャットダウンスクリプトの自動実行の設定を取り消したい場合は、cronの設定をリセット（削除）するだけです。以下コマンドを実行すればOKです。

```sh
$ crontab -r
```

### 動作確認
　上記の設定をすれば、10分以内にディープラーニングでの学習を走らせていないと、自動でインスタンスがシャットダウンされるようになります。

　ディープラーニングの学習（もしくは、負荷が高い計算処理）をしていると、シャットダウンはされません。仕組みとしては、CPUの負荷を監視して判断しています。詳しくは以下のスクリプトの中身を確認ください。
　
[shutdown.sh](https://raw.githubusercontent.com/karaage0703/gcp_tools/main/shutdown.sh)

　あまりないと思いますが、学習の負荷が極端に軽い場合などは、必要に応じてスレッショルド`LOAD_TH`を調整してください。

　10分待つのがめんどくさい場合は、実際に学習を走らせている間に以下コマンドでシャットダウンスクリプトを走らせましょう。以下のように`instance not working`と表示されて、インスタンスが停止しなければOKです。

```
$ ~/gcp_tools/shutdown.sh
"instance not working"
```

　学習など走っていないときに、シャットダウンスクリプトを実行すると、シャットダウンコマンドが走りインスタンスが終了します。

### より安全な運用のために
　クラウド破産しないためにも、事前に十分に動作確認をした上で使用するようにしましょう。また、このスクリプトは特性上、学習がずっと走り続けていたり、何かしらの要因でGCP上の負荷が高い状態が続いたとき、インスタンスを停止できません。

　そのような自体を備えて、1日1度は負荷に関わらず強制的に停止するなどして、安全な運用の工夫をするとより良いかもしれません。

## cronの手動設定
　以下はcronの設定に関する補足です。

### cron実行時間の設定を変更する
　cronの実行時間の設定を変えたい場合は、crontabコマンドを使いましょう。編集する場合は以下です。

```sh
$ crontab -e
```

　以下のようにcronの設定が表示されます。

```
*/10 * * * * ./gcp_tools/shutdown.sh
```

　デフォルトでは10分間隔でシャットダウンスクリプトが走るようになっています。cronを知らない人でもなんとなく想像つくかもしれませんが、設定の頭を例えば`*/30`に変えると実行の時間間隔が30分になります。

　cronでは、他にも1日に1回、1時間に1回、決まった時間に実行等、色々な設定ができます。cronの使い方に関して本記事では解説しないので、必要に応じて調べてみてください。

### タイムゾーン設定
　決められた時間に実行したいとき、日本時間に合わせておいた方が分かりやすい人も多いと思うので、好みに応じて設定しましょう。

　以下で日本時間に設定できるので試してみましょう。

```sh
$ timedatectl set-timezone Asia/Tokyo
```

　`jupyter`というユーザのパスワードが要求されます。

```
==== AUTHENTICATING FOR org.freedesktop.timedate1.set-timezone===
Authentication is required to set the system timezone.
Authenticating as: jupyter
Password:
polkit-agent-helper-1: pam_authenticate failed: Authentication failure
==== AUTHENTICATION FAILED ===
Failed to set time zone: Access denied
```

　`jupyter`のパスワードなんて知らないよー、ということで好きなパスワードを設定しましょう。

```sh
$ sudo passwd jupyter
```

　再度コマンド実行して、先ほど設定したパスワードを入力しましょう。以下のように`AUTHENTICATION COMPLETE`と表示されたらOKです。

```sh
$ timedatectl set-timezone Asia/Tokyo
==== AUTHENTICATING FOR org.freedesktop.timedate1.set-timezone===
Authentication is required to set the system timezone.
Authenticating as: jupyter
Password:
==== AUTHENTICATION COMPLETE ===
```

　確認する時は`date`コマンドが良いでしょう。JSTと日本時間表示になっていればOKです。

```sh
$ date
Wed Oct 14 00:40:18 JST 2020
```

## まとめ
　GCPでディープラーニング学習後に自動シャットダウンする仕組みを紹介しました。

　繰り返しになりますが、この記事を参考にして起きた事故に関しては、一切の責任はとれませんのでご了承ください。

　スクリプト応用すれば、シャットダウン以外にも学習完了の通知等、色々な応用ができると思います。もっと良い方法を知っている、作っているという人は是非教えてください（めちゃ知りたいです）。

　この記事がディープラーニングの学習の見守りにより睡眠不足の人（そんな人いるのか？）を1人でも救えたら幸いです。

## 参考リンク
[シェルスクリプトでtry-catch-finally](https://qiita.com/ryo0301/items/7bf1eaf00b037c38e2ea)

[GCPでできるだけ安くディープラーニング](https://blog.hiroshiba.jp/gcp-low-cost-deeplearning/)

## 関連記事
[GCPでのディープラーニング学習環境構築方法](https://qiita.com/karaage0703/items/77d6d75db9105a5e8983)