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ż usługę TensorFlow Serving i chcesz dowiedzieć się więcej o działaniu wewnętrznych elementów serwera, zapoznaj się z zaawansowanym samouczkiem TensorFlow Serving .
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. Eksportując nowszą wersję 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 używać wykresu do serwowania, używamy taguserve
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 budowaniapredict_signature
iclassification_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ć natensorflow/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 („scores” ' -> '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
Możemy użyć dostarczonego narzędzia mnist_client do przetestowania serwera. 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!