LoginSignup
1

More than 3 years have passed since last update.

EKSからSageMakerを動かす

Posted at

はじめに

re:Invent 2019の直前にAmazon SageMaker Operators for Kubernetesというものがひっそりと(?)リリースされています。
https://aws.amazon.com/jp/blogs/news/introducing-amazon-sagemaker-operators-for-kubernetes/
KubernetesからSageMakerをコントロールできるよーっていうものみたいです。

image.png
https://sagemaker.readthedocs.io/en/stable/amazon_sagemaker_operators_for_kubernetes.html

おっ!と思ったけど誰も試してないっぽいので誰にもささらなかったんでしょうか?
Sagemakerあんまり分かってないですが、ちょっと試しにやってみたところ、ブログに書いてあるとおりではなかなかうまくいかなかったので、手順まとめときます。

EKSセットアップ

EKSクラスタの作成

EKSクラスタを作ります。

cluster.yaml
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: sagemaker-cluster
  region: ap-northeast-1

iam:
  withOIDC: true
  serviceAccounts:
  - metadata:
      name: sagemaker-k8s-operator-default
      namespace: sagemaker-k8s-operator-system
    attachPolicyARNs:
    - "arn:aws:iam::aws:policy/AmazonSageMakerFullAccess"

nodeGroups:
  - name: "ng-1"
    desiredCapacity: 1
$ eksctl create cluster -f cluster.yaml

インスタンスはなんでもいいです。
MLで使うインスタンスはクラスタのWorkerNodeではなく、SageMakerで作成されるので、EKSで考慮する必要はないです。

SageMaker Operatorsのインストール

$ curl -O https://raw.githubusercontent.com/aws/amazon-sagemaker-operator-for-k8s/master/release/rolebased/installer.yaml

eks.amazonaws.com/role-arn を作成したものに変えます。

$ eksctl get iamserviceaccount --cluster sagemaker-cluster
NAMESPACE                       NAME                            ROLE ARN
sagemaker-k8s-operator-system   sagemaker-k8s-operator-default  arn:aws:iam::123456789012:role/eksctl-sagemaker-cluster-addon-iamserviceacc-Role1-NH9RC551YX3B
installer.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  annotations:
    eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/eksctl-sagemaker-cluster-addon-iamserviceacc-Role1-NH9RC551YX3B
$ kubectl apply -f installer.yaml

SageMaker関連のCRDが作成されます。

$ kubectl get crd | grep sagemaker
batchtransformjobs.sagemaker.aws.amazon.com         2019-12-18T07:23:42Z
endpointconfigs.sagemaker.aws.amazon.com            2019-12-18T07:23:42Z
hostingdeployments.sagemaker.aws.amazon.com         2019-12-18T07:23:42Z
hyperparametertuningjobs.sagemaker.aws.amazon.com   2019-12-18T07:23:42Z
models.sagemaker.aws.amazon.com                     2019-12-18T07:23:42Z
trainingjobs.sagemaker.aws.amazon.com               2019-12-18T07:23:42Z

EKS側の準備はここまでです。

TrainingJobを動かす

AWSブログ に書いているサンプルは説明もあんまりないし、ちょっとよくわからなかったので、こちらのドキュメントのTrainingJobを動かしてみます。

https://sagemaker.readthedocs.io/en/stable/amazon_sagemaker_operators_for_kubernetes_jobs.html#trainingjob-operator
https://github.com/aws/amazon-sagemaker-operator-for-k8s/blob/master/samples/xgboost-mnist-trainingjob.yaml

その前にデータの準備します。
このへん全然書いてないんですよね・・・

S3バケットの作成

データソースの保存と作成したモデルのアップロード用にS3バケットを作成します。

$ aws s3api create-bucket --bucket $BUCKET_NAME --create-bucket-configuration LocationConstraint=ap-northeast-1 

データはこちらのMNISTのショートバージョンを使わせてもらいました。
https://github.com/ozt-ca/tjo.hatenablog.samples/tree/master/r_samples/public_lib/jp/mnist_reproduced
(他も試したんですけど、なかなかうまくいかず・・・)

$ curl -O https://raw.githubusercontent.com/ozt-ca/tjo.hatenablog.samples/master/r_samples/public_lib/jp/mnist_reproduced/short_prac_train.csv
$ curl -O https://raw.githubusercontent.com/ozt-ca/tjo.hatenablog.samples/master/r_samples/public_lib/jp/mnist_reproduced/short_prac_test.csv

そのまま使うと、こんなエラーが出て失敗します。

