Kompatybilność wersji TensorFlow

Zadbaj o dobrą organizację dzięki kolekcji Zapisuj i kategoryzuj treści zgodnie ze swoimi preferencjami.

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/ i tools/ 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.

  • 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.

  • API C.

  • 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 lub Experimental ; 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 .
  • Inne języki : interfejsy API TensorFlow w językach innych niż Python i C, takich jak:

  • 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 wersji GraphDef 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.

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 danych bad_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 mamy TF_GRAPH_DEF_VERSION , TF_GRAPH_DEF_VERSION_MIN_CONSUMER i TF_GRAPH_DEF_VERSION_MIN_PRODUCER .
  • W przypadku wersji punktu kontrolnego mamy TF_CHECKPOINT_VERSION , TF_CHECKPOINT_VERSION_MIN_CONSUMER i TF_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:

  1. Jeśli wymagana jest kompatybilność w przód, ustaw strip_default_attrs na True podczas eksportowania modelu przy użyciu metod tf.saved_model.SavedModelBuilder.add_meta_graph_and_variables i tf.saved_model.SavedModelBuilder.add_meta_graph klasy SavedModelBuilder lub tf.estimator.Estimator.export_saved_model
  2. 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.
  3. 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ć

  1. Zaimplementuj nową funkcjonalność konsumencką i zwiększ wersję GraphDef .
  2. 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ć.
  3. 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

  1. Napraw wszystkie skrypty producenta (nie sam TensorFlow), aby nie korzystały z zablokowanej operacji lub funkcjonalności.
  2. 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ć, dodaj REGISTER_OP(...).Deprecated(deprecated_at_version, message) .
  3. Poczekaj na główne wydanie w celu zapewnienia kompatybilności wstecznej.
  4. Zwiększ min_producer do wersji GraphDef z (2) i całkowicie usuń funkcjonalność.

Zmień funkcjonalność operacji

  1. 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.
  2. Usuń starą operację (Może to nastąpić tylko przy dużej zmianie wersji ze względu na kompatybilność wsteczną).
  3. Zwiększ min_consumer , aby wykluczyć konsumentów ze starą op, dodaj starą op jako alias dla SomethingV2 i przejdź przez proces, aby przełączyć istniejące opakowania Pythona, aby z niego korzystały.
  4. Przejdź przez proces usuwania SomethingV2 .

Zablokuj jedną niebezpieczną wersję konsumencką

  1. Podbij wersję GraphDef i dodaj złą wersję do bad_consumers dla wszystkich nowych GraphDefs. Jeśli to możliwe, dodaj do bad_consumers tylko dla GraphDefs, które zawierają określony op lub podobny.
  2. Jeśli obecni konsumenci mają złą wersję, wypchnij ich tak szybko, jak to możliwe.