Este documento é destinado a usuários que precisam de compatibilidade retroativa entre diferentes versões do TensorFlow (seja para código ou dados) e para desenvolvedores que desejam modificar o TensorFlow preservando a compatibilidade.
Versionamento semântico 2.0
O TensorFlow segue o Semantic Versioning 2.0 ( semver ) para sua API pública. Cada versão de lançamento do TensorFlow tem o formato MAJOR.MINOR.PATCH
. Por exemplo, o TensorFlow versão 1.2.3 tem MAJOR
versão 1, MINOR
versão 2 e PATCH
versão 3. As alterações em cada número têm o seguinte significado:
PRINCIPAL : Alterações potencialmente incompatíveis com versões anteriores. O código e os dados que funcionaram com uma versão principal anterior não funcionarão necessariamente com a nova versão. No entanto, em alguns casos, os gráficos e pontos de verificação existentes do TensorFlow podem ser migráveis para a versão mais recente; consulte Compatibilidade de gráficos e pontos de verificação para obter detalhes sobre compatibilidade de dados.
MENOR : Recursos compatíveis com versões anteriores, melhorias de velocidade, etc. Código e dados que funcionaram com uma versão secundária anterior e que dependem apenas da API pública não experimental continuarão a funcionar inalterados. Para obter detalhes sobre o que é ou não a API pública, consulte O que é coberto .
PATCH : Correções de bugs compatíveis com versões anteriores.
Por exemplo, a versão 1.0.0 introduziu alterações incompatíveis com versões anteriores da versão 0.12.1. No entanto, a versão 1.1.1 era compatível com versões anteriores da versão 1.0.0.
O que está coberto
Somente as APIs públicas do TensorFlow são compatíveis com versões anteriores e versões secundárias e de patch. As APIs públicas consistem em
Todas as funções e classes Python documentadas no módulo
tensorflow
e seus submódulos, exceto- Símbolos privados: qualquer função, classe, etc., cujo nome comece com
_
- Símbolos experimentais e
tf.contrib
, veja abaixo para detalhes.
Observe que o código nos diretórios
examples/
etools/
não pode ser acessado por meio do módulotensorflow
Python e, portanto, não é coberto pela garantia de compatibilidade.Se um símbolo estiver disponível por meio do módulo
tensorflow
Python ou de seus submódulos, mas não estiver documentado, ele não será considerado parte da API pública.- Símbolos privados: qualquer função, classe, etc., cujo nome comece com
A API de compatibilidade (em Python, o módulo
tf.compat
). Nas versões principais, podemos lançar utilitários e endpoints adicionais para ajudar os usuários na transição para uma nova versão principal. Esses símbolos de API estão obsoletos e não são suportados (ou seja, não adicionaremos nenhum recurso e não corrigiremos bugs além de corrigir vulnerabilidades), mas eles se enquadram em nossas garantias de compatibilidade.A API C do TensorFlow:
Os seguintes arquivos de buffer de protocolo:
Número de versão separado para TensorFlow Lite
Atualmente o TensorFlow Lite é distribuído como parte do TensorFlow. No entanto, reservamo-nos o direito de, no futuro, lançar alterações nas APIs do TensorFlow Lite em uma programação diferente das outras APIs do TensorFlow, ou até mesmo mover o TensorFlow Lite para uma distribuição de origem separada e/ou um repositório de origem separado do TensorFlow.
Por causa disso, usamos um número de versão diferente para TensorFlow Lite ( TFLITE_VERSION_STRING
em tensorflow/lite/version.h
e TfLiteVersion()
em tensorflow/lite/c/c_api.h
) do que para TensorFlow ( TF_VERSION_STRING
em tensorflow/core/public/version.h
e TF_Version()
em tensorflow/c/c_api.h
). Atualmente, esses dois números de versão têm o mesmo valor. Mas no futuro poderão divergir; por exemplo, podemos incrementar o número da versão principal do TensorFlow Lite sem incrementar o número da versão principal do TensorFlow ou vice-versa.
A superfície da API coberta pelo número de versão do TensorFlow Lite é composta pelas seguintes APIs públicas:
A API TensorFlow Lite C:
API TensorFlow Lite para Android (Java/Kotlin):
- Em
org.tensorflow.lite
: - Em
org.tensorflow.lite.gpu
:
- Em
As APIs TensorFlow Lite Objective-C:
- tensorflow/lite/objc/apis/
- TFLCoreMLDelegate.h
- TFLDelegate.h
- TFLInterpreter.h
- TFLInterpreterOptions.h
- TFLMetalDelegate.h
- TFLQuantizationParameters.h
- TFLSignatureRunner.h
- TFLTensorFlowLite.h
- TFLTensor.h
- tensorflow/lite/objc/apis/
As APIs Swift do TensorFlow Lite:
- tensorflow/lite/swift/Sources/ .
- CoreMLDelegate.swift
- Delegado.swift
- InterpreterError.swift
- Intérprete.Swift
- MetalDelegate.swift
- Modelo.swift
- QuantizationParameters.swift
- SignatureRunnerError.swift
- SignatureRunner.swift
- TensorFlowLite.swift
- Tensor.Swift
- tensorflow/lite/swift/Sources/ .
Os símbolos experimentais não são abrangidos; veja abaixo para obter detalhes.
Número de versão separado para APIs de extensão do TensorFlow Lite
O TensorFlow Lite fornece APIs C para estender o interpretador do TensorFlow Lite com "operações personalizadas", que fornecem operações definidas pelo usuário em um gráfico, ou "delegados", que permitem delegar a computação de um gráfico (ou de um subconjunto de um gráfico) para um back-end personalizado. Essas APIs, que chamamos coletivamente de "APIs de extensão do TensorFlow Lite", exigem dependências mais íntimas de alguns detalhes da implementação do TensorFlow Lite.
Reservamo-nos o direito de lançar alterações nessas APIs no futuro, incluindo potencialmente alterações não compatíveis com versões anteriores, em uma programação diferente das outras APIs do TensorFlow Lite. Portanto, usamos um número de versão diferente para as APIs de extensão do TensorFlow Lite do que os números de versão do TensorFlow Lite ou TensorFlow (que foram descritos na seção anterior). Estamos introduzindo algumas novas APIs no TensorFlow Lite versão 2.15 para obter a versão das APIs de extensão do TensorFlow Lite ( TFLITE_EXTENSION_APIS_VERSION_STRING
em tensorflow/lite/version.h
e TfLiteExtensionApisVersion() em tensorflow/lite/c/c_api.h
). O número da versão das APIs de extensão do TensorFlow Lite é atualmente igual ao número da versão do TensorFlow e do TensorFlow Lite. Mas no futuro poderão divergir; por exemplo, podemos incrementar o número da versão principal para as APIs de extensão do TensorFlow Lite sem incrementar o número da versão principal do TensorFlow Lite ou vice-versa.
A superfície da API coberta pelo número de versão das APIs de extensão do TensorFlow Lite é composta pelas seguintes APIs públicas:
- tensorflow/lite/c/c_api_opaque.h
- tensorflow/lite/c/common.h
- tensorflow/lite/c/builtin_op_data.h
- tensorflow/lite/builtin_ops.h
Novamente, os símbolos experimentais não são abrangidos; veja abaixo para obter detalhes.
O que não está coberto
Algumas partes do TensorFlow podem mudar de maneira incompatível com versões anteriores a qualquer momento. Esses incluem:
APIs experimentais : Para facilitar o desenvolvimento, isentamos alguns símbolos de API claramente marcados como experimentais das garantias de compatibilidade. Em particular, não estão cobertos por quaisquer garantias de compatibilidade:
- qualquer símbolo no módulo
tf.contrib
ou em seus submódulos; - qualquer símbolo (módulo, função, argumento, propriedade, classe, constante, tipo, pacote, etc.) cujo nome contenha
experimental
ouExperimental
; ou - qualquer símbolo cujo nome totalmente qualificado inclua um módulo ou classe ou pacote que seja experimental. Isso inclui campos e submensagens de qualquer buffer de protocolo chamado
experimental
.
- qualquer símbolo no módulo
Outras linguagens : APIs do TensorFlow em linguagens diferentes de Python e C, como:
- C++ (exposto por meio de arquivos de cabeçalho em
tensorflow/cc/
). - Java ,
- Ir
- JavaScript
e APIs TensorFlow Lite em linguagens diferentes de Java/Kotlin, C, Objective-C e Swift, em particular
- C++ (exposto por meio de arquivos de cabeçalho em
tensorflow/lite/
)
- C++ (exposto por meio de arquivos de cabeçalho em
Detalhes de operações compostas: muitas funções públicas em Python se expandem para várias operações primitivas no gráfico, e esses detalhes farão parte de quaisquer gráficos salvos no disco como
GraphDef
s. Esses detalhes podem mudar para lançamentos menores. Em particular, os testes de regressão que verificam a correspondência exata entre os gráficos provavelmente serão interrompidos em versões menores, mesmo que o comportamento do gráfico deva permanecer inalterado e os pontos de verificação existentes ainda funcionem.Detalhes numéricos de ponto flutuante: os valores específicos de ponto flutuante calculados pelas operações podem mudar a qualquer momento. Os usuários devem confiar apenas na precisão aproximada e na estabilidade numérica, e não nos bits específicos computados. As alterações nas fórmulas numéricas em versões secundárias e de patch devem resultar em precisão comparável ou melhorada, com a ressalva de que, no aprendizado de máquina, a precisão aprimorada de fórmulas específicas pode resultar em menor precisão para o sistema geral.
Números aleatórios: Os números aleatórios específicos calculados podem mudar a qualquer momento. Os usuários devem confiar apenas em distribuições aproximadamente corretas e força estatística, e não nos bits específicos computados. Consulte o guia de geração de números aleatórios para obter detalhes.
Distorção de versão no Tensorflow distribuído: a execução de duas versões diferentes do TensorFlow em um único cluster não é compatível. Não há garantias sobre a compatibilidade retroativa do protocolo wire.
Bugs: Reservamo-nos o direito de fazer alterações de comportamento incompatível com versões anteriores (embora não de API) se a implementação atual estiver claramente quebrada, ou seja, se contradizer a documentação ou se um comportamento pretendido bem conhecido e bem definido não for implementado corretamente devido para um bug. Por exemplo, se um otimizador afirma implementar um algoritmo de otimização bem conhecido, mas não corresponde a esse algoritmo devido a um bug, então corrigiremos o otimizador. Nossa correção pode quebrar o código dependendo do comportamento errado para convergência. Notaremos essas mudanças nas notas de lançamento.
API não utilizada: reservamo-nos o direito de fazer alterações incompatíveis com versões anteriores em APIs para as quais não encontramos usos documentados (realizando auditoria do uso do TensorFlow por meio da pesquisa no GitHub). Antes de fazer qualquer alteração, anunciaremos nossa intenção de fazer a alteração na lista de e-mail anuncia@ , fornecendo instruções sobre como resolver quaisquer quebras (se aplicável) e aguardaremos duas semanas para dar à nossa comunidade a chance de compartilhar seus comentários. .
Comportamento de erro: podemos substituir erros por comportamento sem erro. Por exemplo, podemos alterar uma função para calcular um resultado em vez de gerar um erro, mesmo que esse erro esteja documentado. Também nos reservamos o direito de alterar o texto das mensagens de erro. Além disso, o tipo de erro pode mudar, a menos que o tipo de exceção para uma condição de erro específica seja especificado na documentação.
Compatibilidade de SavedModels, gráficos e pontos de verificação
SavedModel é o formato de serialização preferido para usar em programas TensorFlow. SavedModels contém duas partes: um ou mais gráficos codificados como GraphDefs
e um Checkpoint. Os gráficos descrevem o fluxo de dados das operações a serem executadas e os pontos de verificação contêm os valores tensores salvos das variáveis em um gráfico.
Muitos usuários do TensorFlow criam SavedModels e os carregam e executam com uma versão posterior do TensorFlow. Em conformidade com semver , SavedModels escritos com uma versão do TensorFlow podem ser carregados e avaliados com uma versão posterior do TensorFlow com a mesma versão principal.
Oferecemos garantias adicionais para SavedModels suportados . Chamamos um SavedModel que foi criado usando apenas APIs não obsoletas, não experimentais e sem compatibilidade na versão principal N
do TensorFlow como SavedModel compatível com a versão N
. Qualquer SavedModel compatível com a versão principal N
do TensorFlow pode ser carregado e executado com a versão principal N+1
do TensorFlow. No entanto, a funcionalidade necessária para construir ou modificar tal modelo pode não estar mais disponível, portanto esta garantia se aplica apenas ao SavedModel não modificado.
Faremos o possível para preservar a compatibilidade com versões anteriores pelo maior tempo possível, para que os arquivos serializados possam ser usados por longos períodos de tempo.
Compatibilidade com GraphDef
Os gráficos são serializados por meio do buffer do protocolo GraphDef
. Para facilitar alterações incompatíveis com versões anteriores em gráficos, cada GraphDef
tem um número de versão separado da versão do TensorFlow. Por exemplo, GraphDef
versão 17 descontinuou o inv
op em favor do reciprocal
. A semântica é:
Cada versão do TensorFlow oferece suporte a um intervalo de versões
GraphDef
. Esse intervalo será constante entre versões de patch e só aumentará em versões secundárias. A eliminação do suporte para uma versãoGraphDef
ocorrerá apenas para uma versão principal do TensorFlow (e apenas alinhada com o suporte de versão garantido para SavedModels).Os gráficos recém-criados recebem o número de versão mais recente
GraphDef
.Se uma determinada versão do TensorFlow oferecer suporte à versão
GraphDef
de um gráfico, ele carregará e avaliará com o mesmo comportamento da versão do TensorFlow usada para gerá-lo (exceto para detalhes numéricos de ponto flutuante e números aleatórios conforme descrito acima), independentemente do principal versão do TensorFlow. Em particular, um GraphDef compatível com um arquivo de ponto de verificação em uma versão do TensorFlow (como é o caso de um SavedModel) permanecerá compatível com esse ponto de verificação em versões subsequentes, desde que o GraphDef seja compatível.Observe que isso se aplica apenas a gráficos serializados em GraphDefs (e SavedModels): o código que lê um ponto de verificação pode não ser capaz de ler pontos de verificação gerados pelo mesmo código executando uma versão diferente do TensorFlow.
Se o limite superior
GraphDef
for aumentado para X em uma versão (menor), levará pelo menos seis meses antes que o limite inferior seja aumentado para X. Por exemplo (estamos usando números de versão hipotéticos aqui):- O TensorFlow 1.2 pode oferecer suporte
GraphDef
versões 4 a 7. - O TensorFlow 1.3 pode adicionar
GraphDef
versão 8 e oferecer suporte às versões 4 a 8. - Pelo menos seis meses depois, o TensorFlow 2.0.0 pode abandonar o suporte para as versões 4 a 7, deixando apenas a versão 8.
Observe que, como as versões principais do TensorFlow geralmente são publicadas com mais de 6 meses de intervalo, as garantias para SavedModels suportados detalhadas acima são muito mais fortes do que a garantia de 6 meses para GraphDefs.
- O TensorFlow 1.2 pode oferecer suporte
Finalmente, quando o suporte para uma versão GraphDef
for abandonado, tentaremos fornecer ferramentas para converter gráficos automaticamente para uma versão mais recente GraphDef
suportada.
Compatibilidade de gráfico e ponto de verificação ao estender o TensorFlow
Esta seção é relevante apenas ao fazer alterações incompatíveis no formato GraphDef
, como ao adicionar operações, remover operações ou alterar a funcionalidade de operações existentes. A seção anterior deve ser suficiente para a maioria dos usuários.
Compatibilidade retroativa e parcial
Nosso esquema de versionamento tem três requisitos:
- Compatibilidade com versões anteriores para oferecer suporte ao carregamento de gráficos e pontos de verificação criados com versões mais antigas do TensorFlow.
- Compatibilidade futura para oferecer suporte a cenários em que o produtor de um gráfico ou ponto de verificação é atualizado para uma versão mais recente do TensorFlow antes do consumidor.
- Habilite a evolução do TensorFlow de maneiras incompatíveis. Por exemplo, remover operações, adicionar atributos e remover atributos.
Observe que, embora o mecanismo de versão GraphDef
seja separado da versão do TensorFlow, as alterações incompatíveis com versões anteriores no formato GraphDef
ainda são restritas pelo controle de versão semântico. Isso significa que a funcionalidade só pode ser removida ou alterada entre versões MAJOR
do TensorFlow (como 1.7
a 2.0
). Além disso, a compatibilidade futura é imposta nas versões de patch ( 1.x.1
a 1.x.2
por exemplo).
Para obter compatibilidade retroativa e futura e saber quando impor alterações nos formatos, os gráficos e pontos de verificação possuem metadados que descrevem quando foram produzidos. As seções abaixo detalham a implementação do TensorFlow e as diretrizes para a evolução das versões GraphDef
.
Esquemas de versão de dados independentes
Existem diferentes versões de dados para gráficos e pontos de verificação. Os dois formatos de dados evoluem em taxas diferentes um do outro e também em taxas diferentes do TensorFlow. Ambos os sistemas de versionamento são definidos em core/public/version.h
. Sempre que uma nova versão é adicionada, uma nota é adicionada ao cabeçalho detalhando o que mudou e a data.
Dados, produtores e consumidores
Distinguimos entre os seguintes tipos de informações de versão de dados:
- produtores : binários que produzem dados. Os produtores têm uma versão (
producer
) e uma versão mínima do consumidor com a qual são compatíveis (min_consumer
). - consumidores : binários que consomem dados. Os consumidores têm uma versão (
consumer
) e uma versão mínima do produtor com a qual são compatíveis (min_producer
).
Cada parte dos dados versionados possui um campo de VersionDef versions
que registra o producer
que criou os dados, o min_consumer
com o qual é compatível e uma lista de versões bad_consumers
que não são permitidas.
Por padrão, quando um produtor cria alguns dados, os dados herdam as versões do producer
e min_consumer
do produtor. bad_consumers
pode ser definido se versões específicas do consumidor contêm bugs e devem ser evitadas. Um consumidor pode aceitar um dado se o seguinte for verdadeiro:
-
consumer
>=min_consumer
dos dados -
producer
de dados >=min_producer
do consumidor -
consumer
não está nos dadosbad_consumers
Como produtores e consumidores vêm da mesma base de código do TensorFlow, core/public/version.h
contém uma versão de dados principal que é tratada como producer
ou consumer
dependendo do contexto e min_consumer
e min_producer
(necessários para produtores e consumidores, respectivamente) . Especificamente,
- Para versões
GraphDef
, temosTF_GRAPH_DEF_VERSION
,TF_GRAPH_DEF_VERSION_MIN_CONSUMER
eTF_GRAPH_DEF_VERSION_MIN_PRODUCER
. - Para versões de checkpoint, temos
TF_CHECKPOINT_VERSION
,TF_CHECKPOINT_VERSION_MIN_CONSUMER
eTF_CHECKPOINT_VERSION_MIN_PRODUCER
.
Adicione um novo atributo padrão a uma operação existente
Seguir as orientações abaixo oferece compatibilidade futura somente se o conjunto de operações não tiver sido alterado:
- Se a compatibilidade futura for desejada, defina
strip_default_attrs
comoTrue
ao exportar o modelo usando os métodostf.saved_model.SavedModelBuilder.add_meta_graph_and_variables
etf.saved_model.SavedModelBuilder.add_meta_graph
da classeSavedModelBuilder
outf.estimator.Estimator.export_saved_model
- Isso elimina os atributos com valor padrão no momento da produção/exportação dos modelos. Isso garante que o
tf.MetaGraphDef
exportado não contenha o novo atributo operacional quando o valor padrão for usado. - Ter esse controle poderia permitir que consumidores desatualizados (por exemplo, servindo binários que ficam atrás dos binários de treinamento) continuassem carregando os modelos e evitassem interrupções no atendimento do modelo.
Versões em evolução do GraphDef
Esta seção explica como usar esse mecanismo de controle de versão para fazer diferentes tipos de alterações no formato GraphDef
.
Adicionar uma operação
Adicione a nova operação aos consumidores e produtores ao mesmo tempo e não altere nenhuma versão GraphDef
. Esse tipo de alteração é automaticamente compatível com versões anteriores e não afeta o plano de compatibilidade futura, uma vez que os scripts de produtor existentes não usarão repentinamente a nova funcionalidade.
Adicione uma operação e troque os wrappers Python existentes para usá-la
- Implemente novas funcionalidades de consumidor e incremente a versão
GraphDef
. - Se for possível fazer com que os wrappers utilizem a nova funcionalidade apenas em casos que não funcionavam antes, os wrappers poderão ser atualizados agora.
- Altere os wrappers do Python para usar a nova funcionalidade. Não incremente
min_consumer
, pois modelos que não utilizam esta operação não devem quebrar.
Remover ou restringir a funcionalidade de uma operação
- Corrija todos os scripts do produtor (não o próprio TensorFlow) para não usar a operação ou funcionalidade banida.
- Aumente a versão
GraphDef
e implemente uma nova funcionalidade de consumidor que proíba a operação ou funcionalidade removida para GraphDefs na nova versão e superior. Se possível, faça o TensorFlow parar de produzirGraphDefs
com a funcionalidade banida. Para fazer isso, adicione oREGISTER_OP(...).Deprecated(deprecated_at_version, message)
. - Aguarde um lançamento principal para fins de compatibilidade com versões anteriores.
- Aumente
min_producer
para a versão GraphDef de (2) e remova totalmente a funcionalidade.
Alterar a funcionalidade de uma operação
- Adicione uma nova operação semelhante chamada
SomethingV2
ou similar e passe pelo processo de adicioná-la e trocar os wrappers Python existentes para usá-la. Para garantir a compatibilidade futura, use as verificações sugeridas em compat.py ao alterar os wrappers do Python. - Remova a operação antiga (só pode ocorrer com uma alteração importante de versão devido à compatibilidade com versões anteriores).
- Aumente
min_consumer
para descartar consumidores com a operação antiga, adicione novamente a operação antiga como um alias paraSomethingV2
e siga o processo para trocar os wrappers Python existentes para usá-lo. - Siga o processo para remover
SomethingV2
.
Banir uma única versão insegura para o consumidor
- Altere a versão
GraphDef
e adicione a versão incorreta abad_consumers
para todos os novos GraphDefs. Se possível, adicionebad_consumers
apenas para GraphDefs que contenham uma determinada operação ou similar. - Se os consumidores existentes tiverem a versão ruim, elimine-os o mais rápido possível.