TensorFlow version compatibility (original) (raw)

This document is for users who need backwards compatibility across different versions of TensorFlow (either for code or data), and for developers who want to modify TensorFlow while preserving compatibility.

Semantic versioning 2.0

TensorFlow mostly follows Semantic Versioning 2.0 (semver) for its public API. Each release version of TensorFlow has the formMAJOR.MINOR.PATCH. For example, TensorFlow version 1.2.3 has MAJOR version 1, MINOR version 2, and PATCH version 3. Changes to each number have the following meaning:

For example, release 1.0.0 introduced backwards incompatible changes from release 0.12.1. However, release 1.1.1 was backwards compatible with release 1.0.0.

What is covered

Only the public APIs of TensorFlow are backwards compatible across minor and patch versions. The public APIs consist of

Separate version number for TensorFlow Lite

Currently TensorFlow Lite is distributed as a part of TensorFlow. However, we reserve the right to in future release changes to the TensorFlow Lite APIs on a different schedule than for the other TensorFlow APIs, or even to move TensorFlow Lite into a separate source distribution and/or a separate source repository than TensorFlow.

Because of this, we use a different version number for TensorFlow Lite (TFLITE_VERSION_STRING in tensorflow/lite/version.h, and TfLiteVersion()in tensorflow/lite/c/c_api.h) than for TensorFlow (TF_VERSION_STRING intensorflow/core/public/release_version.h, and TF_Version() intensorflow/c/c_api.h). Currently, these two version numbers happen to have the same value. But in future, they may diverge; for example, we may increment the major version number for TensorFlow Lite without incrementing the major version number for TensorFlow, or vice versa.

The API surface that is covered by the TensorFlow Lite version number is comprised of the following public APIs:

Experimental symbols are not covered; see below for details.

Separate version number for TensorFlow Lite Extension APIs

TensorFlow Lite provides C APIs for extending the TensorFlow Lite interpreter with "custom ops", which provide user-defined operations in a graph, or "delegates", which allow delegating the computation for a graph (or for a subset of a graph) to a custom backend. These APIs, which we collectively call the "TensorFlow Lite Extension APIs", require more intimate dependencies on some of the details of the TensorFlow Lite implementation.

We reserve the right to in future release changes to these APIs, potentially including non-backwards-compatible changes, on a different schedule than for the other TensorFlow Lite APIs. So we use a different version number for the TensorFlow Lite Extension APIs than the version numbers for TensorFlow Lite or TensorFlow (which were described in the previous section). We are introducing some new APIs in TensorFlow Lite version 2.15 to get the TensorFlow Lite Extension APIs version (TFLITE_EXTENSION_APIS_VERSION_STRING intensorflow/lite/version.h, and TfLiteExtensionApisVersion() intensorflow/lite/c/c_api.h). The version number for the TensorFlow Lite Extension APIs is currently the same as the version number for TensorFlow and TensorFlow Lite. But in future, they may diverge; for example, we may increment the major version number for the TensorFlow Lite Extension APIs without incrementing the major version number for TensorFlow Lite, or vice versa.

The API surface that is covered by the TensorFlow Lite Extension APIs version number is comprised of the following public APIs:

Again, experimental symbols are not covered; see below for details.

What is not covered

Some parts of TensorFlow can change in backward incompatible ways at any point. These include:

Compatibility of SavedModels, graphs and checkpoints

SavedModel is the preferred serialization format to use in TensorFlow programs. SavedModels contain two parts: One or more graphs encoded as GraphDefs and a Checkpoint. The graphs describe the data flow of ops to be run, and checkpoints contain the saved tensor values of variables in a graph.

Many TensorFlow users create SavedModels, and load and execute them with a later release of TensorFlow. In compliance with semver, SavedModels written with one version of TensorFlow can be loaded and evaluated with a later version of TensorFlow with the same major release.

We make additional guarantees for supported SavedModels. We call a SavedModel which was created using only non-deprecated, non-experimental, non-compatibility APIs in TensorFlow major version N a SavedModel supported in version N. Any SavedModel supported in TensorFlow major version N can be loaded and executed with TensorFlow major version N+1. However, the functionality required to build or modify such a model may not be available any more, so this guarantee only applies to the unmodified SavedModel.

We will endeavor to preserve backwards compatibility as long as possible, so that the serialized files are usable over long periods of time.

GraphDef compatibility

Graphs are serialized via the GraphDef protocol buffer. To facilitate backwards incompatible changes to graphs, each GraphDef has a version number separate from the TensorFlow version. For example, GraphDef version 17 deprecated the inv op in favor of reciprocal. The semantics are:

