Amazon Web Services ブログ

Scikit Docker コンテナを構築して、Amazon SageMaker で Scikit-learnモデルのトレーニングとホストを行う

re:Invent 2017 で登場した Amazon SageMaker は機械学習モデルを規模に応じてビルド、トレーニング、デプロイするためのサーバーレスデータサイエンス環境を提供します。お客様はまた、Scikit-learn など、最も身近なフレームワークで作業できます。

このブログ記事では次の 2 つの目標に沿って進めていきます。まずは、Amazon SageMaker がモデルのトレーニングやホストのためにどのようにコンテナを使用するかについて、高水準の説明を行います。続いて、Amazon SageMaker で Scikit モデルのトレーニングおよびホスト用に Docker コンテナをビルドする方法について説明します。

概要では、モデルのトレーニングとホスト用に Amazon Elastic Container Service (ECS) からロードされた Docker イメージが Amazon SageMaker 上でどのように実行されるかについて説明します。また、トレーニングコードや推論コードなど、SageMaker Docker イメージの仕組みについても説明します。

そのため、Amazon SageMaker で Scikit モデルをビルド、トレーニング、デプロイする方法についてのみ興味をお持ちの場合は、概要の部分を飛ばしてお読みください。SageMaker で最小限の手間で Scikit モデルをコンテナ化するかについて、ハンズオンでもご覧いただけます。

目次


Amazon SageMaker 用コンテナの概要

SageMaker は、ユーザーがアルゴリズムをトレーニングし、デプロイできるように、Docker コンテナの用途を拡張します。開発者とデータサイエンティストたちは、コンテナを活用することで Docker をサポートするあらゆるプラットフォームで着実に稼動する標準化されたユニットにソフトウェアをパッケージングできるようになります。コンテナ化することで、コード、ランタイム、システムツール、システムライブラリ、設定などのすべてを 1 か所にまとめ、環境から分離し、どこで開始するかに関係なく、一貫したランタイムを確保します。

Amazon SageMaker でモデルを開発する際、トレーニングコードと推論コード用に別々の Docker イメージを提供することも、1 つの Docker イメージに両方を組み込むことも可能です。このブログ投稿記事では、トレーニングとホスティングの両方に対応した 1 つのイメージをビルドします。

Amazon SageMaker コンテナの仕組み

このパワフルなコンテナ環境を使用することで、開発者はあらゆる種類のコードを Amazon SageMaker エコシステムにデプロイできます。また、DevOps、セキュリティ、インフラストラクチャなどの各種チーム (コンテナの保守作業を行う) やデータサイエンティストチーム (コンテナに後で追加されるモデルの作成を重点的に担う) など、デプロイチームを作成することで、論理的な分業が可能です。

サンプルのコンテナフォルダ

本書では Amazon SageMaker がどのように Docker を実行して、皆さんの独自のアルゴリズムをトレーニングし、ホストするかについて、サンプルコンテナフォルダを用いて説明します。キーファイルは次のコンテナに表示されます。

container/
    decision_trees/
        nginx.conf
        predictor.py
        serve
        train
        wsgi.py
    Dockerfile

Dockerfile はコンテナのビルドに使用されます。 Dockerfile、コンテナにインストールする必要のある要件や依存条件を指定できます (Python、NGINX、Scikit など)。次に、インストール済みコンテナがプログラムフォルダに格納されているプログラムを実行します。そのため、コンテナフォルダに含まれるプログラムフォルダに名前を付ける必要があります。サンプルコンテナフォルダのプログラムフォルダには次に示すように Scikit モデルから取った名前が付けられています: decision_trees。次に、 Dockerfile に 1 行を作成して、プログラムフォルダをコンテナの WORKDIRにコピーする必要があります。これは次でも定義されています: Dockerfile。この指定により、インストール済みプログラムの検索先をコンテナに示すことができます。

コンテナセットアッププログラム

Docker イメージを実行するとき、コンテナは ENTRYPOINTで定義されたプログラムを実行するために開始するか、引数として渡された名前のプログラムを検索します。もし、 ENTRYPOINT が定義されている場合は、次のコマンドがデフォルトのスタートアップを実行します。

docker run <イメージ>

あるいは、次のコマンドを使用して指定のプログラムを実行することもできます。

docker run <イメージ> <スタートアッププログラム>

トレーニングまたホスト用のいずれかとして (両方でなく) ビルドされたイメージの場合は、プログラムフォルダに未使用の機能をビルドする必要はありません。トレーニング目的でのみイメージをビルドするときは、 train ファイルのみをプログラムフォルダに配置します。この train はまた、 ENTRYPOINTとして設定することも可能で、そのイメージはトレーニングサービス用にデフォルトでトレーニング用プログラムを開始します。

同様に、ホスト用にのみイメージをビルドするときは、プログラムフォルダに含める必要のあるファイルは次のとおりです。 nginx.conf predictor.pyserve、および wsgi.py serve は、 ENTRYPOINTとして設定でき、イメージは serve プログラムをデフォルトで開始します。

