TensorFlow
SavedModel
Keras
Model Saving
Deep Learning

Difference between tf.saved_model.savemodel, path_to_dir and tf.keras.model.save

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

TensorFlow model-saving APIs overlap in name but not in purpose. The core distinction is that tf.saved_model.save exports a TensorFlow SavedModel directory for serving-style use cases, while tf.keras.Model.save is the high-level Keras API for saving a reloadable Keras model, typically in the .keras format.

What tf.saved_model.save Produces

tf.saved_model.save(obj, path_to_dir) writes a SavedModel directory. This is TensorFlow's general export format for tf.Module objects and subclasses such as tf.keras.Model.

python
1import tensorflow as tf
2
3model = tf.keras.Sequential([
4    tf.keras.layers.Input(shape=(4,)),
5    tf.keras.layers.Dense(8, activation="relu"),
6    tf.keras.layers.Dense(1)
7])
8
9model(tf.random.normal((1, 4)))
10
11tf.saved_model.save(model, "export/saved_model_dir")

The result is a directory containing files such as saved_model.pb, variables/, and asset metadata. This format is designed for TensorFlow runtimes and serving-style consumers.

You usually load it with:

python
restored = tf.saved_model.load("export/saved_model_dir")
print(restored.signatures.keys())

Notice that the restored object is not necessarily the same rich Keras model instance you started with. It is a TensorFlow-loaded object with callable signatures.

What tf.keras.Model.save Produces

model.save(...) is the Keras whole-model saving API. In current Keras workflows, the normal target is the native .keras format.

python
1import tensorflow as tf
2
3model = tf.keras.Sequential([
4    tf.keras.layers.Input(shape=(4,)),
5    tf.keras.layers.Dense(8, activation="relu"),
6    tf.keras.layers.Dense(1)
7])
8
9model.save("export/my_model.keras")

You load that file back with Keras and recover a Keras model object:

python
reloaded = tf.keras.models.load_model("export/my_model.keras")
reloaded.summary()

This is usually the right choice when your goal is Python-side model persistence, training continuation, or easy reload inside another Keras program.

Why the Difference Matters

Although both approaches save the model's learned parameters, they target different consumers.

Use tf.saved_model.save when you want:

  • TensorFlow serving-style export
  • explicit signature control
  • a generic TensorFlow artifact for TensorFlow tooling

Use model.save("something.keras") when you want:

  • a Keras-native artifact
  • convenient reload with load_model
  • a smoother Python training workflow

That is the practical boundary most teams care about.

Signature Control and Serving Behavior

One strength of tf.saved_model.save is signature control. If you want a stable serving contract, you can export explicit functions.

python
1import tensorflow as tf
2
3@tf.function(input_signature=[tf.TensorSpec([None, 4], tf.float32)])
4def serve_fn(x):
5    return {"scores": model(x)}
6
7tf.saved_model.save(
8    model,
9    "export/custom_saved_model",
10    signatures={"serving_default": serve_fn}
11)

That is useful when another system expects well-defined input names, shapes, and output keys.

Current Keras Note: SavedModel Export Is a Separate Step

One place developers get tripped up is old examples that suggest model.save("some_directory") for SavedModel export. In modern Keras, the recommended whole-model save format is .keras, and SavedModel export for inference is handled separately.

If you want a SavedModel-style inference export from Keras, use the export workflow:

python
1import tensorflow as tf
2
3model = tf.keras.Sequential([
4    tf.keras.layers.Input(shape=(4,)),
5    tf.keras.layers.Dense(8, activation="relu"),
6    tf.keras.layers.Dense(1)
7])
8
9model.export("export/serving_artifact")

That distinction clears up a lot of confusion in codebases that mix older TensorFlow examples with newer Keras conventions.

Checkpoints Are Yet Another Thing

Do not confuse either full-model save API with checkpoints. Checkpoints primarily store variable state for training recovery.

python
checkpoint = tf.train.Checkpoint(model=model)
checkpoint.save("checkpoints/ckpt")

A checkpoint is useful for resuming training, but it is not the same as a whole-model artifact that you can hand to serving infrastructure or reload as a self-contained Keras model.

Common Pitfalls

The most common mistake is assuming all save APIs round-trip into the same kind of object. They do not. tf.saved_model.load and tf.keras.models.load_model solve different loading problems.

Another mistake is using outdated examples without noticing the version assumptions. Old tutorials often blur the line between Keras and SavedModel workflows in ways that no longer reflect the current recommended path.

Developers also sometimes save checkpoints and expect them to behave like deployable model exports. Checkpoints are related, but they are not interchangeable with whole-model artifacts.

Finally, if a serving system depends on named signatures, do not rely on defaults blindly. Make the serving function explicit so the export contract stays stable.

Summary

  • 'tf.saved_model.save writes a TensorFlow SavedModel directory.'
  • 'tf.keras.Model.save is the Keras whole-model API and is typically used with .keras.'
  • 'tf.saved_model.load restores a generic TensorFlow-loaded object, while load_model restores a Keras model.'
  • For serving-style Keras export, use the dedicated SavedModel export workflow.
  • Checkpoints are for training state and should not be confused with full model saves.

Course illustration
Course illustration

All Rights Reserved.