1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

SageMaker 推論エンドポイントのコスト削減方法

Last updated at Posted at 2025-09-17

アミフィアブル株式会社AI研究部、エンジニアの吉村です。

はじめに

SageMaker AI を利用することで、モデルの訓練や訓練済みモデルを手軽に利用できます。しかし、モデルの訓練や利用にはそれなりの料金が発生します。本記事では主に SageMaker を利用した推論モデルのデプロイ・利用に焦点を当て、効果的なコスト削減方法について解説します。

対象読者は、AWS の基本知識があり、SageMaker を既に使用している、または使用検討中の方です。

SageMaker の料金は主にインスタンスタイプ利用時間によって決まります。モデルの性能要件に適したインスタンスを必要な時間だけ使用することが、コスト最適化の基本となります

SageMaker インスタンス

インスタンスの料金は、CPU/GPU の数、メモリ容量、およびリージョンによって決定されます。 詳細な料金情報は公式料金ページ で確認できます。

SageMaker 推論タイプ

SageMaker には主に以下の推論方式があります:

  1. リアルタイム推論:常時インスタンスが稼働し、リクエストをリアルタイムに処理
  2. 非同期推論:バッチ処理に適した非同期型の推論
  3. サーバーレス推論:リクエストに応じてインスタンスを自動的に起動・停止

リアルタイム推論と非同期推論は、あらかじめインスタンスを起動しておくため応答が速い一方、常時料金が発生します。サーバーレス推論はアクセス後にインスタンスを起動するため、アクセス頻度が低く、起動時間の遅延が許容できる場合に最もコスト効率が高くなります。

ただし、サーバーレス推論は現時点では GPU インスタンスに対応していない点に注意が必要です。GPU を必要とするモデルの場合は、リアルタイム推論か非同期推論を選択する必要があります。

Autoscaling

リアルタイム推論と非同期推論でコスト最適化を図る上で重要なのが、Autoscaling(自動スケーリング)機能です。これにより、需要に応じてインスタンス数を動的に調整できます。

Autoscaling には主に以下の 2 種類があります:

  1. スケジュールベース:時間帯によってインスタンス数を調整
  2. メトリクスベース:CPU/GPU 使用率やリクエスト数などの指標に基づいてスケーリング

※リアルタイム推論は最小インスタンス数が 1 であるのに対し、非同期推論は最小値を 0 に設定できます。そのため、夜間などの低使用時間帯には、非同期推論を使うことで完全にコストをゼロにできる可能性があります。

スケジュールベース実装例

SageMakerScalableTarget:
    Type: AWS::ApplicationAutoScaling::ScalableTarget
    Properties:
        MaxCapacity: 3
        MinCapacity: 0
        ResourceId: !Sub "endpoint/${SageMakerEndpoint.EndpointName}/variant/${variantName}"
        RoleARN: !GetAtt SageMakerScalableTargetRole.Arn
        ScalableDimension: "sagemaker:variant:DesiredInstanceCount"
        ServiceNamespace: "sagemaker"
        ScheduledActions:
            - ScalableTargetAction:
                MaxCapacity: 3
                MinCapacity: 1
              Schedule: "cron(00 9 ? * MON-FRI *)"
              ScheduledActionName: ScaleOutSchedule
              Timezone: Asia/Tokyo
            - ScalableTargetAction:
                MaxCapacity: 0
                MinCapacity: 0
              Schedule: "cron(00 17 ? * MON-FRI *)"
              ScheduledActionName: ScaleInSchedule
              Timezone: Asia/Tokyo

この設定では、平日の9時に最小1、最大3インスタンスとなり、17時に0インスタンスになります。

メトリクスベース実装例

SageMakerScalableTarget:
    Type: AWS::ApplicationAutoScaling::ScalableTarget
    Properties:
        MaxCapacity: 3
        MinCapacity: 0
        ResourceId: !Sub "endpoint/${SageMakerEndpoint.EndpointName}/variant/${variantName}"
        RoleARN: !GetAtt SageMakerScalableTargetRole.Arn
        ScalableDimension: "sagemaker:variant:DesiredInstanceCount"
        ServiceNamespace: "sagemaker"