このブログ投稿記事では、トレーニング用とホスト用の両方に 1 つのイメージをビルドし、デフォルトのスタートアッププログラムとして次を定義しません: ENTRYPOINT。その代わりに、Amazon SageMaker は次の 2 つのコマンドのいずれかを使用して、イメージを実行します。次にコンテナはトレーニングとホストのサービスのいずれであるかに応じて、プログラムを開始します。

docker run <イメージ> train

docker run <イメージ> serve

このブログ記事の後半で、これらのプログラムの機能をローカルでテストし、デバッグする方法について解説します。

Amazon SageMaker が Docker コンテナを実行する方法

次のセクションでは、トレーニングとサーブ用コンテナの違いについて説明します。これによってユーザーは Amazon SageMaker の独自のアルゴリズム用にコンテナをビルドするためにどのファイルを再利用し、変更するべきかを知ることができます。

Amazon SageMaker のトレーニング用コンテナを実行する

Amazon SageMaker は次のコマンドのバージョンを実行することでトレーニング用のコードを呼び出します。

docker run <イメージ> train

これはユーザーの Docker イメージに次の名前を付けた実行可能ファイルが含まれていなければならないことを意味します: train。皆さん独自のトレーニングアルゴリズムを実装するにはこのプログラムを変更してください。 これは Docker 環境内で実行可能なあらゆる言語に有効ですが、データサイエンティスト向けに最も一般的な言語オプションとしては Python、R、Scala、および Java が挙げられます。Scikit の例では Python を使用しています。

実行時、Amazon SageMaker はコンテナに Amazon S3 ロケーションからのトレーニングデータを注入します。 トレーニングプログラムは理想的にはモデルの成果物を生成するものとします。この成果物はコンテナ内部に書き込まれ、圧縮された tar アーカイブとしてパッケージ化されて、Amazon SageMaker により Amazon S3 ロケーションへプッシュされます。

SageMaker のホスト用コンテナを実行する

Amazon SageMaker は次のコマンドのバージョンを実行することでホスト用のサービスを呼び出します。

docker run <イメージ> serve

これにより論理用に HTTP リクエストをサーブするための RESTful API が呼び出されます。繰り返しになりますが、これは Docker 環境で機能する言語やフレームワークで実行できます。この例では Python のマイクロフレームワークである Flask を使用します。

ほとんどの Amazon SageMaker コンテナでは、 serveは論理サーバーを開始するラッパーに過ぎません。また、Amazon SageMaker はトレーニング中に生成されたモデルの成果物をコンテナに注入し、自動的に展開します。

皆さんが RESTful マイクロサービス用に Flask を実行するのであれば、Amazon SageMaker サンプルノートブックから次のファイルをそのまま使用できます。

ホストサービス用に変更を考慮する必要のある唯一のファイルは次のとおりです:predictor.py。推論コードは predictor.py に含まれ、予測を提供するために Flask アプリを実装します。このファイルについては、Scikit の例の中で詳しく解説します。

SageMaker コンテナの保存先

SageMaker でトレーニングまたはホスト用にコンテナを実行するには、イメージリポジトリである Amazon Elastic Container Registry (Amazon ECR) でホストされているイメージを検出できなければなりません。 このプロセスの主要なステップ 3 つはローカルでビルドされ、リポジトリの場所がタグ付けされ、リポジトリにイメージをプッシュします。これがどのようにして行われるかについて高水準で解説し、「コンテナをビルドする」セクションで実践的なハンズオンに挑戦していただきます。

ローカルイメージをビルドするには、次のコマンドを呼び出します。

docker build <イメージ名>

これは前述の Dockerfile の指示に従い、ローカルインスタンスにイメージを生成します。イメージがビルドされたら、Docker のローカルインスタンスにイメージの格納先を指定し、SageMaker が見つけられるようにします。これは次のコマンドでイメージにタグ付けすることで行います。

docker tag <イメージ名> <リポジトリ名>

リポジトリ名は次の規則に沿って指定されます。

<アカウント番号>.dkr.ecr.<リージョン>.amazonaws.com/<イメージ名>:<タグ>

リポジトリ名付きでイメージをタグ付けしないと、Docker は Amazon ECR ではなく、Docker ハブへアップロードするようにデフォルト設定されています。Amazon SageMaker では現在、Amazon ECR に常駐するために Docker イメージを必要とします。イメージを Docker の中央レジストリではなく、ECR へプッシュするには、レジストリのホスト名でタグ付けする必要があります。

Docker ハブとは異なり、Amazon ECR イメージはデフォルトでプライベートであるため、Amazon SageMaker で使用するのに適しています。Amazon SageMaker のイメージを外部と共有したいときは、Amazon ECR ユーザーガイドでさらに詳しい情報をご覧ください。

最後に、リポジトリ名タグにリージョンを設定してイメージを Amazon ECR にアップロードするには、次のコマンドを呼び出します。

docker push <リポジトリ名>

これが実践ではどのように機能するかについて詳しくは、Scikit のハンズオン中に説明します。ここでは Amazon SageMaker が Docker と併用することでどのように機能するかについて説明します。

