Questo documento è per gli utenti che necessitano di retrocompatibilità tra diverse versioni di TensorFlow (per codice o dati) e per gli sviluppatori che desiderano modificare TensorFlow preservando la compatibilità.
Versione semantica 2.0
TensorFlow segue Semantic Versioning 2.0 ( semver ) per la sua API pubblica. Ogni versione di rilascio di TensorFlow ha il formato MAJOR.MINOR.PATCH
. Ad esempio, TensorFlow versione 1.2.3 ha MAJOR
versione 1, MINOR
versione 2 e PATCH
versione 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 possono essere migrati alla versione più recente; vedere Compatibilità di grafici e punti di controllo per i dettagli sulla compatibilità dei dati.
MINOR : funzionalità compatibili con le versioni precedenti, 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 dettagli su cosa è e cosa non è l'API pubblica, vedi 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 tra versioni secondarie 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
, vedi sotto per i dettagli.
Si noti che il codice nelle directory examples
examples/
etools/
non è raggiungibile tramite il modulo Pythontensorflow
e quindi non è coperto dalla garanzia di compatibilità.Se un simbolo è disponibile tramite il modulo Python
tensorflow
o i suoi sottomoduli, ma non è documentato, non è considerato parte dell'API pubblica.- Simboli privati: qualsiasi funzione, classe, ecc., il cui nome inizia con
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 obsoleti e non supportati (ovvero, non aggiungeremo alcuna funzionalità e non correggeremo bug se non per correggere vulnerabilità), ma rientrano nelle nostre garanzie di compatibilità.L' API C.
I seguenti file di buffer del protocollo:
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 alcuni simboli API chiaramente contrassegnati come sperimentali dalle garanzie di compatibilità. 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 o costante) il cui nome contiene
experimental
oExperimental
; o - qualsiasi simbolo il cui nome completo include un modulo o una classe che è esso stesso sperimentale. Questo include campi e sottomessaggi di qualsiasi buffer di protocollo chiamato
experimental
.
- qualsiasi simbolo nel modulo
Altri linguaggi : API TensorFlow in linguaggi diversi da Python e C, come:
- C++ (esposto tramite file di intestazione in
tensorflow/cc
). - Giava ,
- andare
- javascript
- C++ (esposto tramite file di intestazione in
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 possono cambiare per le versioni minori. In particolare, è probabile che i test di regressione che verificano l'esatta corrispondenza tra i grafici interrompano le versioni minori, anche se il comportamento del grafico dovrebbe rimanere invariato e i punti di controllo 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 sull'accuratezza approssimativa e sulla stabilità numerica, non sui bit specifici calcolati. Le modifiche alle formule numeriche nelle versioni minori e patch dovrebbero comportare una precisione comparabile o migliorata, con l'avvertenza che nell'apprendimento automatico una maggiore precisione di formule specifiche può comportare una minore 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.
Variazione della versione in Tensorflow distribuito: l' esecuzione di due diverse versioni di TensorFlow in un singolo cluster non è supportata. Non ci sono garanzie sulla retrocompatibilità del protocollo wire.
Bug: ci riserviamo il diritto di apportare modifiche al comportamento incompatibile con le versioni precedenti (sebbene non 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, allora correggeremo l'ottimizzatore. La nostra correzione potrebbe interrompere il codice basandosi sul comportamento errato per la convergenza. Prenderemo nota di tali modifiche nelle note di rilascio.
API inutilizzate: ci riserviamo il diritto di apportare modifiche incompatibili con le versioni precedenti alle API per le quali non troviamo usi documentati (eseguendo la verifica dell'utilizzo di TensorFlow tramite la ricerca su GitHub). Prima di apportare tali modifiche, annunceremo la nostra intenzione di apportare la modifica sulla mailing list di advertise@ , fornendo istruzioni su come risolvere eventuali problemi (se applicabile) e attendere due settimane per dare alla nostra comunità la possibilità di condividere il proprio feedback .
Comportamento in caso di errore: potremmo sostituire gli errori con un comportamento non inerente. Ad esempio, possiamo 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 il tipo di eccezione per una specifica condizione di errore non sia specificato nella documentazione.
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 punti di controllo contengono i valori tensoriali salvati delle variabili in un grafico.
Molti utenti di TensorFlow creano SavedModels 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 major release.
Forniamo ulteriori garanzie per i modelli salvati supportati . Chiamiamo SavedModel che è stato creato utilizzando solo API non obsolete, non sperimentali e non compatibili nella versione principale N
di TensorFlow come SavedModel supportato nella versione N
. Qualsiasi SavedModel supportato in TensorFlow major version N
può essere caricato ed eseguito con TensorFlow major version 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 retrocompatibilità 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 TensorFlow. Ad esempio, la versione 17 di GraphDef
ha deprecato inv
op a favore di reciprocal
. La semantica è:
Ogni versione di TensorFlow supporta un intervallo di versioni di
GraphDef
. Questo intervallo sarà costante tra i rilasci delle patch e crescerà solo tra i rilasci secondari. L'eliminazione del supporto per una versione diGraphDef
si verificherà 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 l'ultimo numero di versione
GraphDef
.Se una data 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 indicato sopra), indipendentemente dal principale versione di TensorFlow. In particolare, un GraphDef compatibile con un file di checkpoint in una versione di TensorFlow (come nel caso di un SavedModel) rimarrà compatibile con quel checkpoint nelle versioni successive, purché GraphDef sia supportato.Si noti 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 di
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 usando numeri di versione ipotetici):- TensorFlow 1.2 potrebbe supportare
GraphDef
versioni da 4 a 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 abbandonare il supporto per le versioni da 4 a 7, lasciando solo la versione 8.
Si noti che poiché le versioni principali di TensorFlow vengono generalmente pubblicate a più di 6 mesi di distanza, le garanzie per i SavedModels supportati descritti sopra sono molto più forti della garanzia di 6 mesi per GraphDefs.
- TensorFlow 1.2 potrebbe supportare
Infine, quando il supporto per una versione di GraphDef
verrà abbandonato, cercheremo di fornire strumenti per convertire automaticamente i grafici in una nuova versione supportata GraphDef
.
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à delle operazioni esistenti. La sezione precedente dovrebbe essere sufficiente per la maggior parte degli utenti.
Compatibilità con versioni precedenti e parziali
Il nostro schema di versioning ha tre requisiti:
- Compatibilità con le versioni precedenti per supportare il caricamento di grafici e checkpoint creati con versioni precedenti di TensorFlow.
- Compatibilità con le versioni successive per supportare scenari in cui il produttore di un grafico o checkpoint viene aggiornato a una versione più recente di TensorFlow prima del consumatore.
- Abilita l'evoluzione di TensorFlow in modi incompatibili. Ad esempio, rimozione di operazioni, aggiunta di attributi e rimozione di attributi.
Si noti che mentre il meccanismo della versione GraphDef
è separato dalla versione TensorFlow, le modifiche incompatibili con le versioni precedenti al formato GraphDef
sono ancora limitate da Semantic Versioning. Ciò significa che la funzionalità può essere rimossa o modificata solo tra le versioni MAJOR
di TensorFlow (come da 1.7
a 2.0
). Inoltre, la compatibilità con le versioni successive viene applicata all'interno delle versioni Patch (da 1.x.1
a 1.x.2
ad esempio).
Per ottenere la compatibilità con le versioni precedenti e successive e per sapere quando applicare modifiche ai formati, i grafici e i punti di controllo 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 di GraphDef
.
Schemi di versione dei dati indipendenti
Esistono diverse versioni di dati per grafici e punti di controllo. I due formati di dati si evolvono a velocità diverse l'uno dall'altro e anche a velocità diverse rispetto a TensorFlow. Entrambi i sistemi di controllo delle versioni sono definiti in core/public/version.h
. Ogni volta che viene aggiunta una nuova versione, viene aggiunta una nota all'intestazione che specifica cosa è cambiato e la data.
Dati, produttori e consumatori
Distinguiamo tra i seguenti tipi di informazioni sulla versione dei dati:
- producer : binari che producono dati. I producer 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 pezzo di dati 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 producer crea alcuni dati, i dati ereditano le versioni producer
e min_consumer
del produttore. bad_consumers
può essere impostato se è noto che specifiche versioni consumer contengono bug e devono essere evitate. Un consumatore può accettare un dato se le seguenti condizioni sono tutte vere:
-
consumer
>=min_consumer
dei dati -
producer
di dati >=min_producer
del consumatore -
consumer
non inbad_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 principali che viene trattata come producer
o consumer
a seconda del contesto e sia min_consumer
che min_producer
(richiesti rispettivamente da produttori e consumatori) . Nello specifico,
- Per le versioni
GraphDef
, abbiamoTF_GRAPH_DEF_VERSION
,TF_GRAPH_DEF_VERSION_MIN_CONSUMER
eTF_GRAPH_DEF_VERSION_MIN_PRODUCER
. - Per le versioni checkpoint, abbiamo
TF_CHECKPOINT_VERSION
,TF_CHECKPOINT_VERSION_MIN_CONSUMER
eTF_CHECKPOINT_VERSION_MIN_PRODUCER
.
Aggiungi un nuovo attributo con valore predefinito a un op esistente
Seguendo le indicazioni di seguito si ottiene la compatibilità con le versioni successive solo se il set di operazioni non è cambiato:
- Se si desidera la compatibilità con le versioni successive, impostare
strip_default_attrs
suTrue
durante l'esportazione del modello utilizzando i metoditf.saved_model.SavedModelBuilder.add_meta_graph_and_variables
etf.saved_model.SavedModelBuilder.add_meta_graph
della classeSavedModelBuilder
otf.estimator.Estimator.export_saved_model
- Questo rimuove gli attributi con valore predefinito al momento della produzione/esportazione dei modelli. Ciò garantisce che il
tf.MetaGraphDef
esportato non contenga il nuovo attributo op quando viene utilizzato il valore predefinito. - Avere questo controllo potrebbe consentire ai consumatori obsoleti (ad esempio, la pubblicazione di file binari che sono in ritardo rispetto ai file binari di addestramento) di continuare a caricare i modelli e prevenire interruzioni nella fornitura di modelli.
Versioni di 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 op
Aggiungi la nuova operazione sia ai consumatori che ai produttori contemporaneamente e non modificare alcuna versione di GraphDef
. Questo tipo di modifica è automaticamente compatibile con le versioni precedenti e non influisce sul piano di compatibilità con le versioni successive poiché gli script dei produttori esistenti non utilizzeranno improvvisamente la nuova funzionalità.
Aggiungi un op e cambia i wrapper Python esistenti per usarlo
- Implementa nuove funzionalità consumer e incrementa la versione
GraphDef
. - 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.
- Modifica i wrapper Python per utilizzare la nuova funzionalità. Non incrementare
min_consumer
, poiché i modelli che non utilizzano questa operazione non dovrebbero rompersi.
Rimuovi o limita la funzionalità di un'operazione
- Correggi tutti gli script del produttore (non TensorFlow stesso) per non utilizzare l'operazione o la funzionalità vietata.
- Incrementa la versione di
GraphDef
e implementa nuove funzionalità consumer che vietano l'operazione o la funzionalità rimossa per GraphDefs dalla nuova versione e successive. Se possibile, fai in modo che TensorFlow smetta di produrreGraphDefs
con la funzionalità vietata. Per farlo, aggiungiREGISTER_OP(...).Deprecated(deprecated_at_version, message)
. - Attendi una versione principale per motivi di compatibilità con le versioni precedenti.
- Aumenta
min_producer
alla versione GraphDef da (2) e rimuovi completamente la funzionalità.
Cambia la funzionalità di un'operazione
- Aggiungi una nuova operazione simile denominata
SomethingV2
o simile e segui il processo di aggiunta e modifica dei wrapper Python esistenti per utilizzarla. Per garantire la compatibilità con le versioni successive, utilizzare i controlli suggeriti in compat.py quando si modificano i wrapper Python. - Rimuovi la vecchia operazione (può avvenire solo con una modifica di versione principale a causa della compatibilità con le versioni precedenti).
- Aumenta
min_consumer
per escludere i consumatori con il vecchio op, aggiungi nuovamente il vecchio op come alias perSomethingV2
e segui il processo per cambiare i wrapper Python esistenti per usarlo. - Segui il processo per rimuovere
SomethingV2
.
Divieto di una singola versione consumer non sicura
- Aumenta la versione di
GraphDef
e aggiungi la versione errata abad_consumers
per tutti i nuovi GraphDef. Se possibile, aggiungi abad_consumers
solo per GraphDefs che contengono un certo op o simili. - Se i consumatori esistenti hanno la versione cattiva, respingili il prima possibile.