SageMakerScalingPolicy:
    Type: AWS::ApplicationAutoScaling::ScalingPolicy
    Properties:
        PolicyName: SageMakerAutoScalingPolicy
        PolicyType: TargetTrackingScaling
        ScalingTargetId: !Ref SageMakerScalableTarget
        ServiceNamespace: sagemaker
        ScalableDimension: sagemaker:variant:DesiredInstanceCount
        TargetTrackingScalingPolicyConfiguration:
            TargetValue: 1
            ScaleInCooldown: 300
            ScaleOutCooldown: 300
            CustomizedMetricSpecification:
                MetricName: ApproximateBacklogSizePerInstance
                Namespace: 'AWS/SageMaker'
                Dimensions:
                 - Name: EndpointName
                   Value: !GetAtt SageMakerEndpoint.EndpointName
                Statistic: Average

この設定では、インスタンスあたりのバックログサイズの平均値が1を超えると自動的にスケールアウトし、1を下回るとスケールインします。クールダウン期間(300秒)を設けることで、頻繁なスケーリングを防ぎます。

スケジュールベースとメトリクスベースのミスマッチ

通常、スケジュールベースの設定(ScheduledActions)とメトリクスベースの設定(ScalingPolicy)を単純に組み合わせようとすると、意図した動作を得られないことがあります。例えば:

SageMakerScalableTarget:
    Type: AWS::ApplicationAutoScaling::ScalableTarget
    Properties:
        MaxCapacity: 3
        MinCapacity: 0
        ResourceId: !Sub "endpoint/${SageMakerEndpoint.EndpointName}/variant/${variantName}"
        RoleARN: !GetAtt SageMakerScalableTargetRole.Arn
        ScalableDimension: "sagemaker:variant:DesiredInstanceCount"
        ServiceNamespace: "sagemaker"
        ScheduledActions:
            - ScalableTargetAction:
                MaxCapacity: 3
                MinCapacity: 1
              Schedule: "cron(00 9 ? * MON-FRI *)"
              ScheduledActionName: ScaleOutSchedule
              Timezone: Asia/Tokyo
            - ScalableTargetAction:
                MaxCapacity: 0
                MinCapacity: 0
              Schedule: "cron(00 17 ? * MON-FRI *)"
              ScheduledActionName: ScaleInSchedule
              Timezone: Asia/Tokyo
SageMakerScalingPolicy:
    Type: AWS::ApplicationAutoScaling::ScalingPolicy
    Properties:
        PolicyName: SageMakerAutoScalingPolicy
        PolicyType: TargetTrackingScaling
        ScalingTargetId: !Ref SageMakerScalableTarget
        ServiceNamespace: sagemaker
        ScalableDimension: sagemaker:variant:DesiredInstanceCount
        TargetTrackingScalingPolicyConfiguration:
            TargetValue: 1
            ScaleInCooldown: 300
            ScaleOutCooldown: 300
            CustomizedMetricSpecification:
                MetricName: ApproximateBacklogSizePerInstance
                Namespace: 'AWS/SageMaker'
                Dimensions:
                 - Name: EndpointName
                   Value: !GetAtt SageMakerEndpoint.EndpointName
                Statistic: Average              

この方法では、メトリクスベースのスケーリングポリシーが常に ScalableTarget の MinCapacity と MaxCapacity の範囲内でしか動作しません。そのため、17時以降に完全にインスタンスをゼロにするスケジュールアクションが設定されたとしても、ScalableTargetの基本設定が異なると期待通りに動作しない場合があります。

EventBridge による解決

この問題を解決するために、スケジュールベースのアクションとして ScheduledActions を使用する代わりに、EventBridge Scheduler を使用して、時間帯に応じて ScalableTarget 自体の MinCapacity と MaxCapacity を動的に変更する方法が効果的です。

基本的なScalableTargetの設定メトリクスベースのスケーリングポリシーに以下の実装例を加えることで
EventBridge Schedulerを使って時間帯によって ScalableTarget の範囲自体を変更します