Amazon SageMaker Docker コンテナに関する最終メモ。トレーニングとホストの両方に対応した Docker コンテナを 1 つビルドすることも、それぞれに 1 つずつコンテナをビルドすることも可能であることについては既にご覧いただきました。2 つの Docker イメージをビルドすると共通ライブラリが重複することから、ストレージの要求事項とコストが増大する一方で、格段に小さな推論コンテナをビルドできるということは、増大した通信量に対応する際、ホストサービスをより素早くスケールできるので、メリットになることも考えられます。これはトレーニング用に GPU を使用するものの、推論コードは CPU 用に最適化されている場合に特に顕著です。ビルドするコンテナを 1 つにするか、2 つにするかを決定するときは、トレードオフについても考慮する必要があります。

独自のトレーニングイメージのレジストリパス

イメージがビルドされ、Amazon ECR にプッシュされると、Amazon SageMaker は先にご紹介した Docker コマンドを実行してアルゴリズムのトレーニングサービスを呼び出します。Amazon ECR に格納された独自のトレーニングイメージのレジストリパスを SageMaker に定義する際に Amazon SageMaker コンソールを使用できます。後で AWS のコマンドラインインターフェイスを使用して効果的にトレーニングジョブとエンドポイントを起動する方法について解説します。これらの項目がコンソール上でどのように対応するかといった情報は便利です。

独自の論理イメージのレジストリパス

同様に、Amazon ECR に格納された論理コードイメージと Amazon S3 のトレーニング済みモデルの成果物の場所を示すことで、Amazon SageMaker は SageMaker Runtime HTTPS エンドポイントを介してアルゴリズム用のホストサービスを呼び出します。ここで推論リクエストは次のスクリーンショットに示す様に、モデルから予想を取得するために送信されます。

詳細についてはあとでさらに手順を追って掘り下げます。ここではこれらの各項目がどのように連携しているかを理解することに集中しましょう。

/opt/ml/

実行時、Amazon SageMaker は Docker コンテナで利用できる外部のモデル成果物、トレーニングデータ、その他の設定情報を次の場所に注入します: /opt/ml/。この場所は Amazon SageMaker がモデル成果物を処理する場所でもあり、また、Docker コンテナの外部でアクセスを望むプログラム出力が置かれる場所でもあります。このことを認識しておくことは、トレーニングと推論のコードを書く際に有用です。

/opt/ml/
    input/
        config/
        data/
    model/
    output/
        failure/

特に重要なのはユーザープログラムの正しいトレーニングの入力場所 (/opt/ml/input/data/) とモデルの場所 (/opt/ml/model/) です。これはローカルでのテストやデバッグに役立つためです。詳細なマウント場所のマッピングは独自のトレーニングアルゴリズムの使用独自の推論コードの使用で参照できます。

Scikit-学習との連携のビルド

全 Amazon SageMaker ワークフローでの最初の一歩は「ビルド」です。特に Scikit の場合、ビルドに関する 3 つのものを呼び出します。1) モデル、2) トレーニングコード、3) 推論コードです。この作業は Docker イメージ内でコンテナ化する必要があります。

Docker のトレーニングコードをビルドする

私たちが Scikit モデルをビルドしたときと同じく、独自のコードをビルドするときは Jupyter ノートブックの中の代わりに、Python ファイルの中にモデルをビルドする必要があります。ノートブックインスタンス内ではまだモデルパイプラインに様々な着想を試してみることができますが、トレーニングクラスターへ移行する準備ができたら、独自のファイルのコードが必要になります。これは Docker でコンテナ化できることを意味します。

ここで train という名前のサンプルノートブックに付属するサンプルトレーニングファイルを見てみましょう。これは Amazon SageMaker がコンテナとともにトレーニングジョブを起動するときに起動されるコードです。このファイルの内容に驚かれるかもしれませんので、重要な項目を絞って見ていきましょう。

まず、21~31 行目では、SageMaker が次のコンテナに下記の関心ある内容をマウントする全パスを定義しています: /opt/ml/:

  • トレーニングデータ、チャンネル
  • 設定情報、
  • モデル
  • 出力

それから、トレーニングを実行する関数を定義します。主に Amazon SageMaker での Scikit モデルのビルドについて考えている場合は、最初の重要な行は 52~53 行目になります:

train_y = train_data.ix[:,0]
train_X = train_data.ix[:,1:]

これらの行はデータのどの列がラベル列かを指定します。この例では Iris dataset を使用します。CSV ファイルの 1 列目はターゲットレベルのため、train_y 変数に割り当てています。残りの列は次に割り当てられます: train_X。また Iris データにはヘッダー列がない点を考慮することも重要です。ユーザー自身のデータである場合、これらのコード行を trainで編集するか、Iris データに似たものを探すために入力データファイルを編集します。

コードの次のブロックはトレーニングジョブの一部として渡された可能性のあるハイパーパラメータの取得とともに実行する必要があります。 これは 57~59 行目です。

max_leaf_nodes = trainingParams.get('max_leaf_nodes', None)
if max_leaf_nodes is not None:
    max_leaf_nodes = int(max_leaf_nodes)

