Este documento está dirigido a usuarios que necesitan compatibilidad con versiones anteriores de diferentes versiones de TensorFlow (ya sea para código o datos) y para desarrolladores que desean modificar TensorFlow sin perder la compatibilidad.
Control de versiones semántico 2.0
TensorFlow sigue Semantic Versioning 2.0 ( semver ) para su API pública. Cada versión de lanzamiento de TensorFlow tiene el formato MAJOR.MINOR.PATCH
. Por ejemplo, TensorFlow versión 1.2.3 tiene MAJOR
versión 1, MINOR
versión 2 y PATCH
versión 3. Los cambios en cada número tienen el siguiente significado:
MAYOR : Cambios potencialmente incompatibles hacia atrás. El código y los datos que funcionaron con una versión principal anterior no necesariamente funcionarán con la nueva versión. Sin embargo, en algunos casos, los puntos de control y los gráficos de TensorFlow existentes se pueden migrar a la versión más reciente; consulte Compatibilidad de gráficos y puntos de control para obtener detalles sobre la compatibilidad de datos.
MENOR : Funciones compatibles con versiones anteriores, mejoras de velocidad, etc. El código y los datos que funcionaron con una versión menor anterior y que dependen solo de la API pública no experimental continuarán funcionando sin cambios. Para obtener detalles sobre qué es y qué no es la API pública, consulte Qué está cubierto .
PARCHE : correcciones de errores compatibles con versiones anteriores.
Por ejemplo, la versión 1.0.0 introdujo cambios incompatibles con versiones anteriores de la versión 0.12.1. Sin embargo, la versión 1.1.1 era compatible con versiones anteriores de la versión 1.0.0.
Que esta cubierto
Solo las API públicas de TensorFlow son compatibles con versiones anteriores y versiones secundarias. Las API públicas consisten en
Todas las funciones y clases de Python documentadas en el módulo
tensorflow
y sus submódulos, excepto para- Símbolos privados: cualquier función, clase, etc., cuyo nombre comience con
_
- Experimental y
tf.contrib
símbolos, ver a continuación para más detalles.
Tenga en cuenta que el código en los directorios
examples/
ytools/
no es accesible a través del módulo Python detensorflow
y, por lo tanto, no está cubierto por la garantía de compatibilidad.Si un símbolo está disponible a través de la
tensorflow
módulo de Python o sus submódulos, pero no está documentado, entonces no se considera parte de la API pública.- Símbolos privados: cualquier función, clase, etc., cuyo nombre comience con
La API de compatibilidad (en Python, el módulo
tf.compat
). En las versiones principales, podemos lanzar utilidades y puntos finales adicionales para ayudar a los usuarios con la transición a una nueva versión principal. Estos símbolos de API están obsoletos y no son compatibles (es decir, no agregaremos ninguna función y no corregiremos errores que no sean para corregir vulnerabilidades), pero están cubiertos por nuestras garantías de compatibilidad.La API C.
Los siguientes archivos de búfer de protocolo:
Que no esta cubierto
Algunas partes de TensorFlow pueden cambiar de formas incompatibles con versiones anteriores en cualquier momento. Éstas incluyen:
API experimentales : para facilitar el desarrollo, eximimos de las garantías de compatibilidad algunos símbolos de API claramente marcados como experimentales. En particular, lo siguiente no está cubierto por ninguna garantía de compatibilidad:
- cualquier símbolo en el módulo
tf.contrib
o sus submódulos; cualquier símbolo (módulo, función, argumento, propiedad, clase o constante) cuyo nombre contenga
experimental
oExperimental
; ocualquier símbolo cuyo nombre completo incluya un módulo o clase que sea en sí mismo experimental. Esto incluye campos y submensajes de cualquier búfer de protocolo llamado
experimental
.
- cualquier símbolo en el módulo
Otros lenguajes : API de TensorFlow en lenguajes distintos de Python y C, como:
- C ++ (expuesto a través de archivos de encabezado en
tensorflow/cc
). - Java ,
- Vamos
- JavaScript
- C ++ (expuesto a través de archivos de encabezado en
Detalles de las operaciones compuestas: muchas funciones públicas en Python se expanden a varias operaciones primitivas en el gráfico, y estos detalles serán parte de cualquier gráfico guardado en el disco como
GraphDef
s. Estos detalles pueden cambiar para versiones menores. En particular, es probable que las pruebas de regresión que verifican la coincidencia exacta entre gráficos se rompan en versiones menores, aunque el comportamiento del gráfico no debe cambiar y los puntos de control existentes seguirán funcionando.Detalles numéricos de coma flotante: los valores de coma flotante específicos calculados por las operaciones pueden cambiar en cualquier momento. Los usuarios deben confiar solo en la precisión aproximada y la estabilidad numérica, no en los bits específicos calculados. Los cambios en las fórmulas numéricas en versiones menores y de parches deberían dar como resultado una precisión comparable o mejorada, con la salvedad de que en el aprendizaje automático, la precisión mejorada de fórmulas específicas puede resultar en una menor precisión para el sistema en general.
Números aleatorios: los números aleatorios específicos calculados pueden cambiar en cualquier momento. Los usuarios deben confiar solo en distribuciones aproximadamente correctas y fuerza estadística, no en los bits específicos calculados. Consulte la guía de generación de números aleatorios para obtener más detalles.
Sesgo de versión en Tensorflow distribuido: no se admite la ejecución de dos versiones diferentes de TensorFlow en un solo clúster. No hay garantías sobre la compatibilidad con versiones anteriores del protocolo de cable.
Errores: Nos reservamos el derecho de realizar cambios de comportamiento incompatible hacia atrás (aunque no API) si la implementación actual está claramente rota, es decir, si contradice la documentación o si un comportamiento previsto bien conocido y bien definido no se implementa correctamente debido a un error. Por ejemplo, si un optimizador afirma implementar un algoritmo de optimización conocido pero no coincide con ese algoritmo debido a un error, arreglaremos el optimizador. Nuestra solución puede romper el código basándose en un comportamiento incorrecto para la convergencia. Observaremos estos cambios en las notas de la versión.
API no utilizada: nos reservamos el derecho de realizar cambios incompatibles hacia atrás en las API para las que no encontramos usos documentados (mediante la realización de una auditoría del uso de TensorFlow a través de la búsqueda de GitHub). Antes de realizar dichos cambios, anunciaremos nuestra intención de realizar el cambio en la lista de correo de publish @ , brindando instrucciones sobre cómo abordar las roturas (si corresponde) y esperaremos dos semanas para darle a nuestra comunidad la oportunidad de compartir sus comentarios. .
Comportamiento de error: podemos reemplazar los errores con un comportamiento que no es de error. Por ejemplo, podemos cambiar una función para calcular un resultado en lugar de generar un error, incluso si ese error está documentado. También nos reservamos el derecho a cambiar el texto de los mensajes de error. Además, el tipo de error puede cambiar a menos que se especifique en la documentación el tipo de excepción para una condición de error específica.
Compatibilidad de modelos guardados, gráficos y puntos de control
SavedModel es el formato de serialización preferido para usar en los programas de TensorFlow. SavedModels contiene dos partes: uno o más gráficos codificados como GraphDefs
y un punto de control. Los gráficos describen el flujo de datos de las operaciones que se ejecutarán y los puntos de control contienen los valores de tensor guardados de las variables en un gráfico.
Muchos usuarios de TensorFlow crean modelos guardados y los cargan y ejecutan con una versión posterior de TensorFlow. De acuerdo con semver , SavedModels escritos con una versión de TensorFlow se pueden cargar y evaluar con una versión posterior de TensorFlow con la misma versión principal.
Ofrecemos garantías adicionales para los modelos guardados compatibles . Llamamos a un modelo guardado que se creó utilizando solo API no obsoletas, no experimentales y no compatibles en la versión principal de TensorFlow N
un modelo guardado compatible con la versión N
Cualquier modelo guardado compatible con la versión principal N
TensorFlow se puede cargar y ejecutar con la versión principal N+1
TensorFlow. Sin embargo, es posible que la funcionalidad necesaria para crear o modificar dicho modelo ya no esté disponible, por lo que esta garantía solo se aplica al modelo guardado sin modificar.
Nos esforzaremos por preservar la compatibilidad con versiones anteriores el mayor tiempo posible, para que los archivos serializados se puedan utilizar durante largos períodos de tiempo.
Compatibilidad GraphDef
Los gráficos se serializan a través del GraphDef
protocolo GraphDef
. Para facilitar cambios incompatibles con versiones anteriores en los gráficos, cada GraphDef
tiene un número de versión independiente de la versión de TensorFlow. Por ejemplo, GraphDef
versión 17 desaprobó el inv
op a favor del reciprocal
. La semántica es:
Cada versión de TensorFlow admite un intervalo de versiones de
GraphDef
. Este intervalo será constante en las versiones de parches y solo aumentará en las versiones menores. La eliminación de la compatibilidad con una versión deGraphDef
solo ocurrirá para una versión principal de TensorFlow (y solo se alineará con la compatibilidad de la versión garantizada para SavedModels).A los gráficos recién creados se les asigna el último número de versión de
GraphDef
.Si una versión determinada de TensorFlow es compatible con la versión
GraphDef
de un gráfico, se cargará y evaluará con el mismo comportamiento que la versión de TensorFlow que se usó para generarlo (excepto por los detalles numéricos de punto flotante y los números aleatorios como se describe anteriormente), independientemente de la principal versión de TensorFlow. En particular, un GraphDef que sea compatible con un archivo de punto de control en una versión de TensorFlow (como es el caso en un modelo guardado) seguirá siendo compatible con ese punto de control en versiones posteriores, siempre que se admita GraphDef.Tenga en cuenta que esto se aplica solo a los gráficos serializados en GraphDefs (y modelos guardados): el código que lee un punto de control puede no ser capaz de leer los puntos de control generados por el mismo código que ejecuta una versión diferente de TensorFlow.
Si el
GraphDef
superior deGraphDef
aumenta a X en una versión (menor), habrá al menos seis meses antes de que el límite inferior aumente a X. Por ejemplo (aquí estamos usando números de versión hipotéticos):- TensorFlow 1.2 puede ser compatible
GraphDef
versiones 4 a 7 deGraphDef
. - TensorFlow 1.3 podría agregar
GraphDef
versión 8 y admitir las versiones 4 a 8. - Al menos seis meses después, TensorFlow 2.0.0 podría dejar de admitir las versiones 4 a 7, dejando solo la versión 8.
Tenga en cuenta que debido a que las versiones principales de TensorFlow generalmente se publican con más de 6 meses de diferencia, las garantías para los modelos guardados compatibles que se detallan anteriormente son mucho más sólidas que la garantía de 6 meses para GraphDefs.
- TensorFlow 1.2 puede ser compatible
Finalmente, cuando se GraphDef
compatibilidad con una versión de GraphDef
, intentaremos proporcionar herramientas para convertir automáticamente los gráficos a una versión más nueva de GraphDef
compatible.
Compatibilidad de gráficos y puntos de control al extender TensorFlow
Esta sección es relevante solo cuando se realizan cambios incompatibles en el formato GraphDef
, como al agregar operaciones, eliminar operaciones o cambiar la funcionalidad de operaciones existentes. La sección anterior debería ser suficiente para la mayoría de los usuarios.
Compatibilidad con versiones anteriores y posteriores parciales
Nuestro esquema de control de versiones tiene tres requisitos:
- Compatibilidad con versiones anteriores para admitir la carga de gráficos y puntos de control creados con versiones anteriores de TensorFlow.
- Compatibilidad con versiones posteriores para admitir escenarios en los que el productor de un gráfico o punto de control se actualiza a una versión más nueva de TensorFlow antes que el consumidor.
- Habilite la evolución de TensorFlow de formas incompatibles. Por ejemplo, eliminar operaciones, agregar atributos y eliminar atributos.
Tenga en cuenta que, si bien el mecanismo de la versión GraphDef
es independiente de la versión de TensorFlow, los cambios incompatibles con GraphDef
formato GraphDef
aún están restringidos por el control de versiones semántico. Esto significa que la funcionalidad solo se puede eliminar o cambiar entre las versiones MAJOR
de TensorFlow (como la 1.7
a la 2.0
). Además, la compatibilidad con versiones 1.x.1
se aplica en las versiones de parche ( 1.x.1
a 1.x.2
por ejemplo).
Para lograr la compatibilidad con versiones anteriores y posteriores y saber cuándo aplicar cambios en los formatos, los gráficos y los puntos de control tienen metadatos que describen cuándo se produjeron. Las secciones siguientes detallan la implementación de TensorFlow y las pautas para la evolución de GraphDef
versiones de GraphDef
.
Esquemas de versión de datos independientes
Existen diferentes versiones de datos para gráficos y puntos de control. Los dos formatos de datos evolucionan a diferentes velocidades entre sí y también a diferentes velocidades de TensorFlow. Ambos sistemas de control de versiones están definidos en core/public/version.h
. Cada vez que se agrega una nueva versión, se agrega una nota al encabezado que detalla qué cambió y la fecha.
Datos, productores y consumidores
Distinguimos entre los siguientes tipos de información de versión de datos:
- productores : binarios que producen datos. Los productores tienen una versión (
producer
) y una versión mínima para el consumidor con las que son compatibles (min_consumer
). - consumidores : binarios que consumen datos. Los consumidores tienen una versión (
consumer
) y una versión mínima de productor con las que son compatibles (min_producer
).
Cada pieza de datos versionados tiene un campo de VersionDef versions
que registra el producer
que hizo los datos, el min_consumer
que es compatible y una lista de versiones bad_consumers
que no están permitidas.
De forma predeterminada, cuando un productor genera algunos datos, los datos heredan las versiones de producer
y min_consumer
del producer
. bad_consumers
se puede configurar si se sabe que versiones específicas para consumidores contienen errores y deben evitarse. Un consumidor puede aceptar un dato si todo lo siguiente es cierto:
-
consumer
> =min_consumer
de datos -
producer
de datos> =min_producer
del consumidor -
consumer
no enbad_consumers
de datos
Dado que tanto los productores como los consumidores provienen de la misma base de código de TensorFlow, core/public/version.h
contiene una versión de datos principal que se trata como producer
o consumer
según el contexto y tanto min_consumer
como min_producer
(necesarios para productores y consumidores, respectivamente) . Específicamente,
- Para
GraphDef
versiones deGraphDef
, tenemosTF_GRAPH_DEF_VERSION
,TF_GRAPH_DEF_VERSION_MIN_CONSUMER
yTF_GRAPH_DEF_VERSION_MIN_PRODUCER
. - Para las versiones de punto de control, tenemos
TF_CHECKPOINT_VERSION
,TF_CHECKPOINT_VERSION_MIN_CONSUMER
yTF_CHECKPOINT_VERSION_MIN_PRODUCER
.
Agregar un nuevo atributo por defecto a una operación existente
Seguir la guía a continuación le brinda compatibilidad con versiones posteriores solo si el conjunto de operaciones no ha cambiado:
- Si se desea la compatibilidad hacia adelante, establecer
strip_default_attrs
aTrue
al exportar el modelo usando lastf.saved_model.SavedModelBuilder.add_meta_graph_and_variables
ytf.saved_model.SavedModelBuilder.add_meta_graph
métodos de laSavedModelBuilder
clase, otf.estimator.Estimator.export_saved_model
- Esto elimina los atributos valorados por defecto en el momento de producir / exportar los modelos. Esto asegura que el
tf.MetaGraphDef
exportado no contenga el nuevo atributo op cuando se usa el valor predeterminado. - Tener este control podría permitir que los consumidores desactualizados (por ejemplo, sirviendo binarios que se retrasan con respecto a los binarios de entrenamiento) continúen cargando los modelos y eviten interrupciones en el servicio de modelos.
Evolución de las versiones de GraphDef
Esta sección explica cómo utilizar este mecanismo de control de versiones para realizar diferentes tipos de cambios en el formato GraphDef
.
Agregar una operación
Agregue la nueva operación a consumidores y productores al mismo tiempo, y no cambie ninguna versión de GraphDef
. Este tipo de cambio es automáticamente compatible con versiones anteriores y no afecta el plan de compatibilidad futura, ya que los scripts de productor existentes no utilizarán repentinamente la nueva funcionalidad.
Agregue una operación y cambie los envoltorios de Python existentes para usarla
- Implemente una nueva funcionalidad para el consumidor e incremente la versión
GraphDef
. - Si es posible hacer que los contenedores usen la nueva funcionalidad solo en casos que no funcionaban antes, los contenedores se pueden actualizar ahora.
- Cambie los envoltorios de Python para usar la nueva funcionalidad. No incremente
min_consumer
, ya que los modelos que no usan estamin_consumer
no deberían romperse.
Eliminar o restringir la funcionalidad de una operación
- Corrija todas las secuencias de comandos del productor (no TensorFlow en sí) para que no utilicen la operación o la funcionalidad prohibidas.
-
GraphDef
versión deGraphDef
e implemente una nueva funcionalidad para el consumidor queGraphDef
laGraphDef
o funcionalidad eliminada para GraphDefs en la nueva versión y superior. Si es posible, haga que TensorFlow deje de producirGraphDefs
con la funcionalidad prohibida. Para hacerlo, agregueREGISTER_OP(...).Deprecated(deprecated_at_version, message)
. - Espere una versión importante para fines de compatibilidad con versiones anteriores.
- Aumente
min_producer
a la versión GraphDef de (2) y elimine la funcionalidad por completo.
Cambiar la funcionalidad de una operación
- Agregue una nueva operación similar llamada
SomethingV2
o similar y siga el proceso de agregarla y cambiar los envoltorios de Python existentes para usarla. Para garantizar la compatibilidad con versiones posteriores, utilice las comprobaciones sugeridas en compat.py al cambiar las envolturas de Python. - Elimine la operación anterior (solo se puede realizar con un cambio de versión importante debido a la compatibilidad con versiones anteriores).
- Aumente
min_consumer
para descartar a los consumidores con lamin_consumer
anterior, vuelva a agregar lamin_consumer
anterior como un alias paraSomethingV2
y siga el proceso para cambiar los envoltorios de Python existentes para usarlo. - Siga el proceso para eliminar
SomethingV2
.
Prohibir una única versión para el consumidor que no sea segura
-
GraphDef
versión deGraphDef
y agregue la versión incorrecta abad_consumers
para todas las GraphDefs nuevas. Si es posible, agregue abad_consumers
solo para GraphDefs que contenga una determinada operación o similar. - Si los consumidores existentes tienen la versión incorrecta, elimínelos lo antes posible.