Skip to content

In this tutorial we will learn how to load a pre-trained Tensorflow saved model

We will use the Universal Sentence Encoder from tfhub as an example

Download and extract

Fisrt, download the file universal-sentence-encoder-multilingual_3.tar.gz and extract it in a asset_name/1 directory

In this tutorial we will use /tmp/use/1

tar -xzvf universal-sentence-encoder-multilingual_3.tar.gz --directory /tmp/use/1

this will create the following tree:

use
└── 1
    ├── assets
    ├── saved_model.pb
    └── variables
        ├── variables.data-00000-of-00001
        └── variables.index

Check the model configuration

In order to use modelkit to use the model we have to check the model configuation in order to exctract outputs informations (key name, layer name, shape and type) and the inputs key name:

import tensorflow as tf
import tensorflow_text  # module need by use model
model = tf.saved_model.load("/tmp/use/1/")
print(model.signatures["serving_default"].output_dtypes)
print(model.signatures["serving_default"].output_shapes)
print(model.signatures["serving_default"].outputs)
print(model.signatures["serving_default"].inputs[0])

# Output:
# {'outputs': tf.float32}
# {'outputs': TensorShape([None, 512])}
# [<tf.Tensor 'Identity:0' shape=(None, 512) dtype=float32>]
# <tf.Tensor 'inputs:0' shape=(None,) dtype=string>

Quick load with modelkit

We can now load the model by creating a TensorflowModel class and configuring it with information we just got from the model.

Note that we have to declare a "virtual" asset "asset": "use" to directly set an asset path /tmp/use (without the 1 directory)

import numpy as np
import tensorflow_text

import modelkit
from modelkit.core.models.tensorflow_model import TensorflowModel

class USEModel(TensorflowModel):
    CONFIGURATIONS = {
        "use": {
            "asset": "use",
            "model_settings": {
                "output_tensor_mapping": {"outputs": "Identity:0"},
                "output_shapes": {"outputs": (512,)},
                "output_dtypes": {"outputs": np.float32},
                "asset_path": "/tmp/use",
            },
        }
    }

and then we can test it using load_model

model = modelkit.load_model("use", models=USEModel)
model.predict({"inputs": "Hello world"})
# note that the "inputs" keyword is extracted from the previous model configuration

That's all !

We can start testing/using our model

from sklearn.metrics.pairwise import cosine_distances

sentence_1 = model.predict({"inputs": "My dog is quite calm today"})["outputs"]
sentence_2 = model.predict({"inputs": "Mon chien est assez calme aujourd'hui"})["outputs"]
sentence_3 = model.predict({"inputs": "It rains on my house"})["outputs"]
sentence_4 = model.predict({"inputs": "Il pleut sur ma maison"})["outputs"]

print(cosine_similarity([sentence_1, sentence_2, sentence_3, sentence_4]))
# output :
# [[1.         0.93083745 0.3172922  0.3379839 ]
#  [0.93083745 0.99999994 0.3522399  0.39009082]
#  [0.3172922  0.3522399  0.9999999  0.8444551 ]
#  [0.3379839  0.39009082 0.8444551  0.9999999 ]]

#  - sentence_1 close to sentence_2 (0.93)
#  - sentence_3 close to sentence_4 (0.84)
#  - other distances < 0.5

# => seems to work :-)

Create an asset

Once we have tested our model, we may want push and use it as an versioned asset

modelkit assets new /tmp/use my_assets/use

and then we can remove asset_path and add our asset name to our TensorflowModel

import numpy as np
import tensorflow_text

import modelkit
from modelkit.core.models.tensorflow_model import TensorflowModel

class USEModel(TensorflowModel):
    CONFIGURATIONS = {
        "use": {
            "asset": "my_assets/use:0.0",
            "model_settings": {
                "output_tensor_mapping": {"outputs": "Identity:0"},
                "output_shapes": {"outputs": (512,)},
                "output_dtypes": {"outputs": np.float32},
            },
        }
    }

and then we may use a ModelLibrary to load it

model_library = modelkit.ModelLibrary(
    required_models=["use"],
    models=USEModel,
)
model = model_library.get("use")
model.predict({"inputs": "Hello world"})

Using tensorflow serving

Our model is directly compatible with our tensorflow-serving loading scripts

Let's say we have saved our model in modelkit/use.py file, generate the configuation:

modelkit tf-serving local-docker modelkit.use -r "use"

it will create a config file ${MODELKIT_ASSETS_DIR}/config.config

then we can start our tf-serving running

docker run --name local-tf-serving -d -p 8500:8500 -p 8501:8501 -v ${MODELKIT_ASSETS_DIR}:/config -t tensorflow/serving --model_config_file=/config/config.config --rest_api_port=8501 --port=8500

then we can try use use our model with MODELKIT_TF_SERVING_ENABLE=1, we should see the log line when loading the model

[info ] Connecting to tensorflow serving mode=rest model_name=use port=8501 tf_serving_host=localhost