Ten dokument jest przeznaczony dla użytkowników, którzy potrzebują wstecznej zgodności między różnymi wersjami TensorFlow (kodu lub danych) oraz dla programistów, którzy chcą zmodyfikować TensorFlow przy zachowaniu zgodności.
Wersja semantyczna 2.0
TensorFlow stosuje Semantic Versioning 2.0 ( semver ) dla swojego publicznego API. Każda wersja wydania TensorFlow ma postać MAJOR.MINOR.PATCH
. Na przykład TensorFlow w wersji 1.2.3 ma wersję MAJOR
1, wersję MINOR
2 i wersję PATCH
3. Zmiany każdej liczby mają następujące znaczenie:
MAJOR : Potencjalnie niekompatybilne wstecznie zmiany. Kod i dane, które działały w poprzedniej wersji głównej, niekoniecznie będą działać w nowej wersji. Jednak w niektórych przypadkach istniejące wykresy i punkty kontrolne TensorFlow mogą być migrowane do nowszej wersji; zobacz Zgodność wykresów i punktów kontrolnych, aby uzyskać szczegółowe informacje na temat zgodności danych.
MINOR : wstecznie kompatybilne funkcje, ulepszenia szybkości itp. Kod i dane, które działały z poprzednią wersją drobną i które zależą tylko od nieeksperymentalnego publicznego interfejsu API, będą nadal działać bez zmian. Aby uzyskać szczegółowe informacje na temat tego, co jest, a co nie jest publicznym interfejsem API, zobacz Co obejmuje .
PATCH : Wstecznie kompatybilne poprawki błędów.
Na przykład wersja 1.0.0 wprowadziła niekompatybilne wstecz zmiany z wersji 0.12.1. Jednak wersja 1.1.1 była wstecznie kompatybilna z wersją 1.0.0.
Co jest objęte
Tylko publiczne interfejsy API TensorFlow są wstecznie kompatybilne z wersjami pomocniczymi i poprawkami. Publiczne interfejsy API składają się z
Wszystkie udokumentowane funkcje i klasy języka Python w module
tensorflow
i jego podmodułach, z wyjątkiem- Symbole prywatne: dowolna funkcja, klasa itp., której nazwa zaczyna się od
_
- Symbole eksperymentalne i
tf.contrib
, szczegóły poniżej .
Należy pamiętać, że kod w katalogach example
examples/
itools/
nie jest osiągalny przez modułtensorflow
Pythona i dlatego nie jest objęty gwarancją zgodności.Jeśli symbol jest dostępny za pośrednictwem modułu
tensorflow
Pythona lub jego podmodułów, ale nie jest udokumentowany, nie jest uważany za część publicznego interfejsu API.- Symbole prywatne: dowolna funkcja, klasa itp., której nazwa zaczyna się od
Interfejs API kompatybilności (w Pythonie moduł
tf.compat
). W wersjach głównych możemy udostępniać narzędzia i dodatkowe punkty końcowe, aby pomóc użytkownikom w przejściu do nowej wersji głównej. Te symbole API są przestarzałe i nie są obsługiwane (tj. nie będziemy dodawać żadnych funkcji ani naprawiać błędów poza naprawianiem luk), ale podlegają one naszym gwarancjom zgodności.Następujące pliki buforów protokołów:
Co nie jest objęte
Niektóre części TensorFlow mogą w dowolnym momencie zmienić się w sposób niekompatybilny wstecz. Obejmują one:
Eksperymentalne interfejsy API : aby ułatwić programowanie, wyłączamy niektóre symbole interfejsu API wyraźnie oznaczone jako eksperymentalne z gwarancji zgodności. W szczególności następujące elementy nie są objęte żadnymi gwarancjami kompatybilności:
- dowolny symbol w module
tf.contrib
lub jego podmodułach; - dowolny symbol (moduł, funkcja, argument, właściwość, klasa lub stała), którego nazwa zawiera
experimental
lubExperimental
; lub - dowolny symbol, którego pełna nazwa zawiera moduł lub klasę, która sama w sobie jest eksperymentalna. Obejmuje to pola i podkomunikaty dowolnego bufora protokołu zwanego
experimental
.
- dowolny symbol w module
Inne języki : interfejsy API TensorFlow w językach innych niż Python i C, takich jak:
- C++ (ujawnione przez pliki nagłówkowe w
tensorflow/cc
). - Jawa ,
- Iść
- JavaScript
- C++ (ujawnione przez pliki nagłówkowe w
Szczegóły operacji złożonych: wiele funkcji publicznych w Pythonie rozszerza się do kilku prymitywnych operacji na grafie, a te szczegóły będą częścią każdego wykresu zapisanego na dysku jako
GraphDef
s. Te szczegóły mogą ulec zmianie w przypadku mniejszych wydań. W szczególności testy regresji, które sprawdzają dokładne dopasowanie między wykresami, prawdopodobnie rozbiją się na mniejsze wersje, nawet jeśli zachowanie wykresu powinno pozostać niezmienione, a istniejące punkty kontrolne będą nadal działać.Szczegóły liczbowe zmiennoprzecinkowe: określone wartości zmiennoprzecinkowe obliczane przez operatorów mogą ulec zmianie w dowolnym momencie. Użytkownicy powinni polegać tylko na przybliżonej dokładności i stabilności numerycznej, a nie na konkretnych obliczonych bitach. Zmiany formuł numerycznych w wydaniach mniejszych i łatkach powinny skutkować porównywalną lub lepszą dokładnością, z zastrzeżeniem, że w uczeniu maszynowym zwiększona dokładność określonych formuł może skutkować zmniejszeniem dokładności całego systemu.
Liczby losowe: Konkretne obliczone liczby losowe mogą ulec zmianie w dowolnym momencie. Użytkownicy powinni polegać tylko na w przybliżeniu poprawnych rozkładach i sile statystycznej, a nie na konkretnych obliczonych bitach. Aby uzyskać szczegółowe informacje, zobacz przewodnik dotyczący generowania liczb losowych .
Pochylenie wersji w rozproszonym Tensorflow: uruchamianie dwóch różnych wersji TensorFlow w jednym klastrze nie jest obsługiwane. Nie ma żadnych gwarancji co do wstecznej kompatybilności protokołu przewodowego.
Błędy: Zastrzegamy sobie prawo do wprowadzania wstecznie niekompatybilnych zmian zachowania (ale nie API), jeśli bieżąca implementacja jest wyraźnie zepsuta, to znaczy, jeśli jest sprzeczna z dokumentacją lub jeśli dobrze znane i dobrze zdefiniowane zamierzone zachowanie nie jest prawidłowo zaimplementowane z powodu do błędu. Na przykład, jeśli optymalizator twierdzi, że zaimplementował dobrze znany algorytm optymalizacji, ale nie pasuje do tego algorytmu z powodu błędu, naprawimy optymalizator. Nasza poprawka może złamać kod, opierając się na niewłaściwym zachowaniu konwergencji. Odnotujemy takie zmiany w informacjach o wydaniu.
Nieużywany interfejs API: zastrzegamy sobie prawo do wprowadzania niekompatybilnych wstecznie zmian w interfejsach API, dla których nie znaleźliśmy udokumentowanych zastosowań (poprzez przeprowadzenie audytu użycia TensorFlow za pomocą wyszukiwania GitHub). Przed wprowadzeniem takich zmian ogłosimy nasz zamiar wprowadzenia zmiany na liście mailingowej translate@ , podając instrukcje, jak zaradzić wszelkim awariom (jeśli dotyczy) i poczekamy dwa tygodnie, aby dać naszej społeczności szansę na podzielenie się swoją opinią .
Błędne zachowanie: możemy zastąpić błędy zachowaniami niebędącymi błędami. Na przykład możemy zmienić funkcję, aby obliczała wynik zamiast zgłaszać błąd, nawet jeśli ten błąd jest udokumentowany. Zastrzegamy sobie również prawo do zmiany treści komunikatów o błędach. Ponadto typ błędu może ulec zmianie, chyba że w dokumentacji określono typ wyjątku dla określonego warunku błędu.
Zgodność zapisanych modeli, wykresów i punktów kontrolnych
SavedModel to preferowany format serializacji używany w programach TensorFlow. SavedModels zawiera dwie części: jeden lub więcej wykresów zakodowanych jako GraphDefs
i punkt kontrolny. Wykresy opisują przepływ danych operacji do wykonania, a punkty kontrolne zawierają zapisane wartości tensorów zmiennych na wykresie.
Wielu użytkowników TensorFlow tworzy SavedModels oraz ładuje je i wykonuje w późniejszej wersji TensorFlow. Zgodnie z semver , SavedModels napisane za pomocą jednej wersji TensorFlow można ładować i oceniać za pomocą późniejszej wersji TensorFlow z tą samą główną wersją.
Udzielamy dodatkowych gwarancji dla obsługiwanych modeli SavedModels. Nazywamy SavedModel, który został utworzony przy użyciu tylko niewycofanych, nieeksperymentalnych i niezgodnych interfejsów API w głównej wersji TensorFlow N
, a SavedModel jest obsługiwany w wersji N
. Każdy model SavedModel obsługiwany w wersji głównej TensorFlow N
można załadować i wykonać za pomocą wersji głównej TensorFlow N+1
. Jednak funkcjonalność wymagana do zbudowania lub zmodyfikowania takiego modelu może być już niedostępna, więc ta gwarancja dotyczy tylko niezmodyfikowanego modelu SavedModel.
Dołożymy wszelkich starań, aby zachować kompatybilność wsteczną tak długo, jak to możliwe, aby serializowane pliki były użyteczne przez długi czas.
Kompatybilność GraphDef
Wykresy są serializowane przez bufor protokołu GraphDef
. Aby ułatwić wprowadzanie niekompatybilnych wstecznie zmian w wykresach, każdy GraphDef
ma inny numer wersji niż wersja TensorFlow. Na przykład GraphDef
w wersji 17 wycofał inv
op na korzyść reciprocal
. Semantyka to:
Każda wersja TensorFlow obsługuje interwał wersji
GraphDef
. Odstęp ten będzie stały w przypadku wydań łat i będzie się zwiększał tylko w przypadku mniejszych wydań. Rezygnacja ze wsparcia dla wersjiGraphDef
nastąpi tylko w przypadku głównej wersji TensorFlow (i tylko zgodnie z gwarantowaną obsługą wersji dla SavedModels).Nowo utworzonym wykresom przypisywany jest najnowszy numer wersji
GraphDef
.Jeśli dana wersja TensorFlow obsługuje wersję
GraphDef
wykresu, zostanie ona załadowana i oceniona z takim samym zachowaniem, jak wersja TensorFlow użyta do jej wygenerowania (z wyjątkiem szczegółów liczbowych zmiennoprzecinkowych i liczb losowych, jak opisano powyżej), niezależnie od głównego wersja TensorFlow. W szczególności GraphDef, który jest zgodny z plikiem punktu kontrolnego w jednej wersji TensorFlow (tak jak w przypadku SavedModel), pozostanie zgodny z tym punktem kontrolnym w kolejnych wersjach, o ile GraphDef jest obsługiwany.Należy zauważyć, że dotyczy to tylko serializowanych wykresów w GraphDefs (i SavedModels): kod , który odczytuje punkt kontrolny, może nie być w stanie odczytać punktów kontrolnych wygenerowanych przez ten sam kod z inną wersją TensorFlow.
Jeśli górna granica
GraphDef
zostanie zwiększona do X w (podrzędnej) wersji, minie co najmniej sześć miesięcy, zanim dolna granica zostanie zwiększona do X. Na przykład (używamy tutaj hipotetycznych numerów wersji):- TensorFlow 1.2 może obsługiwać wersje
GraphDef
od 4 do 7. - TensorFlow 1.3 może dodać
GraphDef
wersji 8 i obsługiwać wersje od 4 do 8. - Co najmniej sześć miesięcy później TensorFlow 2.0.0 mógł zrezygnować z obsługi wersji od 4 do 7, pozostawiając tylko wersję 8.
Należy pamiętać, że ponieważ główne wersje TensorFlow są zwykle publikowane w odstępie ponad 6 miesięcy, gwarancje dotyczące obsługiwanych modeli SavedModels wyszczególnionych powyżej są znacznie silniejsze niż 6-miesięczna gwarancja dla GraphDefs.
- TensorFlow 1.2 może obsługiwać wersje
Wreszcie, gdy wsparcie dla wersji GraphDef
zostanie wycofane, postaramy się zapewnić narzędzia do automatycznej konwersji wykresów do nowszej obsługiwanej wersji GraphDef
.
Zgodność wykresów i punktów kontrolnych podczas rozszerzania TensorFlow
Ta sekcja jest istotna tylko w przypadku wprowadzania niekompatybilnych zmian w formacie GraphDef
, takich jak dodawanie operacji, usuwanie operacji lub zmiana funkcjonalności istniejących operacji. Poprzednia sekcja powinna wystarczyć większości użytkowników.
Wsteczna i częściowa kompatybilność w przód
Nasz schemat wersjonowania ma trzy wymagania:
- Kompatybilność wsteczna do obsługi ładowania wykresów i punktów kontrolnych utworzonych za pomocą starszych wersji TensorFlow.
- Kompatybilność w przód w celu obsługi scenariuszy, w których producent wykresu lub punktu kontrolnego jest aktualizowany do nowszej wersji TensorFlow przed konsumentem.
- Włącz ewolucję TensorFlow w niekompatybilny sposób. Na przykład usuwanie operacji, dodawanie atrybutów i usuwanie atrybutów.
Należy zauważyć, że chociaż mechanizm wersji GraphDef
jest niezależny od wersji TensorFlow, wstecznie niezgodne zmiany formatu GraphDef
są nadal ograniczone przez wersjonowanie semantyczne. Oznacza to, że funkcjonalność można usuwać lub zmieniać tylko między MAJOR
wersjami TensorFlow (takimi jak 1.7
do 2.0
). Ponadto zgodność z przyszłymi wersjami jest wymuszana w ramach wydań poprawek (na przykład od 1.x.1
do 1.x.2
).
Aby osiągnąć kompatybilność wsteczną i do przodu oraz wiedzieć, kiedy wymusić zmiany w formatach, wykresy i punkty kontrolne mają metadane opisujące, kiedy zostały utworzone. Poniższe sekcje szczegółowo opisują implementację TensorFlow i wytyczne dotyczące rozwijania wersji GraphDef
.
Niezależne schematy wersji danych
Istnieją różne wersje danych dla wykresów i punktów kontrolnych. Te dwa formaty danych ewoluują w różnym tempie od siebie, a także w różnym tempie od TensorFlow. Oba systemy wersjonowania są zdefiniowane w core/public/version.h
. Za każdym razem, gdy dodawana jest nowa wersja, do nagłówka dodawana jest notatka z wyszczególnieniem zmian i datą.
Dane, producenci i konsumenci
Rozróżniamy następujące rodzaje informacji o wersji danych:
- producenci : pliki binarne generujące dane. Producenci mają wersję (
producer
) i minimalną wersję konsumencką, z którą są zgodni (min_consumer
). - konsumenci : pliki binarne, które zużywają dane. Konsumenci mają wersję (
consumer
) i minimalną wersję producenta, z którą są zgodni (min_producer
).
Każda część wersjonowanych danych ma pole VersionDef versions
, które rejestruje producer
, który stworzył dane, min_consumer
, z którym jest kompatybilny, oraz listę wersji bad_consumers
, które są niedozwolone.
Domyślnie, gdy producent tworzy pewne dane, dane dziedziczą wersje producer
i min_consumer
producenta. bad_consumers
można ustawić, jeśli wiadomo, że określone wersje konsumenckie zawierają błędy i należy ich unikać. Konsument może zaakceptować dane, jeśli spełnione są wszystkie poniższe warunki:
-
consumer
>=min_consumer
danych -
producer
danych >=min_producer
konsumenta -
consumer
nie znajduje się w danychbad_consumers
Ponieważ zarówno producenci, jak i konsumenci pochodzą z tej samej bazy kodu TensorFlow, core/public/version.h
zawiera główną wersję danych, która jest traktowana jako producer
lub consumer
w zależności od kontekstu oraz zarówno min_consumer
, jak i min_producer
(potrzebne odpowiednio producentom i konsumentom) . Konkretnie,
- Dla wersji
GraphDef
mamyTF_GRAPH_DEF_VERSION
,TF_GRAPH_DEF_VERSION_MIN_CONSUMER
iTF_GRAPH_DEF_VERSION_MIN_PRODUCER
. - W przypadku wersji punktu kontrolnego mamy
TF_CHECKPOINT_VERSION
,TF_CHECKPOINT_VERSION_MIN_CONSUMER
iTF_CHECKPOINT_VERSION_MIN_PRODUCER
.
Dodaj nowy atrybut z wartością domyślną do istniejącego op
Postępowanie zgodnie z poniższymi wskazówkami zapewnia kompatybilność w przód tylko wtedy, gdy zestaw operacji nie uległ zmianie:
- Jeśli wymagana jest kompatybilność w przód, ustaw
strip_default_attrs
naTrue
podczas eksportowania modelu przy użyciu metodtf.saved_model.SavedModelBuilder.add_meta_graph_and_variables
itf.saved_model.SavedModelBuilder.add_meta_graph
klasySavedModelBuilder
lubtf.estimator.Estimator.export_saved_model
- Spowoduje to usunięcie atrybutów o wartości domyślnej w momencie tworzenia/eksportowania modeli. Daje to pewność, że wyeksportowany
tf.MetaGraphDef
nie zawiera nowego atrybutu op, gdy używana jest wartość domyślna. - Posiadanie tej kontroli może pozwolić nieaktualnym konsumentom (na przykład obsługującym pliki binarne, które pozostają w tyle za plikami binarnymi szkoleniowymi) na dalsze ładowanie modeli i zapobieganie przerwom w udostępnianiu modeli.
Ewoluujące wersje GraphDef
W tej sekcji wyjaśniono, jak używać tego mechanizmu wersjonowania do wprowadzania różnych typów zmian w formacie GraphDef
.
Dodaj op
Dodaj nową operację zarówno do konsumentów, jak i producentów w tym samym czasie i nie zmieniaj żadnych wersji GraphDef
. Ten typ zmiany jest automatycznie zgodny z poprzednimi wersjami i nie wpływa na plan zgodności z przyszłymi wersjami, ponieważ istniejące skrypty producenta nie będą nagle korzystać z nowej funkcjonalności.
Dodaj op i przełącz istniejące opakowania Pythona, aby z niego korzystać
- Zaimplementuj nową funkcjonalność konsumencką i zwiększ wersję
GraphDef
. - Jeśli istnieje możliwość, aby wrappery korzystały z nowej funkcjonalności tylko w przypadkach, które wcześniej nie działały, wrappersy można teraz zaktualizować.
- Zmień opakowania języka Python, aby korzystać z nowej funkcjonalności. Nie zwiększaj
min_consumer
, ponieważ modele, które nie używają tej operacji, nie powinny się zepsuć.
Usuń lub ogranicz funkcjonalność operacji
- Napraw wszystkie skrypty producenta (nie sam TensorFlow), aby nie korzystały z zablokowanej operacji lub funkcjonalności.
- Zwiększ wersję
GraphDef
i zaimplementuj nową funkcjonalność konsumencką, która blokuje usuniętą operację lub funkcjonalność GraphDefs w nowej wersji i nowszych. Jeśli to możliwe, spraw, aby TensorFlow przestał produkowaćGraphDefs
z zakazaną funkcjonalnością. Aby to zrobić, dodajREGISTER_OP(...).Deprecated(deprecated_at_version, message)
. - Poczekaj na główne wydanie w celu zapewnienia kompatybilności wstecznej.
- Zwiększ
min_producer
do wersji GraphDef z (2) i całkowicie usuń funkcjonalność.
Zmień funkcjonalność operacji
- Dodaj nową podobną operację o nazwie
SomethingV2
lub podobną i przejdź przez proces dodawania jej oraz przełączania istniejących opakowań Pythona, aby z niej korzystać. Aby zapewnić kompatybilność w przód, użyj kontroli sugerowanych w compat.py podczas zmiany opakowań Pythona. - Usuń starą operację (Może to nastąpić tylko przy dużej zmianie wersji ze względu na kompatybilność wsteczną).
- Zwiększ
min_consumer
, aby wykluczyć konsumentów ze starą op, dodaj starą op jako alias dlaSomethingV2
i przejdź przez proces, aby przełączyć istniejące opakowania Pythona, aby z niego korzystały. - Przejdź przez proces usuwania
SomethingV2
.
Zablokuj jedną niebezpieczną wersję konsumencką
- Podbij wersję
GraphDef
i dodaj złą wersję dobad_consumers
dla wszystkich nowych GraphDefs. Jeśli to możliwe, dodaj dobad_consumers
tylko dla GraphDefs, które zawierają określony op lub podobny. - Jeśli obecni konsumenci mają złą wersję, wypchnij ich tak szybko, jak to możliwe.