Compatibilità della versione di TensorFlow

Questo documento è rivolto agli utenti che necessitano di compatibilità con le versioni precedenti tra diverse versioni di TensorFlow (per codice o dati) e per gli sviluppatori che desiderano modificare TensorFlow preservando la compatibilità.

Versionamento semantico 2.0

TensorFlow segue il Semantic Versioning 2.0 ( semver ) per la sua API pubblica. Ogni versione di TensorFlow ha il formato MAJOR.MINOR.PATCH . Ad esempio, la versione 1.2.3 di TensorFlow ha la versione MAJOR 1, la versione MINOR 2 e la versione PATCH 3. Le modifiche a ciascun numero hanno il seguente significato:

  • MAJOR : modifiche potenzialmente incompatibili con le versioni precedenti. Il codice e i dati che funzionavano con una versione principale precedente non funzioneranno necessariamente con la nuova versione. Tuttavia, in alcuni casi i grafici e i checkpoint TensorFlow esistenti potrebbero essere migrabili alla versione più recente; vedere Compatibilità di grafici e punti di controllo per dettagli sulla compatibilità dei dati.

  • MINOR : funzionalità retrocompatibili, miglioramenti della velocità, ecc. Il codice e i dati che funzionavano con una versione minore precedente e che dipendono solo dall'API pubblica non sperimentale continueranno a funzionare invariati. Per informazioni dettagliate su cos'è e cosa non è l'API pubblica, vedere Cosa è coperto .

  • PATCH : correzioni di bug compatibili con le versioni precedenti.

Ad esempio, la versione 1.0.0 ha introdotto modifiche incompatibili con le versioni precedenti rispetto alla versione 0.12.1. Tuttavia, la versione 1.1.1 era retrocompatibile con la versione 1.0.0.

Cosa è coperto

Solo le API pubbliche di TensorFlow sono retrocompatibili con le versioni minori e patch. Le API pubbliche sono costituite da

  • Tutte le funzioni e le classi Python documentate nel modulo tensorflow e nei suoi sottomoduli, ad eccezione di

    • Simboli privati: qualsiasi funzione, classe, ecc., il cui nome inizia con _
    • Simboli sperimentali e tf.contrib , vedere sotto per i dettagli.

    Tieni presente che il codice nelle directory examples/ e tools/ non è raggiungibile tramite il modulo tensorflow Python e quindi non è coperto dalla garanzia di compatibilità.

    Se un simbolo è disponibile tramite il modulo tensorflow Python o i suoi sottomoduli, ma non è documentato, non è considerato parte dell'API pubblica.

  • L'API di compatibilità (in Python, il modulo tf.compat ). Nelle versioni principali, potremmo rilasciare utilità ed endpoint aggiuntivi per aiutare gli utenti nella transizione a una nuova versione principale. Questi simboli API sono deprecati e non supportati (ovvero, non aggiungeremo alcuna funzionalità e non correggeremo bug se non per correggere le vulnerabilità), ma rientrano nelle nostre garanzie di compatibilità.

  • L'API TensorFlow C:

  • I seguenti file buffer del protocollo:

Numero di versione separato per TensorFlow Lite

Attualmente TensorFlow Lite è distribuito come parte di TensorFlow. Tuttavia, ci riserviamo il diritto di rilasciare in futuro modifiche alle API TensorFlow Lite secondo una pianificazione diversa rispetto alle altre API TensorFlow, o anche di spostare TensorFlow Lite in una distribuzione sorgente separata e/o in un repository sorgente separato rispetto a TensorFlow.

Per questo motivo, utilizziamo un numero di versione diverso per TensorFlow Lite ( TFLITE_VERSION_STRING in tensorflow/lite/version.h e TfLiteVersion() in tensorflow/lite/c/c_api.h ) rispetto a TensorFlow ( TF_VERSION_STRING in tensorflow/core/public/version.h e TF_Version() in tensorflow/c/c_api.h ). Attualmente, questi due numeri di versione hanno lo stesso valore. Ma in futuro potrebbero divergere; ad esempio, potremmo incrementare il numero della versione principale per TensorFlow Lite senza incrementare il numero della versione principale per TensorFlow o viceversa.

La superficie API coperta dal numero di versione di TensorFlow Lite è composta dalle seguenti API pubbliche:

I simboli sperimentali non sono coperti; vedere sotto per i dettagli.

Numero di versione separato per le API di estensione TensorFlow Lite