例の train ファイルではパラメータが 1 つしか渡されていませんが、渡された未加工の文字列を取得する方法と、文字列を適切な形式に変換する方法について解説しています。このケースでの私たちの目的は max_leaf_nodes パラメータを integer にすることです。これは自身のモデルに設定したいハイパーパラメータの数に拡張できます。

次に、そしておそらく最も重要な点として、Scikit モデルを定義してフィットを呼び出します。これは 62 行目と 63 行目になります。

clf = tree.DecisionTreeClassifier(max_leaf_nodes=max_leaf_nodes)
clf = clf.fit(train_X, train_y)

このコードはこれまで Scikit の使用経験のあるユーザーには極めて馴染みのあるものでしょう。ハイパーパラメータの設定方法は別にして、モデル定義とモデルフィットは、ノートブックでの処理と全く同じです。ハイパーパラメータでは上記のハイパーパラメータのセクションから取得した max_leaf_nodes 変数を引いてきている点に注意してください。皆さんのデータに最適な Scikit モデルのいずれかにこのモデル定義を設定します。

そして最後に、train ファイルでこのモデルがどのように保存されたかを確認します。この部分は 66~67 行目で見ることができます。

with open(os.path.join(model_path, 'decision-tree-model.pkl'), 'w') as out:
    pickle.dump(clf, out)

このモデルを保存するために、オブジェクトのシリアル化に pickle を使用しています。これは Docker コンテナの出力フォルダに置かれ、最終的には Amazon S3 ロケーションにプッシュされます。 これらの行は train で唯一の行で、Amazon SageMaker で独自の Scikit モデルをビルドする場合には考慮する必要があります。

Docker の推論コードをビルドする

この train コード (トレーニングジョブで実行) に加えて、コンテナにも推論コードを追加します。このコードは predictor.py に含まれます。これは SageMaker エンドポイントへ接続しようとしたときに呼び出されるコードです。

まず始めに、モデルのロードを確実に行う必要があります。このコードは 30~31 行目で見ることができます。

with open(os.path.join(model_path, 'decision-tree-model.pkl'), 'r') as inp:
    cls.model = pickle.load(inp)

ここで重要なのは、pickle ファイル用に正しい名前を付けておくことです。このファイル decision-tree-model.pkl の命名方法については train コードで既に触れましたので、ここでも同じように記述してください。

次の重要な行は、実際の予測行で 42~43 行目です。

        clf = cls.get_model()
        return clf.predict(input)

このコードに変更を加える必要はまったくありませんが、Scikit モデル用に実際の予測関数がどのように呼び出されるかを知っておくことは重要です。

最後に、モデルが入力データを挿入する方法について見ておきましょう。これは 67~69 行目になります。

data = flask.request.data.decode('utf-8')
s = StringIO.StringIO(data)
data = pd.read_csv(s, header=None)

これらはおそらく最も重要な学習すべき行と言えます。ほとんどのデータサイエンティストが通常のワークフローで精通しているデータのローディングと異なるためです。ここにあるデータは Flask フレームワークから取得したもので、メモリ (StringIO) 上ファイル様オブジェクトとして取り扱い、その後、Pandas にロードするために read_csv 関数を使用します。データそのものは、http POST メソッドで Flask に渡された CSV データです。

その後、この 76 行目から予測結果を取得します。

predictions = ScoringService.predict(data)

最後に、次の行 (79-83) を使用して、CSV ファイルにデータを戻すことで、予測結果を戻します。

out = StringIO.StringIO()
pd.DataFrame({'results':predictions}).to_csv(out, header=False, index=False)
result = out.getvalue()

return flask.Response(response=result, status=200, mimetype='text/csv')

ご覧のようにモデルを効率的にデプロイするのに predictor.py へ変更を加える必要はありませんでした。入力データの形式が正しいこと、トレーニングから保存した同じ pickle ファイルがロードされていることを確認してください。

コンテナをビルドする

これで train および predictor.py のコードができたので、Docker コンテナをビルドし、Amazon ECR にプッシュできます。次のファイルを含めたディレクトリを作成します。

decision_trees/
    nginx.conf
    predictor.py
    serve
    train
    wsgi.py

これが概要で説明したプログラムフォルダです。繰り返しますが、ここで注目するのは次のものだけです。 predictor.py および train。残りは、SageMaker サンプルノートブックから、そのまま利用できます。詳細については、こちらをご覧ください。

container/
    decision_trees/
    Dockerfile

また次に示すようにイメージのビルド方法を Docker に示すファイルが必要になります。Dockerfile。これは先に作成したプログラムフォルダの親コンテナフォルダに格納されます。次のプログラムフォルダの名前を除き、このファイルに変更を加える必要はありません。例の decision_trees です。これはサンプルの SageMaker ノートブックからダウンロードできます。

また、Docker イメージをビルドするためのヘルパースクリプト、build_and_push.sh を用意しました。これですべての項目が揃ったので、このスクリプトを実行できます。

