Edge コンテナのチュートリアル

AutoML Vision Edge モデルを作成して Google Cloud Storage バケットにエクスポートすると、RESTful サービスで AutoML Vision Edge モデルTF Serving Docker イメージを使用できるようになります。

作業内容

Docker コンテナで、Edge モデルをさまざまなデバイスに簡単にデプロイできるようになります。コンテナから任意の言語で REST API を呼び出し、Edge モデルを実行できます。依存関係をインストールする必要もなく、適切な TensorFlow バージョンを探す必要もありません。

このチュートリアルでは、Docker コンテナを使用して Edge モデルをデバイス上で実行する手順を詳しく説明します。

このチュートリアルでは特に、次の 3 つの手順について説明します。

  1. ビルド済みのコンテナを取得する。
  2. Edge モデルを含むコンテナを実行し、REST API を開始する。
  3. 予測を作成する。

多くのデバイスには CPU しかありませんが、一部のデバイスでは GPU を使用して予測を高速化できます。ここでは、事前にビルドされた CPU と GPU コンテナの両方を使用する場合について説明します。

目標

このチュートリアルでは、コードを使用して次の作業を行います。

  1. Docker コンテナを取得する。
  2. Edge モデルを含む Docker コンテナを使用して REST API を起動する。
  3. 予測を行い分析結果を取得する。

始める前に

このチュートリアルを完了するには、次のことが必要です。

  1. エクスポート可能な Edge モデルをトレーニングします。Edge デバイスモデル クイックスタートに沿って Edge モデルをトレーニングします。
  2. AutoML Vision Edge モデルをエクスポートします。このモデルは、REST API としてコンテナとともに提供されます。
  3. Docker をインストールします。これは、Docker コンテナを実行するために必要なソフトウェアです。
  4. (省略可)NVIDIA Docker とドライバをインストールします。これは任意のステップです。GPU を搭載したデバイスで予測を高速化できます。
  5. テスト画像を準備します。これらの画像は、分析結果を取得するためのリクエストで送信されます。

以下では、モデルのエクスポートと必要なソフトウェアのインストールについて詳しく説明します。

AutoML Vision Edge モデルをエクスポートする

Edge モデルをトレーニングしたら、別のデバイスにエクスポートできるようになります。

コンテナは、エクスポート時に saved_model.pb という名前の TensorFlow モデルをサポートします。

コンテナの AutoML Vision Edge モデルをエクスポートするには、UI の [コンテナ] タブを選択し、モデルを Google Cloud Storage の ${YOUR_MODEL_PATH} にエクスポートします。このエクスポートされたモデルは、後で REST API としてコンテナとともに提供されます。

[コンテナ] オプションにエクスポートする

エクスポートしたモデルをローカルでダウンロードするには、次のコマンドを実行します。

