A collection of notes and resources
インフラストラクチャとコストをモニタリングおよび最適化する
import boto3
logs = boto3.client('logs')
# ロググループの作成
logs.create_log_group(
logGroupName='/aws/sagemaker/TrainingJobs'
)
# 保持期間の設定
logs.put_retention_policy(
logGroupName='/aws/sagemaker/TrainingJobs',
retentionInDays=30
)
# ログストリームの作成
logs.create_log_stream(
logGroupName='/aws/sagemaker/TrainingJobs',
logStreamName='job-2025-01-01'
)
cloudwatch = boto3.client('cloudwatch')
# CPU使用率のアラーム
cloudwatch.put_metric_alarm(
AlarmName='HighCPUUtilization',
ComparisonOperator='GreaterThanThreshold',
EvaluationPeriods=2,
MetricName='CPUUtilization',
Namespace='AWS/SageMaker',
Period=300,
Statistic='Average',
Threshold=80.0,
ActionsEnabled=True,
AlarmActions=['arn:aws:sns:us-east-1:123456789012:alerts'],
Dimensions=[
{
'Name': 'EndpointName',
'Value': 'production-endpoint'
}
]
)
import boto3
cloudtrail = boto3.client('cloudtrail')
# 証跡の作成
response = cloudtrail.create_trail(
Name='ml-audit-trail',
S3BucketName='my-cloudtrail-bucket',
IncludeGlobalServiceEvents=True,
IsMultiRegionTrail=True,
EnableLogFileValidation=True,
Tags=[
{'Key': 'Environment', 'Value': 'Production'},
{'Key': 'Purpose', 'Value': 'ML-Audit'}
]
)
# ログ記録の開始
cloudtrail.start_logging(Name='ml-audit-trail')
# イベントセレクタの設定(SageMaker イベントのみ)
cloudtrail.put_event_selectors(
TrailName='ml-audit-trail',
EventSelectors=[
{
'ReadWriteType': 'All',
'IncludeManagementEvents': True,
'DataResources': [
{
'Type': 'AWS::SageMaker::TrainingJob',
'Values': ['arn:aws:sagemaker:*:*:training-job/*']
},
{
'Type': 'AWS::SageMaker::Endpoint',
'Values': ['arn:aws:sagemaker:*:*:endpoint/*']
}
]
}
]
)
import json
import boto3
cloudwatch = boto3.client('cloudwatch')
dashboard_body = {
"widgets": [
{
"type": "metric",
"properties": {
"metrics": [
["AWS/SageMaker", "CPUUtilization", {"stat": "Average"}],
[".", "MemoryUtilization", {"stat": "Average"}],
[".", "DiskUtilization", {"stat": "Average"}]
],
"period": 300,
"stat": "Average",
"region": "us-east-1",
"title": "Resource Utilization",
"yAxis": {"left": {"min": 0, "max": 100}}
}
},
{
"type": "metric",
"properties": {
"metrics": [
["AWS/SageMaker", "ModelLatency", {"stat": "Average"}],
[".", "Invocations", {"stat": "Sum", "yAxis": "right"}]
],
"period": 300,
"stat": "Average",
"region": "us-east-1",
"title": "Performance Metrics",
"yAxis": {
"left": {"label": "Latency (ms)"},
"right": {"label": "Invocations"}
}
}
}
]
}
cloudwatch.put_dashboard(
DashboardName='ML-Performance-Dashboard',
DashboardBody=json.dumps(dashboard_body)
)
import boto3
quicksight = boto3.client('quicksight')
# データソースの作成
response = quicksight.create_data_source(
AwsAccountId='123456789012',
DataSourceId='sagemaker-metrics-datasource',
Name='SageMaker Metrics',
Type='ATHENA',
DataSourceParameters={
'AthenaParameters': {
'WorkGroup': 'primary'
}
},
Permissions=[
{
'Principal': 'arn:aws:iam::123456789012:role/QuickSightRole',
'Actions': [
'quicksight:DescribeDataSource',
'quicksight:PassDataSource'
]
}
]
)
import boto3
import json
events = boto3.client('events')
# エンドポイント状態変更イベントのルール
events.put_rule(
Name='endpoint-state-change',
EventPattern=json.dumps({
'source': ['aws.sagemaker'],
'detail-type': ['SageMaker Endpoint State Change'],
'detail': {
'EndpointStatus': ['Failed', 'OutOfService']
}
}),
State='ENABLED',
Description='Alert on endpoint state changes'
)
# SNS トピックをターゲットに設定
events.put_targets(
Rule='endpoint-state-change',
Targets=[
{
'Id': '1',
'Arn': 'arn:aws:sns:us-east-1:123456789012:alerts',
'InputTransformer': {
'InputPathsMap': {
'endpoint': '$.detail.EndpointName',
'status': '$.detail.EndpointStatus'
},
'InputTemplate': '"Endpoint <endpoint> is now <status>"'
}
}
]
)
from sagemaker.model import Model
from sagemaker.predictor import Predictor
model = Model(
image_uri=container,
model_data=f's3://{bucket}/model.tar.gz',
role=role
)
# Inference Recommender ジョブの実行
recommender_job = model.right_size(
sample_payload_url=f's3://{bucket}/sample-payload.jsonl',
supported_instance_types=['ml.m5.large', 'ml.m5.xlarge', 'ml.c5.large', 'ml.c5.xlarge'],
framework='pytorch',
job_name='model-sizing-job'
)
# 推奨結果の取得
recommendations = recommender_job.describe()
print(recommendations)
import boto3
compute_optimizer = boto3.client('compute-optimizer')
# 推奨事項の取得
response = compute_optimizer.get_ec2_instance_recommendations(
instanceArns=[
'arn:aws:ec2:us-east-1:123456789012:instance/i-xxxxx'
]
)
for recommendation in response['instanceRecommendations']:
print(f"Current: {recommendation['currentInstanceType']}")
for option in recommendation['recommendationOptions']:
print(f"Recommended: {option['instanceType']}")
print(f"Expected savings: {option['savingsOpportunity']}")
import boto3
from datetime import datetime, timedelta
cloudwatch = boto3.client('cloudwatch')
# レイテンシーメトリクスの取得
response = cloudwatch.get_metric_statistics(
Namespace='AWS/SageMaker',
MetricName='ModelLatency',
Dimensions=[
{'Name': 'EndpointName', 'Value': 'production-endpoint'},
{'Name': 'VariantName', 'Value': 'AllTraffic'}
],
StartTime=datetime.now() - timedelta(hours=24),
EndTime=datetime.now(),
Period=300,
Statistics=['Average', 'Maximum', 'p99']
)
# 分析
datapoints = response['Datapoints']
avg_latency = sum(d['Average'] for d in datapoints) / len(datapoints)
max_latency = max(d['Maximum'] for d in datapoints)
print(f"Average Latency: {avg_latency}ms")
print(f"Maximum Latency: {max_latency}ms")
# レイテンシーが高い場合の対応
if avg_latency > 100: # 100ms閾値
print("Consider scaling up or using faster instance types")
import boto3
sagemaker = boto3.client('sagemaker')
# トレーニングジョブにタグ付け
response = sagemaker.create_training_job(
TrainingJobName='tagged-training-job',
RoleArn=role,
AlgorithmSpecification={...},
InputDataConfig=[...],
OutputDataConfig={...},
ResourceConfig={...},
Tags=[
{'Key': 'Project', 'Value': 'CustomerChurn'},
{'Key': 'Environment', 'Value': 'Production'},
{'Key': 'CostCenter', 'Value': 'ML-Team'},
{'Key': 'Owner', 'Value': 'data-science-team'}
]
)
# エンドポイントにタグ付け
sagemaker.create_endpoint(
EndpointName='production-endpoint',
EndpointConfigName='endpoint-config',
Tags=[
{'Key': 'Project', 'Value': 'CustomerChurn'},
{'Key': 'Environment', 'Value': 'Production'},
{'Key': 'CostCenter', 'Value': 'ML-Team'}
]
)
# Lambda のプロビジョニング済み同時実行
lambda_client = boto3.client('lambda')
lambda_client.put_provisioned_concurrency_config(
FunctionName='ml-inference-function',
Qualifier='$LATEST',
ProvisionedConcurrentExecutions=10
)
import boto3
service_quotas = boto3.client('service-quotas')
# 現在のクォータを確認
response = service_quotas.get_service_quota(
ServiceCode='sagemaker',
QuotaCode='L-D9C0F13C' # ml.p3.2xlarge インスタンス数
)
print(f"Current quota: {response['Quota']['Value']}")
# クォータ引き上げリクエスト
request = service_quotas.request_service_quota_increase(
ServiceCode='sagemaker',
QuotaCode='L-D9C0F13C',
DesiredValue=20.0
)
import boto3
budgets = boto3.client('budgets')
# 予算の作成
response = budgets.create_budget(
AccountId='123456789012',
Budget={
'BudgetName': 'ML-Monthly-Budget',
'BudgetLimit': {
'Amount': '10000',
'Unit': 'USD'
},
'TimeUnit': 'MONTHLY',
'BudgetType': 'COST',
'CostFilters': {
'Service': ['Amazon SageMaker']
}
},
NotificationsWithSubscribers=[
{
'Notification': {
'NotificationType': 'ACTUAL',
'ComparisonOperator': 'GREATER_THAN',
'Threshold': 80.0,
'ThresholdType': 'PERCENTAGE'
},
'Subscribers': [
{
'SubscriptionType': 'EMAIL',
'Address': 'ml-team@example.com'
}
]
}
]
)
import boto3
from datetime import datetime, timedelta
ce = boto3.client('ce')
# 過去30日間のコスト取得
response = ce.get_cost_and_usage(
TimePeriod={
'Start': (datetime.now() - timedelta(days=30)).strftime('%Y-%m-%d'),
'End': datetime.now().strftime('%Y-%m-%d')
},
Granularity='DAILY',
Metrics=['UnblendedCost'],
GroupBy=[
{'Type': 'DIMENSION', 'Key': 'SERVICE'},
{'Type': 'TAG', 'Key': 'Project'}
]
)
# コスト分析
for result in response['ResultsByTime']:
print(f"Date: {result['TimePeriod']['Start']}")
for group in result['Groups']:
service = group['Keys'][0]
project = group['Keys'][1]
cost = group['Metrics']['UnblendedCost']['Amount']
print(f" {service} - {project}: ${cost}")
from sagemaker.estimator import Estimator
# トレーニングでスポットインスタンス使用
estimator = Estimator(
image_uri=container,
role=role,
instance_count=2,
instance_type='ml.p3.2xlarge',
use_spot_instances=True,
max_run=3600, # 最大実行時間
max_wait=7200 # スポット中断時の待機時間
)
estimator.fit(training_data)
# AWS CLIでSavings Planを購入
aws savingsplans purchase-savings-plan \
--savings-plan-offering-id offering-xxxxx \
--commitment 100 # 1時間あたり$100のコミットメント