Este documento es para usuarios que necesitan compatibilidad con versiones anteriores de TensorFlow (ya sea para código o datos) y para desarrolladores que desean modificar TensorFlow conservando la compatibilidad.
Versionado 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, la versión 1.2.3 de TensorFlow tiene la versión 1 MAJOR
, la versión 2 MINOR
y la versión 3 PATCH
. Los cambios en cada número tienen el siguiente significado:
PRINCIPAL : Cambios potencialmente incompatibles con versiones anteriores. El código y los datos que funcionaban con una versión principal anterior no funcionarán necesariamente con la nueva versión. Sin embargo, en algunos casos, los gráficos y puntos de control existentes de TensorFlow pueden migrarse 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 : características 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 seguirán funcionando sin cambios. Para obtener detalles sobre qué es y qué no es la API pública, consulte Lo que se cubre .
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 retrocompatible con la versión 1.0.0.
que esta cubierto
Solo las API públicas de TensorFlow son compatibles con versiones anteriores en versiones secundarias y parches. Las API públicas consisten en
Todas las funciones y clases de Python documentadas en el módulo
tensorflow
y sus submódulos, a excepción de- Símbolos privados: cualquier función, clase, etc., cuyo nombre comience con
_
- Símbolos experimentales y
tf.contrib
, consulte los detalles a continuación .
Tenga en cuenta que no se puede acceder al código en los directorios Examples
examples/
y Toolstools/
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 del módulo Python de
tensorflow
o sus submódulos, pero no está documentado, 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 terminales adicionales para ayudar a los usuarios con la transición a una nueva versión principal. Estos símbolos de API están en desuso y no son compatibles (es decir, no agregaremos ninguna función y no corregiremos errores que no sean vulnerabilidades), pero se incluyen en nuestras garantías de compatibilidad.La API de C.
Los siguientes archivos de búfer de protocolo:
Lo que no está cubierto
Algunas partes de TensorFlow pueden cambiar de formas incompatibles con versiones anteriores en cualquier punto. Éstos incluyen:
API experimentales : para facilitar el desarrollo, excluimos algunos símbolos de API claramente marcados como experimentales de las garantías de compatibilidad. 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
; o - cualquier 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 idiomas : API de TensorFlow en idiomas 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 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 punto flotante: los valores de punto flotante específicos calculados por ops 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 parches deberían dar como resultado una precisión comparable o mejorada, con la advertencia 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 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 información.
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 incompatibles con versiones anteriores (aunque no de API) si la implementación actual está claramente rota, es decir, si contradice la documentación o si un comportamiento previsto conocido y bien definido no se implementa correctamente debido a un error Por ejemplo, si un optimizador afirma implementar un algoritmo de optimización bien conocido pero no coincide con ese algoritmo debido a un error, entonces arreglaremos el optimizador. Nuestra solución puede romper el código basándose en el comportamiento incorrecto para la convergencia. Tomaremos nota de dichos cambios en las notas de la versión.
API no utilizada: Nos reservamos el derecho de realizar cambios incompatibles con versiones anteriores en las API para las que no encontramos usos documentados (realizando 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 Announce@ , brindando instrucciones sobre cómo abordar cualquier falla (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 sea 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 de cambiar el texto de los mensajes de error. Además, el tipo de error puede cambiar a menos que el tipo de excepción para una condición de error específica se especifique en la documentación.
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. Los modelos guardados contienen 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 conformidad con semver , los modelos guardados 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 admitidos . Llamamos a un modelo guardado que se creó usando 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
de TensorFlow se puede cargar y ejecutar con la versión principal N+1
de TensorFlow. Sin embargo, es posible que la funcionalidad requerida para construir 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, de modo que los archivos serializados se puedan utilizar durante largos períodos de tiempo.
Compatibilidad con GraphDef
Los gráficos se serializan a través del búfer del protocolo GraphDef
. Para facilitar los cambios incompatibles con versiones anteriores de 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ó inv
op a favor de reciprocal
. La semántica es:
Cada versión de TensorFlow admite un intervalo de versiones de
GraphDef
. Este intervalo será constante entre los lanzamientos de parches y solo aumentará entre los lanzamientos 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 los modelos guardados).A los gráficos recién creados se les asigna el último número de versión
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 utilizada para generarlo (excepto los detalles numéricos de coma 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 de 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 gráficos serializados en GraphDefs (y modelos guardados): es posible que el código que lee un punto de control no pueda leer los puntos de control generados por el mismo código que ejecuta una versión diferente de TensorFlow.
Si el límite superior de
GraphDef
aumenta a X en una versión (menor), pasarán al menos seis meses antes de que el límite inferior aumente a X. Por ejemplo (estamos usando números de versión hipotéticos aquí):- TensorFlow 1.2 podría ser compatible con las versiones 4 a 7 de
GraphDef
. - TensorFlow 1.3 podría agregar la versión 8 de
GraphDef
y admitir las versiones 4 a 8. - Al menos seis meses después, TensorFlow 2.0.0 podría eliminar la compatibilidad con 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 detalladas anteriormente son mucho más sólidas que la garantía de 6 meses para GraphDefs.
- TensorFlow 1.2 podría ser compatible con las versiones 4 a 7 de
Finalmente, cuando se elimine la compatibilidad con una versión de GraphDef
, intentaremos proporcionar herramientas para convertir automáticamente los gráficos a una versión GraphDef
compatible más reciente.
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 cuando se agregan operaciones, se eliminan operaciones o se cambia la funcionalidad de las operaciones existentes. La sección anterior debería ser suficiente para la mayoría de los usuarios.
Compatibilidad con versiones anteriores y parciales hacia adelante
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 futura 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 maneras incompatibles. Por ejemplo, eliminar operaciones, agregar atributos y eliminar atributos.
Tenga en cuenta que, si bien el mecanismo de la versión de GraphDef
es independiente de la versión de TensorFlow, los cambios incompatibles con versiones anteriores del formato de 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 versiones MAJOR
de TensorFlow (como 1.7
a 2.0
). Además, la compatibilidad con versiones anteriores se aplica dentro de las versiones de parches ( 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 siguientes secciones detallan la implementación de TensorFlow y las pautas para la evolución de las versiones de GraphDef
.
Esquemas de versiones de datos independientes
Hay diferentes versiones de datos para gráficos y puntos de control. Los dos formatos de datos evolucionan a ritmos diferentes entre sí y también a ritmos diferentes 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 de consumidor con la 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 la que son compatibles (min_producer
).
Cada pieza de datos versionados tiene un campo de VersionDef versions
que registra el producer
que creó los datos, el min_consumer
con el que es compatible y una lista de versiones de bad_consumers
que no están permitidas.
De forma predeterminada, cuando un productor crea algunos datos, los datos heredan las versiones de producer
y min_consumer
del productor. bad_consumers
se puede configurar si se sabe que las versiones específicas del consumidor 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 min_consumer
y min_producer
(necesitados por productores y consumidores, respectivamente) . Específicamente,
- Para las versiones de
GraphDef
, 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
.
Agregue un nuevo atributo con valor predeterminado a una operación existente
Seguir la guía a continuación le brinda compatibilidad hacia adelante solo si el conjunto de operaciones no ha cambiado:
- Si se desea compatibilidad con versiones anteriores, establezca
strip_default_attrs
enTrue
al exportar el modelo usando los métodostf.saved_model.SavedModelBuilder.add_meta_graph_and_variables
ytf.saved_model.SavedModelBuilder.add_meta_graph
de la claseSavedModelBuilder
, 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 van a la zaga de los binarios de entrenamiento) continúen cargando los modelos y evitando 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 tanto a los consumidores como a los productores al mismo tiempo, y no cambie ninguna versión GraphDef
. Este tipo de cambio es automáticamente compatible con versiones anteriores y no afecta el plan de compatibilidad con versiones anteriores, ya que los scripts de productores existentes no utilizarán repentinamente la nueva funcionalidad.
Agregue una operación y cambie los envoltorios de Python existentes para usarlo
- Implemente una nueva funcionalidad de consumidor e incremente la versión de
GraphDef
. - Si es posible hacer que los wrappers usen la nueva funcionalidad solo en casos que no funcionaban antes, los wrappers se pueden actualizar ahora.
- Cambie los contenedores de Python para usar la nueva funcionalidad. No incremente
min_consumer
, ya que los modelos que no usan esta operación no deberían fallar.
Eliminar o restringir la funcionalidad de una operación
- Corrija todos los scripts de producción (no TensorFlow en sí) para que no usen la operación o funcionalidad prohibida.
- Incremente la versión de
GraphDef
e implemente una nueva funcionalidad para el consumidor que prohíba la operación 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 principal para fines de compatibilidad con versiones anteriores.
- Aumente
min_producer
a la versión de GraphDef desde (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 realice el proceso de agregarla y cambiar los contenedores de Python existentes para usarla. Para garantizar la compatibilidad con versiones posteriores, utilice las comprobaciones sugeridas en compat.py al cambiar los contenedores de Python. - Elimine la operación anterior (solo puede tener lugar con un cambio de versión importante debido a la compatibilidad con versiones anteriores).
- Aumente
min_consumer
para descartar consumidores con la operación anterior, vuelva a agregar la operación anterior como un alias paraSomethingV2
y siga el proceso para cambiar los contenedores de Python existentes para usarlo. - Realice el proceso para eliminar
SomethingV2
.
Prohibir una única versión insegura para el consumidor
- Mejora la versión de
GraphDef
y agrega la versión incorrecta abad_consumers
para todos los GraphDef nuevos. Si es posible, agregue abad_consumers
solo para GraphDefs que contengan una determinada operación o similar. - Si los consumidores existentes tienen la versión mala, sáquelos lo antes posible.