Ajuda a proteger a Grande Barreira de Corais com TensorFlow em Kaggle Junte Desafio

Criação de um módulo que descobre novos caminhos de serviço

Este documento explica como estender o TensorFlow Serving para monitorar diferentes sistemas de armazenamento para descobrir novos (versões de) modelos ou dados para servir. Em particular, ele aborda como criar e usar um módulo que monitora um caminho do sistema de armazenamento para o aparecimento de novos subcaminhos, onde cada subcaminho representa uma nova versão servível para carregar. Esse tipo de módulo é chamado de Source<StoragePath> , porque emite objetos do tipo StoragePath (typedefed a string ). Ele pode ser composto com um SourceAdapter que cria um que possa ser veiculado Loader de um determinado caminho que as descobertas de origem.

Primeiro, uma nota sobre generalidade

O uso de caminhos como identificadores para dados servíveis não é necessário; apenas ilustra uma maneira de ingerir servables no sistema. Mesmo que seu ambiente não encapsule dados que podem ser servidos em caminhos, este documento irá familiarizá-lo com as principais abstrações. Você tem a opção de criar Source<T> e SourceAdapter<T1, T2> módulos para tipos que se adequar ao seu ambiente (por exemplo RPC ou pub / sub mensagens, registros de banco de dados), ou simplesmente para criar um monolítico Source<std::unique_ptr<Loader>> que emite carregadores veiculáveis diretamente.

Obviamente, seja qual for o tipo de dados que sua fonte emite (sejam caminhos POSIX, caminhos do Google Cloud Storage ou identificadores RPC), deve haver módulo (s) de acompanhamento que seja capaz de carregar servables com base nisso. Esses módulos são chamados SourceAdapters . Criando um personalizado é descrito na personalizado veiculável documento. O TensorFlow Serving vem com um para instanciar sessões do TensorFlow com base em caminhos em sistemas de arquivos compatíveis com o TensorFlow. Pode-se adicionar suporte para sistemas de arquivos adicionais para TensorFlow estendendo o RandomAccessFile abstração ( tensorflow/core/public/env.h ).

Este documento se concentra na criação de uma fonte que emite caminhos em um sistema de arquivos compatível com o TensorFlow. Ele termina com um passo a passo de como usar sua fonte em conjunto com módulos pré-existentes para atender aos modelos do TensorFlow.

Criando sua fonte

Temos uma implementação de referência de uma Source<StoragePath> , chamado FileSystemStoragePathSource (em sources/storage_path/file_system_storage_path_source* ). FileSystemStoragePathSource monitora um caminho de sistema de arquivo específico, relógios para sub-diretórios numéricos, e relata a última delas como a versão que aspira a carga. Este documento orienta através dos aspectos mais salientes do FileSystemStoragePathSource . Você pode achar que é conveniente para fazer uma cópia de FileSystemStoragePathSource e, em seguida, modificá-lo para atender às suas necessidades.

Primeiro, FileSystemStoragePathSource implementa a Source<StoragePath> API, que é uma especialização da Source<T> API com T obrigado a StoragePath . O API é composto por um único método SetAspiredVersionsCallback() , que fornece um fecho a fonte pode invocar a comunicar que quer um conjunto particular de versões veiculáveis para ser carregado.

FileSystemStoragePathSource usa os aspiravam-versões retorno de chamada de uma forma muito simples: ele inspeciona periodicamente o sistema de arquivos (fazendo um ls , essencialmente), e, se encontrar um ou mais caminhos que se parecem com versões veiculáveis determina qual é a versão mais recente e invoca o retorno de chamada com uma lista de tamanho um contendo apenas essa versão (na configuração padrão). Então, em determinado momento FileSystemStoragePathSource pedidos no máximo um que possa ser veiculado a ser carregado, e sua implementação aproveita a idempotência da chamada de retorno para manter-se apátrida (não há nenhum dano em invocar o callback repetidamente com os mesmos argumentos).

FileSystemStoragePathSource tem uma fábrica estática inicialização (o Create() método), que leva uma mensagem de protocolo de configuração. A mensagem de configuração inclui detalhes como o caminho base para monitorar e o intervalo de monitoramento. Também inclui o nome do fluxo de serviço a ser emitido. (Abordagens alternativas podem extrair o nome do fluxo de serviço do caminho de base, para emitir vários fluxos de serviço com base na observação de uma hierarquia de diretório mais profunda; essas variantes estão além do escopo da implementação de referência.)

A maior parte da implementação consiste em um encadeamento que examina periodicamente o sistema de arquivos, junto com alguma lógica para identificar e classificar quaisquer subcaminhos numéricos que descobrir. O fio é lançado dentro SetAspiredVersionsCallback() (não em Create() ) porque esse é o ponto em que a fonte deve "começar" e sabe para onde enviar solicitações de versão aspirava.

Usando sua fonte para carregar sessões do TensorFlow

Você provavelmente vai querer usar o seu módulo de fonte nova em conjunto com SavedModelBundleSourceAdapter ( servables/tensorflow/saved_model_bundle_source_adapter* ), que irá interpretar cada caminho de seus emite source como uma exportação TensorFlow, e converter cada caminho para um carregador para uma TensorFlow SavedModelBundle que possa ser veiculado. Você provavelmente vai ligar o SavedModelBundle adaptador em uma AspiredVersionsManager , que cuida de realmente carregar e servir os servables. Uma boa ilustração de encadeamento esses três tipos de módulos em conjunto para obter uma biblioteca de servidor de trabalho é encontrado em servables/tensorflow/simple_servers.cc . Aqui está um passo a passo do fluxo do código principal (com tratamento de erros ruim; o código real deve ser mais cuidadoso):

Primeiro, crie um gerente:

std::unique_ptr<AspiredVersionsManager> manager = ...;

Em seguida, crie um SavedModelBundle adaptador de fonte e conecte-o ao gerente:

std::unique_ptr<SavedModelBundleSourceAdapter> bundle_adapter;
SavedModelBundleSourceAdapterConfig config;
// ... populate 'config' with TensorFlow options.
TF_CHECK_OK(SavedModelBundleSourceAdapter::Create(config, &bundle_adapter));
ConnectSourceToTarget(bundle_adapter.get(), manager.get());

Por último, criar sua fonte caminho e conecte-o ao SavedModelBundle adaptador:

auto your_source = new YourPathSource(...);
ConnectSourceToTarget(your_source, bundle_adapter.get());

O ConnectSourceToTarget() função (definido no core/target.h ) meramente invoca SetAspiredVersionsCallback() para conectar uma Source<T> para um Target<T> (a Target é um módulo que as capturas aspirava-versão pedidos, ou seja, um adaptador ou gerente )