<jupyter_start><jupyter_text>TensorFlow Deploy - TFHub  Storing TensorFlow modules with `tfd` helps solve two problems. First of all, it allows to store and archive our own modules in a safe location, with no need of publishing them anywhere. Second of all, it allows to use internal modules within external company resources, once we clone world modules of our interest.We will show you here how modules embedded in [tfhub.dev](tfhub.dev) can be moved to `tfd`. Next, we will build a model using the module.<jupyter_code>import tensorflow as tf
import tensorflow_deploy_utils as tfd
import tensorflow_hub as tfh
from helpers import grpc_text_client
tf.__version__, tfd.__version__, tfh.__version__<jupyter_output><empty_output><jupyter_text>Let's download a module from [tfhub.dev](tfhub.dev).<jupyter_code># It may take a while for the first time, because module weights almost 200MB
tfhub_module = tfh.load("https://tfhub.dev/google/nnlm-en-dim50/2")<jupyter_output><empty_output><jupyter_text>Let's see if the module works properly<jupyter_code>embed1 = tfhub_module(["this model is quite heavy"])
embed1<jupyter_output><empty_output><jupyter_text>Now we will save the module so that we can send it to our `tfd`<jupyter_code>EXPORT_PATH = "/tmp/tfhub_module/"
tf.saved_model.save(tfhub_module, EXPORT_PATH)<jupyter_output><empty_output><jupyter_text>In order to be able to send our module to local `tfd` repository, we need to add README.md file. Therefore, we will create a cursor that will provide us with such a possibility.<jupyter_code>tfd_cursor = tfd.TFD(team="google", project="textembedding", name="nnlmendim50", host="tfd")
tfd_cursor.generate_module_readme(dst_path=EXPORT_PATH, 
                                  description="Module copy from https://tfhub.dev/google/nnlm-en-dim50/2")
tfd_cursor.upload_module(EXPORT_PATH)<jupyter_output><empty_output><jupyter_text>Ready. The module we have chosen is now in our local `tfd` repository. Let's double check if it really is there.<jupyter_code>tfd_cursor.list_modules()<jupyter_output><empty_output><jupyter_text>Perfect, it seems that everything is working propely. Let's now build a model that will be using our module.   Model with our own module<jupyter_code>class MyModel(tf.keras.Model):
    
    def __init__(self, module_url):
        super(MyModel, self).__init__()
        self.module = tfh.load(module_url)
    
    @tf.function(input_signature=[tf.TensorSpec(shape=None, dtype=tf.dtypes.string, name="x")])
    def call(self, x):
        return self.module(x)
    
    @tf.function(input_signature=[tf.TensorSpec(shape=None, dtype=tf.dtypes.string, name="x")])
    def serve(self, x):
        return self.call(x)
my_model = MyModel("http://tfd:9500/v1/modules/google/textembedding/names/nnlmendim50/versions/1")<jupyter_output><empty_output><jupyter_text>We have built a model that includes a module to embed the text. Let's test if it works.<jupyter_code>embed2 = my_model(["this model is quite heavy"])
embed2<jupyter_output><empty_output><jupyter_text>It seems to be working. But is it working correctly? Let's compare the results of module embedding `embed1` with model's embedding `embed2`. If everything is OK, the results should be identical.<jupyter_code>embed1 == embed2<jupyter_output><empty_output><jupyter_text>As expected, both vectors are identical. Let's implement our new model into a respective `tfs` instance and see how it works.<jupyter_code>NEW_EXPORT_PATH = "/tmp/my_model/"
tf.saved_model.save(my_model, NEW_EXPORT_PATH)
tfd_cursor = tfd.TFD(team="demo", project="hub", name="nnlmendim50", host="tfd")
tfd_cursor.generate_model_readme(dst_path=NEW_EXPORT_PATH, 
                                 description="Model created on top of tfhub.dev module: https://tfhub.dev/google/nnlm-en-dim50/2")
response = tfd_cursor.deploy_model(src_path=NEW_EXPORT_PATH)
print(response)<jupyter_output><empty_output><jupyter_text>Great, we have got a new model in our production. Let's test it now.<jupyter_code>response = grpc_text_client(dataset=[["this model is quite heavy"]], host="tfs-demo-hub", port=8500, 
                            model_name="nnlmendim50", model_label="canary")
response<jupyter_output><empty_output><jupyter_text>Let's see again if the response from `tfs` is the same as in the initial module.<jupyter_code>embed3 = response[0].outputs["output_1"].float_val
embed3
embed1 == embed3<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.101288718064662, 'fraction_numerical': 0.009947999095636446, 'mean_word_length': 5.49632892804699, 'pattern_counts': {'":': 0, '<': 49, '<?xml version=': 0, '>': 49, 'https://': 3, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 3, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '12', 'dir': 'jupyter-structured-clean-dedup', 'id': '278495', 'license': '0BSD', 'n_tokens_mistral': 1453, 'n_tokens_neox': 1412, 'n_words': 394, 'path': 'demo/notebook/notebooks/3_tfd_tfhub.ipynb', 'repo_name': 'grupawp/tensorflow-deploy', 'size': '4423'}