はじめに
この記事は DENSO アドベントカレンダー 2025 の3日目の記事です。
業務でSageMaker AIのTraining Jobsを触ったので、つまずいたことやTipsをざっくばらんにまとめます。
同じところでつまずく方の参考になれば幸いです。
注意
私はモデルの作成を行っているわけではなく、機械学習環境を提供する目的でSageMaker AIを利用しているため、MLOps機能などは活用できていません。
SageMaker AIとは
Amazon SageMaker AIは、AWSが提供するフルマネージド型の機械学習(ML)サービスです。
2024年12月のre:Invent 2024で、従来の「Amazon SageMaker」は「Amazon SageMaker AI」に名称変更されました。同時に、データ分析とAI開発を統合した次世代の「Amazon SageMaker」が発表されています。
参考: AWS re:Invent 2024のAmazon SageMaker AIのアップデートまとめ
本記事では、主にTraining Jobs(トレーニングジョブ)を中心としたSageMaker AIの機能について触れます。
SageMaker AIがマネージしてくれること
Training Jobsを使用する場合、以下をAWSがマネージしてくれます
-
インスタンスの確保・管理
- 指定したインスタンスタイプの起動・終了を自動で行う
- スポットインスタンスの利用もサポート
-
ログ出力
- CloudWatch Logsへの自動連携
- 標準出力・標準エラー出力がそのままログとして記録される
-
S3とのファイル連携
- input: トレーニング開始時にS3から入力データを自動取得
- output: トレーニング完了時に成果物(モデルなど)をS3へ自動アップロード
-
インスタンスのメトリクス表示
- CPU/GPU使用率、メモリ使用量などをCloudWatchで確認可能
Tips
1. エントリーポイントのデフォルトは train
SageMaker AI Training Jobsを使い始めたとき、最初につまずいたのがエントリーポイントの問題でした。
SageMaker AIでは、デフォルトのエントリーポイントが train に設定されています。そのため、オリジナルのコードやモデルを使って学習しようとすると、「スクリプトが見つからない」といったエラーに遭遇することがあります。
私の場合は、DockerfileでENTRYPOINTを指定することで解決しました。ここで注意が必要なのは、CMDでは上書きできないという点です。
# 例:ENTRYPOINTで上書き
ENTRYPOINT ["python", "-m", "model.main_allinone"]
他にも SAGEMAKER_PROGRAM 環境変数や、SageMaker Python SDKの entry_point パラメータで指定する方法もあるようです。
参考: How Amazon SageMaker AI Runs Your Training Image
2. ジョブ名が重複すると起動に失敗する
これは地味にハマりやすいポイントです。
Training Jobのジョブ名はAWSリージョン・アカウント内で一意である必要があります。つまり、過去に使用したジョブ名を再利用しようとすると起動に失敗します。
私が引っかかったのは、dev環境をリセットして以前と同じインデックスを使ったときや、動作確認用だからと test や debug といった適当なジョブ名を設定したときでした。一度使った名前は二度と使えないので、注意が必要です。
対策としては、タイムスタンプやUUIDを付与して常に一意になるようにするのが確実です。
参考: CreateTrainingJob - Amazon SageMaker
3. インスタンスが確保できない問題
SageMaker AIを運用していて一番頭を悩ませたのが、インスタンスの確保問題でした。
まず前提として、SageMaker AI Training Jobsでは2種類のインスタンスを使用できます。
| 種類 | 特徴 | コスト |
|---|---|---|
| オンデマンド | 中断なし、安定稼働 | 高い |
| スポット(Managed Spot Training) | 最大90%割引、中断の可能性あり | 安い |
コストを抑えるためにスポットインスタンスを選びたくなりますが、ここに落とし穴があります。スポットインスタンスは需要が高いとなかなか確保できなかったり、学習中に突然インスタンスを没収されて学習が中断されることがあるのです。最近はSageMaker AIの需要が高まっているのか、争奪戦が激しくなっている印象です。特にGPUインスタンスは人気が高く、確保が難しい傾向があります。
参考: Managed Spot Training in Amazon SageMaker AI
では、オンデマンドインスタンスなら安心かというと、そうでもありませんでした。一時期(2025年5月末ごろ)は時間帯によってオンデマンドインスタンスすら確保が難しく、6割近くの学習がインスタンスを確保できず実行できなかったこともありました。
ただし現在はこの問題は解消されており、オンデマンドインスタンスはほぼ100%確保できるようになっています。
対策として考えられること
当時、対策として以下のようなことを検討しました。
- キャパシティ予約(Capacity Reservations)
- 複数のインスタンスタイプをフォールバックとして設定
- 別リージョンのインスタンスを使用する
ただし実際は、使用量に波があったりデータの輸出の問題などもあり、なかなか対策が難しいことが多かったです。繰り返しになりますが、現在はインスタンスを確保しやすくなっているので、今からSageMaker AIを使い始める方はあまり心配しなくて良いと思います。
私たちの環境での工夫
コスト最適化のため、まずスポットインスタンスの確保を試み、確保できない場合はオンデマンドインスタンスにフォールバックする実装をしています。これにより、スポットインスタンスが使えるときはコストを抑えつつ、確保できないときも学習が止まらないようにしています。
なお、スポットインスタンスの中断リスクは AWS EC2 Spot Instance Advisor でざっくりと確認できます。かなり大まかな情報ですが、インスタンスの人気度の参考にはなります。
4. raiseするだけではSageMaker AIがエラーメッセージを拾ってくれない
学習が失敗したとき、原因をすぐに特定したいですよね。SageMaker AIはコンソール上に失敗の原因を表示してくれるのですが、ここにも落とし穴がありました。
メモリのOOMやインスタンスが確保できないなど、SageMaker AIがあらかじめ用意しているエラーはきちんと表示されます。しかし、学習コード内での失敗は、コンソールに以下のようにしか表示されません。
AlgorithmError: , exit code: 1
これだと「コード内で何かエラーが起きた」ということしかわかりません。結局、CloudWatch Logsを開いてエラーログを探しに行く必要があります。
カスタムエラーメッセージを設定する方法
調べてみると、実はカスタムエラーメッセージを設定する方法がありました。/opt/ml/output/failure ファイルにエラーメッセージを書き込むと、DescribeTrainingJob APIの FailureReason に反映されます(最初の1024文字まで)。
import sys
try:
raise Exception("Intentional error for testing failure output")
except Exception as e:
# カスタムエラーメッセージをfailureファイルに書き込む
with open('/opt/ml/output/failure', 'w') as f:
f.write(str(e)[:1024])
sys.exit(1)
上記のようなコードで実行したところ、コンソールに以下のように表示されます。
AlgorithmError: Intentional error for testing failure output, exit code: 1
ただし、これでもコンソール上の表示には反映されないことがあるようです。確実にエラー内容を把握するには、やはりCloudWatch Logsを確認するのが一番です。
参考: How to send own failure info in case of failed SageMaker Training Job?
余談ですが、学習の進捗などを標準出力していると、ログが大量になってエラーログの調査が大変になります。学習の進捗はCSVファイルに出力しておくのもおすすめです。
まとめ
SageMaker AIのTraining Jobsを使う上で、私がハマったポイントや学んだことをまとめました。
他にも工夫した点や知見がまだまだあるので、時間があるときに追記していく予定です。