Obsługa modelu TensorFlow

W tym samouczku pokazano, jak używać składników udostępniania TensorFlow do eksportowania przeszkolonego modelu TensorFlow i używania standardowego serwera tensorflow_model_server do jego obsługi. Jeśli znasz już obsługę TensorFlow i chcesz dowiedzieć się więcej o działaniu elementów wewnętrznych serwera, zapoznaj się z zaawansowanym samouczkiem dotyczącym obsługi TensorFlow .

W tym samouczku zastosowano prosty model regresji Softmax, który klasyfikuje cyfry pisane odręcznie. Jest bardzo podobny do tego wprowadzonego w samouczku TensorFlow dotyczącym klasyfikacji obrazów przy użyciu zbioru danych Fashion MNIST .

Kod tego samouczka składa się z dwóch części:

  • Plik Pythona mnist_saved_model.py , który szkoli i eksportuje model.

  • Plik binarny ModelServer, który można zainstalować przy użyciu Apt lub skompilować z pliku C++ ( main.cc ). Serwer obsługujący model TensorFlow wykrywa nowe wyeksportowane modele i uruchamia usługę gRPC w celu ich obsługi.

Zanim zaczniesz, najpierw zainstaluj Docker .

Trenuj i eksportuj model TensorFlow

Na potrzeby fazy uczenia wykres TensorFlow jest uruchamiany w sesji TensorFlow sess z tensorem wejściowym (obrazem) jako x i tensorem wyjściowym (wynik Softmax) jako y .

Następnie używamy modułu SavedModelBuilder TensorFlow do eksportowania modelu. SavedModelBuilder zapisuje „migawkę” wyszkolonego modelu w niezawodnym magazynie, dzięki czemu można go później załadować w celu wyciągnięcia wniosków.

Szczegółowe informacje na temat formatu SavedModel można znaleźć w dokumentacji SavedModel README.md .

Z mnist_saved_model.py poniżej znajduje się krótki fragment kodu ilustrujący ogólny proces zapisywania modelu na dysku.

export_path_base = sys.argv[-1]
export_path = os.path.join(
    tf.compat.as_bytes(export_path_base),
    tf.compat.as_bytes(str(FLAGS.model_version)))
print('Exporting trained model to', export_path)
builder = tf.saved_model.builder.SavedModelBuilder(export_path)
builder.add_meta_graph_and_variables(
    sess, [tf.compat.v1.saved_model.tag_constants.SERVING],
    signature_def_map={
        'predict_images':
            prediction_signature,
        tf.compat.v1.saved_model.signature_constants
            .DEFAULT_SERVING_SIGNATURE_DEF_KEY:
            classification_signature,
    },
    main_op=tf.compat.v1.tables_initializer(),
    strip_default_attrs=True)
builder.save()

SavedModelBuilder.__init__ przyjmuje następujący argument:

  • export_path to ścieżka do katalogu eksportu.

SavedModelBuilder utworzy katalog, jeśli nie istnieje. W przykładzie łączymy argument wiersza poleceń i FLAGS.model_version , aby uzyskać katalog eksportu. FLAGS.model_version określa wersję modelu. Podczas eksportowania nowszej wersji tego samego modelu należy określić większą wartość całkowitą. Każda wersja zostanie wyeksportowana do innego podkatalogu pod podaną ścieżką.

Możesz dodać metagraf i zmienne do konstruktora za pomocą SavedModelBuilder.add_meta_graph_and_variables() z następującymi argumentami:

  • sess to sesja TensorFlow, w której przechowywany jest wytrenowany model, który eksportujesz.

  • tags to zestaw tagów, za pomocą których można zapisać metagraf. W tym przypadku, ponieważ zamierzamy wykorzystać wykres do serwowania, używamy tagu serve z predefiniowanych stałych tagu SavedModel. Aby uzyskać więcej informacji, zobacz tag_constants.py i powiązaną dokumentację interfejsu API TensorFlow .

  • signature_def_map określa mapę klucza dostarczonego przez użytkownika dla podpisu do tensorflow::SignatureDef, który ma zostać dodany do metagrafu. Podpis określa typ eksportowanego modelu oraz tensory wejścia/wyjścia, z którymi należy się powiązać podczas uruchamiania wnioskowania.

    Specjalny klucz podpisu serving_default określa domyślny podpis obsługujący. Domyślny klucz def podpisu obsługującego, wraz z innymi stałymi związanymi z podpisami, są zdefiniowane jako część stałych podpisu SavedModel. Aby uzyskać więcej informacji, zobacz plik podpis_constants.py i powiązaną dokumentację interfejsu API TensorFlow .

    Co więcej, aby pomóc w łatwym budowaniu definicji sygnatur, interfejs API SavedModel udostępnia narzędzia sygnatur def . W szczególności w oryginalnym pliku mnist_saved_model.py używamy signature_def_utils.build_signature_def() do budowania predict_signature i classification_signature .

    Jako przykład definicji predict_signature , util przyjmuje następujące argumenty:

    • inputs={'images': tensor_info_x} określa informację o tensorze wejściowym.

    • outputs={'scores': tensor_info_y} określa informacje o tensorze wyników.

    • method_name to metoda używana do wnioskowania. W przypadku żądań przewidywania należy ustawić na tensorflow/serving/predict . Aby zapoznać się z innymi nazwami metod, zobacz plik podpis_constants.py i powiązaną dokumentację interfejsu API TensorFlow .

