【完結編】AWS Amazon SageMaker つかってみた4 〜GPU利用でサンプルの実行〜

はじめに

Amazon SageMaker を利用する上で自分が気になったところ、詰まったところを中心にまとめていきます。
この記事では前回の記事で失敗したサンプルの実行について再度まとめます。
前回の記事はこちら
次回の記事は作成中

サンプルの場所

Jupyterの導入については前回の記事を参照

  1. Jupyterのホーム画面を開きます。
  2. sample-notebooks ディレクトリを開きます。
  3. sagemaker-python-sdk ディレクトリを開きます。
  4. mxnet_gluon_cifar10 ディレクトリを開きます。
  5. cifar10.ipynb ファイルを開きます。

サンプルの実行

Jupyter NotebookにはPythonのコードと説明が含まれます。
右に In [ ]: と書かれているのがコードで、それ以外は説明です。

サンプルについて

  • 用いるデータセット: CIFAR-10という6万枚の画像データのデータセット
  • 学習内容: 34層の深層学習により画像を10種類にクラスタリングする。

セットアップ

scikit-image のライブラリが必要なのでcondaのページから入れてください。

  1. conda tab のリンクをクリックするか、Jupyterのホームから Conda のタブをクリックします。
  2. Available packages のところのSearchで scikit-image を検索します。
  3. scikit-image を選択します。
  4. 右矢印を押下してインストールします。

はじめのpythonコードを実行してみましょう。
以下のコードを選択して、画面上部の Cell から Run Cells を選択します。

import os
import boto3
import sagemaker
from sagemaker.mxnet import MXNet
from mxnet import gluon
from sagemaker import get_execution_role

sagemaker_session = sagemaker.Session()

role = get_execution_role()

右の表示が In [*]: に変わります。
* は実行中であることを表します。
実行が終わると In [1]: のような表示になります。
数字は実行された順番を表します。

初めて実行すると以下のWarningが表示されます。
こちらの原因と解消方法を知っている人がいれば教えてください。

/home/ec2-user/anaconda3/envs/mxnet_p27/lib/python2.7/site-packages/urllib3/contrib/pyopenssl.py:46: DeprecationWarning: OpenSSL.rand is deprecated - you should use os.urandom instead
  import OpenSSL.SSL

もう一度実行するとWarningが消えます。

データのダウンロード

CIFAR10をダウンロードします。

from cifar10_utils import download_training_data
download_training_data()

少し時間がかかります。

データのアップロード

Amazon SageMakerで学習させるにはまずS3に学習データをアップロードする必要があります。
S3へデータをアップロードするには sagemaker.Session.upload_data の関数を使います。
戻り値の inputs にはアップロード先のIDが入っており、後ほど学習の際に利用します。

inputs = sagemaker_session.upload_data(path='data', key_prefix='data/gluon-cifar10')
print('input spec (in this case, just an S3 path): {}'.format(inputs))

train 関数の確認

SageMakerで利用可能な学習スクリプトを用意する必要があります。
学習スクリプトは train 関数として実装されている必要があります。
学習環境の情報が train 関数の引数として渡されます。

!cat 'cifar10.py'

学習スクリプトの実行

MXNet クラスを用いると分散環境での学習が可能です。
以下の設定をします。

  • 学習スクリプト
  • IAMロール
  • インスタンス数
  • インスタンスタイプ

デフォルトでは2個の ml.p2.xlarge インスタンスで学習ができるように設定されています。
3行目の train_instance_count の値を 1 に変更して1個のインスタンスで学習するように変更してください。(理由は考察の項目を参照)
※GPUインスタンスはデフォルトで使用制限があります。制限解除方法についてはこちらの記事にまとめています。

m = MXNet("cifar10.py", 
          role=role, 
          train_instance_count=1, 
          train_instance_type="ml.p2.xlarge",
          hyperparameters={'batch_size': 128, 
                           'epochs': 50, 
                           'learning_rate': 0.1, 
                           'momentum': 0.9})

MXNet クラスができましたので、アップロードしたデータを使って学習を開始します。

m.fit(inputs)

