Todos los productos
Search
Centro de documentos

Platform For AI:Construcción de una solicitud para un servicio de TensorFlow

Última actualización: Sep 11, 2026

Este tema describe cómo construir una solicitud para un servicio de TensorFlow que utiliza un procesador universal.

Datos de entrada

EAS proporciona un procesador de TensorFlow integrado que usa el formato protobuf para la entrada y la salida, con el fin de garantizar un alto rendimiento.

Ejemplos

EAS implementó un servicio de prueba público en un entorno VPC dentro de la región China (Shanghai). El nombre del servicio es mnist_saved_model_example y el token de acceso está vacío. Acceda al servicio mediante la siguiente dirección: http://pai-eas-vpc.cn-shanghai.aliyuncs.com/api/predict/mnist_saved_model_example. A continuación se describen los pasos para acceder a este servicio:

  1. Obtenga la información del modelo.

    Envíe una solicitud GET para obtener la información del modelo. Esta incluye signature_name, name, type y shape. En el siguiente código se muestra la respuesta.

    $curl http://pai-eas-vpc.cn-shanghai.aliyuncs.com/api/predict/mnist_saved_model_example | python -mjson.tool
    {
        "inputs": [
            {
                "name": "images",
                "shape": [
                    -1,
                    784
                ],
                "type": "DT_FLOAT"
            }
        ],
        "outputs": [
            {
                "name": "scores",
                "shape": [
                    -1,
                    10
                ],
                "type": "DT_FLOAT"
            }
        ],
        "signature_name": "predict_images"
    }

    Se trata de un modelo de clasificación que utiliza el conjunto de datos Mixed National Institute of Standards and Technology (MNIST) (Descargue el conjunto de datos MNIST). El tipo de datos de entrada es DT_FLOAT. Por ejemplo, el parámetro shape es [-1,784]. La primera dimensión representa el parámetro batch_size. Si una sola solicitud contiene únicamente una imagen, el valor de batch_size es 1. La segunda dimensión representa un vector de 784 dimensiones. Dado que la entrada de este modelo se aplanó en un vector unidimensional durante el entrenamiento, cada imagen de entrada también debe transformarse en un vector unidimensional de 28 × 28 = 784. Aplane la entrada cuando la construya, sin importar el valor de shape. En este ejemplo, si introduce una sola imagen, la entrada será un vector unidimensional de 1 × 784. Si el parámetro shape de entrada durante el entrenamiento del modelo era [-1, 28, 28], construya la entrada con una forma de 1 × 28 × 28. Si el parámetro shape especificado en la solicitud del servicio no coincide con el parámetro shape del modelo, la solicitud de predicción devuelve un error.

  2. Instale protobuf y llame al servicio. En el siguiente ejemplo se muestra cómo llamar a un servicio de TensorFlow con Python 2.

    EAS proporciona un paquete protobuf pregenerado para Python. Ejecute el siguiente comando para instalarlo.

    $ pip install http://eas-data.oss-cn-shanghai.aliyuncs.com/sdk/pai_tf_predict_proto-1.0-py2.py3-none-any.whl

    En el siguiente código de ejemplo se muestra cómo llamar al servicio para generar una predicción con Python 2.

    #!/usr/bin/env python
    # -*- coding: UTF-8 -*-
    import json
    from urlparse import urlparse
    from com.aliyun.api.gateway.sdk import client
    from com.aliyun.api.gateway.sdk.http import request
    from com.aliyun.api.gateway.sdk.common import constant
    from pai_tf_predict_proto import tf_predict_pb2
    import cv2
    import numpy as np
    with open('2.jpg', 'rb') as infile:
        buf = infile.read()
        # Use NumPy to convert the byte stream to an array.
        x = np.fromstring(buf, dtype='uint8')
        # Decode the read array to get a 28 × 28 matrix.
        img = cv2.imdecode(x, cv2.IMREAD_UNCHANGED)
        # The prediction service API requires a one-dimensional vector of length 784, so reshape the matrix to 784.
        img = np.reshape(img, 784)
    def predict(url, app_key, app_secret, request_data):
        cli = client.DefaultClient(app_key=app_key, app_secret=app_secret)
        body = request_data
        url_ele = urlparse(url)
        host = 'http://' + url_ele.hostname
        path = url_ele.path
        req_post = request.Request(host=host, protocol=constant.HTTP, url=path, method="POST", time_out=6000)
        req_post.set_body(body)
        req_post.set_content_type(constant.CONTENT_TYPE_STREAM)
        stat,header, content = cli.execute(req_post)
        return stat, dict(header) if header is not None else {}, content
    def demo():
        # Enter the model information. Click the model name to obtain it.
        app_key = 'YOUR_APP_KEY'
        app_secret = 'YOUR_APP_SECRET'
        url = 'YOUR_APP_URL'
        # Construct the service.
        request = tf_predict_pb2.PredictRequest()
        request.signature_name = 'predict_images'
        request.inputs['images'].dtype = tf_predict_pb2.DT_FLOAT  # The type of the images parameter.
        request.inputs['images'].array_shape.dim.extend([1, 784])  # The shape of the images parameter.
        request.inputs['images'].float_val.extend(img)  # Data.
        request.inputs['keep_prob'].dtype = tf_predict_pb2.DT_FLOAT  # The type of the keep_prob parameter.
        request.inputs['keep_prob'].float_val.extend([0.75])  # Enter a default value.
        # Serialize the protobuf to a string for transmission.
        request_data = request.SerializeToString()
        stat, header, content = predict(url, app_key, app_secret, request_data)
        if stat != 200:
            print 'Http status code: ', stat
            print 'Error msg in header: ', header['x-ca-error-message'] if 'x-ca-error-message' in header else ''
            print 'Error msg in body: ', content
        else:
            response = tf_predict_pb2.PredictResponse()
            response.ParseFromString(content)
            print(response)
    if __name__ == '__main__':
        demo()

    Se devuelve el siguiente resultado.

    outputs {
      key: "scores"
      value {
        dtype: DT_FLOAT
        array_shape {
          dim: 1
          dim: 10
        }
        float_val: 0.0
        float_val: 0.0
        float_val: 1.0
        float_val: 0.0
        float_val: 0.0
        float_val: 0.0
        float_val: 0.0
        float_val: 0.0
        float_val: 0.0
        float_val: 0.0
      }
    }

    El campo outputs contiene las puntuaciones de las 10 categorías. Cuando la imagen de entrada es 2.jpg, todos los valores son 0 excepto value[2]. Por lo tanto, el resultado final de la predicción es 2, lo cual es correcto.

