3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ローカルの学習環境をそのままクラウドへ。Docker + AWS ECS (EC2) で構築するポータブルなGPU学習ワークフロー

Posted at

1. この記事で実現できること

深層学習を用いた研究・案件を進めていると、多くの方が一度はこのような課題に直面するのではないでしょうか。

  • 一時的なリソース不足

「論文(or プロジェクト)の締め切り前に、多くの実験を並行して行いたいが、手元のPCだけでは1つの実験しか実行できない…。」

  • ハードウェア購入の躊躇

「新しいGPUがもうすぐ発表されそうで、今高価なワークステーションを買うのは避けたい。」

  • VRAM不足への対応

「ローカルマシンのVRAMでは、最新の巨大なモデルを読み込むことすらできない。」

  • 環境構築の煩雑さ

「普段使い慣れたローカルの学習コードを、Google Colabなどのクラウドサービスに移植して、ライブラリのバージョンを合わせるのが大変…。」

本記事では、これらの課題を解決するため、AWS (Amazon Web Services) を活用した、柔軟かつ再現性の高いGPU学習環境を構築する方法をご紹介します

この手法を用いることで、以下のことが可能になります。

  • 必要な時だけ、強力なGPUインスタンスを一時的に利用できます。
  • Dockerを使い、ローカルの学習環境をそのままクラウドへ移行できます。
  • S3を使い、大容量の学習データや学習済みモデルをクラウドで一元管理できます。
  • 簡単なコマンド一つで、自動的に学習を開始する仕組みを構築できます。
  • モデルの構造を変更しても、コンテナを更新するだけで、すぐに新しいモデルでの学習に対応できます。

2. ワークフローの全体像

このワークフローは、大きく分けて「事前準備」と「学習実行」の2つのフェーズから構成されます。

  1. 学習データのアップロード (S3)
    まず、学習に用いるデータセットをAWSのストレージサービスであるS3バケットにアップロードしておきます。S3は容量を気にせずデータを保管できるため、大規模データの扱いにも適しています。

  2. 学習環境(Dockerイメージ)の登録 (ECR)
    次に、ローカル環境で作成した学習用のDockerイメージを、AWSのコンテナレジストリサービスであるECR (Elastic Container Registry) に登録します。これにより、自作した環境をプライベートかつ安全にAWS上で管理できます。

  3. 学習基盤とタスク定義の作成

    CloudFormationを使い、GPUが利用可能なECSクラスターや関連リソースを一度の操作で構築します。同時に、タスク定義を作成し、「どのDockerイメージを、どれくらいのCPU・メモリ・GPUリソースを使って動かすか」といった、コンテナの実行設計図を定めます。

  4. 学習タスクの実行と自動データ連携
    準備が整ったら、ECSタスクを実行します。タスクが開始されると、以下の処理が自動で行われます。

    • S3バケットから学習データをコンテナ内に同期します。
    • コンテナ内で学習スクリプトが実行されます。
    • 学習によって生成されたモデルの重みやログなどの結果が、再びS3バケットへ保存されます。

image.png

3. アーキテクチャ

3.1. 全体アーキテクチャ図

はじめに、学習環境の全体構成を解説します。

以下のファイルはこれから説明するアーキテクチャをすべて含んだtemplateファイルです。CloudFormatinを用いてこのファイルからすべてのリソースを作成できます。

ecs-gpu-cluster.yml
AWSTemplateFormatVersion: '2010-09-09'
Description: >
  汎用テンプレート: プライベートサブネット内にGPU対応のECSクラスタを構築します。
  NAT Gateway経由でのインターネットアクセスと、AWS Systems Manager Session Managerからのアクセスが可能です。
