Unity ML-Agents(v0.9.1)の学習をAWS CodeBuildを利用して実行してみました。

UnityやUnity ML-Agentsの環境構築、Dockerを用いた学習方法などは下記をご参考ください。

Macでhomebrewを使ってUnityをインストールする(Unity Hub、日本語化対応)
https://cloudpack.media/42142

MacでUnity ML-Agentsの環境を構築する(v0.9.1対応) – Qiita
https://cloudpack.media/49048

DockerでUnity ML-Agentsを動作させる(v0.9.1対応) – Qiita
https://cloudpack.media/49085

前提

下記記事を参考にUnity ML-Agents(v0.9.1)のDockerイメージをAmazon Elastic Container Registry(ECR)にPushしている前提です。

AWS CodeBuildを利用してUnity ML-AgentsのDockerイメージを作成する(v0.9.1対応) – Qiita
https://cloudpack.media/50367

手順

AWS CloudFormation(CFn)で環境構築する

CFnを利用して、必要となるリソースを作成します。

  • InputBucket: S3バケット。Unityアプリのビルドファイル置き場
  • OutputBucket: S3バケット。アーティファクト(modelsなど)をアップロード
  • CodeBuildServiceRole: CodeBuildで利用するサービスロール
  • CodeBuildProject: CodeBuildのプロジェクト

Dockerイメージのビルドで作成したテンプレートとほぼ同じです。

template.yaml

---
AWSTemplateFormatVersion: 2010-09-09
Description: Learning Unity ML-Agents

Parameters:
  ProjectName:
    Description: Project Name for CodeBuild
    Default: ml-agents-learning-test
    Type: String
  InputBucketName:
    Description: Input Bucket Name
    Default: ml-agents-learning-input
    Type: String
  OutputBucketName:
    Description: Output Bucket Name
    Default: ml-agents-learning-output
    Type: String

