Cette page a été traduite par l'API Cloud Translation.
Switch to English

Servir un modèle TensorFlow

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à familiarisé avec TensorFlow Serving et que vous souhaitez en savoir plus sur le fonctionnement des composants internes du serveur, consultez le didacticiel avancé TensorFlow Serving .

Ce didacticiel utilise le modèle de régression Softmax simple introduit dans le didacticiel TensorFlow pour la classification d'images manuscrites (données MNIST). Si vous ne savez pas ce qu'est TensorFlow ou MNIST, consultez le didacticiel MNIST pour les débutants en ML .

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 installé à l'aide d'Apt ou compilé à partir d'un fichier C ++ ( main.cc ). Le TensorFlow Serving ModelServer découvre les nouveaux modèles exportés et exécute un service gRPC pour les servir.

Avant de commencer, installez d' abord Docker .

Former et exporter le modèle TensorFlow

Comme vous pouvez le voir dans mnist_saved_model.py , la formation se fait de la même manière que dans le didacticiel MNIST For ML Beginners . Le graphique des tensorflow est lancé en session tensorflow sess , avec le tenseur d'entrée (image) en tant que x et tenseur de sortie (score Softmax) sous la forme 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é plus tard pour l'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 , voici 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(
      compat.as_bytes(export_path_base),
      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.saved_model.tag_constants.SERVING],
      signature_def_map={
           'predict_images':
               prediction_signature,
           signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY:
               classification_signature,
      },
      main_op=tf.tables_initializer())
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 donné.

Vous pouvez ajouter un méta-graphique et des variables au générateur en utilisant 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 des balises avec lesquelles enregistrer le méta-graphique. Dans ce cas, puisque nous avons l'intention d'utiliser le graphique lors de la diffusion, nous utilisons la balise de serve partir des constantes de balise SavedModel prédéfinies. Pour plus de détails, consultez tag_constants.py et la documentation relative à l'API TensorFlow .

  • signature_def_map spécifie la carte de la clé fournie par l'utilisateur pour une signature à un tensorflow :: SignatureDef à ajouter au méta-graphe. 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 serving_default 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 relative à l' API TensorFlow 1.0 .

    De plus, pour aider à créer facilement des définitions de signature, l'API SavedModel fournit des définitions de signature . Plus précisément, dans le fichier mnist_saved_model.py d' origine, nous utilisons signature_def_utils.build_signature_def() pour construire predict_signature et classification_signature .

    À titre d'exemple pour la predict_signature , util prend les arguments suivants:

    • inputs={'images': tensor_info_x} spécifie les informations de tenseur d'entrée.

    • outputs={'scores': tensor_info_y} spécifie les informations du tenseur des scores.

    • method_name est la méthode utilisée pour l'inférence. Pour les demandes de prédiction, il doit être défini sur tensorflow/serving/predict . Pour les autres noms de méthode, consultez signature_constants.py et la documentation relative à l' API TensorFlow 1.0 .

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 les tenseurs, l'API TensorFlow SavedModel fournit également utils.py , avec la documentation relative à l'API TensorFlow 1.0 .

Notez également que les images et les scores sont des noms d'alias de tenseurs. Ils peuvent être les chaînes uniques que vous souhaitez, et ils deviendront les noms logiques du tenseur x et y auxquels vous vous référez pour la liaison de tenseur lors de l'envoi des demandes de prédiction plus tard.

Par exemple, si x fait référence au tenseur avec le nom 'long_tensor_name_foo' et y fait référence au tenseur avec le nom 'generated_tensor_name_bar', le builder stockera le nom logique du tenseur avec le mappage de 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.

Lançons-le!

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înons maintenant le modèle:

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

Cela devrait aboutir à une sortie 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 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 :: SavedModel sérialisé. Il comprend une ou plusieurs définitions de graphes 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 le 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 générer quelque chose comme

    ...
    Inference error rate: 11.13%

Nous prévoyons une précision d'environ 90% pour le modèle Softmax formé et nous obtenons un taux d'erreur d'inférence de 11% pour les 1000 premières images de test. Cela confirme que le serveur se charge et exécute le modèle entraîné avec succès!