Parameters:
  # ------------------------------------------------------------
  # 基本設定
  # ------------------------------------------------------------
  ClusterName:
    Type: String
    Default: your-ecs-cluster
    Description: 作成するECSクラスタの名前。

  # ------------------------------------------------------------
  # ネットワーク設定 (ご利用のAWS環境に合わせて設定してください)
  # ------------------------------------------------------------
  VpcId:
    Type: AWS::EC2::VPC::Id
    Description: クラスタを構築するVPCのIDを選択してください。
  VpcCidr:
    Type: String
    Description: 選択したVPCのCIDRブロック (例: 10.0.0.0/16)。VPCエンドポイントのセキュリティグループで必要です。
  SubnetIds:
    Type: List<AWS::EC2::Subnet::Id>
    Description: EC2インスタンスを配置するプライベートサブネットを1つ以上選択してください。
  PrivateRouteTableId:
    Type: String
    Description: プライベートサブネットに関連付けられているルートテーブルのID。AWSコンソールで確認し、入力してください。このルートテーブルにNAT Gatewayへのルートが追加されます。
  PublicSubnetCidr:
    Type: String
    Default: 10.0.255.0/24 # 例。既存のサブネットと重複しないように注意してください。
    Description: NAT Gatewayを配置する新しいパブリックサブネットのCIDRブロック。既存のサブネットと重複しないようにしてください。

  # ------------------------------------------------------------
  # インスタンス・コンテナ設定
  # ------------------------------------------------------------
  GpuInstanceType:
    Type: String
    AllowedValues: [g4dn.xlarge, g5.xlarge, p3.2xlarge] # 必要に応じて他のインスタンスタイプを追加
    Default: g4dn.xlarge
    Description: ECSインスタンスとして使用するGPUインスタンスのタイプ。
  UseSpot:
    Type: String
    AllowedValues: [true, false]
    Default: true
    Description: スポットインスタンスを使用するかどうか。
  InstanceVolumeSize:
    Type: Number
    Default: 200
    Description: EC2インスタンスのルートボリュームのサイズ (GB)。
  EcrImageUri:
    Type: String
    Description: 'タスクで実行するECR上のDockerイメージのURI (例: 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/your-repo:latest)。'

  # ------------------------------------------------------------
  # アプリケーション・S3・Secrets Manager設定
  # ------------------------------------------------------------
  DatasetBucketName:
    Type: String
    Description: データセットが格納されているS3バケット名。
  WandbSecretArn:
    Type: String
    Description: WANDB_API_KEYを格納しているSecrets ManagerシークレットのARN。
    Default: "arn:aws:secretsmanager:REGION:ACCOUNT_ID:secret:YOUR_SECRET_NAME-XXXXXX"

Conditions:
  UseSpotCond: !Equals [ !Ref UseSpot, 'true' ]

Resources:
#-----------------------------------------------------------------------
# NETWORKING - NAT Gateway and Public Subnet Configuration
#-----------------------------------------------------------------------
  PublicSubnet:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VpcId
      CidrBlock: !Ref PublicSubnetCidr
      AvailabilityZone: !Select [ 0, !GetAZs '' ]
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: !Sub "${ClusterName}-public-subnet-for-nat"

  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: !Sub "${ClusterName}-igw"

  VPCGatewayAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref VpcId
      InternetGatewayId: !Ref InternetGateway

  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VpcId
      Tags:
        - Key: Name
          Value: !Sub "${ClusterName}-public-rt"

  PublicSubnetRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet
      RouteTableId: !Ref PublicRouteTable

  PublicRouteToInternet:
    Type: AWS::EC2::Route
    DependsOn: VPCGatewayAttachment
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway

  NatGatewayEIP:
    Type: AWS::EC2::EIP
    Properties:
      Domain: vpc

  NatGateway:
    Type: AWS::EC2::NatGateway
    Properties:
      AllocationId: !GetAtt NatGatewayEIP.AllocationId
      SubnetId: !Ref PublicSubnet
      Tags:
        - Key: Name
          Value: !Sub "${ClusterName}-nat"

  PrivateRouteToNat:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PrivateRouteTableId
      DestinationCidrBlock: 0.0.0.0/0
      NatGatewayId: !Ref NatGateway

