Skip to content

Instantly share code, notes, and snippets.

@PrithivirajDamodaran
Last active July 19, 2019 01:41
Show Gist options
  • Save PrithivirajDamodaran/96433d2f2cb50ae3c3147cb837d3d0fe to your computer and use it in GitHub Desktop.
Save PrithivirajDamodaran/96433d2f2cb50ae3c3147cb837d3d0fe to your computer and use it in GitHub Desktop.

Serving Encoder-Decoder Models using TF Serving

Prithiviraj Damodaran

Step1 : Save Models/Weights

import tensorflow as tf
from tensorflow.keras.models import model_from_json
from tensorflow.keras.models import load_model

'''
Initialize model from JSON and reload weights
1. load json and create model
'''
with open("dec_model_num.json", "rb") as dec_json_file:
    loaded_dec_model_json = dec_json_file.read()
    loaded_dec_model = model_from_json(loaded_dec_model_json)

with open("enc_model_num.json", "rb") as enc_json_file:
    loaded_enc_model_json = enc_json_file.read()
    loaded_enc_model = model_from_json(loaded_enc_model_json)

enc_json_file.close()
dec_json_file.close()

### 2.load weights into new model
loaded_dec_model.load_weights("dec_model_num.h5")
loaded_enc_model.load_weights("enc_model_num.h5")
print("Loaded models from disk")

tf.keras.backend.set_learning_phase(0) # Ignore dropout at inference

'''
Fetch the Keras session and save the model
The signature definition is defined by the input and output tensors
And stored with the default serving key
'''

with tf.keras.backend.get_session() as sess:
    tf.saved_model.simple_save(
        sess,
        './encoder_model/1',
        inputs={'input_image': loaded_enc_model.input},
        outputs={t.name:t for t in loaded_enc_model.outputs})
    tf.saved_model.simple_save(
        sess,
        './decoder_model/1',
        inputs ={t.name:t for t in loaded_dec_model.input},
        outputs={t.name:t for t in loaded_dec_model.outputs})


print("loaded")

Step2 : Optionally, checkout the saved Models/Weights

encoder_model > tree -c
.
├── variables
│   ├── variables.data-00000-of-00001
│   └── variables.index
└── saved_model.pb

Step3 : install TF serve if you already dont have it

apt-get install tensorflow-model-server

Step4 : Get Layer names using CMDLINE for the encoder model

encoder_model > saved_model_cli show --dir ./ --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_image'] tensor_info:
        dtype: DT_FLOAT
        shape: (-1, 23)
        name: input_7:0
  The given SavedModel SignatureDef contains the following output(s):
    outputs['bidirectional_3/concat:0'] tensor_info:
        dtype: DT_FLOAT
        shape: (-1, 23, 256)
        name: bidirectional_3/concat:0
    outputs['concatenate_6/concat:0'] tensor_info:
        dtype: DT_FLOAT
        shape: (-1, 256)
        name: concatenate_6/concat:0
    outputs['concatenate_7/concat:0'] tensor_info:
        dtype: DT_FLOAT
        shape: (-1, 256)
        name: concatenate_7/concat:0
  Method name is: tensorflow/serving/predict

Step5 : Get Layer names using CMDLINE for the decoder model

decoder_model> saved_model_cli show --dir ./ --all

MetaGraphDef with tag-set: 'serve' contains the following SignatureDefs:

signature_def['serving_default']:
  The given SavedModel SignatureDef contains the following input(s):
    inputs['inf_decoder_inputs:0'] tensor_info:
        dtype: DT_FLOAT
        shape: (-1, -1)
        name: inf_decoder_inputs:0
    inputs['state_input_c:0'] tensor_info:
        dtype: DT_FLOAT
        shape: (-1, 256)
        name: state_input_c:0
    inputs['state_input_h:0'] tensor_info:
        dtype: DT_FLOAT
        shape: (-1, 256)
        name: state_input_h:0
  The given SavedModel SignatureDef contains the following output(s):
    outputs['dense_7/truediv:0'] tensor_info:
        dtype: DT_FLOAT
        shape: (-1, -1, 601)
        name: dense_7/truediv:0
    outputs['lstm_1/while/Exit_2:0'] tensor_info:
        dtype: DT_FLOAT
        shape: (-1, 256)
        name: lstm_1/while/Exit_2:0
    outputs['lstm_1/while/Exit_3:0'] tensor_info:
        dtype: DT_FLOAT
        shape: (-1, 256)
        name: lstm_1/while/Exit_3:0
  Method name is: tensorflow/serving/predict

