Как получить метаданные из обслуживаемой модели TensorFlow? - PullRequest
0 голосов
/ 18 октября 2019

У меня есть несколько моделей, работающих с обслуживанием TensorFlow, и я хотел бы, чтобы модели были самоописуемыми, чтобы наши сервисы, которые их вызывают, не нуждались в непосредственном внедрении таких вещей, как размер ввода. (Например, мы хотим иметь возможность менять модели без обновления нисходящих систем.)

Когда я использую API метаданных, я получаю ответ, который имеет определение сигнатуры, но это явно не то, что можно интерпретировать. Модель работает, поэтому я уверен, что проблема не в самой модели. Я также попробовал инструмент saved_model_cli в модели TensorFlow, и он возвращает правильное определение подписи.

Редактировать: API метаданных также отлично работает, если я вызываю REST API. Но я действительно предпочел бы выяснить, как заставить это работать с gRPC.

Редактировать, 21 октября 2019 года: я понял, что данные в ответе - это сообщение, закодированное с использованием буфера протокола. Если я все правильно понимаю, это значит, что мне нужно проанализировать данные буфера протокола. Я пытался

from google.protobuf import text_format
text_format.Parse(result.metadata['signature_def'].value,
                  get_model_metadata_pb2.SignatureDefMap) 

Это, однако, теперь возвращает ошибку:

ParseError: 2:1 : '>': Expected identifier or number, got >.

Старый код:

$ saved_model_cli show --dir mymodel.pb/ --all
MetaGraphDef with tag-set: 'serve' contains the following SignatureDefs:

signature_def['serving_default']:
  The given SavedModel SignatureDef contains the following input(s):
    inputs['input_data'] tensor_info:
        dtype: DT_FLOAT
        shape: (-1, -1, 286339)
        name: input:0
  The given SavedModel SignatureDef contains the following output(s):
    outputs['output/Softmax:0'] tensor_info:
        dtype: DT_FLOAT
        shape: (-1, 286338)
        name: output/Softmax:0
  Method name is: tensorflow/serving/predict

И:

from tensorflow_serving.apis import get_model_metadata_pb2
import grpc
import tensorflow as tf
from tensorflow_serving.apis import predict_pb2
from tensorflow_serving.apis import prediction_service_pb2_grpc
from tensorflow.contrib import util

MODEL_URI = '10.100.55.9:8500'
channel = grpc.insecure_channel(MODEL_URI)
stub = prediction_service_pb2_grpc.PredictionServiceStub(channel)

request = get_model_metadata_pb2.GetModelMetadataRequest()
request.model_spec.name = 'themodel'
request.model_spec.signature_name = 'serving_default'
request.metadata_field.append('signature_def')
result = stub.GetModelMetadata(request, 1.0)

, который возвращает

In [5]: result.metadata['signature_def']                                                                                                                                             
Out[5]: 
type_url: "type.googleapis.com/tensorflow.serving.SignatureDefMap"
value: "\n>\n\025__saved_model_init_op\022%\022#\n\025__saved_model_init_op\022\n\n\004NoOp\032\002\030\001\n\271\001\n\017serving_default\022\245\001\nJ\n\007input_1\022?\n\031serving_default_input_1:0\020\001\032 \022\013\010\377\377\377\377\377\377\377\377\377\001\022\013\010\377\377\377\377\377\377\377\377\377\001\022\004\010\224\261\021\022;\n\005dense\0222\n\031StatefulPartitionedCall:0\020\001\032\023\022\013\010\377\377\377\377\377\377\377\377\377\001\022\004\010\223\261\021\032\032tensorflow/serving/predict"

1 Ответ

1 голос
/ 21 октября 2019

Я в конце концов понял это сам. Вероятно, есть более элегантный способ сделать это, который требует только парсинга нужного мне отклика и не требует преобразования в JSON, а затем в объект Python, чтобы получить ту часть, которую я хочу. Но это сработало, поэтому я собираюсь опубликовать его.

Путем обратного проектирования кода REST API я обнаружил, что в библиотеке Protocol Buffer есть хорошая служебная функция, которая конвертирует из формата Protocol Buffer в JSON, который затем может быть проанализирован анализатором Python JSON по вашему выбору.

from google.protobuf.json_format import MessageToJson
import simplejson as json

parsed = json.loads(MessageToJson(result))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...