Resources:
  InputBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub ${InputBucketName}
      AccessControl: Private
      PublicAccessBlockConfiguration:
        BlockPublicAcls: True
        BlockPublicPolicy: True
        IgnorePublicAcls: True
        RestrictPublicBuckets: True

  OutputBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub ${OutputBucketName}
      AccessControl: Private
      PublicAccessBlockConfiguration:
        BlockPublicAcls: True
        BlockPublicPolicy: True
        IgnorePublicAcls: True
        RestrictPublicBuckets: True

  CodeBuildServiceRole:
    Type: AWS::IAM::Role
    Properties:
      Path: /
      AssumeRolePolicyDocument:
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - codebuild.amazonaws.com
            Action:
                - sts:AssumeRole
      Policies:
        - PolicyName: !Sub CodeBuildPolicy-${ProjectName}
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Resource:
                  - !Sub arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/${ProjectName}
                  - !Sub arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/${ProjectName}:*
                Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
              - Effect: Allow
                Resource:
                  - !Sub arn:aws:s3:::codepipeline-${AWS::Region}-*
                Action:
                  - s3:PutObject
                  - s3:GetObject
                  - s3:GetObjectVersion
              - Effect: Allow
                Resource:
                  - !Sub arn:aws:s3:::${InputBucketName}/*
                Action:
                  - s3:GetObject
                  - s3:GetObjectVersion
              - Effect: Allow
                Resource:
                  - !Sub arn:aws:s3:::${OutputBucketName}/*
                Action:
                  - s3:PutObject

  CodeBuildProject:
    Type: AWS::CodeBuild::Project
    Properties:
      Name: !Ref ProjectName
      Description: this is a test prj
      ServiceRole: !Ref CodeBuildServiceRole
      Artifacts:
        Location: !Ref OutputBucketName
        Type: S3
        Name: artifacts
        Path: !Sub ${ProjectName}
        NamespaceType: BUILD_ID
      Environment:
        Type: LINUX_CONTAINER
        ComputeType: BUILD_GENERAL1_SMALL
        Image: aws/codebuild/standard:2.0
        PrivilegedMode: True
      Source:
        Location: !Join [ "/", [ !Ref InputBucketName, "dummy.zip" ] ]
        Type: S3
      TimeoutInMinutes: 120
      Tags:
        - Key: Name
          Value: !Ref ProjectName

テンプレートが用意できたらAWS CLIでスタック作成します。サービスロールを作成するので--capabilities CAPABILITY_IAMが必要になります。
--stack-name--regionはお好みで。--parametersを指定するとバケット名やプロジェクト名も指定できます。

> cd テンプレートがあるディレクトリ
> aws cloudformation create-stack \
  --stack-name ml-agents-learning \
  --template-body file://template.yaml \
  --capabilities CAPABILITY_IAM \
  --region <YOUR REGION> \
  --parameters '[
      {
        "ParameterKey": "ProjectName",
        "ParameterValue": "ml-agents-learning-test"
      },
      {
        "ParameterKey": "InputBucketName",
        "ParameterValue": "ml-agents-learning-input"
      },
      {
        "ParameterKey": "OutputBucketName",
        "ParameterValue": "ml-agents-learning-output"
      }
  ]'

スタック実行が完了したか確認します。"CREATE_COMPLETE"になったらOK。

> aws cloudformation describe-stacks \
  --region <YOUR REGION> \
  --stack-name ml-agents-learning \
  --query "Stacks[0].StackStatus"

"CREATE_COMPLETE"

CodeBuildのビルド実行準備

作成したCodeBuildのプロジェクトでビルド実行するための前準備をします。

S3バケットにUnityアプリのビルドファイルをアップロードする

ML-Agentsで学習するUnityアプリのビルド方法は下記を参考にしてください。

DockerでUnity ML-Agentsを動作させる(v0.9.1対応) – Qiita
https://cloudpack.media/49085

手元に3DBallのビルドファイルがある前提で。

> ls
3dball.x86_64       3dball_Data         trainer_config.yaml

> zip -r 3dball.zip 3dball.x86_64 3dball_Data trainer_config.yaml


> aws s3 cp 3dball.zip s3://ml-agents-learning-input/
upload: ./3dball.zip to s3://ml-agents-learning-input/3dball.zip

buildspec.yamlを用意する

CodeBuildのプロジェクトでビルド実行する際の手順を記述したbuildspec.yamlを用意します。
mlagents-learnコマンドで学習実行して、終わったらsummariesmodelsフォルダをartifactsとしてOutputのバケットにアップロードします。

buildspec.yaml

version: 0.2

phases:
  install:
    runtime-versions:
      docker: 18
  build:
    commands:
      - mlagents-learn trainer_config.yaml --train --env=3dball
artifacts:
  files:
    - ./summaries/**/*
    - ./models/**/*

ビルド実行する

buildspec.yamlが用意できたらCodeBuildのプロジェクトでビルド実行します。
--image-overrideでDockerイメージを上書き、--source-location-overrideでUnityアプリのビルドファイルを指定します。ZipファイルはCodeBuildで自動的に展開されます。

> aws codebuild start-build \
  --region <YOUR REGION> \
  --project-name ml-agents-learning-test \
  --buildspec-override file://buildspec.yaml \
  --image-override <YOUR AWS ACCOUNT ID>.dkr.ecr.<YOUR REGION>.amazonaws.com/ml-agents:0.9.1 \
  --source-location-override ml-agents-learning-input/3dball.zip

学習実行している様子。

aws codebuild batch-get-buildsコマンドでビルドが完了したか確認します。各フェーズのステータスがSUCCEEDEDで最後に"phaseType": "COMPLETED"があったらビルド完了です。

aws codebuild batch-get-builds \
  --region <YOUR REGION> \
  --ids ml-agents-learning-test:4f28bf27-194b-4c3d-974c-b553897f290c \
  --query "builds[0].phases"