ClientError: Non-numeric value 'l' found in the header line 'label,pixel0,pixel1,pixel2,pixel3,pixel4,pixel5,pi...' of file 'short_prac_train.csv'. CSV format require no header line in it. If header line is already removed, XGBoost does not accept non-numeric value in the data.

ヘッダ行がいらないってことみたいなので、1行目は削除します。
で、S3にアップロードします。

$ aws s3 cp short_prac_train.csv s3://${BUCKET_NAME}/train/  
$ aws s3 cp short_prac_test.csv s3://${BUCKET_NAME}/validation/ 

SageMaker用IAMRoleを作成

SageMakerで使用するIAMRoleを作成します。
S3からデータソースを持ってくるのと、作成したモデルをS3上にアップロードするので、S3のパーミッションをつけときます。

policy.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "sagemaker.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
$ aws iam create-role --role-name eks-sagemaker-role --assume-role-policy-document file://policy.json
$ aws iam attach-role-policy --role-name eks-sagemaker-role --policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess
$ aws iam attach-role-policy --role-name eks-sagemaker-role --policy-arn arn:aws:iam::aws:policy/AmazonSageMakerFullAccess

TrainingJobを作成

サンプルをダウンロードします。

curl -O https://raw.githubusercontent.com/aws/amazon-sagemaker-operator-for-k8s/m
aster/samples/xgboost-mnist-trainingjob.yaml

ダウンロードしたファイルを下記のように修正します。

xgboost-mnist-trainingjob.yaml
apiVersion: sagemaker.aws.amazon.com/v1
kind: TrainingJob
metadata:
  name: xgboost-mnist
spec:
    hyperParameters:
        - name: max_depth
          value: "5"
        - name: eta
          value: "0.2"
        - name: gamma
          value: "4"
        - name: min_child_weight
          value: "6"
        - name: silent
          value: "0"
        - name: objective
          value: multi:softmax
        - name: num_class
          value: "10"
        - name: num_round
          value: "10"
    algorithmSpecification:
        trainingImage: 501404015308.dkr.ecr.ap-northeast-1.amazonaws.com/xgboost:1 # Regionに合わせて変更 アカウントIDはhttps://docs.aws.amazon.com/ja_jp/sagemaker/latest/dg/sagemaker-algo-docker-registry-paths.html を参照
        trainingInputMode: File
    roleArn: arn:aws:iam::123456789012:role/eks-sagemaker-role # 作成したSageMaker用Roleを指定
    region: ap-northeast-1  # Region変更
    outputDataConfig:
        s3OutputPath: s3://<<Bucket Name>>/output/ # 作成したS3バケット、パスを指定
    resourceConfig:
        instanceCount: 1
        instanceType: ml.m4.xlarge
        volumeSizeInGB: 5
    stoppingCondition:
        maxRuntimeInSeconds: 86400
    inputDataConfig:
        - channelName: train
          dataSource:
            s3DataSource:
                s3DataType: S3Prefix
                s3Uri: s3://<<Bucket Name>>/xgboost/train/ # 作成したS3バケット、パスを指定
                s3DataDistributionType: FullyReplicated
          contentType: text/csv
          compressionType: None
        - channelName: validation
          dataSource:
            s3DataSource:
                s3DataType: S3Prefix
                s3Uri: s3://<<Bucket Name>>/xgboost/validation/ # 作成したS3バケット、パスを指定
                s3DataDistributionType: FullyReplicated
          contentType: text/csv
          compressionType: None
    tags:
      - key: tagKey
        value: tagValue

実行!

$ kubectl apply -f xgboost-mnist-trainingjob.yaml

始まりました。

$ kubectl describe trainingjob 
Name:         xgboost-mnist
Namespace:    default
  (略)
  Sage Maker Training Job Name:  xgboost-mnist-a850b392217011ea86c606020759f870
  Secondary Status:              Starting
  Training Job Status:           InProgress
Events:                          <none>

image.png

終わり!

$ kubectl describe trainingjob 
Name:         xgboost-mnist
Namespace:    default
  (略)
  Sage Maker Training Job Name:  xgboost-mnist-a850b392217011ea86c606020759f870
  Secondary Status:              Completed
  Training Job Status:           Completed
Events:                          <none>

image.png

モデルもできてました。

image.png

まとめ

MLで使うインスタンスはSageMaker側で管理になるので、EKSクラスタでは考慮しなくていいっていうのはなかなかいいんじゃないかなーと。
これスポット使えるのかな?
にしてもこのYAML書けるようになるまでは覚えること多すぎて先が遠いなーっていう印象です。

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