Compatibilidad de la versión TensorFlow

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 preservando 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 MAJOR 1, la versión MINOR 2 y la versión PATCH 3. Los cambios en cada número tienen el siguiente significado:

  • PRINCIPAL : Cambios potencialmente incompatibles con versiones anteriores. El código y los datos que funcionaron con una versión importante anterior no necesariamente funcionarán 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 : 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 únicamente 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 Qué está cubierto .

  • PARCHE : Corrección 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.

¿Qué está cubierto?

Solo las API públicas de TensorFlow son compatibles con versiones menores y de parche. Las API públicas constan de

  • Todas las funciones y clases de Python documentadas en el módulo tensorflow y sus submódulos, excepto

    • Símbolos privados: cualquier función, clase, etc., cuyo nombre comience con _
    • Símbolos experimentales y tf.contrib ; consulte a continuación para obtener más detalles.

    Tenga en cuenta que no se puede acceder al código de los directorios examples/ y tools/ a través del módulo tensorflow Python 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 tensorflow Python o sus submódulos, pero no está documentado, entonces no se considera parte de la API pública.

  • 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 característica y no corregiremos errores más que para corregir vulnerabilidades), pero sí están cubiertos por nuestras garantías de compatibilidad.

  • La API de TensorFlow C:

  • Los siguientes archivos de búfer de protocolo:

Número de versión independiente para TensorFlow Lite

Actualmente, TensorFlow Lite se distribuye como parte de TensorFlow. Sin embargo, nos reservamos el derecho de publicar en el futuro cambios en las API de TensorFlow Lite en un cronograma diferente al de las otras API de TensorFlow, o incluso de mover TensorFlow Lite a una distribución de origen separada y/o a un repositorio de origen separado de TensorFlow.

Debido a esto, usamos un número de versión diferente para TensorFlow Lite ( TFLITE_VERSION_STRING en tensorflow/lite/version.h y TfLiteVersion() en tensorflow/lite/c/c_api.h ) que para TensorFlow ( TF_VERSION_STRING en tensorflow/core/public/version.h y TF_Version() en tensorflow/c/c_api.h ). Actualmente, estos dos números de versión tienen el mismo valor. Pero en el futuro pueden divergir; por ejemplo, podemos incrementar el número de versión principal de TensorFlow Lite sin incrementar el número de versión principal de TensorFlow, o viceversa.

La superficie de API cubierta por el número de versión de TensorFlow Lite se compone de las siguientes API públicas:

Los símbolos experimentales no están cubiertos; consulte a continuación para obtener más detalles.

Número de versión independiente para las API de extensión de TensorFlow Lite

TensorFlow Lite proporciona API de C para ampliar el intérprete de TensorFlow Lite con "operaciones personalizadas", que proporcionan operaciones definidas por el usuario en un gráfico, o "delegados", que permiten delegar el cálculo de un gráfico (o de un subconjunto de un gráfico) a un backend personalizado. Estas API, que colectivamente llamamos "API de extensión de TensorFlow Lite", requieren dependencias más íntimas en algunos de los detalles de la implementación de TensorFlow Lite.

Nos reservamos el derecho de publicar en el futuro cambios en estas API, incluidos potencialmente cambios no compatibles con versiones anteriores, en un cronograma diferente al de las otras API de TensorFlow Lite. Por lo tanto, utilizamos un número de versión diferente para las API de extensión de TensorFlow Lite que los números de versión de TensorFlow Lite o TensorFlow (que se describieron en la sección anterior). Estamos introduciendo algunas API nuevas en la versión 2.15 de TensorFlow Lite para obtener la versión de las API de extensión de TensorFlow Lite ( TFLITE_EXTENSION_APIS_VERSION_STRING en tensorflow/lite/version.h y TfLiteExtensionApisVersion() en tensorflow/lite/c/c_api.h ). El número de versión de las API de extensión de TensorFlow Lite es actualmente el mismo que el número de versión de TensorFlow y TensorFlow Lite. Pero en el futuro pueden divergir; por ejemplo, podemos incrementar el número de versión principal de las API de extensión de TensorFlow Lite sin incrementar el número de versión principal de TensorFlow Lite, o viceversa.

La superficie de API cubierta por el número de versión de las API de extensión de TensorFlow Lite se compone de las siguientes API públicas:

*   [tensorflow/lite/c/c_api_opaque.h](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/c/c_api_opaque.h)
*   [tensorflow/lite/c/common.h](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/c/common.h)
*   [tensorflow/lite/c/builtin_op_data.h](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/c/builtin_op_data.h)
*   [tensorflow/lite/builtin_ops.h](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/builtin_ops.h)

Nuevamente, los símbolos experimentales no están cubiertos; consulte a continuación para obtener más detalles.

Lo que no está cubierto

Algunas partes de TensorFlow pueden cambiar de manera incompatible 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, no están cubiertos por ninguna garantía de compatibilidad los siguientes productos:

    • cualquier símbolo en el módulo tf.contrib o sus submódulos;
    • cualquier símbolo (módulo, función, argumento, propiedad, clase, constante, tipo, paquete, etc.) cuyo nombre contenga experimental o Experimental ; o
    • cualquier símbolo cuyo nombre completo incluya un módulo, clase o paquete que sea en sí mismo experimental. Esto incluye campos y submensajes de cualquier buffer de protocolo llamado experimental .
  • Otros lenguajes : API de TensorFlow en lenguajes distintos de Python y C, como:

    y API de TensorFlow Lite en lenguajes distintos de Java/Kotlin, C, Objective-C y Swift, en particular

  • 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 fallen en versiones menores, aunque el comportamiento del gráfico no debería 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 operaciones pueden cambiar en cualquier momento. Los usuarios deben confiar únicamente 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 una mayor precisión 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 únicamente en distribuciones aproximadamente correctas y en la solidez 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 conexión.

  • Errores: Nos reservamos el derecho de realizar cambios en el comportamiento incompatible con versiones anteriores (aunque no en la 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 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, entonces arreglaremos el optimizador. Nuestra solución puede romper el código dependiendo de un comportamiento incorrecto para la convergencia. Notaremos dichos cambios en las notas de la versión.

  • API no utilizada: nos reservamos el derecho de realizar cambios incompatibles con versiones anteriores de 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 Announce@ , brindando instrucciones sobre cómo solucionar cualquier rotura (si corresponde) y esperaremos dos semanas para brindarle 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 en la documentación se especifique el tipo de excepción para una condición de error específica.

Compatibilidad de SavedModels, gráficos y puntos de control.

SavedModel es el formato de serialización preferido para usar en programas de TensorFlow. Los SavedModels 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 tensoriales guardados de las variables en un gráfico.

Muchos usuarios de TensorFlow crean SavedModels y los cargan y ejecutan con una versión posterior de TensorFlow. De conformidad con semver , los 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 SavedModels compatibles . A un SavedModel que se creó utilizando solo API no obsoletas, no experimentales y no compatibles en la versión principal N de TensorFlow lo llamamos SavedModel compatible con la versión N Cualquier SavedModel 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 necesaria para construir o modificar dicho modelo ya no esté disponible, por lo que esta garantía solo se aplica al SavedModel no modificado.

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 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, la versión 17 GraphDef desaprobó la operación inv en favor de reciprocal . La semántica es:

  • Cada versión de TensorFlow admite un intervalo de versiones de GraphDef . Este intervalo será constante en todas las versiones de parches y solo crecerá en versiones menores. La eliminación del soporte para una versión GraphDef solo se producirá para una versión principal de TensorFlow (y solo se alineará con el soporte de versión garantizado para SavedModels).

  • 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 admite 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 punto flotante y los números aleatorios como se describió anteriormente), independientemente de la principal. versión de TensorFlow. En particular, un GraphDef que es compatible con un archivo de punto de control en una versión de TensorFlow (como es el caso de un SavedModel) seguirá siendo compatible con ese punto de control en versiones posteriores, siempre que GraphDef sea compatible.

    Tenga en cuenta que esto se aplica solo a gráficos serializados en GraphDefs (y SavedModels): 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 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 (aquí usamos números de versión hipotéticos):

    • TensorFlow 1.2 podría admitir las versiones 4 a 7 GraphDef .
    • 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 SavedModels compatibles detalladas anteriormente son mucho más sólidas que la garantía de 6 meses para GraphDefs.

Finalmente, cuando se elimine la compatibilidad con una versión GraphDef , intentaremos proporcionar herramientas para convertir automáticamente gráficos a una versión más nueva 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 hacia atrás y hacia adelante parcial

Nuestro esquema 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 formas incompatibles. Por ejemplo, eliminar operaciones, agregar atributos y eliminar atributos.

Tenga en cuenta que, si bien el mecanismo de versión GraphDef está separado de la versión TensorFlow, los cambios incompatibles con versiones anteriores en el formato GraphDef aún están restringidos por el control de versiones semántica. Esto significa que la funcionalidad solo se puede eliminar o cambiar entre las versiones MAJOR de TensorFlow (como 1.7 a 2.0 ). Además, la compatibilidad con versiones posteriores se aplica en las versiones de parches ( 1.x.1 a 1.x.2 por ejemplo).