学習がスタートしました。
現在実行中の学習はAmazon SageMakerのジョブの画面で確認できます。
学習時間は44分でした。 ml.p2.xlarge が1時間\$1.26ですので学習にかかった費用は\$1ほどです。

予測

学習が終わりましたので学習結果を使ってエンドポイントを作成します。
学習ではGPUインスタンスを利用しましたが、エンドポイントではCPUのインスタンスも利用できます。

deployの戻り値のpredictorオブジェクトでエンドポイントを呼び出してサンプル画像の予測ができます。

predictor = m.deploy(initial_instance_count=1, instance_type='ml.m4.xlarge')

CIFAR10のサンプル画像

サンプル画像でCIFAR10のテストをします。

# load the CIFAR10 samples, and convert them into format we can use with the prediction endpoint
from cifar10_utils import read_images

filenames = ['images/airplane1.png',
             'images/automobile1.png',
             'images/bird1.png',
             'images/cat1.png',
             'images/deer1.png',
             'images/dog1.png',
             'images/frog1.png',
             'images/horse1.png',
             'images/ship1.png',
             'images/truck1.png']

image_data = read_images(filenames)

predictorは入力された画像を予測して結果のラベルを返します。
ラベルはfloat値で返ってくるのでintに変換してから表示しています。

for i, img in enumerate(image_data):
    response = predictor.predict(img)
    print('image {}: class: {}'.format(i, int(response)))

リソースの開放

このサンプルの実行が終わったらインスタンスを開放してエンドポイントを削除するのをお忘れなく。

sagemaker.Session().delete_endpoint(predictor.endpoint)

結果

正解率80%

image 0: class: 0
image 1: class: 9
image 2: class: 2
image 3: class: 3
image 4: class: 4
image 5: class: 5
image 6: class: 2
image 7: class: 7
image 8: class: 8
image 9: class: 9

考察

GPUの圧倒的な処理速度

GPUが得意な画像処理ということもあり60倍程度の処理速度が出ていた。

インスタンスタイプ 1秒間に処理できるサンプル数
ml.m4.xlarge 約 22 サンプル/秒
ml.p2.xlarge 約 1400 サンプル/秒

単位時間あたりはCPUよりGPUの方が高いが、処理速度が段違いなので結果的にGPUを使うほうが安上がりになる。

並列処理の同期のオーバヘッドが大きい

MXNetでは1回の学習ごとに各インスタンス間で同期を取っているようです。
単体のインスタンスで学習をさせたところ1秒間に11回の学習ができたのに対し、2並列で学習させた場合は毎秒各インスタンス1回ずつの合計2回しか学習ができませんでした。
分散学習をさせると性能が1/5に低下してしまいます。

インスタンスタイプ 1秒間に学習できる回数
単体(同期なし) 約 11 回/秒
2並列(毎回同期) 約 2 回/秒

今回の学習では1回の学習に要する時間が0.1秒以下の学習であったために毎回同期を取らないといけない並列処理のほうが遅くなる結果となってしまった。

SageMakerのいいと感じたところ

ワンストップで実行可能

ノートブックの作成、リソースの確保、学習、エンドポイントの作成までワンストップで行える。

リソースの最適化

ノートブック、学習、エンドポイントでそれぞれでインスタンスを選択できる。
学習は学習している間だけ料金が発生する。

続きを読む

Amazon SageMakerでml.p2.xlargeを使おうとしたらResourceLimitExceededって怒られた

事象

Amazon SageMakerで ml.p2.xlarge を使って学習させようとしたら以下のエラーが出て学習ができなかった。

ResourceLimitExceeded: An error occurred (ResourceLimitExceeded) when calling the CreateTrainingJob operation: 
The account-level service limit for training-job/ml.p2.xlarge is 0 Instances, with current utilization of 0 Instances and a request delta of 1 Instances. 
Please contact AWS support to request an increase for this limit.

原因

AWSでは利用できるリソースに制限があります。
詳しくはこちらのページをご確認ください。

Amazon SageMakerにも制限があり、こちらでは ml.p2.xlarge インスタンス のデフォルトの制限は 1 となっています。

対策

