EC2のGPUインスタンスでディープラーニングの学習をしているとき、インスタンスを起動したままにしている方もいるかと思います。
仕事中に学習が終わればいいのですが、夜中に終わる見込みだった場合や土日を挟んで実行していた場合に無駄な課金が発生しないように対策をしたのでまとめておきます。
EC2だけではなく、自宅サーバーでGPUの学習をしている方も電気代がもったいないとか感じる方がいれば同じ方法で解決できるかと思います。
今回はdockerコンテナ内で学習をしていると仮定します。なのでdocker内でsudo shutdown -h 0とコマンドを打ってもホスト側がシャットダウンするわけではないので、何かいい方法はないかと考えていました。
最終的に思いついたのが、ホスト側で実行中のプロセスを監視してプロセスが存在する間は何もせず、プロセスが存在しなくなった場合にシャットダウンするという方法です。
例えば、本記事例では実行するGPUでの学習バッチがgpu_training.shだとします。
dockerコンテナ内で学習を開始
gpu_training.shの中身は何かディープラーニングを学習するプログラムと仮定します。
# パターン1で学習
python3 gpu_training.py
# パターン2で学習
python3 gpu_training2.py
# パターン3で学習
python3 gpu_training3.py
# 実行
nohup gpu_training.sh &
プロセスの確認 (ホスト側でもコンテナ側でもどちらでも確認できると思います)
下記コマンドでgpu_training.shを実行しているプロセスが確認できます。
# プロセス確認
ps -aux | grep gpu_training.sh
ubuntu 4365 0.0 0.0 4644 836 09:26 0.00 gpu_training.sh
このような感じのアウトプットが確認できます。
あとは30分に1回などの頻度でこのプロセスが存在するか確認するだけになります。
ホスト側にプロセス監視バッチを登録する
確認方法はcronが楽だと思います。
cronはcrontab -eコマンドで設定してもいいですが、事前にcron用の設定ファイルを作成しておいてcrontab [ファイル名]で読み込ませる方法もあります。
シャットダウンしたサーバーを再起動した場合に、cronの設定が生きているとタイミングによってはまたすぐシャットダウンしてしまいます。そのため、私はモニター処理の中でcronをオフにする設定を入れています。
# 30分ごとに起動し監視する
0,30 * * * * sh check_gpu_process.sh >> check_gpu_process.log
crontab -eで編集してもいいですし、crontab [ファイル名]で読み込ませてもいいです。
#!/bin/bash
# モニター対象のプロセスが存在するか確認する
CNT=`ps -aux | grep "sh gpu_training.sh" | grep -v grep | wc -l`
if [ $CNT -eq 0 ]; then
echo `date`':shutdown in 5min'
echo 'cron off'
crontab cron_off.txt
sudo shutdown -h 5
else
echo `date`':do nothing'
cron_off.txtの中身は空でも大丈夫だと思いますが、cronの設定をコメントアウトしたものでもわかりやすいと思います。
# 30分ごとに起動し監視する
#0,30 * * * * sh check_gpu_process.sh >> check_gpu_process.log
(オプション)ホスト側で学習スクリプトを実行しているのであれば、gpu_training.shの最後にシャットダウンコマンドを記載してもOK
# パターン1で学習
python3 gpu_training.py
# パターン2で学習
python3 gpu_training2.py
# パターン3で学習
python3 gpu_training3.py
# 5分後にシャットダウンする
sudo shutdown -h 5
他にも色々方法はあるかと思いますが、とりあえず私は本記事の内容で目的が達成できました 笑