O Dia da Comunidade de ML é dia 9 de novembro! Junte-nos para atualização de TensorFlow, JAX, e mais Saiba mais

Servindo um modelo do TensorFlow

Este tutorial mostra como usar os componentes do TensorFlow Serving para exportar um modelo treinado do TensorFlow e usar o tensorflow_model_server padrão para servi-lo. Se você já estiver familiarizado com o TensorFlow Serving e quiser saber mais sobre como funcionam os componentes internos do servidor, consulte o tutorial avançado do TensorFlow Serving .

Este tutorial usa um modelo simples de regressão Softmax que classifica dígitos escritos à mão. É muito semelhante ao apresentado no tutorial do TensorFlow sobre classificação de imagens usando o conjunto de dados Fashion MNIST .

O código deste tutorial consiste em duas partes:

  • Um arquivo Python, mnist_saved_model.py , que treina e exporta o modelo.

  • Um binário ModelServer que pode ser instalado usando Apt ou compilado de um arquivo C ++ ( main.cc ). O TensorFlow Serving ModelServer descobre novos modelos exportados e executa um serviço gRPC para atendê-los.

Antes de começar, primeiro instale o Docker .

Treine e exporte o modelo TensorFlow

Para a fase de formação, o gráfico TensorFlow é lançado em TensorFlow sessão sess , com o tensor de entrada (imagem) como x e tensor de saída (pontuação Softmax) como y .

Em seguida, usamos o módulo SavedModelBuilder do TensorFlow para exportar o modelo. SavedModelBuilder salva um "instantâneo" do modelo treinado em um armazenamento confiável para que possa ser carregado posteriormente para inferência.

Para obter detalhes sobre o formato SavedModel, consulte a documentação em SavedModel README.md .

Em mnist_saved_model.py , o seguinte é um pequeno trecho de código para ilustrar o processo geral de salvar um modelo em disco.

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__ usa o seguinte argumento:

  • export_path é o caminho do diretório de exportação.

SavedModelBuilder criará o diretório se ele não existir. No exemplo, concatenamos o argumento da linha de comando e FLAGS.model_version para obter o diretório de exportação. FLAGS.model_version especifica a versão do modelo. Você deve especificar um valor inteiro maior ao exportar uma versão mais recente do mesmo modelo. Cada versão será exportada para um subdiretório diferente no caminho fornecido.

Você pode adicionar meta gráfico e variáveis ​​ao construtor usando SavedModelBuilder.add_meta_graph_and_variables() com os seguintes argumentos:

  • sess é a sessão do TensorFlow que contém o modelo treinado que você está exportando.

  • tags é o conjunto de tags com o qual salvar o meta gráfico. Nesse caso, como pretendemos usar o gráfico na veiculação, usamos a tag serve das constantes de tag SavedModel predefinidas. Para obter mais detalhes, consulte tag_constants.py e a documentação da API TensorFlow relacionada .

  • signature_def_map especifica o mapa da chave fornecida pelo usuário para uma assinatura para um tensorflow :: SignatureDef para adicionar ao meta gráfico. A assinatura especifica que tipo de modelo está sendo exportado e os tensores de entrada / saída aos quais vincular ao executar a inferência.

    A chave de assinatura especial serving_default especifica a assinatura de serviço padrão. A chave padrão de serviço de assinatura def, junto com outras constantes relacionadas às assinaturas, são definidas como parte das constantes de assinatura do SavedModel. Para obter mais detalhes, consulte signature_constants.py e a documentação da API TensorFlow relacionada .

    Além disso, para ajudar a assinatura construção defs facilmente, a API SavedModel fornece utils def assinatura .. Especificamente, no original mnist_saved_model.py arquivo, usamos signature_def_utils.build_signature_def() para construir predict_signature e classification_signature .

    Como um exemplo de como o predict_signature é definido, o utilitário usa os seguintes argumentos:

    • inputs={'images': tensor_info_x} especifica a informação do tensor de entrada.

    • outputs={'scores': tensor_info_y} especifica a informação do tensor de score.

    • method_name é o método usado para a inferência. Para solicitações de previsão, deve ser definido como tensorflow/serving/predict . Para outros nomes de método, consulte signature_constants.py e a documentação da API TensorFlow relacionada .

Observe que tensor_info_x e tensor_info_y têm a estrutura do buffer de protocolo tensorflow::TensorInfo definida aqui . Para criar facilmente informações sobre tensor, a API TensorFlow SavedModel também fornece utils.py , com a documentação da API TensorFlow relacionada .

Além disso, observe que as images e scores são nomes de alias de tensor. Eles podem ser o que cordas única que você quer, e eles vão se tornar os nomes lógicos de tensor x e y que você consulte para a ligação ao enviar solicitações de previsão mais tarde tensor.

Por exemplo, se x se refere ao tensor com o nome 'long_tensor_name_foo' y se refere ao tensor com o nome 'generated_tensor_name_bar', o builder armazenará o nome lógico do tensor no mapeamento do nome real ('images' -> 'long_tensor_name_foo') e ('scores '->' generated_tensor_name_bar '). Isso permite que o usuário se refira a esses tensores com seus nomes lógicos ao executar a inferência.

Vamos rodar!

Primeiro, se você ainda não fez isso, clone este repositório em sua máquina local:

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

Limpe o diretório de exportação se ele já existir:

rm -rf /tmp/mnist

Agora vamos treinar o modelo:

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

Isso deve resultar em uma saída semelhante a:

Training model...

...

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

Agora, vamos dar uma olhada no diretório de exportação.

$ ls /tmp/mnist
1

Conforme mencionado acima, um subdiretório será criado para exportar cada versão do modelo. FLAGS.model_version tem o valor padrão 1, portanto, o subdiretório 1 é criado.

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

Cada subdiretório de versão contém os seguintes arquivos:

  • saved_model.pb é o tensorflow serializado :: SavedModel. Inclui uma ou mais definições de gráfico do modelo, bem como metadados do modelo, como assinaturas.

  • variables são arquivos que contêm as variáveis ​​serializadas dos gráficos.

Com isso, seu modelo TensorFlow é exportado e pronto para ser carregado!

Carregue o modelo exportado com o TensorFlow ModelServer padrão

Use uma imagem de veiculação do Docker para carregar facilmente o modelo para veiculação:

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

Teste o servidor

Podemos usar o utilitário mnist_client fornecido para testar o servidor. O cliente baixa os dados de teste MNIST, os envia como solicitações ao servidor e calcula a taxa de erro de inferência.

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

Isso deve resultar em algo como

    ...
    Inference error rate: 11.13%

Esperamos cerca de 90% de precisão para o modelo Softmax treinado e obtemos 11% de taxa de erro de inferência para as primeiras 1000 imagens de teste. Isso confirma que o servidor carrega e executa o modelo treinado com sucesso!