커스텀 예측 루틴

커스텀 예측 루틴을 사용하면 AI Platform Prediction에 온라인 예측 요청을 전송할 때 실행할 코드를 결정할 수 있습니다.

커스텀 예측 루틴을 사용하지 않고 AI Platform Prediction에 버전 리소스를 배포하는 경우 학습에 사용한 머신러닝 프레임워크의 예측 작업을 수행하여 예측 요청을 처리합니다.

그러나 커스텀 예측 루틴을 버전 리소스로 배포하는 경우 수신하는 모든 예측 요청에 대한 응답으로 커스텀 Python 코드를 실행하도록 AI Platform Prediction에 지시할 수 있습니다. 학습된 모델이 예측을 수행하기 전에 예측 입력을 사전 처리하거나 예측 결과를 보내기 전에 모델의 예측을 사후 처리할 수 있습니다.

커스텀 예측 루틴을 만들려면 모델 버전을 만들 때 AI Platform Prediction에 두 부분을 제공해야 합니다.

  • 예측에 사용해야 하는 아티팩트가 포함된 Cloud Storage의 모델 디렉터리

  • 예측자 인터페이스 구현과 AI Platform Prediction이 예측 시 사용하도록 할 기타 커스텀 코드가 포함된 Cloud Storage의 .tar.gz Python 소스 배포 패키지

모델 버전에 기존(MLS1) 머신 유형을 사용하는 경우에만 커스텀 예측 루틴을 배포할 수 있습니다.

모델 아티팩트를 모델 디렉터리에 업로드

모델 배포 가이드에 따라 Cloud Storage에 학습된 모델과 AI Platform Prediction이 예측에서 사용할 데이터 또는 스테이트풀(Statefulness)을 제공하는 다른 파일을 함께 업로드합니다.

AI Platform 예측에 배포하는 모델 아티팩트의 전체 파일 크기는 500MB 이하여야 합니다.

학습된 머신러닝 모델을 TensorFlow SavedModel, model.joblib 파일, model.pkl 파일, model.bst 파일로 모델 디렉터리에 업로드할 수 있고, 학습된 tf.keras 모델을 포함하는 HDF5 파일 또는 직렬화된 다른 형식으로 모델을 제공할 수도 있습니다.

직렬화된 학습 상태가 저장된 커스텀 전처리기 클래스의 인스턴스가 있는 피클 파일을 추가로 포함할 수 있습니다.

예를 들어 preprocess.py 파일에 정의된 다음 전처리기를 살펴보겠습니다.

import numpy as np


class ZeroCenterer(object):
    """Stores means of each column of a matrix and uses them for preprocessing."""

    def __init__(self):
        """On initialization, is not tied to any distribution."""
        self._means = None

    def preprocess(self, data):
        """Transforms a matrix.

        The first time this is called, it stores the means of each column of
        the input. Then it transforms the input so each column has mean 0. For
        subsequent calls, it subtracts the stored means from each column. This
        lets you 'center' data at prediction time based on the distribution of
        the original training data.

        Args:
            data: A NumPy matrix of numerical data.

        Returns:
            A transformed matrix with the same dimensions as the input.
        """
        if self._means is None:  # during training only
            self._means = np.mean(data, axis=0)
        return data - self._means

수치 데이터 세트에 대한 학습에서 전처리기는 열의 모든 값에서 각 열의 평균을 빼서 0을 중심으로 데이터를 조정합니다. 그런 다음 전처리기 인스턴스를 피클 파일 preprocessor.pkl로 내보낼 수 있습니다. 이 파일에는 학습 데이터에서 계산된 각 열의 평균이 보존됩니다.

예측 중에 커스텀 예측 루틴은 이 파일에서 전처리기를 로드하여 예측 입력에 동일한 변환을 할 수 있습니다.

커스텀 예측 루틴에서 이와 같은 스테이트풀(Stateful) 전처리기를 사용하는 방법은 예측자 인터페이스 구현 방법이 설명된 다음 섹션을 참조하세요.

