本文档面向需要在不同版本的TensorFlow(代码或数据)之间向后兼容的用户,以及希望在保持兼容性的同时修改TensorFlow的开发人员。
TensorFlow遵循语义版本2.0(semver)为其公共API。 TensorFlow的每个发行版都有MAJOR.MINOR.PATCH格式。例如,TensorFlow版本1.2.3具有MAJOR版本1,MINOR版本2和PATCH版本3.对每个数字的更改具有以下含义:
例如,版本1.0.0从版本0.12.1引入了向后不兼容的更改。但是,版本1.1.1向后兼容版本1.0.0。
什么被覆盖?
只有TensorFlow的公共API在小版本和补丁版本之间向后兼容。 公共API包含
如果一个符号通过张量流Python模块或其子模块可用,但没有记录,那么它不被视为公共API的一部分。
The C API.
The following protocol buffer files:
attr_value
config
event
graph
op_def
reader_base
summary
tensor
tensor_shape
types
什么不被覆盖?
Some API functions are explicitly marked as “experimental” and can change in backward incompatible ways between minor releases. These include:
Compatibility of graphs and checkpoints
你有时需要保存图形和检查点。图表描述了在训练和推断期间要运行的操作的数据流,并且检查点包含图中变量的已保存张量值。
许多TensorFlow用户将图形和训练好的模型保存到磁盘,以便以后进行评估或进行额外的培训,但最终会在更高版本上运行保存的图形或模型。根据semver,用一个版本的TensorFlow写出的任何图形或检查点都可以使用相同主要版本的TensorFlow的更高版本进行加载和评估。但是,如果可能的话,我们将努力保持向后兼容,即使在主要版本中也是如此,以便序列化文件可以在很长一段时间内使用。
图形通过GraphDef协议缓冲区序列化。为了促进(罕见)向后不兼容的图形变化,每个GraphDef都有一个与TensorFlow版本分开的版本号。例如,GraphDef版本17反对支持反对。语义是:
最后,当对GraphDef版本的支持被删除时,我们将尝试提供自动将图转换为更新的受支持的GraphDef版本的工具。
Graph and checkpoint compatibility when extending TensorFlow
This section is relevant only when making incompatible changes to the GraphDef format, 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:
Backward compatibility to support loading graphs and checkpoints created with older versions of TensorFlow.
Forward compatibility to support scenarios where the producer of a graph or checkpoint is upgraded to a newer version of TensorFlow before the consumer.
Enable evolving TensorFlow in incompatible ways. For example, removing Ops, adding attributes, and removing attributes.
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.1 to 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 in core/public/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: producers: binaries that produce data. Producers have a version (producer) and a minimum consumer version that they are compatible with (min_consumer). consumers: binaries that consume data. Consumers have a version (consumer) and a minimum producer version that they are compatible with (min_producer).
Each piece of versioned data has a VersionDef versions field which records the producer that made the data, the min_consumer that 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’s producer 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:
consumer >= data's min_consumer
data's producer >= consumer's min_producer
consumer not in data's bad_consumers
Since both producers and consumers come from the same TensorFlow code base, core/public/version.h contains a main data version which is treated as either producer or consumer depending on context and both min_consumer and min_producer (needed by producers and consumers, respectively). Specifically,
For GraphDef versions, we have TF_GRAPH_DEF_VERSION, TF_GRAPH_DEF_VERSION_MIN_CONSUMER, and TF_GRAPH_DEF_VERSION_MIN_PRODUCER.
For checkpoint versions, we have TF_CHECKPOINT_VERSION, TF_CHECKPOINT_VERSION_MIN_CONSUMER, and TF_CHECKPOINT_VERSION_MIN_PRODUCER.
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
Implement new consumer functionality and increment the GraphDef version.
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.
Change Python wrappers to use the new functionality. Do not increment min_consumer, since models that do not use this Op should not break.
Remove or restrict an Op’s functionality
Fix all producer scripts (not TensorFlow itself) to not use the banned Op or functionality.
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 the REGISTER_OP(...).Deprecated(deprecated_at_version, message).
Wait for a major release for backward compatibility purposes.
Increase min_producer to the GraphDef version from (2) and remove the functionality entirely.
Change an Op’s functionality
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, which may take three weeks if forward compatibility is desired.
Remove the old Op (Can only take place with a major version change due to backward compatibility).
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.
Go through the process to remove SomethingV2.
Ban a single unsafe consumer version
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.
If existing consumers have the bad version, push them out as soon as possible.