Llamada al servicio desde otros lenguajes

Para llamar al servicio desde clientes en lenguajes distintos de Python, genere el código de la solicitud a partir del archivo .proto. A continuación se describen los pasos correspondientes:

  1. Cree un archivo .proto. Por ejemplo, cree un archivo llamado tf.proto con el siguiente contenido.

    syntax = "proto3";
    option cc_enable_arenas = true;
    option java_package = "com.aliyun.openservices.eas.predict.proto";
    option java_outer_classname = "PredictProtos";
    enum ArrayDataType {
      // Not a legal value for DataType. Used to indicate a DataType field
      // has not been set.
      DT_INVALID = 0;
      // Data types that all computation devices are expected to be
      // capable to support.
      DT_FLOAT = 1;
      DT_DOUBLE = 2;
      DT_INT32 = 3;
      DT_UINT8 = 4;
      DT_INT16 = 5;
      DT_INT8 = 6;
      DT_STRING = 7;
      DT_COMPLEX64 = 8;  // Single-precision complex.
      DT_INT64 = 9;
      DT_BOOL = 10;
      DT_QINT8 = 11;     // Quantized int8.
      DT_QUINT8 = 12;    // Quantized uint8.
      DT_QINT32 = 13;    // Quantized int32.
      DT_BFLOAT16 = 14;  // Float32 truncated to 16 bits.  Only for cast ops.
      DT_QINT16 = 15;    // Quantized int16.
      DT_QUINT16 = 16;   // Quantized uint16.
      DT_UINT16 = 17;
      DT_COMPLEX128 = 18;  // Double-precision complex.
      DT_HALF = 19;
      DT_RESOURCE = 20;
      DT_VARIANT = 21;  // Arbitrary C++ data types.
    }
    // Dimensions of an array.
    message ArrayShape {
      repeated int64 dim = 1 [packed = true];
    }
    // Protocol buffer representing an array.
    message ArrayProto {
      // Data Type.
      ArrayDataType dtype = 1;
      // Shape of the array.
      ArrayShape array_shape = 2;
      // DT_FLOAT.
      repeated float float_val = 3 [packed = true];
      // DT_DOUBLE.
      repeated double double_val = 4 [packed = true];
      // DT_INT32, DT_INT16, DT_INT8, DT_UINT8.
      repeated int32 int_val = 5 [packed = true];
      // DT_STRING.
      repeated bytes string_val = 6;
      // DT_INT64.
      repeated int64 int64_val = 7 [packed = true];
      // DT_BOOL.
      repeated bool bool_val = 8 [packed = true];
    }
    // PredictRequest specifies which TensorFlow model to run, along with
    // how inputs are mapped to tensors and how outputs are filtered before
    // returning to user.
    message PredictRequest {
      // A named signature to evaluate. If unspecified, the default signature
      // will be used.
      string signature_name = 1;
      // Input tensors.
      // Names of input tensor are alias names. The mapping from aliases to real
      // input tensor names is expected to be stored as named generic signature
      // under the key "inputs" in the model export.
      // Each alias listed in a generic signature named "inputs" should be provided
      // exactly once to run the prediction.
      map<string, ArrayProto> inputs = 2;
      // Output filter.
      // Names specified are alias names. The mapping from aliases to real output
      // tensor names is expected to be stored as named generic signature under
      // the key "outputs" in the model export.
      // Only tensors specified here will be run/fetched and returned, with the
      // exception that when none is specified, all tensors specified in the
      // named signature will be run/fetched and returned.
      repeated string output_filter = 3;
    }
    // Response for PredictRequest on successful run.
    message PredictResponse {
      // Output tensors.
      map<string, ArrayProto> outputs = 1;
    }

    En el archivo, PredictRequest define el formato de entrada del servicio de TensorFlow, mientras que PredictResponse define el formato de salida del servicio. Para obtener más información, consulte la documentación de protobuf.

  2. Instale protoc.

    #/bin/bash
    PROTOC_ZIP=protoc-3.3.0-linux-x86_64.zip
    curl -OL https://github.com/google/protobuf/releases/download/v3.3.0/$PROTOC_ZIP
    unzip -o $PROTOC_ZIP -d ./ bin/protoc
    rm -f $PROTOC_ZIP
  3. Genere el archivo de código de la solicitud.

    • Java

      $ bin/protoc --java_out=./ tf.proto

      Después de ejecutar el comando, se genera el archivo com/aliyun/openservices/eas/predict/proto/PredictProtos.java en el directorio actual. Luego importe este archivo a su proyecto.

    • Python

      $ bin/protoc --python_out=./ tf.proto

      Tras ejecutar el comando, se genera el archivo tf_pb2.py en el directorio actual. Utilice el comando import para importar el archivo.

    • C++

      $ bin/protoc --cpp_out=./ tf.proto

      Una vez ejecutado el comando, se generan los archivos tf.pb.cc y tf.pb.h en el directorio actual. En su código, incluya tf.pb.h y agregue tf.pb.cc a su lista de compile.