はじめに
AWSのSagemakerが公開されてからExperimentsを作成したり、
Autopilotを試してみたりしているのではないでしょうか。
ただ、色々試してみてゴミのExperimentsが徐々に溜まってきたのではないでしょうか?
そろそろ使わなくなったExperimentsを消そう!私はそう思った訳です。
Studioからは消せない
GUIで消せれば良いのにどうやら消す方法はなさそうです。(2020/3/4現在)
APIで消す
色々調べてたらAPIを使えば消せそうです。
以下を実行!
import boto3
EXPERIMENT_NAME = '<Experiment名>'
client = boto3.client('sagemaker')
client.delete_experiment(
ExperimentName=EXPERIMENT_NAME
)
ClientError: An error occurred (ValidationException) when calling the DeleteExperiment operation: Experiment 'arn:aws:sagemaker:us-east-2:<ID>:experiment/<Experiment名>' has trials and cannot be deleted.
どうやらトライアルを消さないといけないようです。
公式にも書いてありました。
もうこの先を試した方はわかると思いますが、トライアルも消せません。
関連するTrial Componentの関連付けを外さないといけません。
ここまですればTrialを削除することができます。
あとは全てのTrialを削除するだけです。
最終的に書いたコードは以下の通りです。
import boto3
EXPERIMENT_NAME = '<Experiment名>'
MAX_RESULTS = 100 # 一度の検索で取得する数
TRY_NUM = 10 # 再実行も含めて実行する数
client = boto3.client('sagemaker')
def delete_experiment(experiment_name, max_results):
while True:
# Trial listの取得
trial_list = client.list_trials(
ExperimentName=experiment_name,
MaxResults=max_results,
)
trial_num = len(trial_list['TrialSummaries'])
# 全てのTrialを消したら処理終了
if trial_num == 0:
break
print("Info: Number of trials left: Over {}".format(trial_num))
# Trial component listの取得
for trial in trial_list['TrialSummaries']:
trial_name = trial['TrialName']
trial_component_list = client.list_trial_components(
TrialName=trial_name,
MaxResults=max_results,
)
# 関連付けを外す
for trial_component in trial_component_list['TrialComponentSummaries']:
trial_component_name = trial_component['TrialComponentName']
response = client.disassociate_trial_component(
TrialComponentName=trial_component_name,
TrialName=trial_name
)
# Trialの削除
client.delete_trial(
TrialName=trial_name
)
print("Info: Trial deleted. [{}]".format(trial_name))
# 全てのTrialを消したらExperimentを削除
client.delete_experiment(
ExperimentName=experiment_name
)
print("Info: Experiment deleted. [{}]".format(experiment_name))
for i in range(1, TRY_NUM + 1):
try:
# Experimentが存在したら削除処理を実行
experiment_list_all = client.list_experiments(
MaxResults = MAX_RESULTS
)
experiment_name_list = [experiment['ExperimentName'] for experiment in experiment_list_all['ExperimentSummaries']]
if EXPERIMENT_NAME in experiment_name_list:
delete_experiment(EXPERIMENT_NAME, MAX_RESULTS)
except Exception as e:
print("Error: {}".format(e))
print("Try: {i}/{max}".format(i=i, max=TRY_NUM))
except Exception as e:
print(e)
いくつか補足いたします。
MAX_RESULTSは何を指定する?
TrialやTrial Componentのリストを取得する際、
取得できる数に限りがあります。
現状では一度のAPIの実行でMax100件までしか取得できません。
そこで一旦MAX_RESULTSとして100の値を入れています。
そのため、Trialを取得するところは無限ループして全てのTrialを削除するまで実行するようになっています。
Autopilotを使うと100個以上Trialが作られることは結構当たり前だと思いますので。。
本当に厳密にやるならばTrial Componentのリストを取得する際も無限ループにすべきだと思うのですが、
現状一つのTrialで100個以上のTrial Componentを作ることはあまりないのかなと思い、
一旦Trialのリスト取得時のみ無限ループさせる形にしました。
TRY_NUMは何を指定する?
本処理は何度かリトライ動作を行う処理を入れています。(リトライ回数は自身で必要だと思う数を指定してください。)
この理由としては、Disassociateの処理を行う際にたまになぜか失敗してしまうんですよね。
何回か試してみて分かったのですが間隔として10回に1回くらいですね。(でも本当に回数は気まぐれです)
以下のようなエラーがでます。
ClientError: An error occurred (ThrottlingException) when calling the DisassociateTrialComponent operation (reached max retries: 4): Rate exceeded
Disassociateの処理自体が失敗しやすいのか、内部でもリトライを行っているのですが、
4回までしか実施できません。
APIでリトライ回数を指定するか、もうちょっとリトライ回数を増やしてくれればよいのですが。。。
参考
リトライの処理は下記サイトを参考にさせていただきました。
https://uyamazak.hatenablog.com/entry/2017/01/17/170235