TensorFlow Lite fornisce API C per estendere l'interprete TensorFlow Lite con "operazioni personalizzate", che forniscono operazioni definite dall'utente in un grafico, o "delegati", che consentono di delegare il calcolo per un grafico (o per un sottoinsieme di un grafico) a un backend personalizzato. Queste API, che collettivamente chiamiamo "API di estensione TensorFlow Lite", richiedono dipendenze più intime su alcuni dettagli dell'implementazione di TensorFlow Lite.

Ci riserviamo il diritto di rilasciare in futuro modifiche a queste API, includendo potenzialmente modifiche non compatibili con le versioni precedenti, secondo un programma diverso rispetto alle altre API TensorFlow Lite. Pertanto utilizziamo un numero di versione diverso per le API di estensione TensorFlow Lite rispetto ai numeri di versione per TensorFlow Lite o TensorFlow (descritti nella sezione precedente). Stiamo introducendo alcune nuove API in TensorFlow Lite versione 2.15 per ottenere la versione delle API di estensione TensorFlow Lite ( TFLITE_EXTENSION_APIS_VERSION_STRING in tensorflow/lite/version.h e TfLiteExtensionApisVersion() in tensorflow/lite/c/c_api.h ). Il numero di versione delle API di estensione TensorFlow Lite è attualmente lo stesso del numero di versione di TensorFlow e TensorFlow Lite. Ma in futuro potrebbero divergere; ad esempio, potremmo incrementare il numero di versione principale per le API di estensione TensorFlow Lite senza incrementare il numero di versione principale per TensorFlow Lite o viceversa.

La superficie API coperta dal numero di versione delle API di estensione TensorFlow Lite comprende le seguenti API pubbliche:

Ancora una volta, i simboli sperimentali non sono trattati; vedere sotto per i dettagli.

Cosa non è coperto

Alcune parti di TensorFlow possono cambiare in modi incompatibili con le versioni precedenti in qualsiasi momento. Questi includono:

  • API sperimentali : per facilitare lo sviluppo, esentiamo dalle garanzie di compatibilità alcuni simboli API chiaramente contrassegnati come sperimentali. In particolare non sono coperti da alcuna garanzia di compatibilità:

    • qualsiasi simbolo nel modulo tf.contrib o nei suoi sottomoduli;
    • qualsiasi simbolo (modulo, funzione, argomento, proprietà, classe, costante, tipo, pacchetto, ecc.) il cui nome contiene experimental o Experimental ; O
    • qualsiasi simbolo il cui nome completo includa un modulo, una classe o un pacchetto che è esso stesso sperimentale. Ciò include campi e sottomessaggi di qualsiasi buffer di protocollo chiamato experimental .
  • Altri linguaggi : API TensorFlow in linguaggi diversi da Python e C, come:

    e API TensorFlow Lite in linguaggi diversi da Java/Kotlin, C, Objective-C e Swift, in particolare

  • Dettagli delle operazioni composite: molte funzioni pubbliche in Python si espandono in diverse operazioni primitive nel grafico e questi dettagli faranno parte di qualsiasi grafico salvato su disco come GraphDef s. Questi dettagli potrebbero cambiare per versioni minori. In particolare, i test di regressione che controllano l'esatta corrispondenza tra i grafici probabilmente non funzioneranno nei rilasci minori, anche se il comportamento del grafico dovrebbe rimanere invariato e i checkpoint esistenti continueranno a funzionare.

  • Dettagli numerici in virgola mobile: i valori specifici in virgola mobile calcolati da ops possono cambiare in qualsiasi momento. Gli utenti dovrebbero fare affidamento solo sulla precisione approssimativa e sulla stabilità numerica, non sui bit specifici calcolati. Le modifiche alle formule numeriche nelle versioni minori e nelle patch dovrebbero comportare una precisione comparabile o migliorata, con l'avvertenza che nell'apprendimento automatico una maggiore precisione di formule specifiche può comportare una diminuzione della precisione per il sistema complessivo.

  • Numeri casuali: i numeri casuali specifici calcolati possono cambiare in qualsiasi momento. Gli utenti dovrebbero fare affidamento solo su distribuzioni e forza statistica approssimativamente corrette, non sui bit specifici calcolati. Consulta la guida alla generazione di numeri casuali per i dettagli.

  • Differenza di versione in Tensorflow distribuito: l'esecuzione di due diverse versioni di TensorFlow in un singolo cluster non è supportata. Non ci sono garanzie sulla compatibilità con le versioni precedenti del protocollo wire.

  • Bug: ci riserviamo il diritto di apportare modifiche al comportamento incompatibile con le versioni precedenti (anche se non all'API) se l'implementazione corrente è chiaramente interrotta, ovvero se contraddice la documentazione o se un comportamento previsto ben noto e ben definito non è implementato correttamente a causa ad un bug. Ad esempio, se un ottimizzatore afferma di implementare un noto algoritmo di ottimizzazione ma non corrisponde a tale algoritmo a causa di un bug, correggeremo l'ottimizzatore. La nostra soluzione potrebbe danneggiare il codice basandosi sul comportamento sbagliato per la convergenza. Annoteremo tali modifiche nelle note di rilascio.

  • API non utilizzate: ci riserviamo il diritto di apportare modifiche incompatibili con le versioni precedenti alle API per le quali non troviamo usi documentati (eseguendo il controllo dell'utilizzo di TensorFlow tramite la ricerca GitHub). Prima di apportare tali modifiche, annunceremo la nostra intenzione di apportare la modifica sulla mailing list annuncia@ , fornendo istruzioni su come affrontare eventuali interruzioni (se applicabile) e attenderemo due settimane per dare alla nostra comunità la possibilità di condividere il proprio feedback. .

  • Comportamento di errore: potremmo sostituire gli errori con comportamenti non di errore. Ad esempio, potremmo modificare una funzione per calcolare un risultato invece di generare un errore, anche se tale errore è documentato. Ci riserviamo inoltre il diritto di modificare il testo dei messaggi di errore. Inoltre, il tipo di errore può cambiare a meno che nella documentazione non sia specificato il tipo di eccezione per una specifica condizione di errore.

Compatibilità di SavedModels, grafici e checkpoint

SavedModel è il formato di serializzazione preferito da utilizzare nei programmi TensorFlow. SavedModels contiene due parti: uno o più grafici codificati come GraphDefs e un Checkpoint. I grafici descrivono il flusso di dati delle operazioni da eseguire e i checkpoint contengono i valori tensoriali salvati delle variabili in un grafico.

Molti utenti di TensorFlow creano SavedModel e li caricano ed eseguono con una versione successiva di TensorFlow. In conformità con semver , i SavedModel scritti con una versione di TensorFlow possono essere caricati e valutati con una versione successiva di TensorFlow con la stessa versione principale.

Forniamo ulteriori garanzie per i SavedModels supportati . Chiamiamo SavedModel che è stato creato utilizzando solo API non deprecate, non sperimentali e non compatibili nella versione principale di TensorFlow N come SavedModel supportato nella versione N . Qualsiasi SavedModel supportato nella versione principale di TensorFlow N può essere caricato ed eseguito con la versione principale di TensorFlow N+1 . Tuttavia, la funzionalità richiesta per creare o modificare tale modello potrebbe non essere più disponibile, quindi questa garanzia si applica solo al SavedModel non modificato.

Cercheremo di preservare la compatibilità con le versioni precedenti il ​​più a lungo possibile, in modo che i file serializzati siano utilizzabili per lunghi periodi di tempo.

Compatibilità GraphDef

I grafici vengono serializzati tramite il buffer del protocollo GraphDef . Per facilitare modifiche ai grafici incompatibili con le versioni precedenti, ogni GraphDef ha un numero di versione separato dalla versione di TensorFlow. Ad esempio, la versione 17 GraphDef ha deprecato inv op a favore di reciprocal . La semantica è:

  • Ogni versione di TensorFlow supporta un intervallo di versioni GraphDef . Questo intervallo sarà costante tra i rilasci delle patch e aumenterà solo tra i rilasci minori. L'eliminazione del supporto per una versione GraphDef avverrà solo per una versione principale di TensorFlow (e solo in linea con il supporto della versione garantito per SavedModels).

  • Ai grafici appena creati viene assegnato il numero di versione GraphDef più recente.

  • Se una determinata versione di TensorFlow supporta la versione GraphDef di un grafico, verrà caricata e valutata con lo stesso comportamento della versione TensorFlow utilizzata per generarlo (ad eccezione dei dettagli numerici in virgola mobile e dei numeri casuali come descritto sopra), indipendentemente dai principali versione di TensorFlow. In particolare, un GraphDef compatibile con un file checkpoint in una versione di TensorFlow (come nel caso di un SavedModel) rimarrà compatibile con quel checkpoint nelle versioni successive, purché GraphDef sia supportato.

    Tieni presente che questo si applica solo ai grafici serializzati in GraphDefs (e SavedModels): il codice che legge un checkpoint potrebbe non essere in grado di leggere i checkpoint generati dallo stesso codice che esegue una versione diversa di TensorFlow.

  • Se il limite superiore GraphDef viene aumentato a X in una versione (minore), ci vorranno almeno sei mesi prima che il limite inferiore venga aumentato a X. Ad esempio (qui stiamo utilizzando numeri di versione ipotetici):

    • TensorFlow 1.2 potrebbe supportare le versioni GraphDef dalla 4 alla 7.
    • TensorFlow 1.3 potrebbe aggiungere GraphDef versione 8 e supportare le versioni da 4 a 8.
    • Almeno sei mesi dopo, TensorFlow 2.0.0 potrebbe eliminare il supporto per le versioni dalla 4 alla 7, lasciando solo la versione 8.

    Tieni presente che, poiché le versioni principali di TensorFlow vengono generalmente pubblicate a più di 6 mesi di distanza, le garanzie per i SavedModel supportati descritte sopra sono molto più forti della garanzia di 6 mesi per GraphDefs.

Infine, quando il supporto per una versione GraphDef verrà interrotto, cercheremo di fornire strumenti per convertire automaticamente i grafici in una versione GraphDef supportata più recente.

Compatibilità di grafici e checkpoint durante l'estensione di TensorFlow

Questa sezione è rilevante solo quando si apportano modifiche incompatibili al formato GraphDef , ad esempio quando si aggiungono operazioni, si rimuovono operazioni o si modifica la funzionalità di operazioni esistenti. La sezione precedente dovrebbe essere sufficiente per la maggior parte degli utenti.

Compatibilità con le versioni precedenti e parziali

Il nostro schema di controllo delle versioni ha tre requisiti:

  • Compatibilità con le versioni precedenti per supportare il caricamento di grafici e checkpoint creati con versioni precedenti di TensorFlow.
  • Compatibilità futura per supportare scenari in cui il produttore di un grafico o un checkpoint viene aggiornato a una versione più recente di TensorFlow prima del consumatore.
  • Abilita l'evoluzione di TensorFlow in modi incompatibili. Ad esempio, rimuovere operazioni, aggiungere attributi e rimuovere attributi.

Tieni presente che mentre il meccanismo della versione GraphDef è separato dalla versione TensorFlow, le modifiche incompatibili con le versioni precedenti al formato GraphDef sono ancora limitate dal controllo delle versioni semantico. Ciò significa che la funzionalità può essere rimossa o modificata solo tra le versioni MAJOR di TensorFlow (da 1.7 a 2.0 ). Inoltre, la compatibilità futura viene applicata all'interno dei rilasci delle patch ( 1.x.1 a 1.x.2 ad esempio).

Per ottenere la compatibilità con le versioni precedenti e successive e sapere quando applicare le modifiche ai formati, i grafici e i checkpoint dispongono di metadati che descrivono quando sono stati prodotti. Le sezioni seguenti descrivono in dettaglio l'implementazione di TensorFlow e le linee guida per l'evoluzione delle versioni GraphDef .

Schemi di versione dei dati indipendenti

Esistono diverse versioni di dati per grafici e checkpoint. I due formati di dati si evolvono a velocità diverse l'uno dall'altro e anche a velocità diverse da TensorFlow. Entrambi i sistemi di versione sono definiti in core/public/version.h . Ogni volta che viene aggiunta una nuova versione, viene aggiunta una nota all'intestazione che descrive in dettaglio cosa è cambiato e la data.

Dati, produttori e consumatori

Distinguiamo tra i seguenti tipi di informazioni sulla versione dei dati:

  • produttori : binari che producono dati. I produttori hanno una versione ( producer ) e una versione consumer minima con cui sono compatibili ( min_consumer ).
  • consumatori : binari che consumano dati. I consumatori hanno una versione ( consumer ) e una versione minima del produttore con cui sono compatibili ( min_producer ).

Ogni dato con versione ha un campo VersionDef versions che registra il producer che ha creato i dati, il min_consumer con cui è compatibile e un elenco di versioni bad_consumers non consentite.

Per impostazione predefinita, quando un produttore crea dei dati, i dati ereditano le versioni producer e min_consumer del produttore. bad_consumers può essere impostato se è noto che versioni consumer specifiche contengono bug e devono essere evitate. Un consumatore può accettare un dato se sono vere tutte le seguenti condizioni:

  • consumer >= min_consumer dei dati
  • producer dei dati >= min_producer del consumatore
  • consumer non in bad_consumers dei dati

Poiché sia ​​i produttori che i consumatori provengono dalla stessa base di codice TensorFlow, core/public/version.h contiene una versione dei dati principale che viene trattata come producer o consumer a seconda del contesto e sia min_consumer che min_producer (necessari rispettivamente ai produttori e ai consumatori) . Nello specifico,

  • Per le versioni GraphDef , abbiamo TF_GRAPH_DEF_VERSION , TF_GRAPH_DEF_VERSION_MIN_CONSUMER e TF_GRAPH_DEF_VERSION_MIN_PRODUCER .
  • Per le versioni checkpoint, abbiamo TF_CHECKPOINT_VERSION , TF_CHECKPOINT_VERSION_MIN_CONSUMER e TF_CHECKPOINT_VERSION_MIN_PRODUCER .

Aggiungi un nuovo attributo con default a un'operazione esistente

Seguendo le indicazioni riportate di seguito avrai la compatibilità futura solo se l'insieme di operazioni non è cambiato:

  1. Se si desidera la compatibilità futura, impostare strip_default_attrs su True durante l'esportazione del modello utilizzando i metodi tf.saved_model.SavedModelBuilder.add_meta_graph_and_variables e tf.saved_model.SavedModelBuilder.add_meta_graph della classe SavedModelBuilder o tf.estimator.Estimator.export_saved_model
  2. Ciò rimuove gli attributi con valore predefinito al momento della produzione/esportazione dei modelli. Ciò garantisce che tf.MetaGraphDef esportato non contenga il nuovo attributo op quando viene utilizzato il valore predefinito.
  3. Avere questo controllo potrebbe consentire ai consumatori non aggiornati (ad esempio, che servono file binari che sono in ritardo rispetto ai file binari di addestramento) di continuare a caricare i modelli e prevenire interruzioni nella pubblicazione dei modelli.

Versioni GraphDef in evoluzione

Questa sezione spiega come utilizzare questo meccanismo di controllo delle versioni per apportare diversi tipi di modifiche al formato GraphDef .

Aggiungi un'operazione

Aggiungi la nuova operazione sia ai consumatori che ai produttori contemporaneamente e non modificare alcuna versione GraphDef . Questo tipo di modifica è automaticamente compatibile con le versioni precedenti e non influisce sul piano di compatibilità futura poiché gli script del produttore esistente non utilizzeranno improvvisamente la nuova funzionalità.

Aggiungi un'operazione e cambia i wrapper Python esistenti per usarlo

  1. Implementa nuove funzionalità consumer e incrementa la versione GraphDef .
  2. Se è possibile fare in modo che i wrapper utilizzino la nuova funzionalità solo nei casi che prima non funzionavano, i wrapper possono essere aggiornati ora.
  3. Modifica i wrapper Python per utilizzare la nuova funzionalità. Non incrementare min_consumer , poiché i modelli che non utilizzano questa operazione non dovrebbero rompersi.

Rimuovere o limitare la funzionalità di un'operazione

  1. Correggi tutti gli script del produttore (non TensorFlow stesso) per non utilizzare l'operazione o la funzionalità vietata.
  2. Incrementa la versione GraphDef e implementa nuove funzionalità consumer che vietano l'operazione o la funzionalità rimossa per GraphDefs nella nuova versione e successive. Se possibile, fai in modo che TensorFlow smetta di produrre GraphDefs con la funzionalità vietata. Per fare ciò, aggiungi REGISTER_OP(...).Deprecated(deprecated_at_version, message) .
  3. Attendi una versione importante per motivi di compatibilità con le versioni precedenti.
  4. Aumenta min_producer alla versione GraphDef da (2) e rimuovi completamente la funzionalità.

Modifica la funzionalità di un'operazione

  1. Aggiungi una nuova operazione simile denominata SomethingV2 o simile e segui il processo di aggiunta e cambio dei wrapper Python esistenti per usarla. Per garantire la compatibilità futura, utilizzare i controlli suggeriti in compat.py quando si modificano i wrapper Python.
  2. Rimuovere la vecchia operazione (può avvenire solo con una modifica importante della versione a causa della compatibilità con le versioni precedenti).
  3. Aumenta min_consumer per escludere i consumatori con la vecchia operazione, aggiungi nuovamente la vecchia operazione come alias per SomethingV2 e segui il processo per cambiare i wrapper Python esistenti per usarlo.
  4. Segui il processo per rimuovere SomethingV2 .

Vietare una singola versione consumer non sicura

  1. Aumenta la versione GraphDef e aggiungi la versione errata a bad_consumers per tutti i nuovi GraphDef. Se possibile, aggiungi a bad_consumers solo per GraphDef che contengono un determinato operazione o simili.
  2. Se i consumatori esistenti hanno la versione errata, eliminali il prima possibile.