[
    {
        "phaseType": "SUBMITTED",
        "phaseStatus": "SUCCEEDED",
        "startTime": 1571890350.391,
        "endTime": 1571890350.693,
        "durationInSeconds": 0
    },
    {
        "phaseType": "QUEUED",
        "phaseStatus": "SUCCEEDED",
        "startTime": 1571890350.693,
        "endTime": 1571890351.886,
        "durationInSeconds": 1
    },
    {
        "phaseType": "PROVISIONING",
        "phaseStatus": "SUCCEEDED",
        "startTime": 1571890351.886,
        "endTime": 1571890405.483,
        "durationInSeconds": 53,
        "contexts": [
            {
                "statusCode": "",
                "message": ""
            }
        ]
    },
    {
        "phaseType": "DOWNLOAD_SOURCE",
        "phaseStatus": "SUCCEEDED",
        "startTime": 1571890405.483,
        "endTime": 1571890406.992,
        "durationInSeconds": 1,
        "contexts": [
            {
                "statusCode": "",
                "message": ""
            }
        ]
    },
    {
        "phaseType": "INSTALL",
        "phaseStatus": "SUCCEEDED",
        "startTime": 1571890406.992,
        "endTime": 1571890407.158,
        "durationInSeconds": 0,
        "contexts": [
            {
                "statusCode": "",
                "message": ""
            }
        ]
    },
    {
        "phaseType": "PRE_BUILD",
        "phaseStatus": "SUCCEEDED",
        "startTime": 1571890407.158,
        "endTime": 1571890407.354,
        "durationInSeconds": 0,
        "contexts": [
            {
                "statusCode": "",
                "message": ""
            }
        ]
    },
    {
        "phaseType": "BUILD",
        "phaseStatus": "SUCCEEDED",
        "startTime": 1571890407.354,
        "endTime": 1571890828.698,
        "durationInSeconds": 421,
        "contexts": [
            {
                "statusCode": "",
                "message": ""
            }
        ]
    },
    {
        "phaseType": "POST_BUILD",
        "phaseStatus": "SUCCEEDED",
        "startTime": 1571890828.698,
        "endTime": 1571890828.834,
        "durationInSeconds": 0,
        "contexts": [
            {
                "statusCode": "",
                "message": ""
            }
        ]
    },
    {
        "phaseType": "UPLOAD_ARTIFACTS",
        "phaseStatus": "SUCCEEDED",
        "startTime": 1571890828.834,
        "endTime": 1571890830.138,
        "durationInSeconds": 1,
        "contexts": [
            {
                "statusCode": "",
                "message": ""
            }
        ]
    },
    {
        "phaseType": "FINALIZING",
        "phaseStatus": "SUCCEEDED",
        "startTime": 1571890830.138,
        "endTime": 1571890832.33,
        "durationInSeconds": 2,
        "contexts": [
            {
                "statusCode": "",
                "message": ""
            }
        ]
    },
    {
        "phaseType": "COMPLETED",
        "startTime": 1571890832.33
    }
]

summariesmodelsフォルダがアップロードされているか確認します。

> mkdir logs
> aws s3 sync s3://ml-agents-learning-output/ml-agents-learning-test ./logs
> tree logs
logs/
└── 4f28bf27-194b-4c3d-974c-b553897f290c
    └── artifacts
        ├── models
        │   └── ppo-0
        │       ├── 3DBallLearning
        │       │   ├── checkpoint
        │       │   ├── frozen_graph_def.pb
        │       │   ├── model-50000.cptk.data-00000-of-00001
        │       │   ├── model-50000.cptk.index
        │       │   ├── model-50000.cptk.meta
        │       │   ├── model-50001.cptk.data-00000-of-00001
        │       │   ├── model-50001.cptk.index
        │       │   ├── model-50001.cptk.meta
        │       │   └── raw_graph_def.pb
        │       └── 3DBallLearning.nn
        └── summaries
            ├── ppo-0_3DBallLearning
            │   └── events.out.tfevents.1571890414.387f1a8a8f4a
            ├── ppo-0_3DBallLearning.csv
            └── ppo-0_timers.json

7 directories, 13 files

ファイルアップロードされていることが確認できました。やったぜ

参考

Macでhomebrewを使ってUnityをインストールする(Unity Hub、日本語化対応)
https://cloudpack.media/42142

MacでUnity ML-Agentsの環境を構築する(v0.9.1対応) – Qiita
https://cloudpack.media/49048

DockerでUnity ML-Agentsを動作させる(v0.9.1対応) – Qiita
https://cloudpack.media/49085

AWS CodeBuildを利用してUnity ML-AgentsのDockerイメージを作成する(v0.9.1対応) – Qiita
https://cloudpack.media/50367

元記事はこちら

AWS CodeBuildでUnity ML-Agentsを動作させる(v0.9.1対応)