Tensorflow V1¶
Users can now use Tensorflow (v1 and v2 supported) with BentoML with the following API: load
, save
, and load_runner
as follow:
import bentoml
import tensorflow as tf
import tempfile
import numpy as np
location = ""
def simple_model_fn():
x1 = tf.compat.v1.placeholder(shape=[None, 5], dtype=tf.float32, name="x1")
x2 = tf.compat.v1.placeholder(shape=[None, 5], dtype=tf.float32, name="x2")
factor = tf.compat.v1.placeholder(shape=(), dtype=tf.float32, name="factor")
init = tf.constant_initializer([1.0, 1.0, 1.0, 1.0, 1.0])
w = tf.Variable(init(shape=[5, 1], dtype=tf.float32))
x = x1 + x2 * factor
p = tf.matmul(x, w)
return {"p": p, "x1": x1, "x2": x2, "factor": factor}
simple_model = simple_model_fn()
with tempfile.TemporaryDirectory() as temp_dir:
with tf.compat.v1.Session() as sess:
tf.compat.v1.enable_resource_variables()
sess.run(tf.compat.v1.global_variables_initializer())
inputs = {
"x1": simple_model["x1"],
"x2": simple_model["x2"],
"factor": simple_model["factor"],
}
outputs = {"prediction": simple_model["p"]}
tf.compat.v1.saved_model.simple_save(
sess, temp_dir, inputs=inputs, outputs=outputs
)
location = temp_dir
# `save` a given model and retrieve coresponding tag:
tag = bentoml.tensorflow_v1.save("tf1_model", location)
# retrieve metadata with `bentoml.models.get`:
metadata = bentoml.models.get(tag)
# `load` the model back in memory:
model = bentoml.tensorflow_v1.load("tf1_model:latest")
x = tf.convert_to_tensor([[1.0, 2.0, 3.0, 4.0, 5.0]], dtype=tf.float32)
f1 = tf.convert_to_tensor(3.0, dtype=tf.float32)
f2 = tf.convert_to_tensor(2.0, dtype=tf.float32)
# Run a given model under `Runner` abstraction with `load_runner`
r1 = bentoml.tensorflow_v1.load_runner(
tag,
partial_kwargs=dict(factor=f1),
)
r2 = bentoml.tensorflow_v1.load_runner(
tag,
partial_kwargs=dict(factor=f2),
)
res = r1.run_batch(x1=x, x2=x)
assert np.isclose(res[0][0], 60.0)
res = r2.run_batch(x1=x, x2=x)
assert np.isclose(res[0][0], 45.0)
We also offer import_from_tfhub
which enables users to import model from Tensorflow Hub and use it with BentoML:
import tensorflow_text as text
import bentoml
tag = bentoml.tensorflow_v1.import_from_tfhub("https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3")
# load model back with `load`:
model = bentoml.tensorflow_v1.load(tag, load_as_wrapper=True)
Note
You can find more examples for Tensorflow in our gallery repo.
- bentoml.tensorflow_v1.save(name, model, *, signatures=None, options=None, labels=None, custom_objects=None, metadata=None)¶
Save a model instance to BentoML modelstore.
- Parameters
name (
str
) – Name for given model instance. This should pass Python identifier check.model (
Union[tf.keras.Model, tf.Module, path-like objects]
) – Instance of model to be savedmetadata (
Dict[str, Any]
, optional, default toNone
) – Custom metadata for given model.model_store (
ModelStore
, default toBentoMLContainer.model_store
) – BentoML modelstore, provided by DI Container.signatures (
Union[Callable[..., Any], dict]
, optional, default toNone
) – Refers to Signatures explanation from Tensorflow documentation for more information.options (tf.saved_model.SaveOptions, optional, default to
None
) –tf.saved_model.SaveOptions
object that specifies options for saving.labels (
Dict[str, str]
, optional, default toNone
) – user-defined labels for managing models, e.g. team=nlp, stage=devcustom_objects (
Dict[str, Any]]
, optional, default toNone
) – user-defined additional python objects to be saved alongside the model, e.g. a tokenizer instance, preprocessor function, model configuration json
- Raises
ValueError – If
obj
is not trackable.- Returns
A
tag
with a format name:version where name is the user-defined model’s name, and a generated version by BentoML.- Return type
Examples:
import tensorflow as tf import tempfile import bentoml location = "" # Function below builds model graph def cnn_model_fn(): X = tf.placeholder(shape=[None, 2], dtype=tf.float32, name="X") # dense layer inter1 = tf.layers.dense(inputs=X, units=1, activation=tf.nn.relu) p = tf.argmax(input=inter1, axis=1) # loss y = tf.placeholder(tf.float32, shape=[None, 1], name="y") loss = tf.losses.softmax_cross_entropy(y, inter1) # training operation train_op = tf.train.AdamOptimizer().minimize(loss) return {"p": p, "loss": loss, "train_op": train_op, "X": X, "y": y} cnn_model = cnn_model_fn() with tempfile.TemporaryDirectory() as temp_dir: with tf.Session() as sess: sess.run(tf.global_variables_initializer()) sess.run(cnn_model["p"], {cnn_model["X"]: test_data}) inputs = {"X": cnn_model["X"]} outputs = {"prediction": cnn_model["p"]} tf.saved_model.simple_save( sess, temp_dir, inputs=inputs, outputs=outputs ) location = temp_dir # then save the given model to BentoML modelstore: tag = bentoml.tensorflow_v1.save("cnn_model", location)
Note
bentoml.tensorflow.save
API also support saving RaggedTensor model and Keras model. If you choose to save a Keras model withbentoml.tensorflow.save
, then the model will be saved under aSavedModel
format instead ofh5
.
- bentoml.tensorflow_v1.load(bento_tag, tags=None, options=None, load_as_hub_module=None, model_store=<simple_di.providers.SingletonFactory object>)¶
Load a model from BentoML local modelstore with given name.
- Parameters
bento_tag (
Union[str, Tag]
) – Tag of a saved model in BentoML local modelstore.tags (
str
, optional, defaults to None) – A set of strings specifying the graph variant to use, if loading from a v1 module.options (
tensorflow.saved_model.SaveOptions
, optional, default toNone
) –tensorflow.saved_model.LoadOptions
object that specifies options for loading. This argument can only be used from TensorFlow 2.3 onwards.load_as_hub_module (bool, optional, default to
True
) – Load the given weight that is saved from tfhub as either hub.KerasLayer or hub.Module. The latter only applies for TF1.model_store (
ModelStore
, default toBentoMLContainer.model_store
) – BentoML modelstore, provided by DI Container.
- Returns
an instance of
SavedModel
format from BentoML modelstore.- Return type
SavedModel
Examples:
import bentoml # load a model back into memory model = bentoml.tensorflow_v1.load("my_tensorflow_model")
- bentoml.tensorflow_v1.load_runner(tag, *, predict_fn_name='__call__', device_id='CPU:0', name=None, partial_kwargs=None)¶
Runner represents a unit of serving logic that can be scaled horizontally to maximize throughput. bentoml.tensorflow.load_runner implements a Runner class that wrap around a Tensorflow model, which optimize it for the BentoML runtime.
- Parameters
tag (
Union[str, Tag]
) – Tag of a saved model in BentoML local modelstore.predict_fn_name (
str
, default to__call__
) – Inference function to be used.partial_kwargs (
Dict[str, Any]
, optional, default toNone
) – Dictionary of partial kwargs that can be shared across different model.device_id (
str
, optional, default to the first CPU) – Optional devices to put the given model on. Refers to Logical Devices from TF documentation.
- Returns
Runner instances for
bentoml.tensorflow
model- Return type
Runner
Examples:
import bentoml # load a runner from a given flag runner = bentoml.tensorflow_v1.load_runner(tag) # load a runner on GPU:0 runner = bentoml.tensorflow_v1.load_runner(tag, resource_quota=dict(gpus=0), device_id="GPU:0")
- bentoml.tensorflow_v1.import_from_tfhub(identifier, name=None, labels=None, custom_objects=None, metadata=None)¶
Import a model from Tensorflow Hub to BentoML modelstore.
- Parameters
identifier (
Union[str, tensorflow_hub.Module, tensorflow_hub.KerasLayer]
) –Identifier accepts two type of inputs:
if type of
identifier
either of typetensorflow_hub.Module
(legacy tensorflow_hub) ortensorflow_hub.KerasLayer
(tensorflow_hub), then we will save the given model to aSavedModel
format.if type of
identifier
is astr
, we assume that this is the URI retrieved from Tensorflow Hub. We then clean the given URI, and get a local copy of a given model to BentoML modelstore. name (str
, optional, defaults to None): An optional name for the model. Ifidentifier
is astr
, then name can be autogenerated from the given URI.
name (
str
, optional, default to None) – Optional name for the saved model. If None, then name will be generated fromidentifier
.labels (
Dict[str, str]
, optional, default toNone
) – user-defined labels for managing models, e.g. team=nlp, stage=devcustom_objects (
Dict[str, Any]]
, optional, default toNone
) – user-defined additional python objects to be saved alongside the model, e.g. a tokenizer instance, preprocessor function, model configuration jsonmetadata (
Dict[str, Any]
, optional, default toNone
) – Custom metadata for given model.model_store (
ModelStore
, default toBentoMLContainer.model_store
) – BentoML modelstore, provided by DI Container.
- Returns
A
Tag
object that can be used to retrieve the model withbentoml.tensorflow.load()
:- Return type
Example for importing a model from Tensorflow Hub:
import tensorflow_text as text # noqa # pylint: disable import bentoml tag = bentoml.tensorflow_v1.import_from_tfhub("https://tfhub.dev/tensorflow/bert_en_uncased_preprocess/3") # load model back with `load`: model = bentoml.tensorflow_v1.load(tag, load_as_hub_module=True)
Example for importing a custom Tensorflow Hub model:
import tensorflow as tf import tensorflow_hub as hub import bentoml # Simple toy Tensorflow Hub model def _plus_one_model_tf1(): def plus_one(): x = tf.placeholder(dtype=tf.float32, name="x") y = x + 1 hub.add_signature(inputs=x, outputs=y) spec = hub.create_module_spec(plus_one) with tf.get_default_graph().as_default(): module = hub.Module(spec, trainable=True) return module model = _plus_one_model_tf1() # retrieve the given tag: tag = bentoml.tensorflow_v1.import_from_tfhub(model)