Należy zauważyć, że tensor_info_x i tensor_info_y mają zdefiniowaną tutaj strukturę bufora protokołu tensorflow::TensorInfo . Aby łatwo tworzyć informacje o tensorze, interfejs API TensorFlow SavedModel udostępnia również plik utils.py z powiązaną dokumentacją interfejsu API TensorFlow .

Należy również pamiętać, że images i scores są nazwami aliasów tensora. Mogą to być dowolne unikalne ciągi znaków i staną się logicznymi nazwami tensora x i y , do których będziesz się odwoływać w przypadku wiązania tensora podczas późniejszego wysyłania żądań przewidywania.

Na przykład, jeśli x odnosi się do tensora o nazwie „long_tensor_name_foo”, a y odnosi się do tensora o nazwie „generated_tensor_name_bar”, builder zapisze nazwę logiczną tensora na mapowanie prawdziwej nazwy („images” -> „long_tensor_name_foo”) i („wyniki ' -> 'generated_tensor_name_bar'). Dzięki temu użytkownik może podczas wnioskowania odwoływać się do tych tensorów za pomocą ich nazw logicznych.

Uruchommy to!

Po pierwsze, jeśli jeszcze tego nie zrobiłeś, sklonuj to repozytorium na swój komputer lokalny:

git clone https://github.com/tensorflow/serving.git
cd serving

Wyczyść katalog eksportu, jeśli już istnieje:

rm -rf /tmp/mnist

Teraz wytrenujmy model:

tools/run_in_docker.sh python tensorflow_serving/example/mnist_saved_model.py \
  /tmp/mnist

Powinno to dać wynik wyglądający następująco:

Training model...

...

Done training!
Exporting trained model to models/mnist
Done exporting!

Przyjrzyjmy się teraz katalogowi eksportu.

$ ls /tmp/mnist
1

Jak wspomniano powyżej, zostanie utworzony podkatalog do eksportu każdej wersji modelu. FLAGS.model_version ma domyślną wartość 1, dlatego tworzony jest odpowiedni podkatalog 1 .

$ ls /tmp/mnist/1
saved_model.pb variables

Każdy podkatalog wersji zawiera następujące pliki:

  • saved_model.pb to serializowany tensorflow::SavedModel. Zawiera jedną lub więcej definicji wykresów modelu, a także metadane modelu, takie jak podpisy.

  • variables to pliki przechowujące serializowane zmienne wykresów.

Dzięki temu Twój model TensorFlow zostanie wyeksportowany i gotowy do załadowania!

Załaduj wyeksportowany model za pomocą standardowego serwera TensorFlow ModelServer

Użyj obrazu obsługującego Docker, aby łatwo załadować model do wyświetlenia:

docker run -p 8500:8500 \
--mount type=bind,source=/tmp/mnist,target=/models/mnist \
-e MODEL_NAME=mnist -t tensorflow/serving &

Przetestuj serwer

Do przetestowania serwera możemy użyć dostarczonego narzędzia mnist_client . Klient pobiera dane testowe MNIST, wysyła je jako żądania do serwera i oblicza współczynnik błędów wnioskowania.

tools/run_in_docker.sh python tensorflow_serving/example/mnist_client.py \
  --num_tests=1000 --server=127.0.0.1:8500

To powinno wypisać coś takiego

    ...
    Inference error rate: 11.13%

Oczekujemy dokładności wyszkolonego modelu Softmax na poziomie około 90%, a dla pierwszych 1000 obrazów testowych uzyskujemy współczynnik błędów wnioskowania na poziomie 11%. Potwierdza to, że serwer pomyślnie ładuje i uruchamia przeszkolony model!