SageMakerScheduleRole:
    Type: AWS::IAM::Role
    Properties:
        AssumeRolePolicyDocument:
            Version: "2012-10-17"
            Statement:
                - Effect: Allow
                  Principal:
                    Service: scheduler.amazonaws.com
                  Action: sts:AssumeRole
        ManagedPolicyArns:
            - arn:aws:iam::aws:policy/AmazonEventBridgeSchedulerFullAccess
            - !Ref SageMakerSchedulePolicy
SageMakerSchedulePolicy:
    Type: AWS::IAM::ManagedPolicy
    Properties:
        Description: "Permission for EventBridge to manage SageMaker autoscaling"
        PolicyDocument:
            Version: "2012-10-17"
            Statement:
                - Effect: Allow
                  Action:
                    - application-autoscaling:RegisterScalableTarget
                    - application-autoscaling:DescribeScalableTargets
                    - application-autoscaling:TagResource
                    - cloudwatch:PutMetricAlarm
                    - cloudwatch:DeleteAlarms
                    - cloudwatch:DescribeAlarms
                    - sagemaker:DescribeEndpointConfig
                    - sagemaker:DescribeEndpoint
                    - sagemaker:UpdateEndpointWeightsAndCapacities
                  Resource: '*'

SageMakerScaleOutSchedule:
    Type: AWS::Scheduler::Schedule
    Properties:
        ScheduleExpression: "cron(00 9 ? * MON-FRI *)"
        FlexibleTimeWindow:
            Mode: "OFF"
        ScheduleExpressionTimezone: Asia/Tokyo
        Target:
            Arn: arn:aws:scheduler:::aws-sdk:applicationautoscaling:registerScalableTarget
            Input: !Sub |
                {
                    "ServiceNamespace": "sagemaker",
                    "ResourceId": "endpoint/${SageMakerEndpoint.EndpointName}/variant/${variantName}",
                    "ScalableDimension": "sagemaker:variant:DesiredInstanceCount",
                    "MaxCapacity": 3,
                    "MinCapacity": 1
                }
            RoleArn: !GetAtt SageMakerScheduleRole.Arn
            
SageMakerScaleInSchedule:
    Type: AWS::Scheduler::Schedule
    Properties:
        ScheduleExpression: "cron(00 17 ? * MON-FRI *)"
        FlexibleTimeWindow:
            Mode: "OFF"
        ScheduleExpressionTimezone: Asia/Tokyo
        Target:
            Arn: arn:aws:scheduler:::aws-sdk:applicationautoscaling:registerScalableTarget
            Input: !Sub |
                {
                    "ServiceNamespace": "sagemaker",
                    "ResourceId": "endpoint/${SageMakerEndpoint.EndpointName}/variant/${variantName}",
                    "ScalableDimension": "sagemaker:variant:DesiredInstanceCount",
                    "MaxCapacity": 0,
                    "MinCapacity": 0
                }
            RoleArn: !GetAtt SageMakerScheduleRole.Arn

この実装では、EventBridge Schedulerを使用して以下のようなスケーリング制御を行います:

  1. 平日9時:業務時間開始にインスタンス数の最小値を1、最大値を3に設定
  2. 平日17時:業務時間終了後にインスタンス数の最小値と最大値を0に設定し、完全に停止

これにより、ScheduledActions を使用する代わりに、EventBridge Scheduler を使ってより柔軟なスケーリング制御が可能になります。EventBridge Scheduler を使用する大きな利点は、ScalableTarget の MinCapacity と MaxCapacity をAPI経由で直接変更できることです。これにより、メトリクスベースのスケーリングが機能する範囲を時間帯によって動的に変更でき、業務時間中はメトリクスに応じたスケーリング、業務時間外は完全停止という最適な運用が実現できます。

まとめ

SageMakerは強力なML基盤を提供しますが、適切に設計・運用しなければコストが高くなりがちです。しかし、本記事で紹介した手法を取り入れることで、大幅なコスト削減が可能になります。特に:

  1. 適切な推論タイプの選択(リアルタイム、非同期、サーバーレス)
  2. Autoscalingの効果的な活用(メトリクスベース)
  3. EventBridge Schedulerを使用したAutoscalingの設定変更

これらの手法を組み合わせることで、コストを最適化したSageMaker環境を構築できます。また、非同期推論と組み合わせることで、業務時間外のコストを完全にゼロにすることが可能です。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?