ここで

  • ${YOUR_MODEL_PATH} - Google Cloud Storage 上のモデルの場所(たとえば、gs://my-bucket-vcm/models/edge/ICN4245971651915048908/2020-01-20_01-27-14-064_tf-saved-model/)です。
  • ${YOUR_LOCAL_MODEL_PATH} - モデルをダウンロードするローカルパス(たとえば、/tmp)です。
gsutil cp ${YOUR_MODEL_PATH} ${YOUR_LOCAL_MODEL_PATH}/saved_model.pb

Docker のインストール

Docker は、コンテナ内でアプリケーションのデプロイと実行に使用するソフトウェアです。

Docker Community Edition(CE)をシステムにインストールします。これを使用して Edge モデルを REST API として提供します。

NVIDIA Driver と NVIDIA DOCKER のインストール(省略可 - GPU のみ)

一部のデバイスでは GPU を使用して予測を高速化できます。GPU Docker コンテナは NVIDIA GPU に対応しています。

GPU コンテナを実行するには、NVIDIA ドライバNVIDIA Docker をシステムにインストールする必要があります。

CPU を使用してモデル推定を実行する

このセクションでは、CPU コンテナを使用してモデル推定を実行する手順を説明します。インストールされた Docker を使用して CPU コンテナを取得し、実行します。エクスポートされた Edge モデルを REST API として提供し、テストイメージのリクエストを REST API に送信して解析結果を取得します。

Docker イメージを pull する

まず Docker を使用して、ビルド済みの CPU コンテナを取得します。ビルド済みの CPU コンテナには、エクスポートされた Edge モデルを提供する環境が用意されていますが、Edge モデルは含まれてはいません

ビルド済みの CPU コンテナは、Google Container Registry に格納されます。コンテナをリクエストする前に、Google Container Registry でコンテナの場所の環境変数を設定します。

export CPU_DOCKER_GCR_PATH=gcr.io/cloud-devrel-public-resources/gcloud-container-1.14.0:latest

Container Registry パスの環境変数を設定したら、次のコマンドラインを実行して CPU コンテナを取得します。

sudo docker pull ${CPU_DOCKER_GCR_PATH}

Docker コンテナを実行する

既存のコンテナを取得したら、この CPU コンテナを実行して REST API で Edge モデル推定を実行します。

CPU コンテナを開始する前に、システム変数を設定する必要があります。

  • ${CONTAINER_NAME} - 実行時のコンテナ名を示す文字列です。たとえば、CONTAINER_NAME=automl_high_accuracy_model_cpu
  • ${PORT} - デバイスで REST API 呼び出しを受け入れるポートを示す数値です。たとえば、PORT=8501

変数を設定したら、Docker をコマンドラインで実行し、REST API で Edge モデル推定を行います。

sudo docker run --rm --name ${CONTAINER_NAME} -p ${PORT}:8501 -v ${YOUR_MODEL_PATH}:/tmp/mounted_model/0001 -t ${CPU_DOCKER_GCR_PATH}

コンテナが正常に実行されると、REST API は http://localhost:${PORT}/v1/models/default:predict で提供できるようになります。次のセクションでは、予測リクエストをこの場所に送信する方法を詳しく説明します。

予測リクエストを送信する

コンテナが正常に実行されたので、テスト画像の予測リクエストを REST API に送信できます。

コマンドライン

コマンドライン リクエストの本文には、Base64 でエンコードされた image_bytes と文字列 key が含まれています。これらは特定の画像を表します。画像エンコードの詳細については、Base64 エンコードをご覧ください。リクエスト JSON ファイルの形式は次のとおりです。

/tmp/request.json
{
  "instances":
  [
    {
      "image_bytes":
      {
        "b64": "/9j/7QBEUGhvdG9zaG9...base64-encoded-image-content...fXNWzvDEeYxxxzj/Coa6Bax//Z"
      },
      "key": "your-chosen-image-key"
    }
  ]
}

ローカルの JSON リクエスト ファイルを作成したら、予測リクエストを送信できます。

予測リクエストを送信するには、次のコマンドを使用します。

curl -X POST -d  @/tmp/request.json http://localhost:${PORT}/v1/models/default:predict
レスポンス

出力は次のようになります。

{
    "predictions": [
        {
            "labels": ["Good", "Bad"],
            "scores": [0.665018, 0.334982]
        }
    ]
}

Python

詳細については、AutoML Vision Python API のリファレンス ドキュメントをご覧ください。

AutoML Vision に対する認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。

import base64
import cv2
import io
import json

import requests

def preprocess_image(image_file_path, max_width, max_height):
    """Preprocesses input images for AutoML Vision Edge models.

    Args:
        image_file_path: Path to a local image for the prediction request.
        max_width: The max width for preprocessed images. The max width is 640
            (1024) for AutoML Vision Image Classfication (Object Detection)
            models.
        max_height: The max width for preprocessed images. The max height is
            480 (1024) for AutoML Vision Image Classfication (Object
            Detetion) models.
    Returns:
        The preprocessed encoded image bytes.
    """
    # cv2 is used to read, resize and encode images.
    encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), 85]
    im = cv2.imread(image_file_path)
    [height, width, _] = im.shape
    if height > max_height or width > max_width:
        ratio = max(height / float(max_width), width / float(max_height))
        new_height = int(height / ratio + 0.5)
        new_width = int(width / ratio + 0.5)
        resized_im = cv2.resize(
            im, (new_width, new_height), interpolation=cv2.INTER_AREA
        )
        _, processed_image = cv2.imencode(".jpg", resized_im, encode_param)
    else:
        _, processed_image = cv2.imencode(".jpg", im, encode_param)
    return base64.b64encode(processed_image).decode("utf-8")