AWSのサポートに連絡して制限を緩和してもらいましょう。

  1. AWSのコンソールにログイン
  2. 右上の サポート から サポートセンター のページを表示
  3. ケースの作成 を押下
  4. 内容で サービス制限の増加 を選択
  5. 制限タイプで SageMaker を選択
  6. リージョン、リソースタイプ、制限をそれぞれ選択
  7. 新しい制限値を入力
  8. 適当に理由を書いて 送信 を押下

1営業日程度で対応してくれます。
海外のリージョンの申請は海外の担当部署と調整が必要らしく、少し時間がかかるかも

他のサービスも色々制限があったりするので、申請方法を覚えておきましょう。

続きを読む

AWS Amazon SageMaker つかってみた2 〜サンプルの実行〜

はじめに

Amazon SageMaker を利用する上で自分が気になったところ、詰まったところを中心にまとめていきます。
この記事では予めノートブックインスタンスに用意されていたサンプルの実行した時のことを書きます。
前回の記事はこちら
次回の記事は作成中

注意

この記事ではインスタンスの選択で失敗しており、最後まで実行ができていません。
完全版はまた追記する予定です。

サンプルの場所

Jupyterの導入については前回の記事を参照

  1. Jupyterのホーム画面を開きます。
  2. sample-notebooks ディレクトリを開きます。
  3. sagemaker-python-sdk ディレクトリを開きます。
  4. mxnet_gluon_cifar10 ディレクトリを開きます。
  5. cifar10.ipynb ファイルを開きます。

サンプルの実行

Jupyter NotebookにはPythonのコードと説明が含まれます。
右に In [ ]: と書かれているのがコードで、それ以外は説明です。

サンプルについて

  • 用いるデータセット: CIFAR-10という6万枚の画像データのデータセット
  • 学習内容: 34層の深層学習により画像を10種類にクラスタリングする。

セットアップ

scikit-image のライブラリが必要なのでcondaのページから入れてください。

  1. conda tab のリンクをクリックするか、Jupyterのホームから Conda のタブをクリックします。
  2. Available packages のところのSearchで scikit-image を検索します。
  3. scikit-image を選択します。
  4. 右矢印を押下してインストールします。

はじめのpythonコードを実行してみましょう。
以下のコードを選択して、画面上部の Cell から Run Cells を選択します。

import os
import boto3
import sagemaker
from sagemaker.mxnet import MXNet
from mxnet import gluon
from sagemaker import get_execution_role

sagemaker_session = sagemaker.Session()

role = get_execution_role()

右の表示が In [*]: に変わります。
* は実行中であることを表します。
実行が終わると In [1]: のような表示になります。
数字は実行された順番を表します。

初めて実行すると以下のWarningが表示されます。
こちらの原因と解消方法を知っている人がいれば教えてください。

/home/ec2-user/anaconda3/envs/mxnet_p27/lib/python2.7/site-packages/urllib3/contrib/pyopenssl.py:46: DeprecationWarning: OpenSSL.rand is deprecated - you should use os.urandom instead
  import OpenSSL.SSL

もう一度実行するとWarningが消えます。

データのダウンロード

CIFAR10をダウンロードします。

from cifar10_utils import download_training_data
download_training_data()

少し時間がかかります。

データのアップロード

Amazon SageMakerで学習させるにはまずS3に学習データをアップロードする必要があります。
S3へデータをアップロードするには sagemaker.Session.upload_data の関数を使います。
戻り値の inputs にはアップロード先のIDが入っており、後ほど学習の際に利用します。

inputs = sagemaker_session.upload_data(path='data', key_prefix='data/gluon-cifar10')
print('input spec (in this case, just an S3 path): {}'.format(inputs))

train 関数の確認

SageMakerで利用可能な学習スクリプトを用意する必要があります。
学習スクリプトは train 関数として実装されている必要があります。
学習環境の情報が train 関数の引数として渡されます。

!cat 'cifar10.py'

学習スクリプトの実行

MXNet クラスを用いると分散環境での学習が可能です。
以下の設定をします。

  • 学習スクリプト
  • IAMロール
  • インスタンス数
  • インスタンスタイプ