Finally, when support for a GraphDef version is dropped, we will attempt to provide tools for automatically converting graphs to a newer supportedGraphDef version.

Graph and checkpoint compatibility when extending TensorFlow

This section is relevant only when making incompatible changes to the GraphDefformat, such as when adding ops, removing ops, or changing the functionality of existing ops. The previous section should suffice for most users.

Backward and partial forward compatibility

Our versioning scheme has three requirements:

Note that while the GraphDef version mechanism is separate from the TensorFlow version, backwards incompatible changes to the GraphDef format are still restricted by Semantic Versioning. This means functionality can only be removed or changed between MAJOR versions of TensorFlow (such as 1.7 to 2.0). Additionally, forward compatibility is enforced within Patch releases (1.x.1to 1.x.2 for example).

To achieve backward and forward compatibility and to know when to enforce changes in formats, graphs and checkpoints have metadata that describes when they were produced. The sections below detail the TensorFlow implementation and guidelines for evolving GraphDef versions.

Independent data version schemes

There are different data versions for graphs and checkpoints. The two data formats evolve at different rates from each other and also at different rates from TensorFlow. Both versioning systems are defined incore/public/version.handcore/public/release_version.h. Whenever a new version is added, a note is added to the header detailing what changed and the date.

Data, producers, and consumers

We distinguish between the following kinds of data version information:

Each piece of versioned data has a VersionDef versionsfield which records the producer that made the data, the min_consumerthat it is compatible with, and a list of bad_consumers versions that are disallowed.

By default, when a producer makes some data, the data inherits the producer'sproducer and min_consumer versions. bad_consumers can be set if specific consumer versions are known to contain bugs and must be avoided. A consumer can accept a piece of data if the following are all true:

Since both producers and consumers come from the same TensorFlow code base,core/public/version.hcontains a main data version which is treated as either producer orconsumer depending on context and both min_consumer and min_producer(needed by producers and consumers, respectively). Specifically,

Add a new attribute with default to an existing op

Following the guidance below gives you forward compatibility only if the set of ops has not changed:

  1. If forward compatibility is desired, set strip_default_attrs to Truewhile exporting the model using either thetf.saved_model.SavedModelBuilder.add_meta_graph_and_variablesand tf.saved_model.SavedModelBuilder.add_meta_graphmethods of the SavedModelBuilder class, ortf.estimator.Estimator.export_saved_model
  2. This strips off the default valued attributes at the time of producing/exporting the models. This makes sure that the exportedtf.MetaGraphDef does not contain the new op-attribute when the default value is used.
  3. Having this control could allow out-of-date consumers (for example, serving binaries that lag behind training binaries) to continue loading the models and prevent interruptions in model serving.

Evolving GraphDef versions

This section explains how to use this versioning mechanism to make different types of changes to the GraphDef format.

Add an op

Add the new op to both consumers and producers at the same time, and do not change any GraphDef versions. This type of change is automatically backward compatible, and does not impact forward compatibility plan since existing producer scripts will not suddenly use the new functionality.

Add an op and switch existing Python wrappers to use it

  1. Implement new consumer functionality and increment the GraphDef version.
  2. If it is possible to make the wrappers use the new functionality only in cases that did not work before, the wrappers can be updated now.
  3. Change Python wrappers to use the new functionality. Do not incrementmin_consumer, since models that do not use this op should not break.

Remove or restrict an op's functionality

  1. Fix all producer scripts (not TensorFlow itself) to not use the banned op or functionality.
  2. Increment the GraphDef version and implement new consumer functionality that bans the removed op or functionality for GraphDefs at the new version and above. If possible, make TensorFlow stop producing GraphDefs with the banned functionality. To do so, add theREGISTER_OP(...).Deprecated(deprecated_at_version, message).
  3. Wait for a major release for backward compatibility purposes.
  4. Increase min_producer to the GraphDef version from (2) and remove the functionality entirely.

Change an op's functionality

  1. Add a new similar op named SomethingV2 or similar and go through the process of adding it and switching existing Python wrappers to use it. To ensure forward compatibility use the checks suggested incompat.pywhen changing the Python wrappers.
  2. Remove the old op (Can only take place with a major version change due to backward compatibility).
  3. Increase min_consumer to rule out consumers with the old op, add back the old op as an alias for SomethingV2, and go through the process to switch existing Python wrappers to use it.
  4. Go through the process to remove SomethingV2.

Ban a single unsafe consumer version

  1. Bump the GraphDef version and add the bad version to bad_consumers for all new GraphDefs. If possible, add to bad_consumers only for GraphDefs which contain a certain op or similar.
  2. If existing consumers have the bad version, push them out as soon as possible.