Amazon Sagemakerで作成したモデルによる推論処理をREST APIとして公開する


やったこと

SageMakerで作成したモデルを使った推論処理をREST APIとして公開してみた。

構成

API Gatewayで公開されるAPIにアクセスし、Lambdaを実行。LambdaからSageMakerで作成したModelをエンドポントから呼び出し、推論処理を実施、リクエスト側に結果を返す、という感じ。

構築手順

  1. SageMakerで学習モデルを作成
  2. モデルをデプロイ&エンドポント作成
  3. LambdaからSageMakerのエンドポイントを呼び出すためのロールを作成する
  4. Lambda関数実装
  5. Amazon API Gateway設定
  6. CurlでREST APIの動作確認

1,2だけでかなりの量になるので別で執筆中。
以下、3以降について記載。

3. LambdaからSageMakerのエンドポイントを呼び出すためのロールを作成する

LambdaからSageMakerのエンドポイントにアクセスするためにロールを作成します。ここの記載がない記事が多かったので、あえて設定手順記載。

  1. サービスから「IAM」を選択
  2. ナビゲーションから「ロール」を選択し「ロールを作成」をクリック
  3. ユースケースの選択でLambdaを選択して「次のステップ」
    ここではどのサービスにロールを割り当てるか、を考えます。今回、Lambdaにロールを割り当てるのでLambdaを選択します。
  4. ポリシーのフィルタで[sagemaker]と入力。「AmazonSageMakerFullAccess」を選択して「次のステップ」
    ちなみに、ポリシー名をクリックするとこのポリシーのアクセス権限を確認することができます。"Statement"の中をみると、 "Effect": "Allow","Action": ["sagemaker:*"],"の記載があり、これはsagemakerに対するあらゆるアクションを許可するという意味です。これによりLambdaからモデルのエンドポントを呼び出すことができるようになります。
  5. ロール名を指定して、ロールの作成をクリック

4. Lambda関数実装

Lambdaでは推論処理を実装します。下記のような感じで、言語は今回pythonで記載しました。

import boto3

ENDPONT_NAME = "YOUR_ENDPOINT_NAME" #ここにはエンドポイントの名前を指定する


def lambda_handler(event, context):
    runtime_client = boto3.client('runtime.sagemaker', region_name="ap-northeast-1")
    values = list(event.values())

    try:
        response = runtime_client.invoke_endpoint(EndpointName=ENDPONT_NAME, 
                                   ContentType='text/csv', 
                                   #Body=value_single)
                                   Body='{0},{1},{2},{3}'.format(values[0], values[1], values[2], values[3]))

        result = response['Body'].read()
        result = result.decode("utf-8")
        return result

    except:
        return {
            'statusCode': 400,
            'body': 'Exception Occur'
        }

5. Amazon API Gateway設定

ここを参考に設定を済ませました。

6. CurlでREST APIの動作確認

さくっと確認

> curl --request POST --header 'Content-Type: application/json' --data '{\"key1\":0.25,\"key2\":0.666,\"key3\":1,\"key4\":1}' 'https://your-api'
curl: (6) Could not resolve host: application
curl: (1) Protocol "'https" not supported or disabled in libcurl

あれ、なんで。
調べてみると、windowsターミナルではシングルクオーテーションが使えないみたい。
Windows 環境における curl コマンド利用のまとめ (平成最終版)がわかりやすかった。

修正して、もう一度実行。

> curl --request POST --header "Content-Type: application/json" --data "{\"key1\":0.25,\"key2\":0.666,\"key3\":1,\"key4\":1}" "https://your-api"
"106.2766342163086"

ふぅ。OK。