Ce didacticiel vous montre comment utiliser les composants TensorFlow Serving pour exporter un modèle TensorFlow entraîné et utiliser le tensorflow_model_server standard pour le servir. Si vous êtes déjà familier avec TensorFlow Serving et que vous souhaitez en savoir plus sur le fonctionnement interne du serveur, consultez le didacticiel avancé TensorFlow Serving .
Ce didacticiel utilise un modèle de régression Softmax simple qui classe les chiffres manuscrits. Il est très similaire à celui introduit dans le didacticiel TensorFlow sur la classification d'images à l'aide de l'ensemble de données Fashion MNIST .
Le code de ce didacticiel se compose de deux parties :
Un fichier Python, mnist_saved_model.py , qui entraîne et exporte le modèle.
Un binaire ModelServer qui peut être soit installé à l'aide d'Apt, soit compilé à partir d'un fichier C++ ( main.cc ). Le TensorFlow Serving ModelServer découvre de nouveaux modèles exportés et exécute un service gRPC pour les servir.
Avant de commencer, installez d'abord Docker .
Entraîner et exporter le modèle TensorFlow
Pour la phase de formation, le graphique TensorFlow est lancé dans la session TensorFlow sess
, avec le tenseur d'entrée (image) comme x
et le tenseur de sortie (score Softmax) comme y
.
Ensuite, nous utilisons le module SavedModelBuilder de TensorFlow pour exporter le modèle. SavedModelBuilder
enregistre un « instantané » du modèle entraîné dans un stockage fiable afin qu'il puisse être chargé ultérieurement pour inférence.
Pour plus de détails sur le format SavedModel, veuillez consulter la documentation sur SavedModel README.md .
À partir de mnist_saved_model.py , ce qui suit est un court extrait de code pour illustrer le processus général d'enregistrement d'un modèle sur le disque.
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__
prend l'argument suivant :
-
export_path
est le chemin du répertoire d'exportation.
SavedModelBuilder
créera le répertoire s'il n'existe pas. Dans l'exemple, nous concaténons l'argument de ligne de commande et FLAGS.model_version
pour obtenir le répertoire d'exportation. FLAGS.model_version
spécifie la version du modèle. Vous devez spécifier une valeur entière plus grande lors de l'exportation d'une version plus récente du même modèle. Chaque version sera exportée vers un sous-répertoire différent sous le chemin indiqué.
Vous pouvez ajouter un méta-graphique et des variables au générateur à l'aide de SavedModelBuilder.add_meta_graph_and_variables()
avec les arguments suivants :
sess
est la session TensorFlow qui contient le modèle entraîné que vous exportez.tags
est l'ensemble de balises avec lesquelles enregistrer le méta-graphe. Dans ce cas, puisque nous avons l'intention d'utiliser le graphique pour le service, nous utilisons la baliseserve
à partir des constantes prédéfinies de la balise SavedModel. Pour plus de détails, consultez tag_constants.py et la documentation associée de l'API TensorFlow .signature_def_map
spécifie la carte de la clé fournie par l'utilisateur pour une signature vers un tensorflow::SignatureDef à ajouter au méta-graphe. La signature spécifie le type de modèle exporté et les tenseurs d'entrée/sortie auxquels se lier lors de l'exécution de l'inférence.La clé de signature spéciale
serving_default
spécifie la signature de diffusion par défaut. La clé de définition de signature de service par défaut, ainsi que d'autres constantes liées aux signatures, sont définies dans le cadre des constantes de signature SavedModel. Pour plus de détails, consultez signature_constants.py et la documentation associée de l'API TensorFlow .De plus, pour aider à créer facilement des définitions de signature, l'API SavedModel fournit des utilitaires de définition de signature .. Plus précisément, dans le fichier mnist_saved_model.py d'origine, nous utilisons
signature_def_utils.build_signature_def()
pour créerpredict_signature
etclassification_signature
.À titre d'exemple de la façon dont
predict_signature
est défini, l'utilitaire prend les arguments suivants :inputs={'images': tensor_info_x}
spécifie les informations du tenseur d'entrée.outputs={'scores': tensor_info_y}
spécifie les informations sur le tenseur des scores.method_name
est la méthode utilisée pour l'inférence. Pour les requêtes de prédiction, il doit être défini surtensorflow/serving/predict
. Pour d'autres noms de méthodes, consultez signature_constants.py et la documentation associée de l'API TensorFlow .
Notez que tensor_info_x
et tensor_info_y
ont la structure du tampon de protocole tensorflow::TensorInfo
définie ici . Pour créer facilement des informations sur le tensor, l'API TensorFlow SavedModel fournit également utils.py , avec la documentation associée de l'API TensorFlow .
Notez également que images
et scores
sont des noms d'alias de tenseur. Il peut s'agir de n'importe quelle chaîne unique de votre choix, et elles deviendront les noms logiques des tenseurs x
et y
auxquels vous faites référence pour la liaison du tenseur lors de l'envoi ultérieur de requêtes de prédiction.
Par exemple, si x
fait référence au tenseur portant le nom 'long_tensor_name_foo' et y
fait référence au tenseur portant le nom 'generated_tensor_name_bar', builder
stockera le nom logique du tenseur avec le mappage du nom réel ("images" -> "long_tensor_name_foo") et ('scores ' -> 'generated_tensor_name_bar'). Cela permet à l'utilisateur de faire référence à ces tenseurs avec leurs noms logiques lors de l'exécution de l'inférence.
Allons-y !
Tout d'abord, si vous ne l'avez pas encore fait, clonez ce référentiel sur votre machine locale :
git clone https://github.com/tensorflow/serving.git
cd serving
Effacez le répertoire d'exportation s'il existe déjà :
rm -rf /tmp/mnist
Entraîneons maintenant le modèle :
tools/run_in_docker.sh python tensorflow_serving/example/mnist_saved_model.py \
/tmp/mnist
Cela devrait donner un résultat qui ressemble à :
Training model...
...
Done training!
Exporting trained model to models/mnist
Done exporting!
Jetons maintenant un œil au répertoire d'exportation.
$ ls /tmp/mnist
1
Comme mentionné ci-dessus, un sous-répertoire sera créé pour exporter chaque version du modèle. FLAGS.model_version
a la valeur par défaut de 1, donc le sous-répertoire correspondant 1
est créé.
$ ls /tmp/mnist/1
saved_model.pb variables
Chaque sous-répertoire de version contient les fichiers suivants :
saved_model.pb
est le tensorflow sérialisé :: SavedModel. Il comprend une ou plusieurs définitions graphiques du modèle, ainsi que des métadonnées du modèle telles que des signatures.variables
sont des fichiers contenant les variables sérialisées des graphiques.
Avec cela, votre modèle TensorFlow est exporté et prêt à être chargé !
Charger le modèle exporté avec TensorFlow ModelServer standard
Utilisez une image de diffusion Docker pour charger facilement le modèle à diffuser :
docker run -p 8500:8500 \
--mount type=bind,source=/tmp/mnist,target=/models/mnist \
-e MODEL_NAME=mnist -t tensorflow/serving &
Testez le serveur
Nous pouvons utiliser l'utilitaire mnist_client fourni pour tester le serveur. Le client télécharge les données de test MNIST, les envoie sous forme de requêtes au serveur et calcule le taux d'erreur d'inférence.
tools/run_in_docker.sh python tensorflow_serving/example/mnist_client.py \
--num_tests=1000 --server=127.0.0.1:8500
Cela devrait produire quelque chose comme
...
Inference error rate: 11.13%
Nous nous attendons à une précision d'environ 90 % pour le modèle Softmax entraîné et nous obtenons un taux d'erreur d'inférence de 11 % pour les 1 000 premières images de test. Cela confirme que le serveur charge et exécute le modèle entraîné avec succès !