ビルドとプッシュの両処理を試すために、Amazon SageMaker ノートブックインスタンスに付属するサンプルノートブックのスクリプトを再利用し、ノートブックインスタンス上で実行して見ます。ビルドプロセスの要点が掴めたら、レプリカを選び、任意のターミナルでインストールおよび設定済みの AWS コマンドラインインターフェイス (CLI) を使用して、独自のヘルパースクリプトをビルドできます。こちらでは開いたノートブックインスタンスでターミナルを開始する方法についてご覧いただけます。

ターミナルの開始後、サンプルのコンテナフォルダは次のコンテナフォルダに配置されている場合があります。

cd ~/SageMaker/sample-notebooks/advanced_functionality/ \
scikit_bring_your_own/container
ls
ls decision_trees/

この build_and_push.sh スクリプトは現在の AWS CLI 設定からリージョン値を取得します。現在リージョンが設定されていないときは、次の値にデフォルト設定されます: us-west-2。リージョンは次のコマンドで変更できます:

aws configure set region us-east-1

トレーニングの場合、トレーニングデータ用の Amazon S3 バケットを Amazon SageMaker のトレーニングジョブ、そしてトレーニングコンテナと同じリージョンに設定します。推論の場合、Amazon SageMaker で使用したいそれぞれのリージョンにモデルと推論コンテナをプッシュする必要があります。たとえば、レイテンシーを減らすために複数のリージョンに SageMaker エンドポイントをデプロイする計画であれば、コンテナも複数のリージョンへ同様にデプロイする意味があります。

プログラムフォルダ内のファイルが実行可能として設定されるようにするために、ビルドの前に次のコマンドを実行してください。

chmod +x decision_trees/train
chmod +x decision_trees/serve

この build_and_push.sh もまた、実行可能に設定する必要があり、スクリプトを実行するときにはイメージの名前の引数が必要です。ここではイメージに decision_treesという名前を付け、Docker イメージが作成され、Amazon ECR にプッシュされます。

chmod +x build_and_push.sh
./build_and_push.sh decision_trees

ビルドとプッシュが成功すると、このスクリーンショットに似た出力が表示されます。 プッシュは次の形式のリポジトリ名を参照します。

<アカウント番号>.dkr.ecr.<リージョン>.amazonaws.com/<イメージ名>

また、 decision-trees (Amazon ECR 内部) イメージも参照できます。AWS マネジメントコンソールを開き、サービスを選択し、次に Compute (コンピューティング) の下の Elastic Container Service を選択します。左側のリポジトリを選択すると、次が表示されます: decision-trees リポジトリ名。これを選ぶと、リポジトリ URI が表示されます。これは次に示す実行中のターミナルの出力に一致している必要があります: build_and_push.sh。後で使用するために、これを保存しておきます。

テストとデバッグ

ビルドとプッシュは次のスクリプトを実行することで、1 つのステップにまとめられます: build_and_push.sh スクリプト。しかし、論理的に、Amazon ECR へイメージをプッシュする前に、一部のローカルテストを実行し、予測する方法で Docker イメージ機能が動作するかを確認します。テストする Docker イメージはこのときにビルドされると想定してください。 次のリポジトリ、 decision_trees は次を実行してビルドされた Docker イメージをローカルで表示することにより見ることができます。

docker image ls

AWS では Amazon SageMaker でジョブまたはエンドポイントを作成する前に、コンテナのローカルでのテストを実行するためのサンプルスクリプトを提供しています。以下に示します。train_local.shserve_local.sh、および predict.shで、これらは サンプルの local_test フォルダからもアクセスできます。次のサンプルフォルダに一致する同じフォルダ構造であれば local_test フォルダを任意の場所にダウンロードできます: local_test フォルダ。この test_dir/ はユーザーのオペレーティングシステムから /opt/ml/ (Docker コンテナの中) にマウントされます。

local_test/
    test_dir/
        input/
            config/
                hyperparameters.json
                resourceConfig.json
            data/
                training/
                    iris.csv
        model/
        output/
    payload.csv
    predict.sh
    serve_local.sh
    train_local.sh

SageMaker ノートブックインスタンスでテストとデバッグのサンプルスクリプトを実行するため、次のサンプルフォルダに戻ります: local_test フォルダ。

cd ~/SageMaker/sample-notebooks/advanced_functionality/scikit_bring_your_own/container/local_test

次のコマンドを使用して、これらのファイルへの実行可能フラグの設定が必要になる場合がある点に注意してください。

chmod +x *.sh

トレーニング用コンテナのテスト

train_local.sh はローカルにビルドされた Docker イメージでサンプルデータ iris.csv を使用しトレーニングジョブを開始します。in 。/test_dir/input/data/training/。次のコマンドでこれを呼び出します。

./train_local.sh decision_trees

トレーニング用にローカルテストを実行できます、そのときは空の JSON を havehyperparameters.json および resourceConfig.json に使用し、 training チャネルを data/ の下に格納する必要があります (中にはトレーニングデータを含む)。これらはすべてトレーニングコードのロジックに一致するようになっています。次のフォルダ test_dir/input/ の下にあるフォルダ構造とコンテンツはユーザー独自のトレーニングコードに合わせて調整する必要があります。