학습 및 예측 중 스테이트풀(Stateful) 전처리기 사용에 관한 전체 예시를 세부적으로 살펴보려면 Keras로 커스텀 예측 루틴 만들기 또는 scikit-learn으로 커스텀 예측 루틴 만들기를 참조하세요.

예측자 만들기

Predictor 클래스를 제공하여 AI Platform Prediction에 예측 요청을 처리하는 방법을 알립니다. 이 클래스는 다음 인터페이스를 구현합니다.

class Predictor(object):
    """Interface for constructing custom predictors."""

    def predict(self, instances, **kwargs):
        """Performs custom prediction.

        Instances are the decoded values from the request. They have already
        been deserialized from JSON.

        Args:
            instances: A list of prediction input instances.
            **kwargs: A dictionary of keyword args provided as additional
                fields on the predict request body.

        Returns:
            A list of outputs containing the prediction results. This list must
            be JSON serializable.
        """
        raise NotImplementedError()

    @classmethod
    def from_path(cls, model_dir):
        """Creates an instance of Predictor using the given path.

        Loading of the predictor should be done in this method.

        Args:
            model_dir: The local directory that contains the exported model
                file along with any additional files uploaded when creating the
                version resource.

        Returns:
            An instance implementing this Predictor class.
        """
        raise NotImplementedError()

AI Platform Prediction의 예측 노드from_path 클래스 메서드를 사용하여 예측자의 인스턴스를 로드합니다. 이 메서드는 모델 디렉터리에 저장된 아티팩트를 로드해야 하며 이 콘텐츠는 Cloud Storage에서 model_dir 인수로 표시되는 위치로 복사됩니다.

배포에 온라인 예측 요청이 수신될 때마다 from_path에 의해 반환되는 Predictor 클래스의 인스턴스는 predict 메서드를 사용하여 예측을 생성합니다. AI Platform Prediction은 이 메서드의 반환 값을 JSON으로 직렬화하고 예측 요청에 대한 응답으로 전송합니다.

predict 메서드는 입력을 JSON에서 Python 객체로 변환하거나 출력을 JSON으로 변환할 필요가 없습니다. AI Platform Prediction이 predict 메서드 외부에서 이를 알아서 처리하기 때문입니다.

AI Platform Prediction은 predict 요청의 본문에서 instances 필드를 파싱하여 AI Platform Training 및 Prediction API에 instances 인수를 제공합니다. 요청 본문의 다른 모든 필드는 파싱하여 predict 메서드에 **kwargs 사전의 항목으로 제공합니다. 자세한 내용은 predict 요청을 AI Platform Training 및 Prediction API로 구성하는 방법을 참조하세요.

이전 섹션의 예시를 계속 이어서, 모델 디렉터리에 preprocessor.pkl(ZeroCenterer 클래스의 피클 인스턴스)과 model.h5로 내보낸 학습된 tf.keras 모델 또는 model.joblib로 내보낸 scikit-learn 모델이 있다고 가정합니다.

사용하는 머신러닝 프레임워크에 따라 predictor.py 파일에 다음 예측자 클래스 중 하나를 구현할 수 있습니다.

TensorFlow

import os
import pickle

import numpy as np
from tensorflow import keras


class MyPredictor(object):
    """An example Predictor for an AI Platform custom prediction routine."""

    def __init__(self, model, preprocessor):
        """Stores artifacts for prediction. Only initialized via `from_path`."""
        self._model = model
        self._preprocessor = preprocessor

    def predict(self, instances, **kwargs):
        """Performs custom prediction.

        Preprocesses inputs, then performs prediction using the trained Keras
        model.

        Args:
            instances: A list of prediction input instances.
            **kwargs: A dictionary of keyword args provided as additional
                fields on the predict request body.

        Returns:
            A list of outputs containing the prediction results.
        """
        inputs = np.asarray(instances)
        preprocessed_inputs = self._preprocessor.preprocess(inputs)
        outputs = self._model.predict(preprocessed_inputs)
        return outputs.tolist()

    @classmethod
    def from_path(cls, model_dir):
        """Creates an instance of MyPredictor using the given path.

        This loads artifacts that have been copied from your model directory in
        Cloud Storage. MyPredictor uses them during prediction.

        Args:
            model_dir: The local directory that contains the trained Keras
                model and the pickled preprocessor instance. These are copied
                from the Cloud Storage model directory you provide when you
                deploy a version resource.

        Returns:
            An instance of `MyPredictor`.
        """
        model_path = os.path.join(model_dir, "model.h5")
        model = keras.models.load_model(model_path)

        preprocessor_path = os.path.join(model_dir, "preprocessor.pkl")
        with open(preprocessor_path, "rb") as f:
            preprocessor = pickle.load(f)

        return cls(model, preprocessor)