#-----------------------------------------------------------------------
# IAM Roles and Profiles
#-----------------------------------------------------------------------
  ECSInstanceRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal: { Service: ec2.amazonaws.com }
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role
        - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore

  ECSInstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
      Roles: [ !Ref ECSInstanceRole ]

  TaskExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal: { Service: ecs-tasks.amazonaws.com }
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
      Policies:
        - PolicyName: AllowWandbSecretAccess
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action: secretsmanager:GetSecretValue
                Resource: !Ref WandbSecretArn

  TaskRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal: { Service: ecs-tasks.amazonaws.com }
            Action: sts:AssumeRole
      Policies:
        - PolicyName: EcsExecAndAppPermissions
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - ssm:GetConnectionStatus
                  - ssm:StartSession
                  - ssm:TerminateSession
                  - ssm:DescribeSessions
                Resource: "*"
              - Effect: Allow
                Action: secretsmanager:GetSecretValue
                Resource: !Ref WandbSecretArn
        - PolicyName: S3DatasetAccess
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action: [s3:GetObject, s3:PutObject, s3:ListBucket]
                Resource:
                  - !Sub arn:aws:s3:::${DatasetBucketName}
                  - !Sub arn:aws:s3:::${DatasetBucketName}/*

#-----------------------------------------------------------------------
# NETWORKING - Security Groups and VPC Endpoints
#-----------------------------------------------------------------------
  ClusterSG:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Security Group for ECS GPU Instances
      VpcId: !Ref VpcId
      SecurityGroupEgress:
        - IpProtocol: -1
          CidrIp: 0.0.0.0/0

  EndpointSG:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: SG for VPC Endpoints to allow access from within the VPC
      VpcId: !Ref VpcId
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 443
          ToPort: 443
          SourceSecurityGroupId: !GetAtt ClusterSG.GroupId

  S3GatewayEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      VpcId: !Ref VpcId
      ServiceName: !Sub "com.amazonaws.${AWS::Region}.s3"
      VpcEndpointType: Gateway
      RouteTableIds:
        - !Ref PrivateRouteTableId

  # Interface Endpoints for SSM, ECS, ECR, CloudWatch
  SsmEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      VpcId: !Ref VpcId
      ServiceName: !Sub "com.amazonaws.${AWS::Region}.ssm"
      VpcEndpointType: Interface
      SubnetIds: !Ref SubnetIds
      SecurityGroupIds: [!Ref EndpointSG]

  SsmMessagesEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      VpcId: !Ref VpcId
      ServiceName: !Sub "com.amazonaws.${AWS::Region}.ssmmessages"
      VpcEndpointType: Interface
      SubnetIds: !Ref SubnetIds
      SecurityGroupIds: [!Ref EndpointSG]

  Ec2MessagesEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      VpcId: !Ref VpcId
      ServiceName: !Sub "com.amazonaws.${AWS::Region}.ec2messages"
      VpcEndpointType: Interface
      SubnetIds: !Ref SubnetIds
      SecurityGroupIds: [!Ref EndpointSG]

  EcsApiEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      VpcId: !Ref VpcId
      ServiceName: !Sub "com.amazonaws.${AWS::Region}.ecs"
      VpcEndpointType: Interface
      SubnetIds: !Ref SubnetIds
      SecurityGroupIds: [ !Ref EndpointSG ]

  EcsAgentEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      VpcId: !Ref VpcId
      ServiceName: !Sub "com.amazonaws.${AWS::Region}.ecs-agent"
      VpcEndpointType: Interface
      SubnetIds: !Ref SubnetIds
      SecurityGroupIds: [ !Ref EndpointSG ]

  EcrApiEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      VpcId: !Ref VpcId
      ServiceName: !Sub "com.amazonaws.${AWS::Region}.ecr.api"
      VpcEndpointType: Interface
      SubnetIds: !Ref SubnetIds
      SecurityGroupIds: [ !Ref EndpointSG ]

  EcrDkrEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      VpcId: !Ref VpcId
      ServiceName: !Sub "com.amazonaws.${AWS::Region}.ecr.dkr"
      VpcEndpointType: Interface
      SubnetIds: !Ref SubnetIds
      SecurityGroupIds: [ !Ref EndpointSG ]

  CloudWatchLogsEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      VpcId: !Ref VpcId
      ServiceName: !Sub "com.amazonaws.${AWS::Region}.logs"
      VpcEndpointType: Interface
      SubnetIds: !Ref SubnetIds
      SecurityGroupIds: [ !Ref EndpointSG ]

#-----------------------------------------------------------------------
# ECS Cluster and Capacity
#-----------------------------------------------------------------------
  ECSCluster:
    Type: AWS::ECS::Cluster
    Properties:
      ClusterName: !Ref ClusterName
      Configuration:
        ExecuteCommandConfiguration:
          Logging: DEFAULT
      CapacityProviders: [!Ref GpuSpotProvider]
      DefaultCapacityProviderStrategy:
        - CapacityProvider: !Ref GpuSpotProvider
          Weight: 1

  GpuSpotProvider:
    Type: AWS::ECS::CapacityProvider
    Properties:
      AutoScalingGroupProvider:
        AutoScalingGroupArn: !Ref Asg
        ManagedScaling:
          Status: ENABLED
          TargetCapacity: 100
          MinimumScalingStepSize: 1
      Name: !Sub "${ClusterName}-gpu-spot"

  LaunchTemplate:
    Type: AWS::EC2::LaunchTemplate
    Properties:
      LaunchTemplateData:
        BlockDeviceMappings:
          - DeviceName: /dev/xvda
            Ebs:
              VolumeSize: !Ref InstanceVolumeSize
        ImageId: !Sub "{{resolve:ssm:/aws/service/ecs/optimized-ami/amazon-linux-2/gpu/recommended/image_id}}"
        IamInstanceProfile: { Name: !Ref ECSInstanceProfile }
        NetworkInterfaces:
          - DeviceIndex: 0
            AssociatePublicIpAddress: false
            DeleteOnTermination: true
            Groups:
              - !Ref ClusterSG
        InstanceType: !Ref GpuInstanceType
        InstanceMarketOptions:
          !If [UseSpotCond, { MarketType: spot, SpotOptions: { SpotInstanceType: one-time, InstanceInterruptionBehavior: terminate } }, !Ref "AWS::NoValue" ]
        UserData:
          Fn::Base64: !Sub |
            #!/bin/bash
            echo ECS_CLUSTER=${ClusterName} >> /etc/ecs/ecs.config
            echo ECS_ENABLE_GPU_SUPPORT=true >> /etc/ecs/ecs.config
  Asg:
    Type: AWS::AutoScaling::AutoScalingGroup
    Properties:
      VPCZoneIdentifier: !Ref SubnetIds
      MinSize: '1'
      MaxSize: '1'
      DesiredCapacity: '1'
      LaunchTemplate:
        LaunchTemplateId: !Ref LaunchTemplate
        Version: !GetAtt LaunchTemplate.LatestVersionNumber

#-----------------------------------------------------------------------
# Logs and Task Definition
#-----------------------------------------------------------------------
  TrainLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub "/ecs/${ClusterName}/train"
      RetentionInDays: 7 # ログの保持期間

  TrainTaskDef:
    Type: AWS::ECS::TaskDefinition
    Properties:
      Family: !Sub "${ClusterName}-train"
      RequiresCompatibilities: [ EC2 ]
      Cpu: '4096'    # 必要に応じて調整してください
      Memory: '14000' # 必要に応じて調整してください
      ExecutionRoleArn: !GetAtt TaskExecutionRole.Arn
      TaskRoleArn: !GetAtt TaskRole.Arn
      NetworkMode: bridge
      ContainerDefinitions:
        - Name: trainer-container
          Image: !Ref EcrImageUri
          EntryPoint: ["/bin/bash","-c"]
          # --- ↓↓↓ このコマンドは、あなたのアプリケーションに合わせて修正してください ↓↓↓ ---
          Command:
            - !Sub |
              aws s3 sync s3://${DatasetBucketName}/input /app/data &&
              python train.py --data /app/data &&
              aws s3 cp /app/checkpoints s3://${DatasetBucketName}/output/checkpoints --recursive
          ResourceRequirements:
            - Type: GPU
              Value: '1'
          LogConfiguration:
            LogDriver: awslogs
            Options:
              awslogs-group: !Ref TrainLogGroup
              awslogs-region: !Ref AWS::Region
              awslogs-stream-prefix: ecs
          Secrets:
            - Name: WANDB_API_KEY
              ValueFrom: !Ref WandbSecretArn

#-----------------------------------------------------------------------
# ECS Service
#-----------------------------------------------------------------------
  TrainService:
    Type: AWS::ECS::Service
    DependsOn: Asg
    Properties:
      Cluster: !Ref ECSCluster
      DesiredCount: 0 # 手動でタスクを実行する場合は0に設定
      TaskDefinition: !Ref TrainTaskDef
      EnableExecuteCommand: true
      PlacementStrategies:
        - Type: spread
          Field: instanceId
      CapacityProviderStrategy:
        - CapacityProvider: !Ref GpuSpotProvider
          Weight: 1

具体的なアーキテクチャについて説明します。システムの核となるGPUインスタンスで構成されたECSクラスターは、外部から直接アクセスできないプライベートサブネット内に配置することで、セキュリティを確保しています。一方で、ライブラリのダウンロードなどで必要となるインターネットへのアウトバウンド通信は、NAT Gatewayを経由して行います。

学習の実行にあたっては、コンテナイメージをECRから、学習データをS3からそれぞれ取得します。また、実行ログはCloudWatch Logsへ、APIキーなどの秘密情報はSecrets Managerへと、用途に応じてAWSのマネージドサービスと連携する構成です。

以下の図は、これらの主要な構成要素と、それらの間のデータの流れを俯瞰したものです

image 1.png

3.2. 部分的な詳細アーキテクチャ図

次に、システムの各要素をより深く理解するための詳細図を3つに分けて示します。

3.2.A. ネットワーク詳細図

VPC内のサブネット、ルーティング、ゲートウェイ、そしてセキュリティグループの構成に焦点を当てた図です。

image 2.png

3.2.B. ECSコンピューティングレイヤー詳細図

ECSがどのようにEC2インスタンスをプロビジョニングし、タスクを管理するかに焦点を当てた図です。

image 3.png

3.2.C. IAM権限とタスク実行フロー図

EC2インスタンスとコンテナが、どのIAMロールを使って、どのAWSサービスにアクセスするかの権限分離に焦点を当てた図です。

image 4.png

4. 詳細ワークフロー

ここでは、実際にAWS上で学習を実行するための具体的な手順を、ステップごとに解説します。

4.1. フェーズ1: 事前準備

まず、学習に必要な資材をAWS上に配置します。

4.1.A ステップ1: 学習環境(Dockerイメージ)のAWSへの登録

ローカルで開発した学習用のDockerイメージを、AWSのコンテナレジストリサービスであるECR (Elastic Container Registry) に登録します。

  1. ECRリポジトリの作成

    aws ecr create-repository --repository-name <YOUR_APP_NAME> --region <YOUR_AWS_REGION>
    
    
  2. ECRへの認証

    aws ecr get-login-password --region <YOUR_AWS_REGION> | docker login --username AWS --password-stdin <YOUR_AWS_ACCOUNT_ID>.dkr.ecr.<YOUR_AWS_REGION>.amazonaws.com
    
    
  3. イメージのビルドとプッシュ

    # イメージのビルド
    docker build -t <YOUR_APP_NAME>:latest .
    
    # ECRリポジトリ用のタグ付け
    docker tag <YOUR_APP_NAME>:latest <YOUR_AWS_ACCOUNT_ID>.dkr.ecr.<YOUR_AWS_REGION>.amazonaws.com/<YOUR_APP_NAME>:latest
    
    # ECRへのプッシュ
    docker push <YOUR_AWS_ACCOUNT_ID>.dkr.ecr.<YOUR_AWS_REGION>.amazonaws.com/<YOUR_APP_NAME>:latest
    
    

4.1.B ステップ2: 学習データのS3への配置

学習に用いるデータセットをS3バケットにアップロードします。

aws s3 sync ./local-data-directory s3://<YOUR_DATASET_BUCKET_NAME>/

4.1.C ステップ3: APIキーなど秘密情報の登録

外部サービスのAPIキーをAWS Secrets Managerに登録し、作成されたシークレットのARNを控えます。

aws secretsmanager create-secret --name <YOUR_SECRET_NAME> --secret-string '<YOUR_SECRET_API_KEY>'


4.2. フェーズ2: 環境構築 (CloudFormation)

CloudFormationテンプレート (ecs-gpu-cluster.yml) を使用して、GPU学習に必要なAWSインフラを一括で構築します。

以下のコマンドを実行し、CloudFormationスタックを作成します。上記の表で定義した変数を、ご自身の環境の値に置き換えてください。

aws cloudformation deploy \\
  --template-file ecs-gpu-cluster.yml \\
  --stack-name <YOUR_CLOUDFORMATION_STACK_NAME> \\
  --capabilities CAPABILITY_NAMED_IAM \\
  --parameter-overrides \\
    ClusterName=<YOUR_ECS_CLUSTER_NAME> \\
    VpcId=<YOUR_VPC_ID> \\
    SubnetIds=<YOUR_SUBNET_IDS> \\
    PrivateRouteTableId=<YOUR_PRIVATE_ROUTE_TABLE_ID> \\
    DatasetBucketName=<YOUR_DATASET_BUCKET_NAME> \\
    WandbSecretArn="<YOUR_SECRET_ARN>"

4.3. フェーズ3: 学習タスクの実行とモニタリング

環境が整ったら、学習タスクを実行します。

4.3.1 ステップ1: 学習タスクの開始

aws ecs run-task コマンドを使用して、学習ジョブを開始します。

aws ecs run-task \\
  --cluster <YOUR_ECS_CLUSTER_NAME> \\
  --task-definition <YOUR_TASK_DEFINITION_FAMILY> \\
  --capacity-provider-strategy capacityProvider=<YOUR_CAPACITY_PROVIDER_NAME>,weight=1 \\
  --count 1 \\
  --region <YOUR_AWS_REGION>

4.3.2 ステップ2: 実行状況の確認

タスクの実行状況やログは、以下のコマンドで確認できます。

  • 実行中のタスク詳細を確認

    aws ecs describe-tasks --cluster <YOUR_ECS_CLUSTER_NAME> --tasks $(aws ecs list-tasks --cluster <YOUR_ECS_CLUSTER_NAME> --output text --query "taskArns[]")
    
    
  • 学習ログをリアルタイムで確認

    aws logs tail /ecs/<YOUR_TASK_DEFINITION_FAMILY> --follow
    
    

5. コスト

本ワークフローで利用するAWSのサービスは基本的に従量課金制であり、コストは利用時間やデータ量に依存します。特に、学習時間の大半を占めるEC2インスタンスの料金がコストの主要な部分を占めます。

コストを最適化する上で最も重要なのが、オンデマンドインスタンススポットインスタンスの使い分けです。

  • オンデマンドインスタンス: 必要な時にいつでも起動でき、秒単位で利用した分だけ料金が発生する標準的な支払い方法です。料金は安定していますが、スポットインスタンスに比べて高価です。
  • スポットインスタンス: AWSの余剰コンピューティングリソースを、オンデマンド料金に比べて大幅な割引価格(最大90%)で利用できる仕組みです。コストを劇的に削減できる一方、AWS側のリソースが不足すると、実行中のインスタンスが中断される可能性があるという特徴があります。

機械学習の実験のように、処理が中断されてもチェックポイントから再開できるタスクは、スポットインスタンスの利用に非常に適しています。

5.1. 料金比較

以下に、代表的なGPUインスタンスについて、東京リージョン(ap-northeast-1)におけるオンデマンド料金とスポット料金の比較をまとめます。

インスタンスタイプ 搭載GPU (数) GPU VRAM オンデマンド料金/時間 (USD) (円換算) スポット料金/時間 (USD) (円換算) 割引率 (目安)
g4dn.xlarge NVIDIA T4 (1) 16 GB $0.710 (約107円) $0.213 (約32円) 約70%
g5.xlarge NVIDIA A10G (1) 24 GB $1.459 (約219円) $0.583 (約87円) 約60%
g6.xlarge NVIDIA L4 (1) 24 GB $0.988 (約148円) $0.494 (約74円) 約50%
p3.2xlarge NVIDIA V100 (1) 16 GB $4.194 (約629円) $1.321 (約198円) 約68%
p4d.24xlarge NVIDIA A100 (8) 320 GB $42.93 (約6,440円) $25.76 (約3,864円) 約40%
p5.48xlarge NVIDIA H100 (8) 640 GB $120.53 (約18,080円) $72.32 (約10,848円) 約40%

注記:

  • 日本円の料金は、1ドル=150円として計算した参考値です。実際の請求額は、決済時の為替レートによって変動します。
  • 上記料金は、東京リージョン(ap-northeast-1)でLinux OSを利用した場合の2025年7月時点のものです。
  • スポット料金は常に変動しており、上記はあくまで一例です。

5.2. インスタンス選定の目安

タスクの規模や求める性能に応じて、以下の特徴を参考にインスタンスを選択してください。

  • g4dn.xlarge (NVIDIA T4)
    コストパフォーマンスに優れ、推論や小〜中規模の学習に最適なエントリーモデルです。
  • g5.xlarge (NVIDIA A10G)
    g4dnより新しい世代で、VRAMも24GBと大きく、より大きなモデルやバッチサイズでの学習に対応できます。
  • g6.xlarge (NVIDIA L4)
    比較的新しい世代のGPUを搭載し、特に推論性能と電力効率に優れています。最新のAI機能を活用したい場合に良い選択肢です。
  • p3.2xlarge (NVIDIA V100)
    かつてのハイエンドGPUであり、依然として高い計算能力を誇ります。大規模なモデルの学習や科学技術計算に適しています。
  • p4d.24xlarge (NVIDIA A100)
    大規模な分散学習やHPC(高性能コンピューティング)向けです。8基のGPUで並列処理を行い、学習時間を大幅に短縮します。
  • p5.48xlarge (NVIDIA H100)
    現行で最高峰の性能を持つインスタンスです。最新・最大のLLM(大規模言語モデル)の学習など、極めて高い計算能力が求められる最先端の研究開発に利用されます。

情報ソース

3
2
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
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?