ローカルテストを実施するときにはごく小さなサンプルデータを使用し、実際のトレーニングジョブにはフルデータを使用するようお勧めします。スクリプトが成功したら、次のディレクトリに次のモデルファイルが生成されるはずです ./test_dir/model/

続いて失敗した実行のシミュレーションを使ってデバッグに挑戦します。まず、次のファイルを削除してください。 hyperparameters.json ファイル (次のフォルダ内) ./test_dir/input/config/。実行に失敗すると出力ファイルが以下のフォルダに生成されます。 ./test_dir/output/ ここでデバッグとトラブルシューティング用の詳細がログとして記録されます。

ホスト用コンテナのテスト

トレーニングが順調に進んだ場合、推論コードもテストします。まず、次の場所にモデルファイルがあることを確認します。 ./test_dir/model/、次に、ローカルで RESTful サービスを開始します。次のスクリプトを使用してください:

./serve_local.sh <イメージ名> > output.log

Flask アプリケーションからの出力がすべて次に送信されます: ./output.log ファイル。

これで、次のコマンドを使用してエンドポイントコードをテストできます。別のターミナルを起動してください。

./predict <ペイロードファイル> [content-type]

この content-type はオプションで次にデフォルト設定できます: text/csv。続いて ./output.log ファイルを確認してペイロードが正しく承認されたかを確認します。

これらのスクリプトがすべて順調に実行されたら、トレーニングジョブを Amazon SageMaker にデプロイし、後でエンドポイントにコンテナをデプロイする準備がすべて整います。開発環境をクリーンアップするために最後のステップがあります。RESTful サービスを停止する必要があります。これが稼働している唯一の Docker コンテナである場合は、次のコマンドで停止できます。

docker ps -a
docker kill <CONTAINER ID>

インスタンス上で他にも実行中の Docker プロセスがある場合は、個々のプロセスを見つけて、kill コマンドで停止します。

Amazon SageMaker コンソールでトレーニングとデプロイを行う

トレーニングジョブを作成

これで Docker イメージが生成され、トレーニング用と推論用のコードをセットアップできたので、トレーニングジョブを実行できます。AWS マネジメントコンソールにアクセスし、Services (サービス) を選択して、Machine Learning の下で Amazon SageMaker を選択します。左側でジョブを選択し、トレーニングジョブの作成ボタンを選択します。

トレーニングジョブの作成ウィンドウが表示されます。次のようなジョブ名を指定します: decision-trees-<日付時刻>。ジョブ名に 日付時刻 を追加するのはジョブ名で ResourceInUse を回避するために推奨されます。IAM ロールの下で、Create a new role (新しいロールの作成) を選ぶか、カスタム IAM ロール ARN を入力します。これは、AmazonSageMakerFullAccess を持ち、AmazonS3FullAccess ポリシーが設定されているロールであれば任意で指定できます。アルゴリズムカスタムに設定します。この例では、 File入力モードとして使用します。次に、トレーニングイメージセルで、Docker リポジトリ URI イメージタグを配置します ( build_and_push.sh は次のように Docker イメージをタグ付け: latest)。

Resource configuration (リソースの設定) までスクロールダウンします。これらの設定はサンプルでは単独のままにしておいても問題はありませんが、独自のモデルにカスタマイズしても構いません。ここでの主な設定は、インスタンスタイプ、および、インスタンス数の下のインスタンス数です。Scikit アルゴリズムなどの一部のアルゴリズムでは、1 つのインスタンスしか利用できません。この値を高く設定しても、あなたのアルゴリズムが自動的に複数のインスタンス間でスケールする理由にはなりません。

インスタンスタイプの主要な選択肢はインスタンスの mc、および p ファミリーです。この m ファミリーはバランスの取れたインスタンスタイプで、ご使用のモデルがどこに最も集中するかが確かでないときには、良い開始点と言えます。この c ファミリーは集中したワークロードのコンピューティング用で、 p ファミリーは深層学習でよく使用される GPU 容量を提供します。CloudWatch for SageMaker をモニタリングすることで、モデルが最も集中している場所をより良く見ることができます。

このジョブでは ハイパーパラメータ ボックスに任意のハイパーパラメータを設定します。この例で設定できるハイパーパラメータは以下のみです: max_leaf_nodes。ここでオプションとして値を設定することもできます。アルゴリズム用に他のハイパーパラメータのオプションを有効にすることに関心がある場合は、Docker イメージの train ファイルに渡す必要がある点について覚えておいてください。

次に、入力データの設定を指定します。 Channel name (チャネル名) は次のスクリプトでプログラムした内容に一致している必要があります: train スクリプト。データ入力用にセットアップした S3 location (S3 の場所) がチャネル名、チャネルが複数あるときは特に、これを一致させることをお勧めします。こうすることで、Amazon SageMaker は対応するコンテナの場所にチャネルデータを注入できます (例: /opt/ml/input/data/<チャネル名>)、プログラム train がデータを探す場所。この例では、次の名前のチャネルが 1 つだけあります: training。このモデルではヘッダーなし、1 列目がターゲットラベルの CSV ファイルを想定しています。お気軽に有名な Iris データセットをこれ用の S3 の場所にアップロードしてください。このデータセットがこのサンプルで使用されています。 Done (完了) を忘れずに選択してください。