Step6 : Run TFServe servers to server encoder and decoder model. These are gRPC services that can be used as REST services

nohup sudo tensorflow_model_server --model_base_path=$(pwd) --rest_api_port=9000 --model_name=encoder_model &

nohup sudo tensorflow_model_server --model_base_path=$(pwd) --rest_api_port=9001 --model_name=decode_model &

Step7 : Run your app code to that calls the TFServe REST services and serve the results.

import requests
import json
import pickle
import sys

text = "please cal"

with open('input_lang.pkl', 'rb') as input1:
    input_lang = pickle.load(input1)
with open('output_lang.pkl', 'rb') as target:
    target_lang = pickle.load(target)
with open('output_lang1.pkl', 'rb') as target1:
    lang_target = pickle.load(target1)


import numpy as np
len_target = 23
len_input = 23

def sentence_to_vector(sentence, lang):
    pre = sentence
    vec = np.zeros(len_input)
    sentence_list = [lang[s] for s in pre.split(' ')]
    for i,w in enumerate(sentence_list):
        vec[i] = w
    return vec

# Given an input string, an encoder model (infenc_model) and a decoder model (infmodel),
def translate(input_sentence):
    sv = sentence_to_vector(input_sentence, input_lang)
    #sv = sv.reshape(1,len(sv))
    output_sentence = ""
    print(sv.shape)
    print(sv)
                  
    payload = {
            "instances":[{"input_image": sv.tolist()}]
    }
    try:
      r = requests.post('http://localhost:9000/v1/models/encoder_model:predict', json=payload)
      r.raise_for_status()
    except requests.exceptions.HTTPError as e:
        print(r)
        print(r.content)
        return "Error: " + str(e)
        #json.loads(r.content)
        #sys.exit(1)
    epred= json.loads(r.content)['predictions']
    emb_out = epred[0]['bidirectional_3/concat:0']
    sh = epred[0]['concatenate_6/concat:0']
    sc = epred[0]['concatenate_7/concat:0']
    #[emb_out, sh, sc] = loaded_enc_model.predict(x=sv)
    print(epred[0].keys())
    i = 0
    start_vec = target_lang["<start>"]
    stop_vec = target_lang["<end>"]

    cur_vec = np.zeros((1))
    cur_vec[0] = start_vec
    cur_word = "<start>"
    output_sentence = ""
    print(cur_vec.shape)

    while cur_word != "<end>" and i < (len_target-1):
        i += 1
        if cur_word != "<start>":
            output_sentence = output_sentence + " " + cur_word
        #x_in = [cur_vec,sh, sc]

        ####
        payload = {
            "instances":[{
                          "inf_decoder_inputs:0": cur_vec.tolist(),
                          "state_input_c:0"     : sh,
                          "state_input_h:0"     : sc
                        }
                        ]
         }


        try:
          r = requests.post('http://localhost:9001/v1/models/decoder_model:predict', json=payload)
          r.raise_for_status()
        except requests.exceptions.HTTPError as e:
          print(r)
          print(r.content)
          return "Error: " + str(e)
        ####
        dpred= json.loads(r.content)['predictions']
        print(dpred[0].keys())
        nvec = dpred[0]['dense_7/truediv:0']
        sh   = dpred[0]['lstm_1/while/Exit_2:0']
        sc   = dpred[0]['lstm_1/while/Exit_3:0']
        #[nvec, sh, sc] = loaded_dec_model.predict(x=x_in)

        cur_vec[0] = np.argmax(nvec[0])
        cur_word = lang_target[cur_vec[0]]

    return output_sentence

prediction = translate(text.lower())
print(prediction)                                                                                                                                   
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment