1. この記事で実現できること
深層学習を用いた研究・案件を進めていると、多くの方が一度はこのような課題に直面するのではないでしょうか。
- 一時的なリソース不足
「論文(or プロジェクト)の締め切り前に、多くの実験を並行して行いたいが、手元のPCだけでは1つの実験しか実行できない…。」
- ハードウェア購入の躊躇
「新しいGPUがもうすぐ発表されそうで、今高価なワークステーションを買うのは避けたい。」
- VRAM不足への対応
「ローカルマシンのVRAMでは、最新の巨大なモデルを読み込むことすらできない。」
- 環境構築の煩雑さ
「普段使い慣れたローカルの学習コードを、Google Colabなどのクラウドサービスに移植して、ライブラリのバージョンを合わせるのが大変…。」
本記事では、これらの課題を解決するため、AWS (Amazon Web Services) を活用した、柔軟かつ再現性の高いGPU学習環境を構築する方法をご紹介します
この手法を用いることで、以下のことが可能になります。
- 必要な時だけ、強力なGPUインスタンスを一時的に利用できます。
- Dockerを使い、ローカルの学習環境をそのままクラウドへ移行できます。
- S3を使い、大容量の学習データや学習済みモデルをクラウドで一元管理できます。
- 簡単なコマンド一つで、自動的に学習を開始する仕組みを構築できます。
- モデルの構造を変更しても、コンテナを更新するだけで、すぐに新しいモデルでの学習に対応できます。
2. ワークフローの全体像
このワークフローは、大きく分けて「事前準備」と「学習実行」の2つのフェーズから構成されます。
-
学習データのアップロード (S3)
まず、学習に用いるデータセットをAWSのストレージサービスであるS3バケットにアップロードしておきます。S3は容量を気にせずデータを保管できるため、大規模データの扱いにも適しています。 -
学習環境(Dockerイメージ)の登録 (ECR)
次に、ローカル環境で作成した学習用のDockerイメージを、AWSのコンテナレジストリサービスであるECR (Elastic Container Registry) に登録します。これにより、自作した環境をプライベートかつ安全にAWS上で管理できます。 -
学習基盤とタスク定義の作成
CloudFormationを使い、GPUが利用可能なECSクラスターや関連リソースを一度の操作で構築します。同時に、タスク定義を作成し、「どのDockerイメージを、どれくらいのCPU・メモリ・GPUリソースを使って動かすか」といった、コンテナの実行設計図を定めます。
-
学習タスクの実行と自動データ連携
準備が整ったら、ECSタスクを実行します。タスクが開始されると、以下の処理が自動で行われます。- S3バケットから学習データをコンテナ内に同期します。
- コンテナ内で学習スクリプトが実行されます。
- 学習によって生成されたモデルの重みやログなどの結果が、再びS3バケットへ保存されます。
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のマネージドサービスと連携する構成です。
以下の図は、これらの主要な構成要素と、それらの間のデータの流れを俯瞰したものです
3.2. 部分的な詳細アーキテクチャ図
次に、システムの各要素をより深く理解するための詳細図を3つに分けて示します。
3.2.A. ネットワーク詳細図
VPC内のサブネット、ルーティング、ゲートウェイ、そしてセキュリティグループの構成に焦点を当てた図です。
3.2.B. ECSコンピューティングレイヤー詳細図
ECSがどのようにEC2インスタンスをプロビジョニングし、タスクを管理するかに焦点を当てた図です。
3.2.C. IAM権限とタスク実行フロー図
EC2インスタンスとコンテナが、どのIAMロールを使って、どのAWSサービスにアクセスするかの権限分離に焦点を当てた図です。
4. 詳細ワークフロー
ここでは、実際にAWS上で学習を実行するための具体的な手順を、ステップごとに解説します。
4.1. フェーズ1: 事前準備
まず、学習に必要な資材をAWS上に配置します。
4.1.A ステップ1: 学習環境(Dockerイメージ)のAWSへの登録
ローカルで開発した学習用のDockerイメージを、AWSのコンテナレジストリサービスであるECR (Elastic Container Registry) に登録します。
-
ECRリポジトリの作成
aws ecr create-repository --repository-name <YOUR_APP_NAME> --region <YOUR_AWS_REGION>
-
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
-
イメージのビルドとプッシュ
# イメージのビルド 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(大規模言語モデル)の学習など、極めて高い計算能力が求められる最先端の研究開発に利用されます。
情報ソース
-
料金情報:
- AWS EC2 On-Demand Pricing: https://aws.amazon.com/ec2/pricing/on-demand/
- AWS EC2 Spot Instances Pricing: https://aws.amazon.com/ec2/spot/pricing/
-
インスタンススペック:
- Amazon EC2 G4, G5, G6, P3, P4d, P5 Instances: https://aws.amazon.com/ec2/instance-types/