本サンプルでは、次のようにトレーニングデータフォルダが作られます。

最後に、トレーニングジョブの完了後、Amazon S3 のどこにモデルの成果物が保存される場所を指定する必要があります。これはそのコンテナのすべての中身が次のフォルダ /opt/ml/model/に出力され、tar と gzip 形式で圧縮されてアーカイブされます。S3 output path (S3 出力パス) フィールドに Amazon S3 バケットを指定します。

次に、Create training job (トレーニングジョブの作成) ボタンを選択します。

作成されたトレーニングジョブが完了したら、指定した S3 の出力パスに生成されたモデルが表示されるはずです。このモデルのフルパスは次のとおりです:

s3://<バケット名>/models/<ジョブ名>/output/model.tar.gz

エンドポイントをデプロイする

トレーニングジョブが終了したら、モデルを本番環境に移行させるためにエンドポイントをデプロイできるようになります。この作業は SageMaker コンソールから行います。次の 3 つのステップに従ってください。第一に、モデルリソースを作成する必要があります。第二に、エンドポイントの設定を作成します。第三に、実際のエンドポイントをデプロイします。

1 つ目のステップはモデルリソースの作成です。これには、Docker イメージとその成果物の Amazon S3 の場所について Amazon SageMaker で必要な情報が含まれています。

Amazon SageMaker コンソールの左側にあるナビゲーターペインの Resources (リソース) の下で、Models (モデル) を選択します。次に Create model (モデルの作成) ボタンを選択します。

最初に、Model name (モデル) 名に次のようなモデル名を入力します。 decision-trees、その後、IAM role (IAM ロール) を選択するか、作成します。トレーニングジョブに使用したロールに、 AmazonSageMakerFullAccess IAM ポリシーがアタッチされている限り、それと同じロールを使用します。

次にコンテナに関する情報を入力します。トレーニングジョブに使用した同じコンテナを使用できます。以前、Location of inference code image (論理コードイメージの場所) でコンテナ用に保存した ECR URI を指定します。次のようなイメージタグが確実に含まれるようにします。 latest タグ。次に、Location of model artifacts (モデルの成果物の場所) セルで、トレーニングジョブで作成したモデル成果物の S3 URI を指定します。これはあなたがトレーニング中に設定した S3 出力パスでした。

Create model (モデルの作成) ボタンを選択します。

次に、エンドポイントの設定を作成する必要があります。私たちはこれとモデルリソースを組み合わせ、プロビジョニングするインスタンスの種類を決定します。また、これを使用して、A/B テストの実施用に複数のモデルを指定することもできます。このサンプルでは、1 つのモデルのみを使用します。

左側のナビゲーションペインの Resources (リソース) の下で、Endpoint configuration (エンドポイントの設定) を選択します。Create endpoint configuration (エンドポイントの設定の作成) ボタンを選択します。

Endpoint configuration name (エンドポイントの設定名) の下で、エンドポイント設定に名前を付けます。同一モデルのバージョンが複数あることが想定される場合を除き、モデルと同じ名前を付けます。次に、左下側にある Add model (モデルの追加) リンクを選択します。作成したばかりのモデルを選択して save (保存) を選択します。このサンプルのデフォルトとして、追加の値を残すこともできます。

Create endpoint configuration (エンドポイントの設定の作成) ボタンを選択します。

これでモデルとエンドポイントの設定ができたので、実際のエンドポイントをデプロイできます。エンドポイントをアクティブ化することで、インスタンスのプロビジョニングが行われます。エンドポイントがアクティブであれば、課金は正確に行われます。よって、直接の送信先となるエンドポイントのみを有効化することが重要です。

左のナビゲーションペインの Resources (リソース) の下で、Endpoints (エンドポイント) を選択します。Create endpoint (エンドポイントの作成) ボタンを選択します。

Endpoint name (エンドポイント名) の下で、エンドポイント設定に名前を付けます。バリアントなしに 1 つのモデルを展開するのみの場合は、モデルと同じ名前を使用します。この場合、次を使用: decision-treesUse an existing endpoint configuration (既存のエンドポイント設定を使用する) を選択したままにします。

Endpoint configuration (エンドポイント設定) の下で、最後のステップで作成したエンドポイント設定を選択します。Select endpoint configuration (エンドポイントの設定の選択) ボタンを選択します。最後に、Create endpoint (エンドポイントの作成) ボタンを選択します。

以下のような結果が出ます。

AWS CLI を使用してトレーニングおよびデプロイする

トレーニングジョブを作成

次のコマンドを使用して AWS CLI からトレーニングジョブを起動するオプションがあります。