Para lograr 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 las versiones 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 ritmos diferentes entre sí y también a ritmos diferentes de TensorFlow. Ambos sistemas 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 los cambios 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 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 producer y min_consumer del productor. bad_consumers se puede configurar si se sabe que versiones específicas para el consumidor contienen errores y deben evitarse. Un consumidor puede aceptar un dato si se cumple todo lo siguiente:

  • consumer >= min_consumer de datos
  • producer de datos >= min_producer del consumidor
  • consumer no está en bad_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 dependiendo del contexto y tanto min_consumer como min_producer (necesarios para los productores y consumidores, respectivamente). . Específicamente,

  • Para las versiones GraphDef , tenemos TF_GRAPH_DEF_VERSION , TF_GRAPH_DEF_VERSION_MIN_CONSUMER y TF_GRAPH_DEF_VERSION_MIN_PRODUCER .
  • Para las versiones de puntos de control, tenemos TF_CHECKPOINT_VERSION , TF_CHECKPOINT_VERSION_MIN_CONSUMER y TF_CHECKPOINT_VERSION_MIN_PRODUCER .

Agregar un nuevo atributo predeterminado a una operación existente

Seguir las instrucciones a continuación le brinda compatibilidad hacia adelante solo si el conjunto de operaciones no ha cambiado:

  1. Si desea compatibilidad con versiones posteriores, establezca strip_default_attrs en True mientras exporta el modelo utilizando los métodos tf.saved_model.SavedModelBuilder.add_meta_graph_and_variables y tf.saved_model.SavedModelBuilder.add_meta_graph de la clase SavedModelBuilder , o tf.estimator.Estimator.export_saved_model
  2. Esto elimina los atributos valorados por defecto al momento de producir/exportar los modelos. Esto garantiza que el tf.MetaGraphDef exportado no contenga el nuevo atributo de operación cuando se utiliza el valor predeterminado.
  3. Tener este control podría permitir que los consumidores obsoletos (por ejemplo, servidores binarios que van por detrás de los binarios de entrenamiento) continúen cargando los modelos y eviten interrupciones en el servicio de modelos.

Versiones de GraphDef en evolución

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 futura, ya que los scripts de productor existentes no utilizarán repentinamente la nueva funcionalidad.

Agregue una operación y cambie los contenedores de Python existentes para usarlos

  1. Implemente una nueva funcionalidad para el consumidor e incremente la versión GraphDef .
  2. Si es posible hacer que los contenedores utilicen la nueva funcionalidad solo en casos que no funcionaban antes, los contenedores se pueden actualizar ahora.
  3. 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

  1. Corrija todos los scripts de productor (no TensorFlow) para no utilizar la operación o funcionalidad prohibida.
  2. Incrementar la versión GraphDef e implementar una nueva funcionalidad para el consumidor que prohíba la operación o funcionalidad eliminada para GraphDefs en la nueva versión y superiores. Si es posible, haga que TensorFlow deje de producir GraphDefs con la funcionalidad prohibida. Para hacerlo, agregue REGISTER_OP(...).Deprecated(deprecated_at_version, message) .
  3. Espere una versión importante por motivos de compatibilidad con versiones anteriores.
  4. Aumente min_producer a la versión GraphDef desde (2) y elimine la funcionalidad por completo.

Cambiar la funcionalidad de una operación

  1. Agregue una nueva operación similar llamada SomethingV2 o similar y siga el proceso de agregarla y cambiar los contenedores de Python existentes para usarlo. Para garantizar la compatibilidad futura, utilice las comprobaciones sugeridas en compat.py al cambiar los contenedores de Python.
  2. Elimine la operación anterior (solo puede realizarse con un cambio importante de versión debido a la compatibilidad con versiones anteriores).
  3. Aumente min_consumer para descartar consumidores con la operación anterior, vuelva a agregar la operación anterior como alias para SomethingV2 y siga el proceso para cambiar los contenedores de Python existentes para usarlo.
  4. Realice el proceso para eliminar SomethingV2 .

Prohibir una única versión no segura para el consumidor

  1. Elimine la versión GraphDef y agregue la versión incorrecta a bad_consumers para todos los GraphDefs nuevos. Si es posible, agregue a bad_consumers solo para GraphDefs que contengan una determinada operación o similar.
  2. Si los consumidores existentes tienen la versión mala, elimínelos lo antes posible.