デフォルトでは2個の ml.p2.xlarge インスタンスで学習ができるように設定されています。
ml.p2.xlarge インスタンスはGPUのインスタンスで、無料枠ではないので注意してください。
また、私のアカウントでは利用制限がかかっており、制限解除にはサポートへの問い合わせが必要なようです。

今回は無料枠の ml.m4.xlarge インスタンスを4個利用して学習をさせることにしました。

m = MXNet("cifar10.py", 
          role=role, 
          train_instance_count=4, 
          train_instance_type="ml.m4.xlarge",
          hyperparameters={'batch_size': 128, 
                           'epochs': 50, 
                           'learning_rate': 0.1, 
                           'momentum': 0.9})

MXNet クラスができましたので、アップロードしたデータを使って学習を開始します。
SageMakerではローカルディスクからデータを読み出すようにデータを扱えます。

m.fit(inputs)

学習がスタートしました。
現在実行中の学習はAmazon SageMakerのジョブの画面で確認できます。

学習の結果と考察

結論から言いますと、タイムアウトとなって学習が最後まで終わりませんでした。
ジョブの時間はデフォルトで24時間に設定されておりましたが、24時間以内に学習ができませんでした。
24時間時点で正解率は約80%程度でした。

GPU恐るべし

今回ケチってCPUのインスタンス ml.m4.xlarge を4個使ったんですが、まさか24時間で学習が終わらないなんて。。。
GPUのインスタンス ml.p2.xlarge を1個で学習をすると45分ほどで学習できたとの報告もありますので、GPU恐るべしというところです。

料金で見ても

  • ml.p2.xlarge を1時間で$1.26
  • ml.m4.xlarge を96時間で$26.88

とGPUインスタンスを使ったほうが圧倒的に安くなります。
今後の学習ではGPUを積極的に使っていきたいところです。

分散学習の効率がうまくできていない

4個のインスタンスの途中経過を見てみたところ、同じタイミングで同じ正解率しか返していませんでした。
以下に途中経過の一部を載せます。

2017-12-23 21:24:43,320 INFO - root - Epoch [17] Batch [144]#011Speed: 22.750666 samples/sec#011accuracy=0.805550
2017-12-23 21:24:43,319 INFO - root - Epoch [17] Batch [144]#011Speed: 22.242182 samples/sec#011accuracy=0.805550
2017-12-23 21:24:43,321 INFO - root - Epoch [17] Batch [144]#011Speed: 22.460798 samples/sec#011accuracy=0.805550
2017-12-23 21:24:43,309 INFO - root - Epoch [17] Batch [144]#011Speed: 22.502813 samples/sec#011accuracy=0.805550
2017-12-23 21:24:49,176 INFO - root - Epoch [17] Batch [145]#011Speed: 21.862221 samples/sec#011accuracy=0.805544
2017-12-23 21:24:49,123 INFO - root - Epoch [17] Batch [145]#011Speed: 22.058621 samples/sec#011accuracy=0.805544
2017-12-23 21:24:49,051 INFO - root - Epoch [17] Batch [145]#011Speed: 22.333050 samples/sec#011accuracy=0.805544
2017-12-23 21:24:49,128 INFO - root - Epoch [17] Batch [145]#011Speed: 21.997985 samples/sec#011accuracy=0.805544
2017-12-23 21:24:55,092 INFO - root - Epoch [17] Batch [146]#011Speed: 21.445688 samples/sec#011accuracy=0.805538
2017-12-23 21:24:55,111 INFO - root - Epoch [17] Batch [146]#011Speed: 21.570254 samples/sec#011accuracy=0.805538
2017-12-23 21:24:55,115 INFO - root - Epoch [17] Batch [146]#011Speed: 21.379692 samples/sec#011accuracy=0.805538
2017-12-23 21:24:55,088 INFO - root - Epoch [17] Batch [146]#011Speed: 21.204017 samples/sec#011accuracy=0.805538

4個のインスタンスで学習しているので4行ずつ学習結果が出力されています。
分散学習をさせているのに全インスタンスで同じ学習率なのは違和感があります。
これは分散学習がうまくできていなかったと考えています。

