AWS EC2 で Numerai Compute
この記事は、Numerai Advent Calendar 2020の10日目の記事です。
Numerai Compute とは?
Numerai Compute とは、Numeraiトーナメントの予測提出を自動化する仕組みです。
自分の予測プログラムをDockerイメージにしておけば、日曜日にNumerai ComputeサーバーがWebHookからコンテナを起動してくれます。
Numerai Computeを設定しているモデルには素敵なCOMPUTEバッジが付きます。
Numerai Compute(numerai-cli)の問題点
Numerai Compute(numerai-cli)では、DockerコンテナをAWS ECSのFargateで実行します。
現状、FargateではGPUを使えません。ニューラルネットワークでモデルを作成すると、GPUなしに予測を実行するにはとても時間がかかってしまいます。
というわけで、Numerai ComputeをEC2のGPUインスタンスを使って実行する方法を簡単にご紹介します。
構成
Numerai Compute WebHook から EC2 を起動
AWSは不慣れなので、参考になる資料をご紹介します。
- Lambda を使用して、Amazon EC2 インスタンスを一定の間隔で停止および起動するにはどうすればよいですか?
- API Gateway + LambdaでREST API開発を体験しよう [10分で完成編]
- Pythonしか書きたくない人が、AWS上にWEBアプリを作ってみました。
ざっくり流れを追うと、
- IAMを設定
- Lambda関数を設定
- API Gatewayを設定
という感じです。
EC2の起動スクリプトは次のような簡単なものです。
import json
import boto3
region = 'ap-northeast-1'
instances = ['i-YOUR-INSTANCE-ID']
ec2 = boto3.client('ec2', region_name=region)
def lambda_handler(event, context):
ec2.start_instances(InstanceIds=instances)
print('started your instances: ' + str(instances))
return {
'statusCode': 200,
'body': json.dumps('OK')
}
あとは、API Gatewayで作成したURLをNumeraiの設定すれば完成。
EC2インスタンス起動時にpredict.pyを実行する
EC2インスタンスは g4dn.xlarge を使用しています。GPU は NVIDIA T4 で RAMは 16GiB となっており、Google Colabと同等のスペックになっています。Google Colabから移植するにはもってこいですね!
AMIはDeep Learning AMIを使用すれば、最初からTensorFlowやPyTorchがインストールされていて便利です。
さて、EC2インスタンスの起動時にスクリプトを起動するように設定します。
cronで起動時に実行するスクリプトを設定しましょう。
crontab -e
@reboot /home/ubuntu/numerai/on_start.sh
実行するスクリプトはこんな感じです。
#!/bin/bash
cd `dirname $0`
SHELL=/bin/bash
# パスを通す
source /home/ubuntu/.bashrc
# 好きなPython環境を設定
source activate tensorflow2_latest_p37
sudo shutdown +45
python3 predict.py
predict.pyの起動前に、45分後にシャットダウンするように指示しています。
predict.py実行後に即シャットダウンだと、predict.pyがバグってる時にメンテで起動しようとしても、すぐシャットダウンしてしまうので要注意です。
predict.pyではDiscordに通知するようにしておくと便利です。
スクリプト全体をtryで囲って、エラーを全部Discordに流すようにしています。
import requests
import traceback
def discord_post(message, filename=None, url='https://discord.com/api/webhooks/YOUR_DISCORD_URL'):
payload = {"content": " " + message + " "}
try:
if filename is None:
requests.post(url, data=payload)
else:
files = {"imageFile": open(filename, "rb")}
requests.post(url, data=payload, files=files)
except:
pass
discord_post("Start predict.py")
try:
import pandas as pd
import numerapi
(中略)
except:
discord_post(traceback.format_exc() + "\nBAD END...")
ひととおり出来上がったら、NumeraiのSetting画面からWebHookをテスト起動してみて、動作確認をしましょう。
おわりに
最初の設定は面倒ですが、一度やってしまえば寝てる間に予測が提出されていて安心です。
土日の自由時間が増えますよ!ぜひやってみてください!
Discussion