def container_predict(image_file_path, image_key, port_number=8501):
    """Sends a prediction request to TFServing docker container REST API.

    Args:
        image_file_path: Path to a local image for the prediction request.
        image_key: Your chosen string key to identify the given image.
        port_number: The port number on your device to accept REST API calls.
    Returns:
        The response of the prediction request.
    """
    # AutoML Vision Edge models will preprocess the input images.
    # The max width and height for AutoML Vision Image Classification and
    # Object Detection models are 640*480 and 1024*1024 separately. The
    # example here is for Image Classification models.
    encoded_image = preprocess_image(
        image_file_path=image_file_path, max_width=640, max_height=480
    )

    # The example here only shows prediction with one image. You can extend it
    # to predict with a batch of images indicated by different keys, which can
    # make sure that the responses corresponding to the given image.
    instances = {
        "instances": [{"image_bytes": {"b64": str(encoded_image)}, "key": image_key}]
    }

    # This example shows sending requests in the same server that you start
    # docker containers. If you would like to send requests to other servers,
    # please change localhost to IP of other servers.
    url = "http://localhost:{}/v1/models/default:predict".format(port_number)

    response = requests.post(url, data=json.dumps(instances))
    print(response.json())

GPU コンテナを使用したモデル推定の実行(省略可)

このセクションでは、GPU コンテナを使用してモデル推定を実行する方法について説明します。このプロセスは、CPU を使用したモデル推定の実行と非常によく似ています。主な違いは、GPU コンテナパスと GPU コンテナの起動方法です。

Docker イメージを pull する

まず Docker を使用して、ビルド済みの GPU コンテナを取得します。ビルド済みの GPU コンテナには、GPU を備えたエクスポートされた Edge モデルを提供する環境が用意されていますが、Edge モデルやドライバは含まれてはいません。

ビルド済みの CPU コンテナは、Google Container Registry に格納されます。コンテナをリクエストする前に、Google Container Registry でコンテナの場所の環境変数を設定します。

export GPU_DOCKER_GCR_PATH=gcr.io/cloud-devrel-public-resources/gcloud-container-1.14.0-gpu:latest

以下のコマンドラインを実行して、GPU コンテナを取得します。

sudo docker pull ${GPU_DOCKER_GCR_PATH}

Docker コンテナを実行する

このステップでは、GPU コンテナを実行して REST API で Edge モデル推定を行います。前述の NVIDIA ドライバと Docker をインストールする必要があります。また、次のシステム変数も設定する必要があります。

  • ${CONTAINER_NAME} - 実行時のコンテナ名を示す文字列です。たとえば、CONTAINER_NAME=automl_high_accuracy_model_gpu
  • ${PORT} - デバイスで REST API 呼び出しを受け入れるポートを示す数値です。たとえば、PORT=8502

変数を設定したら、Docker をコマンドラインで実行し、REST API で Edge モデル推定を行います。

sudo docker run --runtime=nvidia --rm --name "${CONTAINER_NAME}" -v \
${YOUR_MODEL_PATH}:/tmp/mounted_model/0001 -p \
${PORT}:8501 -t ${GPU_DOCKER_GCR_PATH}

コンテナが正常に実行されると、REST API は http://localhost:${PORT}/v1/models/default:predict で提供できるようになります。次のセクションでは、予測リクエストをこの場所に送信する方法を詳しく説明します。

予測リクエストを送信する