scikit-learn

import os
import pickle

import numpy as np
from sklearn.externals import joblib


class MyPredictor(object):
    """An example Predictor for an AI Platform custom prediction routine."""

    def __init__(self, model, preprocessor):
        """Stores artifacts for prediction. Only initialized via `from_path`."""
        self._model = model
        self._preprocessor = preprocessor

    def predict(self, instances, **kwargs):
        """Performs custom prediction.

        Preprocesses inputs, then performs prediction using the trained
        scikit-learn model.

        Args:
            instances: A list of prediction input instances.
            **kwargs: A dictionary of keyword args provided as additional
                fields on the predict request body.

        Returns:
            A list of outputs containing the prediction results.
        """
        inputs = np.asarray(instances)
        preprocessed_inputs = self._preprocessor.preprocess(inputs)
        outputs = self._model.predict(preprocessed_inputs)
        return outputs.tolist()

    @classmethod
    def from_path(cls, model_dir):
        """Creates an instance of MyPredictor using the given path.

        This loads artifacts that have been copied from your model directory in
        Cloud Storage. MyPredictor uses them during prediction.

        Args:
            model_dir: The local directory that contains the trained
                scikit-learn model and the pickled preprocessor instance. These
                are copied from the Cloud Storage model directory you provide
                when you deploy a version resource.

        Returns:
            An instance of `MyPredictor`.
        """
        model_path = os.path.join(model_dir, "model.joblib")
        model = joblib.load(model_path)

        preprocessor_path = os.path.join(model_dir, "preprocessor.pkl")
        with open(preprocessor_path, "rb") as f:
            preprocessor = pickle.load(f)

        return cls(model, preprocessor)

predict 메서드는 예측 결과를 반환하기 전에 tolist 메서드로 목록으로 변환합니다. NumPy 배열은 JSON 직렬화되지 않으므로 JSON 직렬화가 가능한 숫자 목록으로 변환해야 합니다. 그렇지 않은 경우 AI Platform Prediction은 예측 응답을 전송하지 못합니다.

예측자 및 종속 항목 패키징

예측자를 .tar.gz 소스 배포 패키지로 패키징해야 합니다. NumPy, TensorFlow, scikit-learn은 AI Platform Prediction 런타임 이미지에 포함되어 있으므로 tarball에 이러한 종속 항목을 포함할 필요가 없습니다. 그러나 AI Platform Prediction에 사전 설치되지 않은 예측자의 종속 항목은 포함해야 합니다.

위 예시의 경우 예측자가 명시적으로 가져오지 않더라도 소스 배포 패키지에 preprocess.py를 포함해야 합니다. 그렇지 않은 경우 Python이 피클 파일의 ZeroCenterer 인스턴스 클래스를 인식하지 못하므로 preprocessor = pickle.load(f)가 실패합니다.

다음 setup.py는 이러한 스크립트를 패키징하는 한 가지 방법을 보여줍니다.

from setuptools import setup

setup(name="my_custom_code", version="0.1", scripts=["predictor.py", "preprocess.py"])

