github.com/alwaysproblem/mlserving-tutorial@v0.0.0-20221124033215-121cfddbfbf4/TFserving/ClientAPI/go/README.md (about)

     1  # GO API
     2  
     3  ## Build your own go TFclient (optional) (old version)
     4  
     5  - Thanks to [Maxim Khitrov](https://gist.github.com/mxk) and [datainq](https://github.com/datainq/go-mnist-client). Here is [reference](https://gist.github.com/mxk/b86769306037c9dc49b44d52764cbbdc)
     6  
     7  - requirement
     8    - [go installation](https://golang.org/doc/install)
     9    ```text
    10    go >= 1.11
    11    protoc == 3.6.1
    12    ```
    13  
    14  - setup a new directory and the structure is like this:
    15  
    16    ```text
    17    ---client (your new directory name)
    18        |
    19        ---pkg (for go modules)
    20        |
    21        ---src (for customed modules and source files)
    22        |
    23        ---bin (fo go binary files)
    24    ```
    25  
    26  - copy `dockerfile` to your own directory and build docker image through dockerfile
    27  
    28    ```bash
    29    # assume that you are under go directory.
    30    cp dockerfile <your>
    31    # docker build -t <tag>:<label> path -f <dockerfile>
    32    docker build -t alwaysproblem/tfclient-go:build path -f dockerfile
    33    ```
    34  
    35  - build inside docker
    36  
    37    ```bash
    38    $ docker run --rm -ti --name goenv -v `pwd`:/work alwaysproblem/tfclient-go:build /bin/bash
    39    ```
    40  
    41    <!-- TODO: simplify these with bash run in docker -->
    42  
    43    ```bash
    44    root@8c768509e690:/work# cd src
    45    root@8c768509e690:/work/src# git clone -b r1.15 https://github.com/tensorflow/tensorflow.git
    46    root@8c768509e690:/work/src# git clone -b r1.14 https://github.com/tensorflow/serving.git
    47    root@8c768509e690:/work/src# go run protoc.go # ignore the warning but this procedure only works under specific protoc version
    48    root@8c768509e690:/work/src# go mod init client
    49    root@8c768509e690:/work/src# go mod edit -replace=github.com/tensorflow/tensorflow/tensorflow/go/core=./proto/tensorflow/core
    50    root@8c768509e690:/work/src# go mod edit -replace=github.com/alwaysproblem/tensorflow_serving=./proto/tensorflow/serving
    51    root@8c768509e690:/work/src# cd proto/tensorflow/core && go mod init github.com/tensorflow/tensorflow/tensorflow/go/core && cd -
    52    root@8c768509e690:/work/src# cd proto/tensorflow/serving && go mod init github.com/alwaysproblem/tensorflow_serving && cd -
    53    root@8c768509e690:/work/src# rm -rf tensorflow/ serving/
    54    root@8c768509e690:/work/src# exit
    55    ```
    56  
    57  ## Build your own go TFclient (optional) (new version)
    58  
    59  - [TFServing 2.3](https://github.com/Alwaysproblem/TFServing-setup-tutorial/tree/tfclient-golang-r2.3/go)
    60  
    61  - run server
    62    *if you forget to run in the first place.*
    63    ```bash
    64    $ ROOT=/Users/yongxiyang/Desktop/TFServing-setup-tutorial/
    65    $ docker run --rm -p 8500:8500 -p 8501:8501 --mount type=bind,source=$ROOT,target=/models --mount type=bind,source=$ROOT/config/versionlabels.config,target=/models/versionctrl.config -it tensorflow/serving --model_config_file=/models/versionctrl.config --model_config_file_poll_wait_seconds=60 --allow_version_labels_for_unavailable_models
    66    ```
    67  
    68  - run the test on the client
    69    - install dependency
    70  
    71      ```bash
    72      # assume you are in go directory
    73      $ cd src
    74      $ source env.sh
    75      $ bash basic-run-env.sh
    76      ```
    77  
    78    - run go client for a simple example
    79      **don't forget source env.sh**
    80      - request data from server
    81  
    82        ```bash
    83        # run under src directory
    84        $ bash run.sh main/predict-service.go # test on local host
    85        # model_spec:{name:"Toy"  version:{value:1}  signature_name:"serving_default"}  outputs:{key:"output_1"  value:{dtype:DT_FLOAT  tensor_shape:{dim:{size:3}  dim:{size:1}}  float_val:10.805429  float_val:14.010123  float_val:17.214817}}
    86        ```
    87  
    88      - request different model name
    89  
    90        ```bash
    91        $ go run main/predict-service.go --model_name Toy
    92        # model_spec:{name:"Toy"  version:{value:2}  signature_name:"serving_default"}  outputs:{key:"output_1"  value:{dtype:DT_FLOAT  tensor_shape:{dim:{size:3}  dim:{size:1}}  float_val:0.999035  float_val:0.99973494  float_val:0.9999273}}
    93        $ go run main/predict-service.go --model_name Toy_double
    94        # model_spec:{name:"Toy_double"  version:{value:1}  signature_name:"serving_default"}  outputs:{key:"output_1"  value:{dtype:DT_FLOAT  tensor_shape:{dim:{size:3}  dim:{size:1}}  float_val:6.8030167  float_val:8.262094  float_val:9.72117}}
    95        ```
    96  
    97      - request different version through the version number
    98  
    99        ```bash
   100        $ go run main/predict-service.go --model_name Toy --model_version 1
   101        # model_spec:{name:"Toy"  version:{value:1}  signature_name:"serving_default"}  outputs:{key:"output_1"  value:{dtype:DT_FLOAT  tensor_shape:{dim:{size:3}  dim:{size:1}}  float_val:10.805429  float_val:14.010123  float_val:17.214817}}
   102        $ go run main/predict-service.go --model_name Toy --model_version 2
   103        # model_spec:{name:"Toy"  version:{value:2}  signature_name:"serving_default"}  outputs:{key:"output_1"  value:{dtype:DT_FLOAT  tensor_shape:{dim:{size:3}  dim:{size:1}}  float_val:0.999035  float_val:0.99973494  float_val:0.9999273}}
   104        ```
   105  
   106      - request different version through the version annotation
   107  
   108        ```bash
   109        $ go run main/predict-service.go --model_name Toy --model_version_label stable
   110        # model_spec:{name:"Toy"  version:{value:1}  signature_name:"serving_default"}  outputs:{key:"output_1"  value:{dtype:DT_FLOAT  tensor_shape:{dim:{size:3}  dim:{size:1}}  float_val:10.805429  float_val:14.010123  float_val:17.214817}}
   111        ```
   112  
   113      - request multiple task model <!--  TODO: -->
   114  
   115        ```bash
   116        ```
   117  
   118      - request model status
   119  
   120        ```bash
   121        $ go run main/model-status.go --model_name Toy
   122        # model_version_status:{version:2 state:AVAILABLE status:{}} model_version_status:{version:1 state:AVAILABLE status:{}}
   123        ```
   124  
   125      - request model metadata
   126  
   127        ```bash
   128        $ go run main/predict-model-metadata.go --model_name Toy
   129        # model_spec:{name:"Toy"  version:{value:2}}  metadata:{key:"signature_def"  value:{[type.googleapis.com/tensorflow.serving.SignatureDefMap]:{signature_def:{key:"__saved_model_init_op"  value:{outputs:{key:"__saved_model_init_op"  value:{name:"NoOp"  tensor_shape:{unknown_rank:true}}}}}  signature_def:{key:"serving_default"  value:{inputs:{key:"input_1"  value:{name:"serving_default_input_1:0"  dtype:DT_FLOAT  tensor_shape:{dim:{size:-1}  dim:{size:2}}}}  outputs:{key:"output_1"  value:{name:"StatefulPartitionedCall:0"  dtype:DT_FLOAT  tensor_shape:{dim:{size:-1}  dim:{size:1}}}}  method_name:"tensorflow/serving/predict"}}}}}
   130        ```
   131  
   132      - reload model through gRPC API
   133  
   134        ```bash
   135        $ go run main/model-reload.go --model_name Toy
   136        # model Toy reloaded sucessfully
   137        ```
   138  
   139      - request model log
   140  
   141        ```bash
   142        $ go run main/predict-log.go --model_name Toy # --model_version 1 --model_version_label stable
   143        # model_spec:{name:"Toy"  version:{value:2}  signature_name:"serving_default"}  outputs:{key:"output_1"  value:{dtype:DT_FLOAT  tensor_shape:{dim:{size:3}  dim:{size:1}}  float_val:0.999035  float_val:0.99973494  float_val:0.9999273}}
   144        # log_metadata:{model_spec:{name:"Toy"  signature_name:"serving_default"}}  predict_log:{request:{model_spec:{name:"Toy"  signature_name:"serving_default"}  inputs:{key:"input_1"  value:{dtype:DT_FLOAT  tensor_shape:{dim:{size:3}  dim:{size:2}}  float_val:1  float_val:2  float_val:1  float_val:3  float_val:1  float_val:4}}}  response:{model_spec:{name:"Toy"  version:{value:2}  signature_name:"serving_default"}  outputs:{key:"output_1"  value:{dtype:DT_FLOAT  tensor_shape:{dim:{size:3}  dim:{size:1}}  float_val:0.999035  float_val:0.99973494  float_val:0.9999273}}}}
   145        ```
   146  
   147  - GO gRPC api
   148    1. framework TensorProto
   149  
   150      ```go
   151      type TensorProto struct {
   152        state         protoimpl.MessageState
   153        sizeCache     protoimpl.SizeCache
   154        unknownFields protoimpl.UnknownFields
   155  
   156        Dtype DataType `protobuf:"varint,1,opt,name=dtype,proto3,enum=tensorflow.DataType" json:"dtype,omitempty"`
   157        // Shape of the tensor.  TODO(touts): sort out the 0-rank issues.
   158        TensorShape *TensorShapeProto `protobuf:"bytes,2,opt,name=tensor_shape,json=tensorShape,proto3" json:"tensor_shape,omitempty"`
   159        // Version number.
   160        //
   161        // In version 0, if the "repeated xxx" representations contain only one
   162        // element, that element is repeated to fill the shape.  This makes it easy
   163        // to represent a constant Tensor with a single value.
   164        VersionNumber int32 `protobuf:"varint,3,opt,name=version_number,json=versionNumber,proto3" json:"version_number,omitempty"`
   165        // Serialized raw tensor content from either Tensor::AsProtoTensorContent or
   166        // memcpy in tensorflow::grpc::EncodeTensorToByteBuffer. This representation
   167        // can be used for all tensor types. The purpose of this representation is to
   168        // reduce serialization overhead during RPC call by avoiding serialization of
   169        // many repeated small items.
   170        TensorContent []byte `protobuf:"bytes,4,opt,name=tensor_content,json=tensorContent,proto3" json:"tensor_content,omitempty"`
   171        // DT_HALF, DT_BFLOAT16. Note that since protobuf has no int16 type, we'll
   172        // have some pointless zero padding for each value here.
   173        HalfVal []int32 `protobuf:"varint,13,rep,packed,name=half_val,json=halfVal,proto3" json:"half_val,omitempty"`
   174        // DT_FLOAT.
   175        FloatVal []float32 `protobuf:"fixed32,5,rep,packed,name=float_val,json=floatVal,proto3" json:"float_val,omitempty"`
   176        // DT_DOUBLE.
   177        DoubleVal []float64 `protobuf:"fixed64,6,rep,packed,name=double_val,json=doubleVal,proto3" json:"double_val,omitempty"`
   178        // DT_INT32, DT_INT16, DT_INT8, DT_UINT8.
   179        IntVal []int32 `protobuf:"varint,7,rep,packed,name=int_val,json=intVal,proto3" json:"int_val,omitempty"`
   180        // DT_STRING
   181        StringVal [][]byte `protobuf:"bytes,8,rep,name=string_val,json=stringVal,proto3" json:"string_val,omitempty"`
   182        // DT_COMPLEX64. scomplex_val(2*i) and scomplex_val(2*i+1) are real
   183        // and imaginary parts of i-th single precision complex.
   184        ScomplexVal []float32 `protobuf:"fixed32,9,rep,packed,name=scomplex_val,json=scomplexVal,proto3" json:"scomplex_val,omitempty"`
   185        // DT_INT64
   186        Int64Val []int64 `protobuf:"varint,10,rep,packed,name=int64_val,json=int64Val,proto3" json:"int64_val,omitempty"`
   187        // DT_BOOL
   188        BoolVal []bool `protobuf:"varint,11,rep,packed,name=bool_val,json=boolVal,proto3" json:"bool_val,omitempty"`
   189        // DT_COMPLEX128. dcomplex_val(2*i) and dcomplex_val(2*i+1) are real
   190        // and imaginary parts of i-th double precision complex.
   191        DcomplexVal []float64 `protobuf:"fixed64,12,rep,packed,name=dcomplex_val,json=dcomplexVal,proto3" json:"dcomplex_val,omitempty"`
   192        // DT_RESOURCE
   193        ResourceHandleVal []*ResourceHandleProto `protobuf:"bytes,14,rep,name=resource_handle_val,json=resourceHandleVal,proto3" json:"resource_handle_val,omitempty"`
   194        // DT_VARIANT
   195        VariantVal []*VariantTensorDataProto `protobuf:"bytes,15,rep,name=variant_val,json=variantVal,proto3" json:"variant_val,omitempty"`
   196        // DT_UINT32
   197        Uint32Val []uint32 `protobuf:"varint,16,rep,packed,name=uint32_val,json=uint32Val,proto3" json:"uint32_val,omitempty"`
   198        // DT_UINT64
   199        Uint64Val []uint64 `protobuf:"varint,17,rep,packed,name=uint64_val,json=uint64Val,proto3" json:"uint64_val,omitempty"`
   200      }
   201      ```
   202  
   203    2. PredictRequest proto
   204  
   205      ```go
   206      type PredictRequest struct {
   207        state         protoimpl.MessageState
   208        sizeCache     protoimpl.SizeCache
   209        unknownFields protoimpl.UnknownFields
   210  
   211        // Model Specification. If version is not specified, will use the latest
   212        // (numerical) version.
   213        ModelSpec *ModelSpec `protobuf:"bytes,1,opt,name=model_spec,json=modelSpec,proto3" json:"model_spec,omitempty"`
   214        // Input tensors.
   215        // Names of input tensor are alias names. The mapping from aliases to real
   216        // input tensor names is stored in the SavedModel export as a prediction
   217        // SignatureDef under the 'inputs' field.
   218        Inputs map[string]*framework.TensorProto `protobuf:"bytes,2,rep,name=inputs,proto3" json:"inputs,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
   219        // Output filter.
   220        // Names specified are alias names. The mapping from aliases to real output
   221        // tensor names is stored in the SavedModel export as a prediction
   222        // SignatureDef under the 'outputs' field.
   223        // Only tensors specified here will be run/fetched and returned, with the
   224        // exception that when none is specified, all tensors specified in the
   225        // named signature will be run/fetched and returned.
   226        OutputFilter []string `protobuf:"bytes,3,rep,name=output_filter,json=outputFilter,proto3" json:"output_filter,omitempty"`
   227      }
   228      ```
   229  
   230    3. PredictResponse proto
   231  
   232      ```go
   233      // Response for PredictRequest on successful run.
   234      type PredictResponse struct {
   235        state         protoimpl.MessageState
   236        sizeCache     protoimpl.SizeCache
   237        unknownFields protoimpl.UnknownFields
   238  
   239        // Effective Model Specification used to process PredictRequest.
   240        ModelSpec *ModelSpec `protobuf:"bytes,2,opt,name=model_spec,json=modelSpec,proto3" json:"model_spec,omitempty"`
   241        // Output tensors.
   242        Outputs map[string]*framework.TensorProto `protobuf:"bytes,1,rep,name=outputs,proto3" json:"outputs,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
   243      }
   244      ```
   245  
   246    4. ModelSpec proto
   247  
   248      ```go
   249      // Metadata for an inference request such as the model name and version.
   250      type ModelSpec struct {
   251        state         protoimpl.MessageState
   252        sizeCache     protoimpl.SizeCache
   253        unknownFields protoimpl.UnknownFields
   254  
   255        // Required servable name.
   256        Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
   257        // Optional choice of which version of the model to use.
   258        //
   259        // Recommended to be left unset in the common case. Should be specified only
   260        // when there is a strong version consistency requirement.
   261        //
   262        // When left unspecified, the system will serve the best available version.
   263        // This is typically the latest version, though during version transitions,
   264        // notably when serving on a fleet of instances, may be either the previous or
   265        // new version.
   266        //
   267        // Types that are assignable to VersionChoice:
   268        //	*ModelSpec_Version
   269        //	*ModelSpec_VersionLabel
   270        VersionChoice isModelSpec_VersionChoice `protobuf_oneof:"version_choice"`
   271        // A named signature to evaluate. If unspecified, the default signature will
   272        // be used.
   273        SignatureName string `protobuf:"bytes,3,opt,name=signature_name,json=signatureName,proto3" json:"signature_name,omitempty"`
   274      }
   275      // for VersionChoice
   276      type ModelSpec_Version struct {
   277        // Use this specific version number.
   278        Version *wrappers.Int64Value `protobuf:"bytes,2,opt,name=version,proto3,oneof"`
   279      }
   280  
   281      type ModelSpec_VersionLabel struct {
   282        // Use the version associated with the given label.
   283        VersionLabel string `protobuf:"bytes,4,opt,name=version_label,json=versionLabel,proto3,oneof"`
   284      }
   285      ```
   286  
   287    5. Prediction Log Proto
   288  
   289      ```go
   290      type PredictLog struct {
   291        state         protoimpl.MessageState
   292        sizeCache     protoimpl.SizeCache
   293        unknownFields protoimpl.UnknownFields
   294  
   295        Request  *PredictRequest  `protobuf:"bytes,1,opt,name=request,proto3" json:"request,omitempty"`
   296        Response *PredictResponse `protobuf:"bytes,2,opt,name=response,proto3" json:"response,omitempty"`
   297      }
   298      ```
   299  
   300    6. MutilInferenceLog
   301  
   302      ```go
   303      type MultiInferenceLog struct {
   304        state         protoimpl.MessageState
   305        sizeCache     protoimpl.SizeCache
   306        unknownFields protoimpl.UnknownFields
   307  
   308        Request  *MultiInferenceRequest  `protobuf:"bytes,1,opt,name=request,proto3" json:"request,omitempty"`
   309        Response *MultiInferenceResponse `protobuf:"bytes,2,opt,name=response,proto3" json:"response,omitempty"`
   310      }
   311      ```
   312  
   313    7. PredictionLog
   314  
   315      ```go
   316      // Logged model inference request.
   317      type PredictionLog struct {
   318        state         protoimpl.MessageState
   319        sizeCache     protoimpl.SizeCache
   320        unknownFields protoimpl.UnknownFields
   321  
   322        LogMetadata *LogMetadata `protobuf:"bytes,1,opt,name=log_metadata,json=logMetadata,proto3" json:"log_metadata,omitempty"`
   323        // Types that are assignable to LogType:
   324        //	*PredictionLog_ClassifyLog
   325        //	*PredictionLog_RegressLog
   326        //	*PredictionLog_PredictLog
   327        //	*PredictionLog_MultiInferenceLog
   328        //	*PredictionLog_SessionRunLog
   329        LogType isPredictionLog_LogType `protobuf_oneof:"log_type"`
   330      }
   331      ```
   332    8. model_server api
   333  
   334  <!-- TODO: finish the handbook ,  get rid of todo and comment-->