MXNetに問題があるのか、パラメータの設定に問題があるのか、学習スクリプトに問題があるのかはわかっていませんが、こちらの原因調査は今後の課題です。

続きを読む

AWS Amazon SageMaker つかってみた2 〜ノートブックインスタンスの作成〜

はじめに

Amazon SageMaker を利用する上で自分が気になったところ、詰まったところを中心にまとめていきます。
ノートブックインスタンスを作成したときのことを書きます。
前回の記事はこちら
次回の記事はこちら

ノートブックインスタンスの作成

  1. AWSのダッシュボードからAmazon SageMakerのホーム画面を開きます。

    • 東京リージョンはAmazon SageMakerに対応していないのでオレゴンを選択しました。
  2. 右側のオレンジのボタン ノートブックインスタンスの作成 を押下します。
  3. それぞれのパラメータを設定していきます。
    • ノートブックインスタンス名

      • Lockoff としました。
    • ノートブックインスタンスのタイプ
      • ml.t2.medium を選択します。
      • 無料枠は ml.t2.medium だけです。
      • インスタンスタイプは後で変更可能です。
      • 実際に学習させるインスタンスは後ほど設定するので、今は最小のインスタンスで問題ないかろ思います。
    • IAM ロール
      • 初めての利用の場合にはIAMロールを作成します。

        1. 新しいロールの作成 を選択します。
        2. 指定する S3 バケット - オプション任意のS3バケット を選択します。
        3. ロールの作成 を押下します。
    • VPC – オプション
      • デフォルトを選択します。
    • サブネット – オプション
      • どれでもいいですが、 us-west-2a を選択しました。
    • セキュリティグループ – オプション
      • defultlaunch-wizard-1 を選択します。
    • 暗号化キー – オプション
      • 指定なし
    • タグ – オプション
      • 指定なし
  4. ノートブックインスタンスの作成 を押下します。
  5. インスタンスができるまで待ちます。
    • ステータスが Pending から InService になるのを待ちます。
  6. アクションの オープン リンクを押下します。
    • Jupyterのホーム画面にリダイレクトされます。

JupyterがGUIで簡単に立ち上がりました!

使わないときは停止させるのを忘れないように。

続きを読む

AWS Amazon SageMaker つかってみた1 〜概要〜

はじめに

Amazon SageMaker を利用する上で自分が気になったところ、詰まったところを中心にまとめていきます。
実際にエンドポイントを公開するまで記事にできたらと思っております。
まずは Amazon SageMaker の概要についてまとめます。
詳しくは公式ドキュメントを確認してください。
次の記事はこちら

Amazon SageMakerとは

Amazon SageMaker は、開発者やデータサイエンティストが機械学習モデルをあらゆる規模ですばやく簡単に構築、トレーニング、デプロイできるようにするフルマネージドサービスです。(参考)

できること

分析の前処理から公開までサポートしています。

ノートブックインスタンス

Jupyter Notebook のインスタンスが簡単に立ち上がります。
Jupyter Notebook はデータ分析のための環境です。
こちらでデータ分析の前処理をしたりジョブを実行したりできます。
作業過程を残すことができるのでとても便利です。

ジョブ

S3にある学習データを学習して出力データをS3に保存します。
簡単に分散学習ができて、学習が終わるとリソースを開放してくれます。
最初から主要な学習アルゴリズムが用意されています。
コンテナをつかって独自アルゴリズムで学習させることも可能なようです。

モデル

学習済みデータからモデルを作成できます。

エンドポイント

モデルを公開できます。

料金

最初の2ヶ月間は無料枠があります。

  • ノートブックインスタンス: t2.medium 250時間
  • ジョブ: m4.xlarge 50 時間
  • エンドポイント: m4.xlarge 125 時間

ジョブは実行している時間だけ料金が発生するので安心
くわしくはこちら

使ってみた感想

  • 環境構築が超簡単。
  • 学習で使用するインスタンスのタイプや並列起動数等を簡単にプログラム内で指定できる。
  • Jupyter でトレーニングの手順が残せるので再現性があったり、少しオプションを変えたりとかしやすい。

続きを読む