이 페이지에 설명된 커스텀 코드 예시를 패키징해서 업로드하려면 다음 안내를 따르세요.

  1. 이전 섹션에서 설명한 preprocess.py, predictor.py, setup.py 파일을 모두 같은 디렉터리에 만듭니다. 셸에서 해당 디렉터리로 이동합니다.

  2. python setup.py sdist --formats=gztar을 실행하여 dist/my_custom_code-0.1.tar.gz를 만듭니다.

  3. 이 tarball을 Cloud Storage의 스테이징 위치로 업로드합니다.

    이 위치는 모델 디렉터리와 같을 필요는 없습니다. 커스텀 예측 루틴의 여러 버전을 반복 및 배포할 계획이라면 지정된 스테이징 디렉터리에 커스텀 코드 패키지를 업로드하는 것이 좋습니다. 코드를 업데이트할 때 setup.pyversion 인수를 증분해서 다양한 버전을 추적할 수 있습니다.

    다음 명령어는 소스 배포 패키지를 Cloud Storage에 업로드하는 한 가지 방법을 보여줍니다.

    gcloud storage cp dist/my_custom_code-0.1.tar.gz gs://YOUR_BUCKET/PATH_TO_STAGING_DIR/
    

하나 이상의 패키지에 커스텀 예측 루틴을 위한 코드를 제공할 수 있습니다.

커스텀 예측 루틴 배포

먼저 온라인 예측을 사용할 수 있는 리전을 선택하고 gcloud를 사용하여 모델 리소스를 만듭니다.

gcloud ai-platform models create MODEL_NAME{"</var>"}} \
  --regions CHOSEN_REGION

gcloud beta 구성요소가 업데이트되었는지 확인하고 다음 gcloud 플래그에 특히 주의를 기울여 버전 리소스를 만듭니다.

  • --origin: Cloud Storage에서 모델 디렉터리의 경로입니다.
  • --package-uris: Predictor 클래스가 들어 있는 tarball을 포함하여 Cloud Storage에 있는 사용자 코드 tarball의 쉼표로 구분된 목록입니다.
  • --prediction-class: Predictor 클래스의 정규화된 이름(MODULE_NAME.CLASS_NAME)입니다.
  • --framework: 커스텀 예측 루틴을 배포할 때는 프레임워크를 지정하지 않습니다.
  • --runtime-version: 커스텀 예측 루틴은 런타임 버전 1.4~2.11에서 사용할 수 있습니다.

다음 명령어는 이전 섹션에 설명된 예 파일을 기반으로 버전 리소스를 만드는 방법을 보여줍니다.

gcloud components install beta

gcloud beta ai-platform versions create VERSION_NAME \
  --model MODEL_NAME{"</var>"}} \
  --runtime-version 2.11 \
  --python-version 3.7 \
  --origin gs://YOUR_BUCKET/PATH_TO_MODEL_DIR \
  --package-uris gs://YOUR_BUCKET/PATH_TO_STAGING_DIR/my_custom_code-0.1.tar.gz \
  --prediction-class predictor.MyPredictor

모델 및 버전을 만드는 방법에 대해 더 자세히 알아보거나 gcloud CLI 대신 Google Cloud Console을 사용하여 만드는 방법을 알아보려면 모델 배포 가이드를 참조하세요.

서비스 계정 지정

버전 리소스를 만들 때 커스텀 예측 루틴에서 예측 중에 사용할 서비스 계정을 선택적으로 지정할 수 있습니다. 이렇게 하면 다른 Google Cloud 리소스에 액세스할 권한을 맞춤설정할 수 있습니다. 커스텀 예측 루틴을 위한 서비스 계정 지정에 대해 자세히 알아보세요.

다음 단계

  • Keras 또는 scikit-learn으로 커스텀 예측 루틴을 사용하는 방법에 대한 가이드에 따라 커스텀 예측 루틴을 사용하여 모델을 학습시키고 배포하는 방법에 대한 더 완전한 예시 살펴보기
  • 모델 내보내기 가이드를 참조하여 커스텀 예측 루틴을 사용하지 않고 예측용 아티팩트를 내보내는 방법에 대해 알아보기
  • 모델 배포 가이드에서 AI Platform Prediction에 modelversion 리소스를 배포하여 예측을 수행하는 방법에 대해 자세히 알아보기