コンテナが正常に実行されたので、テスト画像の予測リクエストを REST API に送信できます。

コマンドライン

コマンドライン リクエストの本文には、Base64 でエンコードされた image_bytes と文字列 key が含まれています。これらは特定の画像を表します。画像エンコードの詳細については、Base64 エンコードをご覧ください。リクエスト JSON ファイルの形式は次のとおりです。

/tmp/request.json
{
  "instances":
  [
    {
      "image_bytes":
      {
        "b64": "/9j/7QBEUGhvdG9zaG9...base64-encoded-image-content...fXNWzvDEeYxxxzj/Coa6Bax//Z"
      },
      "key": "your-chosen-image-key"
    }
  ]
}

ローカルの JSON リクエスト ファイルを作成したら、予測リクエストを送信できます。

予測リクエストを送信するには、次のコマンドを使用します。

curl -X POST -d  @/tmp/request.json http://localhost:${PORT}/v1/models/default:predict
レスポンス

出力は次のようになります。

{
    "predictions": [
        {
            "labels": ["Good", "Bad"],
            "scores": [0.665018, 0.334982]
        }
    ]
}

Python

詳細については、AutoML Vision Python API のリファレンス ドキュメントをご覧ください。

AutoML Vision に対する認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。

import base64
import cv2
import io
import json

import requests

def preprocess_image(image_file_path, max_width, max_height):
    """Preprocesses input images for AutoML Vision Edge models.

    Args:
        image_file_path: Path to a local image for the prediction request.
        max_width: The max width for preprocessed images. The max width is 640
            (1024) for AutoML Vision Image Classfication (Object Detection)
            models.
        max_height: The max width for preprocessed images. The max height is
            480 (1024) for AutoML Vision Image Classfication (Object
            Detetion) models.
    Returns:
        The preprocessed encoded image bytes.
    """
    # cv2 is used to read, resize and encode images.
    encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), 85]
    im = cv2.imread(image_file_path)
    [height, width, _] = im.shape
    if height > max_height or width > max_width:
        ratio = max(height / float(max_width), width / float(max_height))
        new_height = int(height / ratio + 0.5)
        new_width = int(width / ratio + 0.5)
        resized_im = cv2.resize(
            im, (new_width, new_height), interpolation=cv2.INTER_AREA
        )
        _, processed_image = cv2.imencode(".jpg", resized_im, encode_param)
    else:
        _, processed_image = cv2.imencode(".jpg", im, encode_param)
    return base64.b64encode(processed_image).decode("utf-8")

def container_predict(image_file_path, image_key, port_number=8501):
    """Sends a prediction request to TFServing docker container REST API.

    Args:
        image_file_path: Path to a local image for the prediction request.
        image_key: Your chosen string key to identify the given image.
        port_number: The port number on your device to accept REST API calls.
    Returns:
        The response of the prediction request.
    """
    # AutoML Vision Edge models will preprocess the input images.
    # The max width and height for AutoML Vision Image Classification and
    # Object Detection models are 640*480 and 1024*1024 separately. The
    # example here is for Image Classification models.
    encoded_image = preprocess_image(
        image_file_path=image_file_path, max_width=640, max_height=480
    )

    # The example here only shows prediction with one image. You can extend it
    # to predict with a batch of images indicated by different keys, which can
    # make sure that the responses corresponding to the given image.
    instances = {
        "instances": [{"image_bytes": {"b64": str(encoded_image)}, "key": image_key}]
    }

    # This example shows sending requests in the same server that you start
    # docker containers. If you would like to send requests to other servers,
    # please change localhost to IP of other servers.
    url = "http://localhost:{}/v1/models/default:predict".format(port_number)

    response = requests.post(url, data=json.dumps(instances))
    print(response.json())

概要

このチュートリアルでは、CPU および GPU Docker コンテナを使用して Edge モデルを実行しました。これで、このコンテナベースのソリューションを他のデバイスにデプロイできるようになりました。

次のステップ