aws sagemaker create-training-job \
    --training-job-name <job name> \
    --algorithm-specification \
        TrainingImage=<Repository URI>:<Image Tag>,TrainingInputMode=File \
    --role-arn <Role ARN> \
    --input-data-config \
        '{"ChannelName":"training", 
          "DataSource":{"S3DataSource":{"S3DataType":"S3Prefix", 
                                        "S3Uri":"s3://<bucket name>/data/training/",
                                        "S3DataDistributionType":"FullyReplicated"
                                        } 
                        } 
          }' \
    --output-data-config \
        S3OutputPath=s3://<bucket name>/models/ \
    --resource-config \
        InstanceType=ml.m4.xlarge,InstanceCount=1,VolumeSizeInGB=1 \
    --stopping-condition \
        MaxRuntimeInSeconds=86400 \
    --hyper-parameters \
        max_leaf_nodes=5 

このコマンドは、Amazon SageMaker コンソールで作成したものと同じ設定の同一トレーニングジョブを生成します。ただし、固有の ID が必要なことからトレーニングジョブの名前は異なります。戻された TrainingJobArn はトレーニングジョブの作成が成功したことを意味します。 Amazon SageMaker コンソールでのトレーニングジョブのステータスは Jobs (ジョブ) ページで追跡できます。

この input-data-config により、チャネル配列オブジェクトを使用できます。たとえば、training チャネルのあとに添付し、これらの 2 つのオブジェクトとは別にスペースを使用することで、定義されていれば別のチャネルを提供できます。この hyper-parameters により、次のようなハイパーパラメータを最大 100 個使用できます: KeyName1=string,KeyName2=string。たとえば、 max_depth が定義されていれば max_depth=10 を次のすぐ後に添付できます: max_leaf_nodes=5AWS CLI を使用して独自のトレーニングジョブを作成する際の詳細については、aws.sagemaker.create-training-jobAWS Command Line Interface を使用した短縮構文の使用を参照してください。

また、次もご覧ください: S3OutputPath には Amazon SageMaker コンソールと AWS CLI で作成された両方のトレーニングジョブが含まれます。

エンドポイントをデプロイする

SageMaker エンドポイントをデプロイするために、次の 3 つの AWS CLI コマンドを使用できます。このコマンドで想定される出力は以下のとおりです。

aws sagemaker create-model \
    --model-name <model name> \
    --primary-container \
        Image=<Repository URL>:<Image Tag>,ModelDataUrl=s3://<bucket name>/models/<job name>/output/model.tar.gz \
    --execution-role-arn <Role ARN>

aws sagemaker create-endpoint-config \
    --endpoint-config-name <endpoint config name> \
    --production-variants \
        VariantName=dev,ModelName=<model name>,InitialInstanceCount=1,InstanceType=ml.m4.xlarge,InitialVariantWeight=1.0

aws sagemaker create-endpoint \
    --endpoint-name <endpoint name> \
    --endpoint-config-name <endpoint config name>

正常に作成されると、エンドポイント InService が表示されます。

理論をテストする

SageMaker ノートブックインスタンスからエンドポイントをテストする最も簡単な方法。セルで次のコードを実行します。

import boto3
import io
import pandas as pd
import itertools

# Set below parameters
bucket = '<bucket name>'
key = 'data/training/iris.csv'
endpointName = 'decision-trees'

# Pull our data from S3
s3 = boto3.client('s3')
f = s3.get_object(Bucket=bucket, Key=key)

# Make a dataframe
shape = pd.read_csv(io.BytesIO(f['Body'].read()), header=None)

# Take a random sample
a = [50*i for i in range(3)]
b = [40+i for i in range(10)]
indices = [i+j for i,j in itertools.product(a,b)]
test_data=shape.iloc[indices[:-1]]
test_X=test_data.iloc[:,1:]
test_y=test_data.iloc[:,0]

# Convert the dataframe to csv data
test_file = io.StringIO()
test_X.to_csv(test_file, header=None, index=None)

# Talk to SageMaker
client = boto3.client('sagemaker-runtime')
response = client.invoke_endpoint(
    EndpointName=endpointName,
    Body=test_file.getvalue(),
    ContentType='text/csv',
    Accept='Accept'
)

print(response['Body'].read().decode('ascii'))

これはあなたのデータファイルのデータからランダムなサンプルを取得し、エンドポイントに送付します。また結果を印刷します。

まとめ

おめでとうございます! これで Amazon SageMaker で Scikit モデルのビルド、トレーニング、デプロイ、テストを実行しました。ワークフローやコードは必要に応じてご自由に書き換えてください。

今回のブログの投稿者について

Morgan Du は AWS プロフェッショナルサービスの機械学習コンサルタントです。彼女は AI、機械学習、深層学習などの分野に情熱を傾けています。私たちの日々の暮らしに影響を及ぼし、パワーを与えてくれるイノベーティブな ML ソリューションの導入を専門としています。

Thomas Hughes は AWS プロフェッショナルサービスのデータサイエンティストです。カリフォルニア大学サンタバーバラ校で博士号を取得した Hughes は、社会科学、教育、および宣伝広告における問題に取り組んできました。Hughes は現在、機械学習がビッグデータに遭遇するときに生じる最も困難な問題の幾つかを解決すべく尽力しています。