如何从自定义 AI 平台模型登录

How to log from a custom ai platform model

我最近将一个自定义模型部署到 google 云的 ai 平台,我正在尝试调试我的预处理逻辑的某些部分。但是,我的打印语句没有记录到 stackdriver 输出中。我也尝试过使用从 google.cloud 导入的日志记录客户端,但无济于事。这是我的自定义预测文件:

import os
import pickle

import numpy as np
from sklearn.datasets import load_iris
import tensorflow as tf

from google.cloud import logging

class MyPredictor(object):
  def __init__(self, model, preprocessor):
    self.logging_client = logging.Client()
    self._model = model
    self._preprocessor = preprocessor
    self._class_names = ["Snare", "Kicks", "ClosedHH", "ClosedHH",  "Clap", "Crash", "Perc"]

  def predict(self, instances, **kwargs):
    log_name = "Here I am"
    logger = self.logging_client.logger(log_name)
    text = 'Hello, world!'
    logger.log_text(text)
    print('Logged: {}'.format(text), kwargs.get("sr"))

    inputs = np.asarray(instances)

    outputs = self._model.predict(inputs)

    if kwargs.get('probabilities'):
      return outputs.tolist()
      #return "[]"
    else:
      return [self._class_names[index] for index in np.argmax(outputs.tolist(), axis=1)]

  @classmethod
  def from_path(cls, model_dir):
    model_path = os.path.join(model_dir, 'model.h5')
    model = tf.keras.models.load_model(model_path, custom_objects={"adam": tf.keras.optimizers.Adam, 
 "categorical_crossentropy":tf.keras.losses.categorical_crossentropy, "lr":0.01, "name": "Adam"})

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

    return cls(model, preprocessor)

我在网上找不到任何关于为什么我的日志没有显示在 stackdriver 中的信息(打印语句和日志库调用都没有)。有人遇到过这个问题吗?

谢谢, 尼基塔

注意:如果您有足够的代表来创建标签,请将 google-ai-platform 标签添加到此 post。我认为这真的可以帮助处于我位置的人。谢谢!

来自 Documentation:

If you want to enable online prediction logging, you must configure it when you create a model resource or when you create a model version resource, depending on which type of logging you want to enable. There are three types of logging, which you can enable independently:

Access logging, which logs information like timestamp and latency for each request to Stackdriver Logging.

You can enable access logging when you create a model resource.

Stream logging, which logs the stderr and stdout streams from your prediction nodes to Stackdriver Logging, and can be useful for debugging. This type of logging is in beta, and it is not supported by Compute Engine (N1) machine types.

You can enable stream logging when you create a model resource.

Request-response logging, which logs a sample of online prediction requests and responses to a BigQuery table. This type of logging is in beta.

You can enable request-response logging by creating a model version resource, then updating that version.

对于您的用例,请使用以下模板将自定义信息记录到 StackDriver:

型号

gcloud beta ai-platform models create {MODEL_NAME} \
 --regions {REGION} \
 --enable-logging \
 --enable-console-logging

车型版本

gcloud beta ai-platform versions create {VERSION_NAME} \
    --model {MODEL_NAME} \
    --origin gs://{BUCKET}/{MODEL_DIR} \
    --python-version 3.7 \
    --runtime-version 1.15 \
    --package-uris gs://{BUCKET}/{PACKAGES_DIR}/custom-model-0.1.tar.gz \
    --prediction-class=custom_prediction.CustomModelPrediction \
    --service-account custom@project_id.iam.gserviceaccount.com

我试过了,效果很好:

  • 由于@classmethod 装饰器,我对构造函数做了一些修改。
  • 创建一个服务帐户并授予它"Stackdriver Debugger User"角色,在模型版本创建期间使用它
  • google-cloud-logging 图书馆添加到您的 setup.py
  • 考虑启用 StackDriver 日志记录的额外费用
  • 使用 log_struct 检查是否传递了正确的类型。 (如果使用 str,请确保在 Python 3 中使用 .decode('utf-8')bytes 转换为 str
  • 在 Stackdriver 客户端创建期间定义 project_id 参数 logging.Client(),否则你会得到:
ERROR:root:Prediction failed: 400 Name "projects//logs/my-custom-prediction-log" is missing the parent component. Expected the form projects/[PROJECT_ID]/logs/[ID]" 

代码如下:

%%writefile cloud_logging.py

import os
import pickle
import numpy as np

from datetime import date
from google.cloud import logging

import tensorflow.keras as keras
LOG_NAME = 'my-custom-prediction-log'

class CustomModelPrediction(object):
    def __init__(self, model, processor, client):    
        self._model = model
        self._processor = processor
        self._client = client

    def _postprocess(self, predictions):
        labels = ['negative', 'positive']
        return [
            {
                "label":labels[int(np.round(prediction))],
                "score":float(np.round(prediction, 4))
            } for prediction in predictions]

    def predict(self, instances, **kwargs):
        logger = self._client.logger(LOG_NAME)
        logger.log_struct({'instances':instances})
        preprocessed_data = self._processor.transform(instances)
        predictions =  self._model.predict(preprocessed_data)
        labels = self._postprocess(predictions)
        return labels

    @classmethod
    def from_path(cls, model_dir):        
        client = logging.Client(project='project_id') # Change to your project
        model = keras.models.load_model(
          os.path.join(model_dir,'keras_saved_model.h5'))
        with open(os.path.join(model_dir, 'processor_state.pkl'), 'rb') as f:
            processor = pickle.load(f)    
        return cls(model, processor, client)

# Verify model locally

from cloud_logging import CustomModelPrediction
classifier = CustomModelPrediction.from_path('.')

requests = ["God I hate the north", "god I love this"]
response = classifier.predict(requests)
response

然后我检查 sample library:

python snippets.py my-custom-prediction-log list
Listing entries for logger my-custom-prediction-log:
* 2020-02-19T19:51:45.809767+00:00: {u'instances': [u'God I hate the north', u'god I love this']}
* 2020-02-19T19:57:18.615159+00:00: {u'instances': [u'God I hate the north', u'god I love this']}

要可视化日志,在 StackDriver > Logging > Select Global 和您的日志名称中,如果您想查看模型日志,您应该能够 select Cloud ML 模型版本。

你可以在这里使用我的文件:model and pre-processor

如果你只是想让你的打印工作而不使用我上面的日志记录方法,你可以在你的打印中添加刷新标志,

print(“logged”,flush=True)